ZGlmZiAtLWdpdCBhLy5naXRhdHRyaWJ1dGVzIGIvLmdpdGF0dHJpYnV0ZXMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTAyY2Q1OQotLS0gL2Rldi9udWxsCisrKyBiLy5naXRhdHRyaWJ1dGVzCkBAIC0wLDAgKzEsMTcgQEAKKyouYXIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiaW5hcnkKKyouYXJqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiaW5hcnkKKyouamF2YSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0IGRpZmY9amF2YQorKi5tZCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHQKKyoudHh0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0CisqLnhtbCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dAorKi55bWwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHQKKyouenN0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiaW5hcnkKKy5naXRhdHRyaWJ1dGVzICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0CisjIFRoZXNlIG11c3QgYmUgaWRlbnRpY2FsIHRvIHRoZSBjb3BpZXMgaW4gU0hSVU5LLlpJUAorc3JjL3Rlc3QvcmVzb3VyY2VzL3Rlc3QxLnhtbCAgICAgICAgICAgIGVvbD1sZgorc3JjL3Rlc3QvcmVzb3VyY2VzL3Rlc3QyLnhtbCAgICAgICAgICAgIGVvbD1sZgorc3JjL3Rlc3QvcmVzb3VyY2VzL3Rlc3QzLnhtbCAgICAgICAgICAgIGVvbD1sZgorc3JjL3Rlc3QvcmVzb3VyY2VzL3Rlc3Q0LnhtbCAgICAgICAgICAgIGVvbD1sZgorc3JjL3Rlc3QvcmVzb3VyY2VzL3Rlc3Q/d2l0aD9zcGFjZXMudHh0IGVvbD1sZgorc3JjL3Rlc3QvcmVzb3VyY2VzL3Rlc3QudHh0ICAgICAgICAgICAgIGVvbD1sZgorc3JjL3Rlc3QvcmVzb3VyY2VzL0NPTVBSRVNTLTM4MC1pbnB1dCAgIGJpbmFyeQpkaWZmIC0tZ2l0IGEvLmdpdGlnbm9yZSBiLy5naXRpZ25vcmUKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTg2ODM4NQotLS0gL2Rldi9udWxsCisrKyBiLy5naXRpZ25vcmUKQEAgLTAsMCArMSw5IEBACit0YXJnZXQNCisucHJvamVjdA0KKy5jbGFzc3BhdGgNCisuc2V0dGluZ3MNCisuaWRlYQ0KKyouaW1sDQorKn4NCisvLmV4dGVybmFsVG9vbEJ1aWxkZXJzLworL21hdmVuLWVjbGlwc2UueG1sCmRpZmYgLS1naXQgYS8ubXZuL3dyYXBwZXIvbWF2ZW4td3JhcHBlci5qYXIgYi8ubXZuL3dyYXBwZXIvbWF2ZW4td3JhcHBlci5qYXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWNjODRlYQotLS0gL2Rldi9udWxsCisrKyBiLy5tdm4vd3JhcHBlci9tYXZlbi13cmFwcGVyLmphcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS8ubXZuL3dyYXBwZXIvbWF2ZW4td3JhcHBlci5wcm9wZXJ0aWVzIGIvLm12bi93cmFwcGVyL21hdmVuLXdyYXBwZXIucHJvcGVydGllcwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NmJiMDE2Ci0tLSAvZGV2L251bGwKKysrIGIvLm12bi93cmFwcGVyL21hdmVuLXdyYXBwZXIucHJvcGVydGllcwpAQCAtMCwwICsxIEBACitkaXN0cmlidXRpb25Vcmw9aHR0cHM6Ly9yZXBvMS5tYXZlbi5vcmcvbWF2ZW4yL29yZy9hcGFjaGUvbWF2ZW4vYXBhY2hlLW1hdmVuLzMuNS4wL2FwYWNoZS1tYXZlbi0zLjUuMC1iaW4uemlwClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvLnRyYXZpcy55bWwgYi8udHJhdmlzLnltbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hZmNmZjNlCi0tLSAvZGV2L251bGwKKysrIGIvLnRyYXZpcy55bWwKQEAgLTAsMCArMSwzNyBAQAorIyBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyMgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisjIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyMgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyMgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyMgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyMKKyMgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorIworIyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisjIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisjIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisjIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorCitzdWRvOiBmYWxzZQorbGFuZ3VhZ2U6IGphdmEKKworamRrOgorICAtIG9wZW5qZGs3CisgIC0gb3BlbmpkazgKKyAgLSBvcmFjbGVqZGs4CisgIC0gb3JhY2xlamRrOQorICAtIG9yYWNsZWpkazEwCisKK2NhY2hlOgorICBkaXJlY3RvcmllczoKKyAgICAtICRIT01FLy5tMgorICAgIC0gLm12bgorIyBkb24ndCBydW4gbXZuIGluc3RhbGwgYmVmb3JlIGJ1aWxkaW5nCitpbnN0YWxsOiB0cnVlCisKKyMgZG8gYWxsIHRoZSBidWlsZGluZyBhbmQgdGVzdGluZyBpbiBhIHNpbmdsZSBwaGFzZSwgaW5zdGVhZCBvZiBjb21waWxpbmcgZXZlcnl0aGluZyB0aHJlZSB0aW1lcworIyBhbmQgcnVubmluZyBhbGwgdGVzdHMgdHdpY2UuCisKK3NjcmlwdDoKKyAgIC0gLi9tdm53IGNsZWFuIGFwYWNoZS1yYXQ6Y2hlY2sgdGVzdCBqYWNvY286cmVwb3J0IGNvdmVyYWxsczpyZXBvcnQgLVB0cmF2aXMtamFjb2NvCmRpZmYgLS1naXQgYS9CVUlMRElORy5tZCBiL0JVSUxESU5HLm1kCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjYxNmUyNzEKLS0tIC9kZXYvbnVsbAorKysgYi9CVUlMRElORy5tZApAQCAtMCwwICsxLDU1IEBACis8IS0tLQorIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKworICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisKKyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCistLT4KKyMgQnVpbGRpbmcgQXBhY2hlIENvbW1vbnMgQ29tcHJlc3MKKworSW4gb3JkZXIgdG8gYnVpbGQgQ29tbW9ucyBDb21wcmVzcyBhIEpESyBpbXBsZW1lbnRhdGlvbiAxLjcgb3IgaGlnaGVyCithbmQgQXBhY2hlIE1hdmVuIDMueCBhcmUgcmVxdWlyZWQuCisKK1RvIGluc3RhbGwgdGhlIGphcnMgaW50byB5b3VyIGxvY2FsIE1hdmVuIHJlcG9zaXRvcnkgc2ltcGx5IHJ1bgorCisgICAgbXZuIGNsZWFuIGluc3RhbGwKKword2hpY2ggd2lsbCBhbHNvIHJ1biB0aGUgdW5pdCB0ZXN0cy4KKworU29tZSB0ZXN0cyBhcmUgb25seSBydW4gd2hlbiBzcGVjaWZpYyBwcm9maWxlcyBhcmUgZW5hYmxlZCwgdGhlc2UKK3Rlc3RzIHJlcXVpcmUgYSBsb3Qgb2YgZGlzayBzcGFjZSBhcyB0aGV5IHRlc3QgYmVoYXZpb3IgZm9yIHZlcnkgbGFyZ2UKK2FyY2hpdmVzLgorCisgICAgbXZuIHRlc3QgLVBydW4tdGFyaXQKKworcnVucyB0ZXN0cyBmb3IgdGFyIGFyY2hpdmVzIGFuZCByZXF1aXJlcyBtb3JlIHRoYW4gOEdpQiBvZiBkaXNrIHNwYWNlLgorCisgICAgbXZuIHRlc3QgLVBydW4temlwaXQKKworcnVucyB0ZXN0cyBmb3IgemlwIGFyY2hpdmVzIHRoYXQgcmVxdWlyZSB1cCB0byAyMCBHaUIgb2YgZGlzaworc3BhY2UuIEluIGFkZGl0aW9uIHRoZSB0ZXN0cyB3aWxsIHJ1biBmb3IgYSBsb25nIHRpbWUgKG1vcmUgdGhlbiB0ZW4KK21pbnV0ZXMsIG1heWJlIGV2ZW4gbG9uZ2VyIGRlcGVuZGluZyBvbiB5b3VyIGhhcmR3YXJlKSBhbmQgaGVhdmlseQorbG9hZCB0aGUgQ1BVIGF0IHRpbWVzLgorCisjIyBCdWlsZGluZyB0aGUgU2l0ZQorCitUaGUgc2l0ZSBidWlsZCBwcm9kdWNlcyBsaWNlbnNlIHJlbGVhc2UgYXVkaXQgKGFrYSBSQVQpIHJlcG9ydHMgYXMKK3dlbGwgYXMgUE1EIGFuZCBmaW5kYnVncyByZXBvcnRzLiBDbGlyciBkaWRuJ3Qgd29yayBmb3IgdXMgYW55bW9yZSBzbword2Ugc3dpdGNoZWQgdG8gamFwaWNtcCwgdGhlIHNhbWUgaXMgdHJ1ZSBmb3IgQ29iZXJ0dXJhIHdoaWNoIHdlIGhhZCB0bworcmVwbGFjZSB3aXRoIGphY29jby4KKworamFwaWNtcCByZXF1aXJlcyB0aGUgamFyIHRvIGJlIHByZXNlbnQgd2hlbiB0aGUgc2l0ZSBpcyBidWlsdCwKK3RoZXJlZm9yZSB0aGUgcGFja2FnZSBnb2FsIG11c3QgYmUgZXhlY3V0ZWQgYmVmb3JlIGNyZWF0aW5nIHRoZSBzaXRlLgorCisgICAgbXZuIHBhY2thZ2Ugc2l0ZSAtUGphY29jbworCitidWlsZHMgdGhlIHNpdGUuCmRpZmYgLS1naXQgYS9DT05UUklCVVRJTkcubWQgYi9DT05UUklCVVRJTkcubWQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWFhMmM4NwotLS0gL2Rldi9udWxsCisrKyBiL0NPTlRSSUJVVElORy5tZApAQCAtMCwwICsxLDExNSBAQAorPCEtLS0KKyBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisKKyAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorCisgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorLS0+Cis8IS0tLQorICs9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09KworIHwqKioqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKioqfAorIHwqKioqICAgICAgVEhJUyBGSUxFIElTIEdFTkVSQVRFRCBCWSBUSEUgQ09NTU9OUyBCVUlMRCBQTFVHSU4gICAgICAqKioqfAorIHwqKioqICAgICAgICAgICAgICAgICAgICBETyBOT1QgRURJVCBESVJFQ1RMWSAgICAgICAgICAgICAgICAgICAgICAqKioqfAorIHwqKioqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKioqfAorICs9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09KworIHwgVEVNUExBVEUgRklMRTogY29udHJpYnV0aW5nLW1kLXRlbXBsYXRlLm1kICAgICAgICAgICAgICAgICAgICAgICAgICAgfAorIHwgY29tbW9ucy1idWlsZC1wbHVnaW4vdHJ1bmsvc3JjL21haW4vcmVzb3VyY2VzL2NvbW1vbnMteGRvYy10ZW1wbGF0ZXMgfAorICs9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09KworIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAorIHwgMSkgUmUtZ2VuZXJhdGUgdXNpbmc6IG12biBjb21tb25zOmNvbnRyaWJ1dGluZy1tZCAgICAgICAgICAgICAgICAgICAgfAorIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAorIHwgMikgU2V0IHRoZSBmb2xsb3dpbmcgcHJvcGVydGllcyBpbiB0aGUgY29tcG9uZW50J3MgcG9tOiAgICAgICAgICAgICAgfAorIHwgICAgLSBjb21tb25zLmppcmEuaWQgIChyZXF1aXJlZCwgYWxwaGFiZXRpYywgdXBwZXIgY2FzZSkgICAgICAgICAgICAgfAorIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAorIHwgMykgRXhhbXBsZSBQcm9wZXJ0aWVzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAorIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAorIHwgIDxwcm9wZXJ0aWVzPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAorIHwgICAgPGNvbW1vbnMuamlyYS5pZD5NQVRIPC9jb21tb25zLmppcmEuaWQ+ICAgICAgICAgICAgICAgICAgICAgICAgICAgfAorIHwgIDwvcHJvcGVydGllcz4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAorIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAorICs9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09KworLS0tPgorQ29udHJpYnV0aW5nIHRvIEFwYWNoZSBDb21tb25zIENvbXByZXNzCis9PT09PT09PT09PT09PT09PT09PT09CisKK1lvdSBoYXZlIGZvdW5kIGEgYnVnIG9yIHlvdSBoYXZlIGFuIGlkZWEgZm9yIGEgY29vbCBuZXcgZmVhdHVyZT8gQ29udHJpYnV0aW5nIGNvZGUgaXMgYSBncmVhdCB3YXkgdG8gZ2l2ZSBzb21ldGhpbmcgYmFjayB0bwordGhlIG9wZW4gc291cmNlIGNvbW11bml0eS4gQmVmb3JlIHlvdSBkaWcgcmlnaHQgaW50byB0aGUgY29kZSB0aGVyZSBhcmUgYSBmZXcgZ3VpZGVsaW5lcyB0aGF0IHdlIG5lZWQgY29udHJpYnV0b3JzIHRvCitmb2xsb3cgc28gdGhhdCB3ZSBjYW4gaGF2ZSBhIGNoYW5jZSBvZiBrZWVwaW5nIG9uIHRvcCBvZiB0aGluZ3MuCisKK0dldHRpbmcgU3RhcnRlZAorLS0tLS0tLS0tLS0tLS0tCisKKysgTWFrZSBzdXJlIHlvdSBoYXZlIGEgW0pJUkEgYWNjb3VudF0oaHR0cHM6Ly9pc3N1ZXMuYXBhY2hlLm9yZy9qaXJhLykuCisrIE1ha2Ugc3VyZSB5b3UgaGF2ZSBhIFtHaXRIdWIgYWNjb3VudF0oaHR0cHM6Ly9naXRodWIuY29tL3NpZ251cC9mcmVlKS4KKysgSWYgeW91J3JlIHBsYW5uaW5nIHRvIGltcGxlbWVudCBhIG5ldyBmZWF0dXJlIGl0IG1ha2VzIHNlbnNlIHRvIGRpc2N1c3MgeW91ciBjaGFuZ2VzIG9uIHRoZSBbZGV2IGxpc3RdKGh0dHBzOi8vY29tbW9ucy5hcGFjaGUub3JnL21haWwtbGlzdHMuaHRtbCkgZmlyc3QuIFRoaXMgd2F5IHlvdSBjYW4gbWFrZSBzdXJlIHlvdSdyZSBub3Qgd2FzdGluZyB5b3VyIHRpbWUgb24gc29tZXRoaW5nIHRoYXQgaXNuJ3QgY29uc2lkZXJlZCB0byBiZSBpbiBBcGFjaGUgQ29tbW9ucyBDb21wcmVzcydzIHNjb3BlLgorKyBTdWJtaXQgYSBbSmlyYSBUaWNrZXRdW2ppcmFdIGZvciB5b3VyIGlzc3VlLCBhc3N1bWluZyBvbmUgZG9lcyBub3QgYWxyZWFkeSBleGlzdC4KKyAgKyBDbGVhcmx5IGRlc2NyaWJlIHRoZSBpc3N1ZSBpbmNsdWRpbmcgc3RlcHMgdG8gcmVwcm9kdWNlIHdoZW4gaXQgaXMgYSBidWcuCisgICsgTWFrZSBzdXJlIHlvdSBmaWxsIGluIHRoZSBlYXJsaWVzdCB2ZXJzaW9uIHRoYXQgeW91IGtub3cgaGFzIHRoZSBpc3N1ZS4KKysgRmluZCB0aGUgY29ycmVzcG9uZGluZyBbcmVwb3NpdG9yeSBvbiBHaXRIdWJdKGh0dHBzOi8vZ2l0aHViLmNvbS9hcGFjaGUvP3F1ZXJ5PWNvbW1vbnMtKSwKK1tmb3JrXShodHRwczovL2hlbHAuZ2l0aHViLmNvbS9hcnRpY2xlcy9mb3JrLWEtcmVwby8pIGFuZCBjaGVjayBvdXQgeW91ciBmb3JrZWQgcmVwb3NpdG9yeS4KKworTWFraW5nIENoYW5nZXMKKy0tLS0tLS0tLS0tLS0tCisKKysgQ3JlYXRlIGEgX3RvcGljIGJyYW5jaF8gZm9yIHlvdXIgaXNvbGF0ZWQgd29yay4KKyAgKiBVc3VhbGx5IHlvdSBzaG91bGQgYmFzZSB5b3VyIGJyYW5jaCBvbiB0aGUgYG1hc3RlcmAgb3IgYHRydW5rYCBicmFuY2guCisgICogQSBnb29kIHRvcGljIGJyYW5jaCBuYW1lIGNhbiBiZSB0aGUgSklSQSBidWcgaWQgcGx1cyBhIGtleXdvcmQsIGUuZy4gYENPTVBSRVNTLTEyMy1JbnB1dFN0cmVhbWAuCisgICogSWYgeW91IGhhdmUgc3VibWl0dGVkIG11bHRpcGxlIEpJUkEgaXNzdWVzLCB0cnkgdG8gbWFpbnRhaW4gc2VwYXJhdGUgYnJhbmNoZXMgYW5kIHB1bGwgcmVxdWVzdHMuCisrIE1ha2UgY29tbWl0cyBvZiBsb2dpY2FsIHVuaXRzLgorICAqIE1ha2Ugc3VyZSB5b3VyIGNvbW1pdCBtZXNzYWdlcyBhcmUgbWVhbmluZ2Z1bCBhbmQgaW4gdGhlIHByb3BlciBmb3JtYXQuIFlvdXIgY29tbWl0IG1lc3NhZ2Ugc2hvdWxkIGNvbnRhaW4gdGhlIGtleSBvZiB0aGUgSklSQSBpc3N1ZS4KKyAgKiBlLmcuIGBDT01QUkVTUy0xMjM6IENsb3NlIGlucHV0IHN0cmVhbSBlYXJsaWVyYAorKyBSZXNwZWN0IHRoZSBvcmlnaW5hbCBjb2RlIHN0eWxlOgorICArIE9ubHkgdXNlIHNwYWNlcyBmb3IgaW5kZW50YXRpb24uCisgICsgQ3JlYXRlIG1pbmltYWwgZGlmZnMgLSBkaXNhYmxlIF9PbiBTYXZlXyBhY3Rpb25zIGxpa2UgX1JlZm9ybWF0IFNvdXJjZSBDb2RlXyBvciBfT3JnYW5pemUgSW1wb3J0c18uIElmIHlvdSBmZWVsIHRoZSBzb3VyY2UgY29kZSBzaG91bGQgYmUgcmVmb3JtYXR0ZWQgY3JlYXRlIGEgc2VwYXJhdGUgUFIgZm9yIHRoaXMgY2hhbmdlIGZpcnN0LgorICArIENoZWNrIGZvciB1bm5lY2Vzc2FyeSB3aGl0ZXNwYWNlIHdpdGggYGdpdCBkaWZmYCAtLSBjaGVjayBiZWZvcmUgY29tbWl0dGluZy4KKysgTWFrZSBzdXJlIHlvdSBoYXZlIGFkZGVkIHRoZSBuZWNlc3NhcnkgdGVzdHMgZm9yIHlvdXIgY2hhbmdlcywgdHlwaWNhbGx5IGluIGBzcmMvdGVzdC9qYXZhYC4KKysgUnVuIGFsbCB0aGUgdGVzdHMgd2l0aCBgbXZuIGNsZWFuIHZlcmlmeWAgdG8gYXNzdXJlIG5vdGhpbmcgZWxzZSB3YXMgYWNjaWRlbnRhbGx5IGJyb2tlbi4KKworTWFraW5nIFRyaXZpYWwgQ2hhbmdlcworLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitUaGUgSklSQSB0aWNrZXRzIGFyZSB1c2VkIHRvIGdlbmVyYXRlIHRoZSBjaGFuZ2Vsb2cgZm9yIHRoZSBuZXh0IHJlbGVhc2UuCisKK0ZvciBjaGFuZ2VzIG9mIGEgdHJpdmlhbCBuYXR1cmUgdG8gY29tbWVudHMgYW5kIGRvY3VtZW50YXRpb24sIGl0IGlzIG5vdCBhbHdheXMgbmVjZXNzYXJ5IHRvIGNyZWF0ZSBhIG5ldyB0aWNrZXQgaW4gSklSQS4KK0luIHRoaXMgY2FzZSwgaXQgaXMgYXBwcm9wcmlhdGUgdG8gc3RhcnQgdGhlIGZpcnN0IGxpbmUgb2YgYSBjb21taXQgd2l0aCAnKGRvYyknIGluc3RlYWQgb2YgYSB0aWNrZXQgbnVtYmVyLgorCisKK1N1Ym1pdHRpbmcgQ2hhbmdlcworLS0tLS0tLS0tLS0tLS0tLS0tCisKKysgU2lnbiBhbmQgc3VibWl0IHRoZSBBcGFjaGUgW0NvbnRyaWJ1dG9yIExpY2Vuc2UgQWdyZWVtZW50XVtjbGFdIGlmIHlvdSBoYXZlbid0IGFscmVhZHkuCisgICogTm90ZSB0aGF0IHNtYWxsIHBhdGNoZXMgJiB0eXBpY2FsIGJ1ZyBmaXhlcyBkbyBub3QgcmVxdWlyZSBhIENMQSBhcworICAgIGNsYXVzZSA1IG9mIHRoZSBbQXBhY2hlIExpY2Vuc2VdKGh0dHBzOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAuaHRtbCNjb250cmlidXRpb25zKQorICAgIGNvdmVycyB0aGVtLgorKyBQdXNoIHlvdXIgY2hhbmdlcyB0byBhIHRvcGljIGJyYW5jaCBpbiB5b3VyIGZvcmsgb2YgdGhlIHJlcG9zaXRvcnkuCisrIFN1Ym1pdCBhIF9QdWxsIFJlcXVlc3RfIHRvIHRoZSBjb3JyZXNwb25kaW5nIHJlcG9zaXRvcnkgaW4gdGhlIGBhcGFjaGVgIG9yZ2FuaXphdGlvbi4KKyAgKiBWZXJpZnkgX0ZpbGVzIENoYW5nZWRfIHNob3dzIG9ubHkgeW91ciBpbnRlbmRlZCBjaGFuZ2VzIGFuZCBkb2VzIG5vdAorICBpbmNsdWRlIGFkZGl0aW9uYWwgZmlsZXMgbGlrZSBgdGFyZ2V0LyouY2xhc3NgCisrIFVwZGF0ZSB5b3VyIEpJUkEgdGlja2V0IGFuZCBpbmNsdWRlIGEgbGluayB0byB0aGUgcHVsbCByZXF1ZXN0IGluIHRoZSB0aWNrZXQuCisKK0lmIHlvdSBwcmVmZXIgdG8gbm90IHVzZSBHaXRIdWIsIHRoZW4geW91IGNhbiBpbnN0ZWFkIHVzZQorYGdpdCBmb3JtYXQtcGF0Y2hgIChvciBgc3ZuIGRpZmZgKSBhbmQgYXR0YWNoIHRoZSBwYXRjaCBmaWxlIHRvIHRoZSBKSVJBIGlzc3VlLgorCisKK0FkZGl0aW9uYWwgUmVzb3VyY2VzCistLS0tLS0tLS0tLS0tLS0tLS0tLQorCisrIFtDb250cmlidXRpbmcgcGF0Y2hlc10oaHR0cHM6Ly9jb21tb25zLmFwYWNoZS5vcmcvcGF0Y2hlcy5odG1sKQorKyBbQXBhY2hlIENvbW1vbnMgQ29tcHJlc3MgSklSQSBwcm9qZWN0IHBhZ2VdW2ppcmFdCisrIFtDb250cmlidXRvciBMaWNlbnNlIEFncmVlbWVudF1bY2xhXQorKyBbR2VuZXJhbCBHaXRIdWIgZG9jdW1lbnRhdGlvbl0oaHR0cHM6Ly9oZWxwLmdpdGh1Yi5jb20vKQorKyBbR2l0SHViIHB1bGwgcmVxdWVzdCBkb2N1bWVudGF0aW9uXShodHRwczovL2hlbHAuZ2l0aHViLmNvbS9hcnRpY2xlcy9jcmVhdGluZy1hLXB1bGwtcmVxdWVzdC8pCisrIFtBcGFjaGUgQ29tbW9ucyBUd2l0dGVyIEFjY291bnRdKGh0dHBzOi8vdHdpdHRlci5jb20vQXBhY2hlQ29tbW9ucykKKysgYCNhcGFjaGUtY29tbW9uc2AgSVJDIGNoYW5uZWwgb24gYGlyYy5mcmVlbm9kZS5uZXRgCisKK1tjbGFdOmh0dHBzOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvI2NsYXMKK1tqaXJhXTpodHRwczovL2lzc3Vlcy5hcGFjaGUub3JnL2ppcmEvYnJvd3NlL0NPTVBSRVNTCmRpZmYgLS1naXQgYS9MSUNFTlNFLnR4dCBiL0xJQ0VOU0UudHh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI2MWVlYjkKLS0tIC9kZXYvbnVsbAorKysgYi9MSUNFTlNFLnR4dApAQCAtMCwwICsxLDIwMSBAQAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXBhY2hlIExpY2Vuc2UKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKKyAgICAgICAgICAgICAgICAgICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy8KKworICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCisKKyAgIDEuIERlZmluaXRpb25zLgorCisgICAgICAiTGljZW5zZSIgc2hhbGwgbWVhbiB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgZm9yIHVzZSwgcmVwcm9kdWN0aW9uLAorICAgICAgYW5kIGRpc3RyaWJ1dGlvbiBhcyBkZWZpbmVkIGJ5IFNlY3Rpb25zIDEgdGhyb3VnaCA5IG9mIHRoaXMgZG9jdW1lbnQuCisKKyAgICAgICJMaWNlbnNvciIgc2hhbGwgbWVhbiB0aGUgY29weXJpZ2h0IG93bmVyIG9yIGVudGl0eSBhdXRob3JpemVkIGJ5CisgICAgICB0aGUgY29weXJpZ2h0IG93bmVyIHRoYXQgaXMgZ3JhbnRpbmcgdGhlIExpY2Vuc2UuCisKKyAgICAgICJMZWdhbCBFbnRpdHkiIHNoYWxsIG1lYW4gdGhlIHVuaW9uIG9mIHRoZSBhY3RpbmcgZW50aXR5IGFuZCBhbGwKKyAgICAgIG90aGVyIGVudGl0aWVzIHRoYXQgY29udHJvbCwgYXJlIGNvbnRyb2xsZWQgYnksIG9yIGFyZSB1bmRlciBjb21tb24KKyAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCisgICAgICAiY29udHJvbCIgbWVhbnMgKGkpIHRoZSBwb3dlciwgZGlyZWN0IG9yIGluZGlyZWN0LCB0byBjYXVzZSB0aGUKKyAgICAgIGRpcmVjdGlvbiBvciBtYW5hZ2VtZW50IG9mIHN1Y2ggZW50aXR5LCB3aGV0aGVyIGJ5IGNvbnRyYWN0IG9yCisgICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKKyAgICAgIG91dHN0YW5kaW5nIHNoYXJlcywgb3IgKGlpaSkgYmVuZWZpY2lhbCBvd25lcnNoaXAgb2Ygc3VjaCBlbnRpdHkuCisKKyAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKKyAgICAgIGV4ZXJjaXNpbmcgcGVybWlzc2lvbnMgZ3JhbnRlZCBieSB0aGlzIExpY2Vuc2UuCisKKyAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAorICAgICAgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0byBzb2Z0d2FyZSBzb3VyY2UgY29kZSwgZG9jdW1lbnRhdGlvbgorICAgICAgc291cmNlLCBhbmQgY29uZmlndXJhdGlvbiBmaWxlcy4KKworICAgICAgIk9iamVjdCIgZm9ybSBzaGFsbCBtZWFuIGFueSBmb3JtIHJlc3VsdGluZyBmcm9tIG1lY2hhbmljYWwKKyAgICAgIHRyYW5zZm9ybWF0aW9uIG9yIHRyYW5zbGF0aW9uIG9mIGEgU291cmNlIGZvcm0sIGluY2x1ZGluZyBidXQKKyAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKKyAgICAgIGFuZCBjb252ZXJzaW9ucyB0byBvdGhlciBtZWRpYSB0eXBlcy4KKworICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKKyAgICAgIE9iamVjdCBmb3JtLCBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgTGljZW5zZSwgYXMgaW5kaWNhdGVkIGJ5IGEKKyAgICAgIGNvcHlyaWdodCBub3RpY2UgdGhhdCBpcyBpbmNsdWRlZCBpbiBvciBhdHRhY2hlZCB0byB0aGUgd29yaworICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KKworICAgICAgIkRlcml2YXRpdmUgV29ya3MiIHNoYWxsIG1lYW4gYW55IHdvcmssIHdoZXRoZXIgaW4gU291cmNlIG9yIE9iamVjdAorICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQorICAgICAgZWRpdG9yaWFsIHJldmlzaW9ucywgYW5ub3RhdGlvbnMsIGVsYWJvcmF0aW9ucywgb3Igb3RoZXIgbW9kaWZpY2F0aW9ucworICAgICAgcmVwcmVzZW50LCBhcyBhIHdob2xlLCBhbiBvcmlnaW5hbCB3b3JrIG9mIGF1dGhvcnNoaXAuIEZvciB0aGUgcHVycG9zZXMKKyAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgorICAgICAgc2VwYXJhYmxlIGZyb20sIG9yIG1lcmVseSBsaW5rIChvciBiaW5kIGJ5IG5hbWUpIHRvIHRoZSBpbnRlcmZhY2VzIG9mLAorICAgICAgdGhlIFdvcmsgYW5kIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZi4KKworICAgICAgIkNvbnRyaWJ1dGlvbiIgc2hhbGwgbWVhbiBhbnkgd29yayBvZiBhdXRob3JzaGlwLCBpbmNsdWRpbmcKKyAgICAgIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoZSBXb3JrIGFuZCBhbnkgbW9kaWZpY2F0aW9ucyBvciBhZGRpdGlvbnMKKyAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQorICAgICAgc3VibWl0dGVkIHRvIExpY2Vuc29yIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsgYnkgdGhlIGNvcHlyaWdodCBvd25lcgorICAgICAgb3IgYnkgYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkgYXV0aG9yaXplZCB0byBzdWJtaXQgb24gYmVoYWxmIG9mCisgICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKKyAgICAgIG1lYW5zIGFueSBmb3JtIG9mIGVsZWN0cm9uaWMsIHZlcmJhbCwgb3Igd3JpdHRlbiBjb21tdW5pY2F0aW9uIHNlbnQKKyAgICAgIHRvIHRoZSBMaWNlbnNvciBvciBpdHMgcmVwcmVzZW50YXRpdmVzLCBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvCisgICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAorICAgICAgYW5kIGlzc3VlIHRyYWNraW5nIHN5c3RlbXMgdGhhdCBhcmUgbWFuYWdlZCBieSwgb3Igb24gYmVoYWxmIG9mLCB0aGUKKyAgICAgIExpY2Vuc29yIGZvciB0aGUgcHVycG9zZSBvZiBkaXNjdXNzaW5nIGFuZCBpbXByb3ZpbmcgdGhlIFdvcmssIGJ1dAorICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKKyAgICAgIGRlc2lnbmF0ZWQgaW4gd3JpdGluZyBieSB0aGUgY29weXJpZ2h0IG93bmVyIGFzICJOb3QgYSBDb250cmlidXRpb24uIgorCisgICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQorICAgICAgb24gYmVoYWxmIG9mIHdob20gYSBDb250cmlidXRpb24gaGFzIGJlZW4gcmVjZWl2ZWQgYnkgTGljZW5zb3IgYW5kCisgICAgICBzdWJzZXF1ZW50bHkgaW5jb3Jwb3JhdGVkIHdpdGhpbiB0aGUgV29yay4KKworICAgMi4gR3JhbnQgb2YgQ29weXJpZ2h0IExpY2Vuc2UuIFN1YmplY3QgdG8gdGhlIHRlcm1zIGFuZCBjb25kaXRpb25zIG9mCisgICAgICB0aGlzIExpY2Vuc2UsIGVhY2ggQ29udHJpYnV0b3IgaGVyZWJ5IGdyYW50cyB0byBZb3UgYSBwZXJwZXR1YWwsCisgICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQorICAgICAgY29weXJpZ2h0IGxpY2Vuc2UgdG8gcmVwcm9kdWNlLCBwcmVwYXJlIERlcml2YXRpdmUgV29ya3Mgb2YsCisgICAgICBwdWJsaWNseSBkaXNwbGF5LCBwdWJsaWNseSBwZXJmb3JtLCBzdWJsaWNlbnNlLCBhbmQgZGlzdHJpYnV0ZSB0aGUKKyAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCisKKyAgIDMuIEdyYW50IG9mIFBhdGVudCBMaWNlbnNlLiBTdWJqZWN0IHRvIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZgorICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAorICAgICAgd29ybGR3aWRlLCBub24tZXhjbHVzaXZlLCBuby1jaGFyZ2UsIHJveWFsdHktZnJlZSwgaXJyZXZvY2FibGUKKyAgICAgIChleGNlcHQgYXMgc3RhdGVkIGluIHRoaXMgc2VjdGlvbikgcGF0ZW50IGxpY2Vuc2UgdG8gbWFrZSwgaGF2ZSBtYWRlLAorICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCisgICAgICB3aGVyZSBzdWNoIGxpY2Vuc2UgYXBwbGllcyBvbmx5IHRvIHRob3NlIHBhdGVudCBjbGFpbXMgbGljZW5zYWJsZQorICAgICAgYnkgc3VjaCBDb250cmlidXRvciB0aGF0IGFyZSBuZWNlc3NhcmlseSBpbmZyaW5nZWQgYnkgdGhlaXIKKyAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKKyAgICAgIHdpdGggdGhlIFdvcmsgdG8gd2hpY2ggc3VjaCBDb250cmlidXRpb24ocykgd2FzIHN1Ym1pdHRlZC4gSWYgWW91CisgICAgICBpbnN0aXR1dGUgcGF0ZW50IGxpdGlnYXRpb24gYWdhaW5zdCBhbnkgZW50aXR5IChpbmNsdWRpbmcgYQorICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yaworICAgICAgb3IgYSBDb250cmlidXRpb24gaW5jb3Jwb3JhdGVkIHdpdGhpbiB0aGUgV29yayBjb25zdGl0dXRlcyBkaXJlY3QKKyAgICAgIG9yIGNvbnRyaWJ1dG9yeSBwYXRlbnQgaW5mcmluZ2VtZW50LCB0aGVuIGFueSBwYXRlbnQgbGljZW5zZXMKKyAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQorICAgICAgYXMgb2YgdGhlIGRhdGUgc3VjaCBsaXRpZ2F0aW9uIGlzIGZpbGVkLgorCisgICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQorICAgICAgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YgaW4gYW55IG1lZGl1bSwgd2l0aCBvciB3aXRob3V0CisgICAgICBtb2RpZmljYXRpb25zLCBhbmQgaW4gU291cmNlIG9yIE9iamVjdCBmb3JtLCBwcm92aWRlZCB0aGF0IFlvdQorICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CisKKyAgICAgIChhKSBZb3UgbXVzdCBnaXZlIGFueSBvdGhlciByZWNpcGllbnRzIG9mIHRoZSBXb3JrIG9yCisgICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKKworICAgICAgKGIpIFlvdSBtdXN0IGNhdXNlIGFueSBtb2RpZmllZCBmaWxlcyB0byBjYXJyeSBwcm9taW5lbnQgbm90aWNlcworICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAorCisgICAgICAoYykgWW91IG11c3QgcmV0YWluLCBpbiB0aGUgU291cmNlIGZvcm0gb2YgYW55IERlcml2YXRpdmUgV29ya3MKKyAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCisgICAgICAgICAgYXR0cmlidXRpb24gbm90aWNlcyBmcm9tIHRoZSBTb3VyY2UgZm9ybSBvZiB0aGUgV29yaywKKyAgICAgICAgICBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdCBwZXJ0YWluIHRvIGFueSBwYXJ0IG9mCisgICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAorCisgICAgICAoZCkgSWYgdGhlIFdvcmsgaW5jbHVkZXMgYSAiTk9USUNFIiB0ZXh0IGZpbGUgYXMgcGFydCBvZiBpdHMKKyAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CisgICAgICAgICAgaW5jbHVkZSBhIHJlYWRhYmxlIGNvcHkgb2YgdGhlIGF0dHJpYnV0aW9uIG5vdGljZXMgY29udGFpbmVkCisgICAgICAgICAgd2l0aGluIHN1Y2ggTk9USUNFIGZpbGUsIGV4Y2x1ZGluZyB0aG9zZSBub3RpY2VzIHRoYXQgZG8gbm90CisgICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCisgICAgICAgICAgb2YgdGhlIGZvbGxvd2luZyBwbGFjZXM6IHdpdGhpbiBhIE5PVElDRSB0ZXh0IGZpbGUgZGlzdHJpYnV0ZWQKKyAgICAgICAgICBhcyBwYXJ0IG9mIHRoZSBEZXJpdmF0aXZlIFdvcmtzOyB3aXRoaW4gdGhlIFNvdXJjZSBmb3JtIG9yCisgICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCisgICAgICAgICAgd2l0aGluIGEgZGlzcGxheSBnZW5lcmF0ZWQgYnkgdGhlIERlcml2YXRpdmUgV29ya3MsIGlmIGFuZAorICAgICAgICAgIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgbm90aWNlcyBub3JtYWxseSBhcHBlYXIuIFRoZSBjb250ZW50cworICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKKyAgICAgICAgICBkbyBub3QgbW9kaWZ5IHRoZSBMaWNlbnNlLiBZb3UgbWF5IGFkZCBZb3VyIG93biBhdHRyaWJ1dGlvbgorICAgICAgICAgIG5vdGljZXMgd2l0aGluIERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSwgYWxvbmdzaWRlCisgICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCisgICAgICAgICAgdGhhdCBzdWNoIGFkZGl0aW9uYWwgYXR0cmlidXRpb24gbm90aWNlcyBjYW5ub3QgYmUgY29uc3RydWVkCisgICAgICAgICAgYXMgbW9kaWZ5aW5nIHRoZSBMaWNlbnNlLgorCisgICAgICBZb3UgbWF5IGFkZCBZb3VyIG93biBjb3B5cmlnaHQgc3RhdGVtZW50IHRvIFlvdXIgbW9kaWZpY2F0aW9ucyBhbmQKKyAgICAgIG1heSBwcm92aWRlIGFkZGl0aW9uYWwgb3IgZGlmZmVyZW50IGxpY2Vuc2UgdGVybXMgYW5kIGNvbmRpdGlvbnMKKyAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKKyAgICAgIGZvciBhbnkgc3VjaCBEZXJpdmF0aXZlIFdvcmtzIGFzIGEgd2hvbGUsIHByb3ZpZGVkIFlvdXIgdXNlLAorICAgICAgcmVwcm9kdWN0aW9uLCBhbmQgZGlzdHJpYnV0aW9uIG9mIHRoZSBXb3JrIG90aGVyd2lzZSBjb21wbGllcyB3aXRoCisgICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgorCisgICA1LiBTdWJtaXNzaW9uIG9mIENvbnRyaWJ1dGlvbnMuIFVubGVzcyBZb3UgZXhwbGljaXRseSBzdGF0ZSBvdGhlcndpc2UsCisgICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKKyAgICAgIGJ5IFlvdSB0byB0aGUgTGljZW5zb3Igc2hhbGwgYmUgdW5kZXIgdGhlIHRlcm1zIGFuZCBjb25kaXRpb25zIG9mCisgICAgICB0aGlzIExpY2Vuc2UsIHdpdGhvdXQgYW55IGFkZGl0aW9uYWwgdGVybXMgb3IgY29uZGl0aW9ucy4KKyAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKKyAgICAgIHRoZSB0ZXJtcyBvZiBhbnkgc2VwYXJhdGUgbGljZW5zZSBhZ3JlZW1lbnQgeW91IG1heSBoYXZlIGV4ZWN1dGVkCisgICAgICB3aXRoIExpY2Vuc29yIHJlZ2FyZGluZyBzdWNoIENvbnRyaWJ1dGlvbnMuCisKKyAgIDYuIFRyYWRlbWFya3MuIFRoaXMgTGljZW5zZSBkb2VzIG5vdCBncmFudCBwZXJtaXNzaW9uIHRvIHVzZSB0aGUgdHJhZGUKKyAgICAgIG5hbWVzLCB0cmFkZW1hcmtzLCBzZXJ2aWNlIG1hcmtzLCBvciBwcm9kdWN0IG5hbWVzIG9mIHRoZSBMaWNlbnNvciwKKyAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQorICAgICAgb3JpZ2luIG9mIHRoZSBXb3JrIGFuZCByZXByb2R1Y2luZyB0aGUgY29udGVudCBvZiB0aGUgTk9USUNFIGZpbGUuCisKKyAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgorICAgICAgYWdyZWVkIHRvIGluIHdyaXRpbmcsIExpY2Vuc29yIHByb3ZpZGVzIHRoZSBXb3JrIChhbmQgZWFjaAorICAgICAgQ29udHJpYnV0b3IgcHJvdmlkZXMgaXRzIENvbnRyaWJ1dGlvbnMpIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKKyAgICAgIGltcGxpZWQsIGluY2x1ZGluZywgd2l0aG91dCBsaW1pdGF0aW9uLCBhbnkgd2FycmFudGllcyBvciBjb25kaXRpb25zCisgICAgICBvZiBUSVRMRSwgTk9OLUlORlJJTkdFTUVOVCwgTUVSQ0hBTlRBQklMSVRZLCBvciBGSVRORVNTIEZPUiBBCisgICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKKyAgICAgIGFwcHJvcHJpYXRlbmVzcyBvZiB1c2luZyBvciByZWRpc3RyaWJ1dGluZyB0aGUgV29yayBhbmQgYXNzdW1lIGFueQorICAgICAgcmlza3MgYXNzb2NpYXRlZCB3aXRoIFlvdXIgZXhlcmNpc2Ugb2YgcGVybWlzc2lvbnMgdW5kZXIgdGhpcyBMaWNlbnNlLgorCisgICA4LiBMaW1pdGF0aW9uIG9mIExpYWJpbGl0eS4gSW4gbm8gZXZlbnQgYW5kIHVuZGVyIG5vIGxlZ2FsIHRoZW9yeSwKKyAgICAgIHdoZXRoZXIgaW4gdG9ydCAoaW5jbHVkaW5nIG5lZ2xpZ2VuY2UpLCBjb250cmFjdCwgb3Igb3RoZXJ3aXNlLAorICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKKyAgICAgIG5lZ2xpZ2VudCBhY3RzKSBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc2hhbGwgYW55IENvbnRyaWJ1dG9yIGJlCisgICAgICBsaWFibGUgdG8gWW91IGZvciBkYW1hZ2VzLCBpbmNsdWRpbmcgYW55IGRpcmVjdCwgaW5kaXJlY3QsIHNwZWNpYWwsCisgICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKKyAgICAgIHJlc3VsdCBvZiB0aGlzIExpY2Vuc2Ugb3Igb3V0IG9mIHRoZSB1c2Ugb3IgaW5hYmlsaXR5IHRvIHVzZSB0aGUKKyAgICAgIFdvcmsgKGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gZGFtYWdlcyBmb3IgbG9zcyBvZiBnb29kd2lsbCwKKyAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCisgICAgICBvdGhlciBjb21tZXJjaWFsIGRhbWFnZXMgb3IgbG9zc2VzKSwgZXZlbiBpZiBzdWNoIENvbnRyaWJ1dG9yCisgICAgICBoYXMgYmVlbiBhZHZpc2VkIG9mIHRoZSBwb3NzaWJpbGl0eSBvZiBzdWNoIGRhbWFnZXMuCisKKyAgIDkuIEFjY2VwdGluZyBXYXJyYW50eSBvciBBZGRpdGlvbmFsIExpYWJpbGl0eS4gV2hpbGUgcmVkaXN0cmlidXRpbmcKKyAgICAgIHRoZSBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiwgWW91IG1heSBjaG9vc2UgdG8gb2ZmZXIsCisgICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAorICAgICAgb3Igb3RoZXIgbGlhYmlsaXR5IG9ibGlnYXRpb25zIGFuZC9vciByaWdodHMgY29uc2lzdGVudCB3aXRoIHRoaXMKKyAgICAgIExpY2Vuc2UuIEhvd2V2ZXIsIGluIGFjY2VwdGluZyBzdWNoIG9ibGlnYXRpb25zLCBZb3UgbWF5IGFjdCBvbmx5CisgICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgorICAgICAgb2YgYW55IG90aGVyIENvbnRyaWJ1dG9yLCBhbmQgb25seSBpZiBZb3UgYWdyZWUgdG8gaW5kZW1uaWZ5LAorICAgICAgZGVmZW5kLCBhbmQgaG9sZCBlYWNoIENvbnRyaWJ1dG9yIGhhcm1sZXNzIGZvciBhbnkgbGlhYmlsaXR5CisgICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCisgICAgICBvZiB5b3VyIGFjY2VwdGluZyBhbnkgc3VjaCB3YXJyYW50eSBvciBhZGRpdGlvbmFsIGxpYWJpbGl0eS4KKworICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCisKKyAgIEFQUEVORElYOiBIb3cgdG8gYXBwbHkgdGhlIEFwYWNoZSBMaWNlbnNlIHRvIHlvdXIgd29yay4KKworICAgICAgVG8gYXBwbHkgdGhlIEFwYWNoZSBMaWNlbnNlIHRvIHlvdXIgd29yaywgYXR0YWNoIHRoZSBmb2xsb3dpbmcKKyAgICAgIGJvaWxlcnBsYXRlIG5vdGljZSwgd2l0aCB0aGUgZmllbGRzIGVuY2xvc2VkIGJ5IGJyYWNrZXRzICJbXSIKKyAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCisgICAgICB0aGUgYnJhY2tldHMhKSAgVGhlIHRleHQgc2hvdWxkIGJlIGVuY2xvc2VkIGluIHRoZSBhcHByb3ByaWF0ZQorICAgICAgY29tbWVudCBzeW50YXggZm9yIHRoZSBmaWxlIGZvcm1hdC4gV2UgYWxzbyByZWNvbW1lbmQgdGhhdCBhCisgICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCisgICAgICBzYW1lICJwcmludGVkIHBhZ2UiIGFzIHRoZSBjb3B5cmlnaHQgbm90aWNlIGZvciBlYXNpZXIKKyAgICAgIGlkZW50aWZpY2F0aW9uIHdpdGhpbiB0aGlyZC1wYXJ0eSBhcmNoaXZlcy4KKworICAgQ29weXJpZ2h0IFt5eXl5XSBbbmFtZSBvZiBjb3B5cmlnaHQgb3duZXJdCisKKyAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICAgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisKKyAgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKworICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAgIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCmRpZmYgLS1naXQgYS9OT1RJQ0UudHh0IGIvTk9USUNFLnR4dApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zZmJlODIxCi0tLSAvZGV2L251bGwKKysrIGIvTk9USUNFLnR4dApAQCAtMCwwICsxLDExIEBACitBcGFjaGUgQ29tbW9ucyBDb21wcmVzcworQ29weXJpZ2h0IDIwMDItMjAxOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKworVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBhdAorVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwczovL3d3dy5hcGFjaGUub3JnLykuCisKK1RoZSBmaWxlcyBpbiB0aGUgcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnNldmVuegord2VyZSBkZXJpdmVkIGZyb20gdGhlIExaTUEgU0RLLCB2ZXJzaW9uIDkuMjAgKEMvIGFuZCBDUFAvN3ppcC8pLAord2hpY2ggaGFzIGJlZW4gcGxhY2VkIGluIHRoZSBwdWJsaWMgZG9tYWluOgorCisiTFpNQSBTREsgaXMgcGxhY2VkIGluIHRoZSBwdWJsaWMgZG9tYWluLiIgKGh0dHA6Ly93d3cuNy16aXAub3JnL3Nkay5odG1sKQpkaWZmIC0tZ2l0IGEvUkVBRE1FLm1kIGIvUkVBRE1FLm1kCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI1NzZjYTMKLS0tIC9kZXYvbnVsbAorKysgYi9SRUFETUUubWQKQEAgLTAsMCArMSwxMDggQEAKKzwhLS0tCisgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorCisgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKworIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKy0tPgorPCEtLS0KKyArPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSsKKyB8KioqKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKioqKnwKKyB8KioqKiAgICAgIFRISVMgRklMRSBJUyBHRU5FUkFURUQgQlkgVEhFIENPTU1PTlMgQlVJTEQgUExVR0lOICAgICAgKioqKnwKKyB8KioqKiAgICAgICAgICAgICAgICAgICAgRE8gTk9UIEVESVQgRElSRUNUTFkgICAgICAgICAgICAgICAgICAgICAgKioqKnwKKyB8KioqKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKioqKnwKKyArPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSsKKyB8IFRFTVBMQVRFIEZJTEU6IHJlYWRtZS1tZC10ZW1wbGF0ZS5tZCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKyB8IGNvbW1vbnMtYnVpbGQtcGx1Z2luL3RydW5rL3NyYy9tYWluL3Jlc291cmNlcy9jb21tb25zLXhkb2MtdGVtcGxhdGVzIHwKKyArPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSsKKyB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKyB8IDEpIFJlLWdlbmVyYXRlIHVzaW5nOiBtdm4gY29tbW9uczpyZWFkbWUtbWQgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKyB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKyB8IDIpIFNldCB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXMgaW4gdGhlIGNvbXBvbmVudCdzIHBvbTogICAgICAgICAgICAgIHwKKyB8ICAgIC0gY29tbW9ucy5jb21wb25lbnRpZCAocmVxdWlyZWQsIGFscGhhYmV0aWMsIGxvd2VyIGNhc2UpICAgICAgICAgIHwKKyB8ICAgIC0gY29tbW9ucy5yZWxlYXNlLnZlcnNpb24gKHJlcXVpcmVkKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKyB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKyB8IDMpIEV4YW1wbGUgUHJvcGVydGllcyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKyB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKyB8ICA8cHJvcGVydGllcz4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKyB8ICAgIDxjb21tb25zLmNvbXBvbmVudGlkPm1hdGg8L2NvbW1vbnMuY29tcG9uZW50aWQ+ICAgICAgICAgICAgICAgICAgIHwKKyB8ICAgIDxjb21tb25zLnJlbGVhc2UudmVyc2lvbj4xLjI8L2NvbW1vbnMucmVsZWFzZS52ZXJzaW9uPiAgICAgICAgICAgIHwKKyB8ICA8L3Byb3BlcnRpZXM+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKyB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKyArPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSsKKy0tLT4KK0FwYWNoZSBDb21tb25zIENvbXByZXNzCis9PT09PT09PT09PT09PT09PT09CisKK1shW0J1aWxkIFN0YXR1c10oaHR0cHM6Ly90cmF2aXMtY2kub3JnL2FwYWNoZS9jb21tb25zLWNvbXByZXNzLnN2ZyldKGh0dHBzOi8vdHJhdmlzLWNpLm9yZy9hcGFjaGUvY29tbW9ucy1jb21wcmVzcykKK1shW0NvdmVyYWdlIFN0YXR1c10oaHR0cHM6Ly9jb3ZlcmFsbHMuaW8vcmVwb3MvYXBhY2hlL2NvbW1vbnMtY29tcHJlc3MvYmFkZ2Uuc3ZnKV0oaHR0cHM6Ly9jb3ZlcmFsbHMuaW8vci9hcGFjaGUvY29tbW9ucy1jb21wcmVzcykKK1shW01hdmVuIENlbnRyYWxdKGh0dHBzOi8vbWF2ZW4tYmFkZ2VzLmhlcm9rdWFwcC5jb20vbWF2ZW4tY2VudHJhbC9vcmcuYXBhY2hlLmNvbW1vbnMvY29tbW9ucy1jb21wcmVzcy9iYWRnZS5zdmcpXShodHRwczovL21hdmVuLWJhZGdlcy5oZXJva3VhcHAuY29tL21hdmVuLWNlbnRyYWwvb3JnLmFwYWNoZS5jb21tb25zL2NvbW1vbnMtY29tcHJlc3MvKQorWyFbTGljZW5zZV0oaHR0cHM6Ly9pbWcuc2hpZWxkcy5pby86bGljZW5zZS1hcGFjaGUtYmx1ZS5zdmcpXShodHRwczovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wLmh0bWwpCisKK0FwYWNoZSBDb21tb25zIENvbXByZXNzIHNvZnR3YXJlIGRlZmluZXMgYW4gQVBJIGZvciB3b3JraW5nIHdpdGgKK2NvbXByZXNzaW9uIGFuZCBhcmNoaXZlIGZvcm1hdHMuICBUaGVzZSBpbmNsdWRlOiBiemlwMiwgZ3ppcCwgcGFjazIwMCwKK2x6bWEsIHh6LCBTbmFwcHksIHRyYWRpdGlvbmFsIFVuaXggQ29tcHJlc3MsIERFRkxBVEUsIERFRkxBVEU2NCwgTFo0LAorQnJvdGxpLCBac3RhbmRhcmQgYW5kIGFyLCBjcGlvLCBqYXIsIHRhciwgemlwLCBkdW1wLCA3eiwgYXJqLgorCitEb2N1bWVudGF0aW9uCistLS0tLS0tLS0tLS0tCisKK01vcmUgaW5mb3JtYXRpb24gY2FuIGJlIGZvdW5kIG9uIHRoZSBbQXBhY2hlIENvbW1vbnMgQ29tcHJlc3MgaG9tZXBhZ2VdKGh0dHBzOi8vY29tbW9ucy5hcGFjaGUub3JnL3Byb3Blci9jb21tb25zLWNvbXByZXNzKS4KK1RoZSBbSmF2YWRvY10oaHR0cHM6Ly9jb21tb25zLmFwYWNoZS5vcmcvcHJvcGVyL2NvbW1vbnMtY29tcHJlc3MvamF2YWRvY3MvYXBpLXJlbGVhc2UpIGNhbiBiZSBicm93c2VkLgorUXVlc3Rpb25zIHJlbGF0ZWQgdG8gdGhlIHVzYWdlIG9mIEFwYWNoZSBDb21tb25zIENvbXByZXNzIHNob3VsZCBiZSBwb3N0ZWQgdG8gdGhlIFt1c2VyIG1haWxpbmcgbGlzdF1bbWxdLgorCitXaGVyZSBjYW4gSSBnZXQgdGhlIGxhdGVzdCByZWxlYXNlPworLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK1lvdSBjYW4gZG93bmxvYWQgc291cmNlIGFuZCBiaW5hcmllcyBmcm9tIG91ciBbZG93bmxvYWQgcGFnZV0oaHR0cHM6Ly9jb21tb25zLmFwYWNoZS5vcmcvcHJvcGVyL2NvbW1vbnMtY29tcHJlc3MvZG93bmxvYWRfY29tcHJlc3MuY2dpKS4KKworQWx0ZXJuYXRpdmVseSB5b3UgY2FuIHB1bGwgaXQgZnJvbSB0aGUgY2VudHJhbCBNYXZlbiByZXBvc2l0b3JpZXM6CisKK2BgYHhtbAorPGRlcGVuZGVuY3k+CisgIDxncm91cElkPm9yZy5hcGFjaGUuY29tbW9uczwvZ3JvdXBJZD4KKyAgPGFydGlmYWN0SWQ+Y29tbW9ucy1jb21wcmVzczwvYXJ0aWZhY3RJZD4KKyAgPHZlcnNpb24+MS4xODwvdmVyc2lvbj4KKzwvZGVwZW5kZW5jeT4KK2BgYAorCitDb250cmlidXRpbmcKKy0tLS0tLS0tLS0tLQorCitXZSBhY2NlcHQgUHVsbCBSZXF1ZXN0cyB2aWEgR2l0SHViLiBUaGUgW2RldmVsb3BlciBtYWlsaW5nIGxpc3RdW21sXSBpcyB0aGUgbWFpbiBjaGFubmVsIG9mIGNvbW11bmljYXRpb24gZm9yIGNvbnRyaWJ1dG9ycy4KK1RoZXJlIGFyZSBzb21lIGd1aWRlbGluZXMgd2hpY2ggd2lsbCBtYWtlIGFwcGx5aW5nIFBScyBlYXNpZXIgZm9yIHVzOgorKyBObyB0YWJzISBQbGVhc2UgdXNlIHNwYWNlcyBmb3IgaW5kZW50YXRpb24uCisrIFJlc3BlY3QgdGhlIGNvZGUgc3R5bGUuCisrIENyZWF0ZSBtaW5pbWFsIGRpZmZzIC0gZGlzYWJsZSBvbiBzYXZlIGFjdGlvbnMgbGlrZSByZWZvcm1hdCBzb3VyY2UgY29kZSBvciBvcmdhbml6ZSBpbXBvcnRzLiBJZiB5b3UgZmVlbCB0aGUgc291cmNlIGNvZGUgc2hvdWxkIGJlIHJlZm9ybWF0dGVkIGNyZWF0ZSBhIHNlcGFyYXRlIFBSIGZvciB0aGlzIGNoYW5nZS4KKysgUHJvdmlkZSBKVW5pdCB0ZXN0cyBmb3IgeW91ciBjaGFuZ2VzIGFuZCBtYWtlIHN1cmUgeW91ciBjaGFuZ2VzIGRvbid0IGJyZWFrIGFueSBleGlzdGluZyB0ZXN0cyBieSBydW5uaW5nIGBgYG12biBjbGVhbiB0ZXN0YGBgLgorCitJZiB5b3UgcGxhbiB0byBjb250cmlidXRlIG9uIGEgcmVndWxhciBiYXNpcywgcGxlYXNlIGNvbnNpZGVyIGZpbGluZyBhIFtjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudF0oaHR0cHM6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy8jY2xhcykuCitZb3UgY2FuIGxlYXJuIG1vcmUgYWJvdXQgY29udHJpYnV0aW5nIHZpYSBHaXRIdWIgaW4gb3VyIFtjb250cmlidXRpb24gZ3VpZGVsaW5lc10oQ09OVFJJQlVUSU5HLm1kKS4KKworTGljZW5zZQorLS0tLS0tLQorVGhpcyBjb2RlIGlzIHVuZGVyIHRoZSBbQXBhY2hlIExpY2VuY2UgdjJdKGh0dHBzOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjApLgorCitTZWUgdGhlIGBOT1RJQ0UudHh0YCBmaWxlIGZvciByZXF1aXJlZCBub3RpY2VzIGFuZCBhdHRyaWJ1dGlvbnMuCisKK0RvbmF0aW9ucworLS0tLS0tLS0tCitZb3UgbGlrZSBBcGFjaGUgQ29tbW9ucyBDb21wcmVzcz8gVGhlbiBbZG9uYXRlIGJhY2sgdG8gdGhlIEFTRl0oaHR0cHM6Ly93d3cuYXBhY2hlLm9yZy9mb3VuZGF0aW9uL2NvbnRyaWJ1dGluZy5odG1sKSB0byBzdXBwb3J0IHRoZSBkZXZlbG9wbWVudC4KKworQWRkaXRpb25hbCBSZXNvdXJjZXMKKy0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKysgW0FwYWNoZSBDb21tb25zIEhvbWVwYWdlXShodHRwczovL2NvbW1vbnMuYXBhY2hlLm9yZy8pCisrIFtBcGFjaGUgSXNzdWUgVHJhY2tlciAoSklSQSldKGh0dHBzOi8vaXNzdWVzLmFwYWNoZS5vcmcvamlyYS9icm93c2UvQ09NUFJFU1MpCisrIFtBcGFjaGUgQ29tbW9ucyBUd2l0dGVyIEFjY291bnRdKGh0dHBzOi8vdHdpdHRlci5jb20vQXBhY2hlQ29tbW9ucykKKysgYCNhcGFjaGUtY29tbW9uc2AgSVJDIGNoYW5uZWwgb24gYGlyYy5mcmVlbm9kZS5vcmdgCisKK1ttbF06aHR0cHM6Ly9jb21tb25zLmFwYWNoZS5vcmcvbWFpbC1saXN0cy5odG1sCmRpZmYgLS1naXQgYS9SRUFETUUudHh0IGIvUkVBRE1FLnR4dApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44YTI2NmE3Ci0tLSAvZGV2L251bGwKKysrIGIvUkVBRE1FLnR4dApAQCAtMCwwICsxLDQzIEBACitBcGFjaGUgQ29tbW9ucyBDb21wcmVzcworPT09PT09PT09PT09PT09PT09PT09PT0KKworQ29tbW9ucyBDb21wcmVzcyBpcyBhIEphdmEgbGlicmFyeSBmb3Igd29ya2luZyB3aXRoIHZhcmlvdXMKK2NvbXByZXNzaW9uIGFuZCBhcmNoaXZpbmcgZm9ybWF0cy4KKworRm9yIGZ1bGwgZG9jdW1lbnRhdGlvbiBzZWUgaHR0cHM6Ly9jb21tb25zLmFwYWNoZS5vcmcvcHJvcGVyL2NvbW1vbnMtY29tcHJlc3MvCisKKyMjIEFwYWNoZSBDb21tb25zIENvbXByZXNzIHdhcyBkZXJpdmVkIGZyb20gdmFyaW91cyBzb3VyY2VzLCBpbmNsdWRpbmc6CisKK09yaWdpbmFsIEJaaXAyIGNsYXNzZXMgY29udHJpYnV0ZWQgYnkgS2Vpcm9uIExpZGRsZQorPGtlaXJvbkBhZnRleHN3LmNvbT4sIEFmdGV4IFNvZnR3YXJlIHRvIHRoZSBBcGFjaGUgQW50IHByb2plY3QuCitUaGV5IGFyZSBiYXNlZCBvbiBhIHBvcnQgb2YgSnVsaWFuIFNld2FyZCdzIGxpYmJ6aXAyLgorCitPcmlnaW5hbCBUYXIgY2xhc3NlcyBmcm9tIGNvbnRyaWJ1dG9ycyBvZiB0aGUgQXBhY2hlIEFudCBwcm9qZWN0LgorCitPcmlnaW5hbCBaaXAgY2xhc3NlcyBmcm9tIGNvbnRyaWJ1dG9ycyBvZiB0aGUgQXBhY2hlIEFudCBwcm9qZWN0LgorCitPcmlnaW5hbCBDUElPIGNsYXNzZXMgY29udHJpYnV0ZWQgYnkgTWFya3VzIEt1c3MgYW5kIHRoZSBqUlBNIHByb2plY3QKKyhqcnBtLnNvdXJjZWZvcmdlLm5ldCkuCisKK1RoaXMgZGlzdHJpYnV0aW9uIGluY2x1ZGVzIGNyeXB0b2dyYXBoaWMgc29mdHdhcmUuIFRoZSBjb3VudHJ5IGluCit3aGljaCB5b3UgY3VycmVudGx5IHJlc2lkZSBtYXkgaGF2ZSByZXN0cmljdGlvbnMgb24gdGhlIGltcG9ydCwKK3Bvc3Nlc3Npb24sIHVzZSwgYW5kL29yIHJlLWV4cG9ydCB0byBhbm90aGVyIGNvdW50cnksIG9mIGVuY3J5cHRpb24KK3NvZnR3YXJlLiBCRUZPUkUgdXNpbmcgYW55IGVuY3J5cHRpb24gc29mdHdhcmUsIHBsZWFzZSBjaGVjayB5b3VyCitjb3VudHJ5J3MgbGF3cywgcmVndWxhdGlvbnMgYW5kIHBvbGljaWVzIGNvbmNlcm5pbmcgdGhlIGltcG9ydCwKK3Bvc3Nlc3Npb24sIG9yIHVzZSwgYW5kIHJlLWV4cG9ydCBvZiBlbmNyeXB0aW9uIHNvZnR3YXJlLCB0byBzZWUgaWYKK3RoaXMgaXMgcGVybWl0dGVkLiBTZWUgPGh0dHA6Ly93d3cud2Fzc2VuYWFyLm9yZy8+IGZvciBtb3JlCitpbmZvcm1hdGlvbi4KKworVGhlIFUuUy4gR292ZXJubWVudCBEZXBhcnRtZW50IG9mIENvbW1lcmNlLCBCdXJlYXUgb2YgSW5kdXN0cnkgYW5kCitTZWN1cml0eSAoQklTKSwgaGFzIGNsYXNzaWZpZWQgdGhpcyBzb2Z0d2FyZSBhcyBFeHBvcnQgQ29tbW9kaXR5CitDb250cm9sIE51bWJlciAoRUNDTikgNUQwMDIuQy4xLCB3aGljaCBpbmNsdWRlcyBpbmZvcm1hdGlvbiBzZWN1cml0eQorc29mdHdhcmUgdXNpbmcgb3IgcGVyZm9ybWluZyBjcnlwdG9ncmFwaGljIGZ1bmN0aW9ucyB3aXRoIGFzeW1tZXRyaWMKK2FsZ29yaXRobXMuIFRoZSBmb3JtIGFuZCBtYW5uZXIgb2YgdGhpcyBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorZGlzdHJpYnV0aW9uIG1ha2VzIGl0IGVsaWdpYmxlIGZvciBleHBvcnQgdW5kZXIgdGhlIExpY2Vuc2UgRXhjZXB0aW9uCitFTkMgVGVjaG5vbG9neSBTb2Z0d2FyZSBVbnJlc3RyaWN0ZWQgKFRTVSkgZXhjZXB0aW9uIChzZWUgdGhlIEJJUworRXhwb3J0IEFkbWluaXN0cmF0aW9uIFJlZ3VsYXRpb25zLCBTZWN0aW9uIDc0MC4xMykgZm9yIGJvdGggb2JqZWN0Citjb2RlIGFuZCBzb3VyY2UgY29kZS4KKworVGhlIGZvbGxvd2luZyBwcm92aWRlcyBtb3JlIGRldGFpbHMgb24gdGhlIGluY2x1ZGVkIGNyeXB0b2dyYXBoaWMKK3NvZnR3YXJlOgorICAqIHRoZSA3emlwIHBhY2thZ2UgY2FuIHJlYWQgQUVTIGVuY3J5cHRlZCBhcmNoaXZlcwpkaWZmIC0tZ2l0IGEvUkVMRUFTRS1OT1RFUy50eHQgYi9SRUxFQVNFLU5PVEVTLnR4dApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNDA5MDFmCi0tLSAvZGV2L251bGwKKysrIGIvUkVMRUFTRS1OT1RFUy50eHQKQEAgLTAsMCArMSwxMDg4IEBACisgICAgICAgICAgICAgIEFwYWNoZSBDb21tb25zIENvbXByZXNzIFJFTEVBU0UgTk9URVMKKworQXBhY2hlIENvbW1vbnMgQ29tcHJlc3Mgc29mdHdhcmUgZGVmaW5lcyBhbiBBUEkgZm9yIHdvcmtpbmcgd2l0aAorY29tcHJlc3Npb24gYW5kIGFyY2hpdmUgZm9ybWF0cy4gIFRoZXNlIGluY2x1ZGU6IGJ6aXAyLCBnemlwLCBwYWNrMjAwLAorbHptYSwgeHosIFNuYXBweSwgdHJhZGl0aW9uYWwgVW5peCBDb21wcmVzcywgREVGTEFURSwgREVGTEFURTY0LCBMWjQsCitCcm90bGksIFpzdGFuZGFyZCBhbmQgYXIsIGNwaW8sIGphciwgdGFyLCB6aXAsIGR1bXAsIDd6LCBhcmouCisKK1JlbGVhc2UgMS4xOAorLS0tLS0tLS0tLS0tCisKK05ldyBmZWF0dXJlczoKK28gSXQgaXMgbm93IHBvc3NpYmxlIHRvIHNwZWNpZnkgdGhlIGFyZ3VtZW50cyBvZiB6c3RkLWpuaSdzCisgIFpzdGRPdXRwdXRTdHJlYW0gY29uc3RydWN0b3JzIHZpYSBDb21tb25zIENvbXByZXNzIGFzIHdlbGwuCisgIElzc3VlOiBDT01QUkVTUy00NjAuCisgIFRoYW5rcyB0byBDYXJtaSBHcnVzaGtvLgorCitGaXhlZCBCdWdzOgorbyBUaGUgZXhhbXBsZSBFeHBhbmRlciBjbGFzcyBoYXMgYmVlbiB2dWxuZXJhYmxlIHRvIGEgcGF0aAorICB0cmF2ZXJzYWwgaW4gdGhlIGVkZ2UgY2FzZSB0aGF0IGhhcHBlbnMgd2hlbiB0aGUgdGFyZ2V0CisgIGRpcmVjdG9yeSBoYXMgYSBzaWJsaW5nIGRpcmVjdG9yeSBhbmQgdGhlIG5hbWUgb2YgdGhlIHRhcmdldAorICBkaXJlY3RvcnkgaXMgYSBwcmVmaXggb2YgdGhlIHNpYmxpbmcgZGlyZWN0b3J5J3MgbmFtZS4KKyAgVGhhbmtzIHRvIERpZGllciBMb2lzZWF1LgorbyBDaGFuZ2VkIHRoZSBPU0dpIEltcG9ydC1QYWNrYWdlIHRvIGFsc28gb3B0aW9uYWxseSBpbXBvcnQKKyAgamF2YXguY3J5cHRvIHNvIGVuY3J5cHRlZCBhcmNoaXZlcyBjYW4gYmUgcmVhZC4KKyAgSXNzdWU6IENPTVBSRVNTLTQ1Ni4KK28gQ2hhbmdlZCB2YXJpb3VzIGltcGxlbWVudGF0aW9ucyBvZiB0aGUgY2xvc2UgbWV0aG9kIHRvIGJldHRlcgorICBlbnN1cmUgYWxsIGhlbGQgcmVzb3VyY2VzIGdldCBjbG9zZWQgZXZlbiBpZiBleGNlcHRpb25zIGFyZQorICB0aHJvd24gZHVyaW5nIHRoZSBjbG9zaW5nIHRoZSBzdHJlYW0uCisgIElzc3VlOiBDT01QUkVTUy00NTcuCitvIFppcEFyY2hpdmVJbnB1dFN0cmVhbSBjYW4gbm93IGRldGVjdCB0aGUgQVBLIFNpZ25pbmcgQmxvY2sKKyAgdXNlZCBpbiBzaWduZWQgQW5kcm9pZCBBUEsgZmlsZXMgYW5kIHRyZWF0cyBpdCBhcyBhbiAiZW5kIG9mCisgIGFyY2hpdmUiIG1hcmtlci4KKyAgSXNzdWU6IENPTVBSRVNTLTQ1NS4KK28gVGhlIGNwaW8gc3RyZWFtcyBkaWRuJ3QgaGFuZGxlIGFyY2hpdmVzIHVzaW5nIGEgbXVsdGktYnl0ZQorICBlbmNvZGluZyBwcm9wZXJseS4KKyAgSXNzdWU6IENPTVBSRVNTLTQ1OS4KKyAgVGhhbmtzIHRvIEplbnMgUmVpbWFubi4KK28gWmlwQXJjaGl2ZUlucHV0U3RyZWFtI3JlYWQgd291bGQgc2lsZW50bHkgcmV0dXJuIC0xIG9uIGEKKyAgY29ycnVwdGVkIHN0b3JlZCBlbnRyeSBhbmQgZXZlbiByZXR1cm4gPiAwIGFmdGVyIGhpdHRpbmcgdGhlCisgIGVuZCBvZiB0aGUgYXJjaGl2ZS4KKyAgSXNzdWU6IENPTVBSRVNTLTQ2My4KK28gQXJBcmNoaXZlSW5wdXRTdHJlYW0jcmVhZCB3b3VsZCBhbGxvdyB0byByZWFkIGZyb20gdGhlIHN0cmVhbQorICB3aXRob3V0IG9wZW5pbmcgYW4gZW50cnkgYXQgYWxsLgorICBJc3N1ZTogQ09NUFJFU1MtNDYyLgorCitSZWxlYXNlIDEuMTcKKy0tLS0tLS0tLS0tLQorCitOZXcgZmVhdHVyZXM6CitvIEFkZGVkIGEgdW5pdCB0ZXN0IHRoYXQgaXMgc3VwcG9zZWQgdG8gZmFpbCBpZiB3ZSBicmVhayB0aGUKKyAgT1NHaSBtYW5pZmVzdCBlbnRyaWVzIGFnYWluLgorICBJc3N1ZTogQ09NUFJFU1MtNDQzLgorbyBBZGQgYSBuZXcgU2tpcFNoaWVsZGluZ0lucHV0U3RyZWFtIGNsYXNzIHRoYXQgY2FuIGJlIHVzZWQgd2l0aAorICBzdHJlYW1zIHRoYXQgdGhyb3cgYW4gSU9FeGNlcHRpb24gd2hlbiBza2lwIGlzIGludm9rZWQuCisgIElzc3VlOiBDT01QUkVTUy00NDkuCitvIE5ldyBjb25zdHJ1Y3RvcnMgaGF2ZSBiZWVuIGFkZGVkIHRvIFNldmVuWkZpbGUgdGhhdCBhY2NlcHQKKyAgY2hhcltdcyByYXRoZXIgdGhhbiBieXRlW11zIGluIG9yZGVyIHRvIGF2b2lkIGEgY29tbW9uIGVycm9yCisgIG9mIHVzaW5nIHRoZSB3cm9uZyBlbmNvZGluZyB3aGVuIGNyZWF0aW5nIHRoZSBieXRlW10uICBUaGlzCisgIGNoYW5nZSBtYXkgYnJlYWsgc291cmNlIGNvbXBhdGliaWxpdHkgZm9yIGNsaWVudCBjb2RlIHRoYXQKKyAgdXNlcyBvbmUgb2YgdGhlIGNvbnN0cnVjdG9ycyBleHBlY3RpbmcgYSBwYXNzd29yZCBhbmQgcGFzc2VzCisgIGluIG51bGwgYXMgcGFzc3dvcmQuIFdlIHJlY29tbWVuZCB0byBjaGFuZ2UgdGhlIGNvZGUgdG8gdXNlIGEKKyAgY29uc3RydWN0b3Igd2l0aG91dCBwYXNzd29yZCBhcmd1bWVudC4KKyAgSXNzdWU6IENPTVBSRVNTLTQ1Mi4KKworRml4ZWQgQnVnczoKK28gUmVtb3ZlZCB0aGUgb2JqZW5lc2lzIGRlcGVuZGVuY3kgZnJvbSB0aGUgcG9tIGFzIGl0IGlzIG5vdAorICBuZWVkZWQgYXQgYWxsLgorbyBGaXhlZCByZXNvdXJjZSBsZWFrIGluIFBhcmFsbGVsU2NhdHRlclppcENyZWF0b3Ijd3JpdGVUby4KKyAgSXNzdWU6IENPTVBSRVNTLTQ0Ni4KK28gQ2VydGFpbiBlcnJvcnMgd2hlbiBwYXJzaW5nIFpJUCBleHRyYSBmaWVsZHMgaW4gY29ycnVwdAorICBhcmNoaXZlcyBhcmUgbm93IHR1cm5lZCBpbnRvIFppcEV4Y2VwdGlvbiwgdGhleSB1c2VkIHRvCisgIG1hbmlmZXN0IGFzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBiZWZvcmUuCisgIElzc3VlOiBDT01QUkVTUy00NDcuCitvIElPVXRpbHMuY29weSBub3cgdmVyaWZpZXMgdGhlIGJ1ZmZlciBzaXplIGlzIGJpZ2dlciB0aGFuIDAuCisgIElzc3VlOiBDT01QUkVTUy00NTEuCitvIFppcEFyY2hpdmVJbnB1dFN0cmVhbSBmYWlsZWQgdG8gcmVhZCBzb21lIGZpbGVzIHdpdGggc3RvcmVkCisgIGVudHJpZXMgdXNpbmcgYSBkYXRhIGRlc2NyaXB0b3IuCisgIElzc3VlOiBDT01QUkVTUy00NTQuCisKK0NoYW5nZXM6CitvIEZpeGVkIHNvbWUgY29kZSBleGFtcGxlcy4KKyAgR2l0aHViIFB1bGwgUmVxdWVzdCAjNjMuCisgIFRoYW5rcyB0byBNYXJjaGVua28gU2VyZ2V5LgorbyBUaGUgc3RyZWFtcyByZXR1cm5lZCBieSBaaXBGaWxlIGFuZCBtb3N0IG90aGVyIGRlY29tcHJlc3NpbmcKKyAgc3RyZWFtcyBub3cgcHJvdmlkZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgbnVtYmVyIG9mIGNvbXByZXNzZWQKKyAgYW5kIHVuY29tcHJlc3NlZCBieXRlcyByZWFkIHNvIGZhci4gVGhpcyBtYXkgYmUgdXNlZCB0byBkZXRlY3QKKyAgYSBaaXBCb21iIGlmIHRoZSBjb21wcmVzc2lvbiByYXRpbyBleGNlZWRzIGEgY2VydGFpbgorICB0aHJlc2hvbGQsIGZvciBleGFtcGxlLgorICBGb3IgU2V2ZW5aRmlsZSBhIG5ldyBtZXRob2QgcmV0dXJucyB0aGUgc3RhdGlzdGljcyBmb3IgdGhlCisgIGN1cnJlbnQgZW50cnkuCisgIElzc3VlOiBDT01QUkVTUy00NDUuCisgIFRoYW5rcyB0byBBbmRyZWFzIEJlZWtlci4KK28gQWRkZWQgYSB3b3JrYXJvdW5kIGZvciBhIGJ1ZyBpbiBBZG9wdE9wZW5KREsgZm9yIFMvMzkwIHRvCisgIEJaaXAyQ29tcHJlc3NvcklucHV0U3RyZWFtLgorICBJc3N1ZTogQ09NUFJFU1MtNDUzLgorCitSZWxlYXNlIDEuMTYuMQorLS0tLS0tLS0tLS0tLS0KKworRml4ZWQgQnVnOgorbyBGaXhlZCB0aGUgT1NHaSBtYW5pZmVzdCBlbnRyeSBmb3IgaW1wb3J0cyB0aGF0IGhhcyBiZWVuIGJyb2tlbgorICBpbiAxLjE2LgorICBJc3N1ZTogQ09NUFJFU1MtNDQyLgorCitSZWxlYXNlIDEuMTYKKy0tLS0tLS0tLS0tLQorCitOZXcgZmVhdHVyZXM6CitvIEFkZCByZWFkLW9ubHkgc3VwcG9ydCBmb3IgWnN0YW5kYXJkIGNvbXByZXNzaW9uIGJhc2VkIG9uIHRoZQorICBac3RkLWpuaSBwcm9qZWN0LgorICBJc3N1ZTogQ09NUFJFU1MtNDIzLiBUaGFua3MgdG8gQW5kcmUgRiBkZSBNaXJhbmRhLgorbyBBZGRlZCBhdXRvLWRldGVjdGlvbiBmb3IgWnN0YW5kYXJkIGNvbXByZXNzZWQgc3RyZWFtcy4KKyAgSXNzdWU6IENPTVBSRVNTLTQyNS4KK28gQWRkZWQgd3JpdGUtc3VwcG9ydCBmb3IgWnN0YW5kYXJkIGNvbXByZXNzaW9uLgorICBJc3N1ZTogQ09NUFJFU1MtNDI2LgorbyBBZGRlZCByZWFkLW9ubHkgREVGTEFURTY0IHN1cHBvcnQgdG8gWklQIGFyY2hpdmVzIGFuZCBhcworICBzdGFuZC1hbG9uZSBDb21wcmVzc29ySW5wdXRTdHJlYW0uCisgIElzc3VlOiBDT01QUkVTUy0zODAuIFRoYW5rcyB0byBDaHJpc3RpYW4gTWFycXVleiBHcmFiaWEuCitvIEFkZGVkIHJlYWQtb25seSBERUZMQVRFNjQgc3VwcG9ydCB0byA3eiBhcmNoaXZlcy4KKyAgSXNzdWU6IENPTVBSRVNTLTQzNy4KKworRml4ZWQgQnVnczoKK28gU3luY2hyb25pemVkIGl0ZXJhdGlvbiBvdmVyIGEgc3luY2hyb25pemVkTGlzdCBpbgorICBQYXJhbGxlbFNjYXR0ZXJaaXBDcmVhdG9yLgorICBJc3N1ZTogQ09NUFJFU1MtNDMwLiBUaGFua3MgdG8gQnJ1bm8gUC4gS2lub3NoaXRhLgorbyBaaXBGaWxlIGNvdWxkIGdldCBzdHVjayBpbiBhbiBpbmZpbml0ZSBsb29wIHdoZW4gcGFyc2luZyBaSVAKKyAgYXJjaGl2ZXMgd2l0aCBjZXJ0YWluIHN0cm9uZyBlbmNyeXB0aW9uIGhlYWRlcnMuCisgIElzc3VlOiBDT01QUkVTUy00MzIuCitvIEFkZGVkIGltcHJvdmVkIGNoZWNrcyB0byBkZXRlY3QgY29ycnVwdGVkIGJ6aXAyIHN0cmVhbXMgYW5kCisgIHRocm93IHRoZSBleHBlY3RlZCBJT0V4Y2VwdGlvbiByYXRoZXIgdGhhbiBvYnNjdXJlCisgIFJ1bnRpbWVFeGNlcHRpb25zLgorICBJc3N1ZTogQ09NUFJFU1MtNDI0LgorCitDaGFuZ2VzOgorbyBSZXBsYWNlcyBpbnN0YW5jZW9mIGNoZWNrcyB3aXRoIGEgdHlwZSBtYXJrZXIgaW4gTFo3NyBzdXBwb3J0IGNvZGUuCisgIElzc3VlOiBDT01QUkVTUy00MzUuIFRoYW5rcyB0byBCRUxVR0EgQkVIUi4KK28gVXBkYXRlZCBYWiBmb3IgSmF2YSBkZXBlbmRlbmN5IHRvIDEuOCBpbiBvcmRlciB0byBwaWNrIHVwIGJ1ZyBmaXgKKyAgdG8gTFpNQTJJbnB1dFN0cmVhbSdzIGF2YWlsYWJsZSBtZXRob2QuCitvIFppcEFyY2hpdmVFbnRyeSBub3cgZXhwb3NlcyBob3cgdGhlIG5hbWUgb3IgY29tbWVudCBoYXZlIGJlZW4KKyAgZGV0ZXJtaW5lZCB3aGVuIHRoZSBlbnRyeSB3YXMgcmVhZC4KKyAgSXNzdWU6IENPTVBSRVNTLTQyOS4gVGhhbmtzIHRvIERhbWlhbm8gQWxiYW5pLgorbyBaaXBGaWxlLmdldElucHV0U3RyZWFtIHdpbGwgbm93IGFsd2F5cyBidWZmZXIgdGhlIHN0cmVhbQorICBpbnRlcm5hbGx5IGluIG9yZGVyIHRvIGltcHJvdmUgcmVhZCBwZXJmb3JtYW5jZS4KKyAgSXNzdWU6IENPTVBSRVNTLTQzOC4KK28gU3BlZWQgaW1wcm92ZW1lbnQgZm9yIERFRkxBVEU2NCBkZWNvbXByZXNzaW9uLgorICBJc3N1ZTogQ09NUFJFU1MtNDQwLiBUaGFua3MgdG8gRGF3aWQgV2Vpc3MuCitvIEFkZGVkIGEgZmV3IGV4dHJhIHNhbml0eSBjaGVja3MgZm9yIHRoZSByYXJlciBjb21wcmVzc2lvbgorICBtZXRob2RzIHVzZWQgaW4gWklQIGFyY2hpdmVzLgorICBJc3N1ZTogQ09NUFJFU1MtNDM2LgorbyBTaW1wbGlmaWVkIHRoZSBzcGVjaWFsIGhhbmRsaW5nIGZvciB0aGUgZHVtbXkgYnl0ZSByZXF1aXJlZCBieQorICB6bGliIHdoZW4gdXNpbmcgamF2YS51dGlsLnppcC5JbmZsYXRlci4KKyAgSXNzdWU6IENPTVBSRVNTLTQ0MS4KK28gVmFyaW91cyBjb2RlIGNsZWFudXBzLgorICBHaXRodWIgUHVsbCBSZXF1ZXN0ICM2MS4gVGhhbmtzIHRvIFNoYWhhYiBLb25kcmkuCitvIFRhckFyY2hpdmVFbnRyeSdzIHByZXNlcnZlTGVhZGluZ1NsYXNoZXMgY29uc3RydWN0b3IgYXJndW1lbnQKKyAgaGFzIGJlZW4gcmVuYW1lZCBhbmQgY2FuIG5vdyBhbHNvIGJlIHVzZWQgdG8gcHJlc2VydmUgdGhlCisgIGRyaXZlIGxldHRlciBvbiBXaW5kb3dzLgorCitSZWxlYXNlIDEuMTUKKy0tLS0tLS0tLS0tLQorCitOZXcgZmVhdHVyZXM6CitvIEFkZGVkIG1hZ2ljIE1BTklGRVNUIGVudHJ5IEF1dG9tYXRpYy1Nb2R1bGUtTmFtZSBzbyB0aGUgbW9kdWxlCisgIG5hbWUgd2lsbCBiZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3Mgd2hlbiB0aGUgamFyIGlzIHVzZWQKKyAgYXMgYW4gYXV0b21hdGljIG1vZHVsZSBpbiBKYXZhOS4KKyAgSXNzdWU6IENPTVBSRVNTLTM5Ny4KK28gQWRkZWQgYSBuZXcgdXRpbGl0eSBjbGFzcyBGaXhlZExlbmd0aEJsb2NrT3V0cHV0U3RyZWFtIHRoYXQKKyAgY2FuIGJlIHVzZWQgdG8gZW5zdXJlIHdyaXRpbmcgYWx3YXlzIGhhcHBlbnMgaW4gYmxvY2tzIG9mIGEKKyAgZ2l2ZW4gc2l6ZS4KKyAgSXNzdWU6IENPTVBSRVNTLTQwNS4gVGhhbmtzIHRvIFNpbW9uIFNwZXJvLgorbyBJdCBpcyBub3cgcG9zc2libGUgdG8gc3BlY2lmeS9yZWFkIGN1c3RvbSBQQVggaGVhZGVycyB3aGVuCisgIHdyaXRpbmcvcmVhZGluZyB0YXIgYXJjaGl2ZXMuCisgIElzc3VlOiBDT01QUkVTUy00MDAuIFRoYW5rcyB0byBTaW1vbiBTcGVyby4KKworRml4ZWQgQnVnczoKK28gTWFrZSBzdXJlICJ2ZXJzaW9uIG5lZWRlZCB0byBleHRyYWN0IiBpbiBsb2NhbCBmaWxlIGhlYWRlciBhbmQKKyAgY2VudHJhbCBkaXJlY3Rvcnkgb2YgYSBaSVAgYXJjaGl2ZSBhZ3JlZSB3aXRoIGVhY2ggb3RoZXIuCisgIEFsc28gZW5zdXJlIHRoZSB2ZXJzaW9uIGlzIHNldCB0byAyLjAgaWYgREVGTEFURSBpcyB1c2VkLgorICBJc3N1ZTogQ09NUFJFU1MtMzk0LgorbyBEb24ndCB1c2UgYSBkYXRhIGRlc2NyaXB0b3IgaW4gWklQIGFyY2hpdmVzIHdoZW4gY29weWluZyBhIHJhdworICBlbnRyeSB0aGF0IGFscmVhZHkga25vd3MgaXRzIHNpemUgYW5kIENSQyBpbmZvcm1hdGlvbi4KKyAgSXNzdWU6IENPTVBSRVNTLTM5NS4KK28gVHJhdmlzIGJ1aWxkIHJlZHVuZGFudGx5IHJlcGVhdHMgY29tcGlsYXRpb24gYW5kIHRlc3RzIHJlZHVuZGFudGx5CisgIEdpdEh1YiBQdWxsIFJlcXVlc3QgIzQzLiBUaGFua3MgdG8gU2ltb24gU3Blcm8uCisgIElzc3VlOiBDT01QUkVTUy00MTMKK28gVGhlIE1BTklGRVNUIG9mIDEuMTQgbGFja3MgYW4gT1NHaSBJbXBvcnQtUGFja2FnZSBmb3IgWFogZm9yCisgIEphdmEuCisgIElzc3VlOiBDT01QUkVTUy0zOTYuCitvIEJVSUxESU5HLm1kIG5vdyBwYXNzZXMgdGhlIFJBVCBjaGVjay4KKyAgSXNzdWU6IENPTVBSRVNTLTQwNi4gVGhhbmtzIHRvIFNpbW9uIFNwZXJvLgorbyBNYWRlIHN1cmUgQ2hlY2tzdW1DYWxjdWxhdGluZ0lucHV0U3RyZWFtIHJlY2VpdmVzIHZhbGlkCisgIGNoZWNrc3VtIGFuZCBpbnB1dCBzdHJlYW0gaW5zdGFuY2VzIHZpYSB0aGUgY29uc3RydWN0b3IuCisgIElzc3VlOiBDT01QUkVTUy00MTIuIFRoYW5rcyB0byBNaWNoYWVsIEhhdXNlZ2dlci4KK28gVGFyQXJjaGl2ZU91dHB1dFN0cmVhbSBub3cgdmVyaWZpZXMgdGhlIGJsb2NrIGFuZCByZWNvcmQgc2l6ZXMKKyAgc3BlY2lmaWVkIGF0IGNvbnN0cnVjdGlvbiB0aW1lIGFyZSBjb21wYXRpYmxlIHdpdGggdGhlIHRhcgorICBzcGVjaWZpY2F0aW9uLiBJbiBwYXJ0aWN1bGFyIDUxMiBpcyB0aGUgb25seSByZWNvcmQgc2l6ZQorICBhY2NlcHRlZCBhbmQgdGhlIGJsb2NrIHNpemUgbXVzdCBiZSBhIG11bHRpcGxlIG9mIDUxMi4KKyAgSXNzdWU6IENPTVBSRVNTLTQwNy4gVGhhbmtzIHRvIFNpbW9uIFNwZXJvLgorbyBGaXhlZCBjbGFzcyBuYW1lcyBvZiBDcGlvQXJjaGl2ZUVudHJ5IGFuZAorICBDcGlvQXJjaGl2ZUlucHV0U3RyZWFtIGluIHZhcmlvdXMgSmF2YWRvY3MuCisgIElzc3VlOiBDT01QUkVTUy00MTUuCitvIFRoZSBjb2RlIG9mIHRoZSBleHRlbmRlZCB0aW1lc3RhbXAgemlwIGV4dHJhIGZpZWxkIGluY29ycmVjdGx5CisgIGFzc3VtZWQgdGhlIHRpbWUgd2FzIHN0b3JlZCBhcyB1bnNpZ25lZCAzMi1iaXQgaW50IGFuZCB0aHVzCisgIGNyZWF0ZWQgaW5jb3JyZWN0IHJlc3VsdHMgZm9yIHllYXJzIGFmdGVyIDIwMzcuCisgIElzc3VlOiBDT01QUkVTUy00MTYuIFRoYW5rcyB0byBTaW1vbiBTcGVyby4KK28gUmVtb3ZlZCBaaXBFbmNvZGluZyBjb2RlIHRoYXQgYmVjYW1lIG9ic29sZXRlIHdoZW4gd2Ugc3RhcnRlZAorICB0byByZXF1aXJlIEphdmEgNSBhcyBiYXNlbGluZSBsb25nIGFnby4KKyAgSXNzdWU6IENPTVBSRVNTLTQxMC4gVGhhbmtzIHRvIFNpbW9uIFNwZXJvLgorbyBUaGUgdGFyIHBhY2thZ2Ugd2lsbCBubyBsb25nZXIgdHJ5IHRvIHBhcnNlIHRoZSBtYWpvciBhbmQKKyAgbWlub3IgZGV2aWNlIG51bWJlcnMgdW5sZXNzIHRoZSBlbnRyeSByZXByZXNlbnRzIGEgY2hhcmFjdGVyCisgIG9yIGJsb2NrIHNwZWNpYWwgZmlsZS4KKyAgSXNzdWU6IENPTVBSRVNTLTQxNy4KK28gV2hlbiByZWFkaW5nIHRhciBoZWFkZXJzIHdpdGggbmFtZSBmaWVsZHMgY29udGFpbmluZyBlbWJlZGRlZAorICBOVUxzLCB0aGUgbmFtZSB3aWxsIG5vdyBiZSB0ZXJtaW5hdGVkIGF0IHRoZSBmaXJzdCBOVUwgYnl0ZS4KKyAgSXNzdWU6IENPTVBSRVNTLTQyMS4gVGhhbmtzIHRvIFJvZWwgU3BpbGtlci4KK28gU2ltcGxpZmllZCBUYXJBcmNoaXZlT3V0cHV0U3RyZWFtIGJ5IHJlcGxhY2luZyB0aGUgaW50ZXJuYWwKKyAgYnVmZmVyaW5nIHdpdGggbmV3IGNsYXNzIEZpeGVkTGVuZ3RoQmxvY2tPdXRwdXRTdHJlYW0uCisgIElzc3VlOiBDT01QUkVTUy00MDkuCisKK1JlbGVhc2UgMS4xNAorLS0tLS0tLS0tLS0tCisKK05ldyBmZWF0dXJlczoKK28gQWRkZWQgd3JpdGUgc3VwcG9ydCBmb3IgU25hcHB5LgorICBJc3N1ZTogQ09NUFJFU1MtMjQ2LgorbyBBZGRlZCBzdXBwb3J0IGZvciBMWjQgKGJsb2NrIGFuZCBmcmFtZSBmb3JtYXQpLgorICBJc3N1ZTogQ09NUFJFU1MtMjcxLgorbyBBZGQgc3RhdGljIGRldGVjdChJbnB1dFN0cmVhbSBpbikgdG8gQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkKKyAgYW5kIEFyY2hpdmVTdHJlYW1GYWN0b3J5CisgIElzc3VlOiBDT01QUkVTUy0zODUuCitvIEFkZGVkIGEgd2F5IHRvIGxpbWl0IGFtb3VudCBvZiBtZW1vcnkgWkNvbXByZXNzb3JTdHJlYW0gbWF5CisgIHVzZS4KKyAgSXNzdWU6IENPTVBSRVNTLTM4Mi4gVGhhbmtzIHRvIFRpbSBBbGxpc29uLgorbyBBZGRlZCBhIHdheSB0byBsaW1pdCBhbW91bnQgb2YgbWVtb3J5IFpDb21wcmVzc29yU3RyZWFtIG1heQorICB1c2UuCisgIElzc3VlOiBDT01QUkVTUy0zODYuIFRoYW5rcyB0byBUaW0gQWxsaXNvbi4KK28gQWRkZWQgYSB3YXkgdG8gbGltaXQgYW1vdW50IG9mIG1lbW9yeSBMWk1BQ29tcHJlc3NvclN0cmVhbSBhbmQKKyAgWFpDb21wcmVzc29ySW5wdXRTdHJlYW0gbWF5IHVzZS4KKyAgSXNzdWU6IENPTVBSRVNTLTM4Mi4gVGhhbmtzIHRvIFRpbSBBbGxpc29uLgorbyBBZGQgQnJvdGxpIGRlY29kZXIgYmFzZWQgb24gdGhlIEdvb2dsZSBCcm90bGkgbGlicmFyeS4KKyAgSXNzdWU6IENPTVBSRVNTLTM5Mi4gVGhhbmtzIHRvIFBoaWxpcHBlIE1vdWF3YWQuCitvIFppcEVudHJ5IG5vdyBleHBvc2VzIGl0cyBkYXRhIG9mZnNldC4KKyAgSXNzdWU6IENPTVBSRVNTLTM5MC4gVGhhbmtzIHRvIFpieW5layBWeXNrb3Zza3kuCitvIFVzaW5nIFppcEFyY2hpdmVFbnRyeSdzIHNldEFsaWdubWVudCBpdCBpcyBub3cgcG9zc2libGUgdG8KKyAgZW5zdXJlIHRoZSBkYXRhIG9mZnNldCBvZiBhbiBlbnRyeSBzdGFydHMgYXQgYSBmaWxlIHBvc2l0aW9uCisgIHRoYXQgYXQgd29yZCBvciBwYWdlIGJvdW5kYXJpZXMuCisgIEEgbmV3IGV4dHJhIGZpZWxkIGhhcyBiZWVuIGFkZGVkIGZvciB0aGlzIHB1cnBvc2UuCisgIElzc3VlOiBDT01QUkVTUy0zOTEuIFRoYW5rcyB0byBaYnluZWsgVnlza292c2t5LgorCitGaXhlZCBCdWdzOgorbyBTbmFwcHlDb21wcmVzc29ySW5wdXRTdHJlYW0gc2xpZGVzIHRoZSB3aW5kb3cgdG9vIGVhcmx5CisgIGxlYWRpbmcgdG8gQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9ucyBmb3Igc29tZSBzdHJlYW1zLgorICBJc3N1ZTogQ09NUFJFU1MtMzc4LgorbyBaaXBBcmNoaXZlRW50cnkjaXNVbml4U3ltbGluayBub3cgb25seSByZXR1cm5zIHRydWUgaWYgdGhlCisgIGNvcnJlc3BvbmRpbmcgbGluayBmbGFnIGlzIHRoZSBvbmx5IGZpbGUtdHlwZSBmbGFnIHNldC4KKyAgSXNzdWU6IENPTVBSRVNTLTM3OS4gVGhhbmtzIHRvIEd1aWxsYXVtZSBCb3XDqS4KK28gRml4ZWQgYW4gaW50ZWdlciBvdmVyZmxvdyBpbiBDUElPJ3MgQ1JDIGNhbGN1bGF0aW9uLgorICBQdWxsIFJlcXVlc3QgIzE3LiBUaGFua3MgdG8gRGFuaWVsIENvbGxpbi4KK28gTWFrZSB1bml0IHRlc3RzIHdvcmsgb24gV2luZG93cyBwYXRocyB3aXRoIHNwYWNlcyBpbiB0aGVpciBuYW1lcy4KKyAgSXNzdWU6IENPTVBSRVNTLTM4Ny4KK28gSW50ZXJuYWwgbG9jYXRpb24gcG9pbnRlciBpbiBaaXBGaWxlIGNvdWxkIGdldCBpbmNyZW1lbnRlZAorICBldmVuIGlmIG5vdGhpbmcgaGFkIGJlZW4gcmVhZC4KKyAgSXNzdWU6IENPTVBSRVNTLTM4OS4KK28gTFpNQUNvbXByZXNzb3JPdXRwdXRTdHJlYW0jZmx1c2ggd291bGQgdGhyb3cgYW4gZXhjZXB0aW9uCisgIHJhdGhlciB0aGFuIGJlIHRoZSBOT1AgaXQgcHJvbWlzZWQgdG8gYmUuCisgIElzc3VlOiBDT01QUkVTUy0zOTMuCisKK0NoYW5nZXM6CitvIFRoZSBibG9ja3NpemUgZm9yIEZyYW1lZFNuYXBweUNvbXByZXNzb3JJbnB1dFN0cmVhbSBjYW4gbm93IGJlCisgIGNvbmZpZ3VyZWQgYXMgc29tZSBJV0EgZmlsZXMgc2VlbSB0byBiZSB1c2luZyBibG9ja3MgbGFyZ2VyCisgIHRoYW4gdGhlIGRlZmF1bHQgMzJrLgorICBJc3N1ZTogQ09NUFJFU1MtMzU4LgorbyBCWmlwMkNvbXByZXNzb3JJbnB1dHN0cmVhbSBub3cgdXNlcyBCaXRJbnB1dFN0cmVhbSBpbnRlcm5hbGx5LgorICBQdWxsIFJlcXVlc3QgIzEzLiBUaGFua3MgdG8gVGhvbWFzIE1leWVyLgorbyBJbXByb3ZlZCBwZXJmb3JtYW5jZSBmb3IgY29uY3VycmVudCByZWFkcyBmcm9tIFppcEZpbGUgd2hlbgorICByZWFkaW5nIGZyb20gYSBmaWxlLgorICBJc3N1ZTogQ09NUFJFU1MtMzg4LiBUaGFua3MgdG8gWmJ5bmVrIFZ5c2tvdnNreS4KKworUmVsZWFzZSAxLjEzCistLS0tLS0tLS0tLS0KKworQ29tbW9ucyBDb21wcmVzcyAxLjEzIGlzIHRoZSBmaXJzdCB2ZXJzaW9uIHRvIHJlcXVpcmUgSmF2YSA3IGF0CitydW50aW1lLgorCitDaGFuZ2VzIGluIHRoaXMgdmVyc2lvbiBpbmNsdWRlOgorCitOZXcgZmVhdHVyZXM6CitvIFNldmVuWkZpbGUsIFNldmVuWk91dHB1dEZpbGUsIFppcEZpbGUgYW5kCisgIFppcEFyY2hpdmVPdXRwdXRTdHJlYW0gY2FuIG5vdyB3b3JrIG9uIG5vbi1maWxlIHJlc291cmNlcyBpZgorICB0aGV5IGNhbiBiZSBhY2Nlc3NlZCB2aWEgU2Vla2FibGVCeXRlQ2hhbm5lbC4KKyAgSXNzdWU6IENPTVBSRVNTLTMyNy4KK28gQWxsb3cgY29tcHJlc3NvciBleHRlbnNpb25zIHRocm91Z2ggYSBzdGFuZGFyZCBKUkUgU2VydmljZUxvYWRlci4KKyAgSXNzdWU6IENPTVBSRVNTLTM2OC4KK28gQWxsb3cgYXJjaGl2ZSBleHRlbnNpb25zIHRocm91Z2ggYSBzdGFuZGFyZCBKUkUgU2VydmljZUxvYWRlci4KKyAgSXNzdWU6IENPTVBSRVNTLTM2OS4KK28gQWRkIHdyaXRlIHN1cHBvcnQgZm9yIHRoZSBsZWdhY3kgTFpNQSBmb3JtYXQsIHRoaXMgcmVxdWlyZXMgWFoKKyAgZm9yIEphdmEgMS42LgorICBJc3N1ZTogQ09NUFJFU1MtMzczLgorbyBBZGQgd3JpdGUgc3VwcG9ydCBmb3IgdGhlIGxlZ2FjeSBMWk1BIHN0cmVhbSB0byA3eiwgdGhpcworICByZXF1aXJlcyBYWiBmb3IgSmF2YSAxLjYuCisgIElzc3VlOiBDT01QUkVTUy0zNzQuCitvIEFsbG93IHRoZSBjbGllbnRzIG9mIFBhcmFsbGVsU2NhdHRlclppcENyZWF0b3IgdG8gcHJvdmlkZQorICBaaXBBcmNoaXZlRW50cnlSZXF1ZXN0U3VwcGxpZXIuCisgIElzc3VlOiBDT01QUkVTUy0zNzUuIFRoYW5rcyB0byBQbGFtZW4gVG90ZXYuCitvIEFkZCBhIHZlcnNpb24taW5kZXBlbmRlbnQgbGluayB0byB0aGUgQVBJIGRvY3Mgb2YgdGhlIGxhdGVzdAorICByZWxlYXNlLgorICBJc3N1ZTogQ09NUFJFU1MtMzcyLgorCitGaXhlZCBCdWdzOgorbyBCaXRJbnB1dFN0cmVhbSBjb3VsZCByZXR1cm4gYmFkIHJlc3VsdHMgd2hlbiBvdmVyZmxvd2luZworICBpbnRlcm5hbGx5IC0gaWYgdHdvIGNvbnNlY3V0aXZlIHJlYWRzIHRyaWVkIHRvIHJlYWQgbW9yZSB0aGFuCisgIDY0IGJpdHMuCisgIElzc3VlOiBDT01QUkVTUy0zNjMuCitvIFppcEFyY2hpdmVJbnB1dFN0cmVhbS5jbG9zZUVudHJ5IGRvZXMgbm90IHByb3Blcmx5IGFkdmFuY2UgdG8KKyAgbmV4dCBlbnRyeSBpZiB0aGVyZSBhcmUganVuayBieXRlcyBhdCBlbmQgb2YgZGF0YSBzZWN0aW9uLgorICBJc3N1ZTogQ09NUFJFU1MtMzY0LiBUaGFua3MgdG8gTWlrZSBNb2xlLgorbyBaaXBBcmNoaXZlSW5wdXRTdHJlYW0gbm93IHRocm93cyBhbiBFeGNlcHRpb24gaWYgaXQgZW5jb3VudGVycworICBhIGJyb2tlbiBaSVAgYXJjaGl2ZSByYXRoZXIgdGhhbiBzaWduYWxpbmcgZW5kLW9mLWFyY2hpdmUuCisgIElzc3VlOiBDT01QUkVTUy0zNjcuIFRoYW5rcyB0byBNaWtlIE1vbGUuCitvIFNjYXR0ZXJaaXBPdXRwdXRTdHJlYW0gZGlkbid0IGNsb3NlIHRoZSBTdHJlYW1Db21wcmVzc29yCisgIGNhdXNpbmcgYSBwb3RlbnRpYWwgcmVzb3VyY2UgbGVhay4KKyAgSXNzdWU6IENPTVBSRVNTLTM3Ny4KKworQ2hhbmdlczoKK28gVXBkYXRlIEphdmEgcmVxdWlyZW1lbnQgZnJvbSA2IHRvIDcuCisgIElzc3VlOiBDT01QUkVTUy0zNjAuCitvIENsYXJpZmllZCB3aGljaCBUYXJBcmNoaXZlRW50cnkgbWV0aG9kcyBhcmUgdXNlbGVzcyBmb3IKKyAgZW50cmllcyByZWFkIGZyb20gYW4gYXJjaGl2ZS4KKyAgSXNzdWU6IENPTVBSRVNTLTM2Ni4KKworUmVsZWFzZSAxLjEyCistLS0tLS0tLS0tLS0KKworQ29tbW9ucyBDb21wcmVzcyAxLjEyIGlzIHRoZSBmaXJzdCB2ZXJzaW9uIHRvIHJlcXVpcmUgSmF2YSA2IGF0CitydW50aW1lLgorCitSZWxlYXNlIDEuMTIgY2hhbmdlcyB0aGUgYmVoYXZpb3Igb2YgQlppcDJDb21wcmVzc29yT3V0cHV0U3RyZWFtJ3MKK2ZpbmFsaXplIG1ldGhvZCBzbyB0aGF0IGl0IG5vIGxvbmdlciBpbnZva2VzIGZpbmlzaC4gVGhpcyBpcyBnb2luZyB0bworYnJlYWsgY29kZSB0aGF0IHJlbGllZCBvbiB0aGUgZmluYWxpemVyIHRvIGNsZWFuIHVwIGFuIHVuZmluaXNoZWQKK3N0cmVhbS4gVGhlIGNvZGUgd2lsbCBuZWVkIHRvIGJlIGNoYW5nZWQgdG8gY2FsbCBmaW5pc2ggb3IgY2xvc2UKK2l0c2VsZi4gTm90ZSB0aGF0IGEgZmluYWxpemVyIGlzIG5vdCBndWFyYW50ZWVkIHRvIHJ1biwgc28gdGhlIGZlYXR1cmUKK3dhcyBub3QgMTAwJSBlZmZlY3RpdmUgaW4gYW55IGNhc2UuCisKK05ldyBmZWF0dXJlczoKKworbyBGcmFtZWRTbmFwcHlDb21wcmVzc29ySW5wdXRTdHJlYW0gbm93IHN1cHBvcnRzIHRoZSBkaWFsZWN0IG9mCisgIFNuYXBweSB1c2VkIGJ5IHRoZSBJV0EgZmlsZXMgY29udGFpbmVkIHdpdGhpbiB0aGUgemlwIGFyY2hpdmVzCisgIHVzZWQgaW4gQXBwbGUncyBpV29yayAxMyBmaWxlcy4KKyAgSXNzdWU6IENPTVBSRVNTLTM1Mi4KKworRml4ZWQgQnVnczoKKworbyBTZXZlblpGaWxlLnJlYWQoKSB0aHJvd3MgYW4gSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGZvciBlbXB0eSBlbnRyaWVzLgorICBJc3N1ZTogQ09NUFJFU1MtMzQ4LgorbyBUYXJBcmNoaXZlSW5wdXRTdHJlYW0gZmFpbGVkIHRvIHBhcnNlIFBBWCBoZWFkZXJzIHRoYXQgaW5jbHVkZWQKKyAgYmxhbmsgbGluZXMuCisgIElzc3VlOiBDT01QUkVTUy0zNTUuIFRoYW5rcyB0byBKZXJlbXkgR3VzdGllLgorbyBUYXJBcmNoaXZlSW5wdXRTdHJlYW0gZmFpbGVkIHRvIHBhcnNlIFBBWCBoZWFkZXJzIHdob3NlIHRhciBlbnRyeQorICBuYW1lIGVuZGVkIHdpdGggYSBzbGFzaC4KKyAgSXNzdWU6IENPTVBSRVNTLTM1Ni4gVGhhbmtzIHRvIEplcmVteSBHdXN0aWUuCisKK0NoYW5nZXM6CitvIFVwZGF0ZSByZXF1aXJlbWVudCBmcm9tIEphdmEgNSB0byA2LgorICBJc3N1ZTogQ09NUFJFU1MtMzQ5LgorbyBUYXJBcmNoaXZlRW50cnkgd2FzdGVmdWxseSBhbGxvY2F0ZXMgZW1wdHkgYXJyYXlzLgorICBJc3N1ZTogQ09NUFJFU1MtMzUwLgorbyBKYXZhZG9jIGZvciBCWmlwMkNvbXByZXNzb3JJbnB1dFN0cmVhbShJbnB1dFN0cmVhbSwgYm9vbGVhbikgc2hvdWxkCisgIHJlZmVyIHRvIElPRXgsIG5vdCBOUEUuCisgIElzc3VlOiBDT01QUkVTUy0zNTMuCitvIFB1cmVKYXZhQ3JjMzJDIGluIHRoZSBzbmFwcHkgcGFja2FnZSBpcyBub3cgZmluYWwgc28gaXQgaXMgbm93IHNhZmUKKyAgdG8gY2FsbCBhIHZpcnR1YWwgbWV0aG9kIGluc2lkZSB0aGUgY29uc3RydWN0b3IuCisgIElzc3VlOiBDT01QUkVTUy0zNTQuCisKK28gWmlwQXJjaGl2ZUlucHV0U3RyZWFtIGFuZCBDcGlvQXJjaGl2ZUlucHV0U3RyZWFtIGNvdWxkIHRocm93CisgIGV4Y2VwdGlvbnMgd2hvJ3MgbWVzc2FnZXMgY29udGFpbmVkIHBvdGVudGlhbGx5IGNvcnJ1cHQgZW50cnkgbmFtZXMKKyAgcmVhZCBmcm9tIGEgYnJva2VuIGFyY2hpdmUuIFRoZXkgd2lsbCBub3cgc2FuaXRpemUgdGhlIG5hbWVzIGJ5CisgIHJlcGxhY2luZyB1bnByaW50YWJsZSBjaGFyYWN0ZXJzIGFuZCByZXN0cmljdGluZyB0aGUgbGVuZ3RoIHRvIDI1NQorICBjaGFyYWN0ZXJzLgorICBJc3N1ZTogQ09NUFJFU1MtMzUxLgorbyBCWmlwMkNvbXByZXNzb3JPdXRwdXRTdHJlYW0gbm8gbG9uZ2VyIHRyaWVzIHRvIGZpbmlzaCB0aGUgb3V0cHV0CisgIHN0cmVhbSBpbiBmaW5hbGl6ZS4gVGhpcyBpcyBhIGJyZWFraW5nIGNoYW5nZSBmb3IgY29kZSB0aGF0IHJlbGllZAorICBvbiB0aGUgZmluYWxpemVyLgorICBJc3N1ZTogQ09NUFJFU1MtMzU3LgorCisKK1JlbGVhc2UgMS4xMQorLS0tLS0tLS0tLS0tCisKK05ldyBmZWF0dXJlczoKK28gVGFyQXJjaGl2ZUlucHV0U3RyZWFtIG5vdyBzdXBwb3J0cyByZWFkaW5nIGdsb2JhbCBQQVggaGVhZGVycy4KKyAgSXNzdWU6IENPTVBSRVNTLTM0Ny4KK28gVGhlIFBBWCBoZWFkZXJzIGZvciBzcGFyc2UgZW50cmllcyB3cml0dGVuIGJ5IHN0YXIgYXJlIG5vdworICBhcHBsaWVkLgorICBJc3N1ZTogQ09NUFJFU1MtMzQ2LgorbyBHTlUgc3BhcnNlIGZpbGVzIHVzaW5nIG9uZSBvZiB0aGUgUEFYIGZvcm1hdHMgYXJlIG5vdworICBkZXRlY3RlZCwgYnV0IGNhbm5vdCBiZSBleHRyYWN0ZWQuCisgIElzc3VlOiBDT01QUkVTUy0zNDUuCitvIE5ldyBtZXRob2QgU2V2ZW5aRmlsZS5nZXRFbnRyaWVzIGNhbiBiZSB1c2VkIHRvIGxpc3QgdGhlCisgIGNvbnRlbnRzIG9mIGEgN3ogYXJjaGl2ZS4KKyAgSXNzdWU6IENPTVBSRVNTLTM0MS4KK28gV2hlbiB1c2luZyBaaXA2NE1vZGUuQWx3YXlzIGFsc28gdXNlIFpJUDY0IGV4dGVuc2lvbnMgaW5zaWRlCisgIHRoZSBjZW50cmFsIGRpcmVjdG9yeS4KKyAgR2l0SHViIFB1bGwgUmVxdWVzdCAjMTAgVGhhbmtzIHRvIE1hdHQgSG92ZXkuCitvIFppcEZpbGUuZ2V0UmF3SW5wdXRTdHJlYW0oKSBpcyBub3cgcGFydCBvZiB0aGUgcHVibGljIEFQSQorICBJc3N1ZTogQ09NUFJFU1MtMzIzLgorbyBBbGxvdyBieXRlLWZvci1ieXRlIHJlcGxpY2F0aW9uIG9mIFppcCBlbnRyaWVzLgorICBHaXRIdWIgUHVsbCBSZXF1ZXN0ICM2LiBUaGFua3MgdG8gSmFzb24gdmFuIFp5bC4KK28gVGFyQXJjaGl2ZUVudHJ5J3MgcHJlc2VydmVMZWFkaW5nU2xhc2hlcyBpcyBub3cgYSBwcm9wZXJ0eSBhbmQgdXNlZAorICBvbiBsYXRlciBjYWxscyB0byBzZXROYW1lLCB0b28uCisgIFRoaXMgYmVoYXZpb3IgaXMgYSBicmVha2luZyBjaGFuZ2UuCisgIElzc3VlOiBDT01QUkVTUy0zMjguCitvIEFkZGVkIHJlYWQtb25seSBzdXBwb3J0IGZvciBiemlwMiBjb21wcmVzc2lvbiB1c2VkIGluc2lkZSBvZgorICBaSVAgYXJjaGl2ZXMuCisgIEdpdEh1YiBQdWxsIFJlcXVlc3QgIzQuIFRoYW5rcyB0byBTw7ZyZW4gR2xpbW0uCisKK0ZpeGVkIEJ1Z3M6CitvIEFyQXJjaGl2ZUlucHV0U3RyZWFtIGNhbiBub3cgcmVhZCBHTlUgZXh0ZW5kZWQgbmFtZXMgdGhhdCBhcmUKKyAgdGVybWluYXRlZCB3aXRoIGEgTlVMIGJ5dGUgcmF0aGVyIHRoYW4gYSBsaW5lZmVlZC4KKyAgSXNzdWU6IENPTVBSRVNTLTM0NC4KK28gTmF0aXZlIE1lbW9yeSBMZWFrIGluIFNldmVuei1EZWZsYXRlRGVjb2Rlci4KKyAgSXNzdWU6IENPTVBSRVNTLTM0My4gVGhhbmtzIHRvIFJlbmUgUHJlaXNzZWwuCitvIFNldmVuWkZpbGUgd2lsbCBub3cgb25seSB0cnkgdG8gZHJhaW4gYW4gZW50cnkncyBjb250ZW50IHdoZW4KKyAgbW92aW5nIG9uIHRvIHRoZSBuZXh0IGVudHJ5IGlmIGRhdGEgaXMgcmVhZCBmcm9tIHRoZSBuZXh0CisgIGVudHJ5LiBUaGlzIHNob3VsZCBpbXByb3ZlIHBlcmZvcm1hbmNlIGZvciBhcHBsaWNhdGlvbnMgdGhhdAorICB0cnkgdG8gc2tpcCBvdmVyIGVudHJpZXMuCisgIElzc3VlOiBDT01QUkVTUy0zNDAuIFRoYW5rcyB0byBEYXdpZCBXZWlzcy4KK28gZmlsZSBuYW1lcyBvZiB0YXIgYXJjaGl2ZXMgdXNpbmcgdGhlIHhzdGFyIGZvcm1hdCBhcmUgbm93CisgIHBhcnNlZCBwcm9wZXJseS4KKyAgSXNzdWU6IENPTVBSRVNTLTMzNi4KK28gY2hlY2tzdW1zIG9mIHRhcnMgdGhhdCBwYWQgdGhlIGNoZWNrc3VtIGZpZWxkIHRvIHRoZSBsZWZ0IGFyZQorICBub3cgY2FsY3VsYXRlZCBwcm9wZXJseS4KKyAgSXNzdWU6IENPTVBSRVNTLTMzNS4KK28gQXJBcmNoaXZlSW5wdXRTdHJlYW0gZmFpbGVkIHRvIHJlYWQgcGFzdCB0aGUgZmlyc3QgZW50cnkgd2hlbgorICBCU0QgbG9uZyBuYW1lcyBoYXZlIGJlZW4gdXNlZC4KKyAgSXNzdWU6IENPTVBSRVNTLTMzNC4gVGhhbmtzIHRvIEplcmVteSBHdXN0aWUuCitvIEFkZGVkIGJ1ZmZlcmluZyBmb3IgcmFuZG9tIGFjY2VzcyB3aGljaCBzcGVlZHMgdXAgN1ogc3VwcG9ydC4KKyAgSXNzdWU6IENPTVBSRVNTLTMzMy4gVGhhbmtzIHRvIERhd2lkIFdlaXNzLgorbyBUaGUgY2hlY2tzdW0gdmFsaWRhdGlvbiBvZiBUYXJhcmNoaXZlRW50cnkgaXMgbm93IGFzIHN0cmljdCBhcworICB0aGUgdmFsaWRhdGlvbiBvZiBHTlUgdGFyLCB3aGljaCBlbGltaW5hdGVzIGEgZmV3IGNhc2VzIG9mCisgIGZhbHNlIHBvc2l0aXZlcyBvZiBBcmNoaXZlU3RyZWFtRmFjdG9yeS4KKyAgVGhpcyBiZWhhdmlvciBpcyBhIGJyZWFraW5nIGNoYW5nZSBzaW5jZSB0aGUgY2hlY2sgaGFzIGJlY29tZQorICBtb3JlIHN0cmljdCBidXQgYW55IGFyY2hpdmUgdGhhdCBmYWlscyB0aGUgY2hlY2tzdW0gdGVzdCBub3cKKyAgd291bGQgYWxzbyBmYWlsIGl0IHdoZW4gZXh0cmFjdGVkIHdpdGggb3RoZXIgdG9vbHMgYW5kIG11c3QgYmUKKyAgY29uc2lkZXJlZCBhbiBpbnZhbGlkIGFyY2hpdmUuCisgIElzc3VlOiBDT01QUkVTUy0zMzEuCitvIFNuYXBweUNvbXByZXNzb3JJbnB1dFN0cmVhbSBhbmQKKyAgRnJhbWVkU25hcHB5Q29tcHJlc3NvcklucHV0U3RyZWFtIHJldHVybmVkIDAgYXQgdGhlIGVuZCBvZiB0aGUKKyAgc3RyZWFtIHVuZGVyIGNlcnRhaW4gY2lyY3Vtc3RhbmNlcy4KKyAgSXNzdWU6IENPTVBSRVNTLTMzMi4KK28gQWRqdXN0ZWQgdW5pdCB0ZXN0IHRvIHVwZGF0ZXMgaW4gSmF2YTggYW5kIGxhdGVyIHRoYXQgY2hhbmdlCisgIHRoZSBsb2dpYyBvZiBaaXBFbnRyeSNnZXRUaW1lLgorICBJc3N1ZTogQ09NUFJFU1MtMzI2LgorbyBUYXJBcmNoaXZlT3V0cHV0U3RyZWFtIHdpbGwgbm93IHJlY29nbml6ZSBHTlUgbG9uZyBuYW1lIGFuZAorICBsaW5rIGVudHJpZXMgZXZlbiBpZiB0aGUgc3BlY2lhbCBlbnRyeSBoYXMgYSBkaWZmZXJlbnQgbmFtZQorICB0aGFuIEdOVSB0YXIgdXNlcyBpdHNlbGYuICBUaGlzIHNlZW1zIHRvIGJlIHRoZSBjYXNlIGZvcgorICBhcmNoaXZlcyBjcmVhdGVkIGJ5IHN0YXIuCisgIElzc3VlOiBDT01QUkVTUy0zMjQuCitvIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB3aGVuIEluZm9aSVAgdHlwZSA3ODc1IGV4dHJhCisgIGZpZWxkcyBhcmUgcmVhZCBmcm9tIHRoZSBjZW50cmFsIGRpcmVjdG9yeS4KKyAgSXNzdWU6IENPTVBSRVNTLTMyMS4KKworUmVsZWFzZSAxLjEwCistLS0tLS0tLS0tLS0KKworUmVsZWFzZSAxLjEwIG1vdmVzIHRoZSBmb3JtZXIKK29yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy56Ll9pbnRlcm5hbF8gcGFja2FnZSB3aGljaAorYnJlYWtzIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5IGZvciBjb2RlIHdoaWNoIHVzZWQgdGhlIG9sZCBwYWNrYWdlLgorCitUaGlzIGFsc28gY2hhbmdlcyB0aGUgc3VwZXJjbGFzcyBvZiBaQ29tcHJlc3NvcklucHV0U3RyZWFtIHdoaWNoIG1ha2VzCit0aGlzIGNsYXNzIGJpbmFyeSBpbmNvbXBhdGlibGUgd2l0aCB0aGUgb25lIG9mIENvbXByZXNzIDEuOS4gIENvZGUKK3RoYXQgZXh0ZW5kcyBaQ29tcHJlc3NvcklucHV0U3RyZWFtIHdpbGwgbmVlZCB0byBiZSByZWNvbXBpbGVkIGluCitvcmRlciB0byB3b3JrIHdpdGggQ29tcHJlc3MgMS4xMC4KKworTmV3IGZlYXR1cmVzOgorbyBDb21wcmVzc29yU3RyZWFtRmFjdG9yeSBjYW4gbm93IGF1dG8tZGV0ZWN0IERFRkxBVEUgc3RyZWFtcworICB3aXRoIFpMSUIgaGVhZGVyLgorICBJc3N1ZTogQ09NUFJFU1MtMzE2LiBUaGFua3MgdG8gTmljayBCdXJjaC4KK28gQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkgY2FuIG5vdyBhdXRvLWRldGVjdCBMWk1BIHN0cmVhbXMuCisgIElzc3VlOiBDT01QUkVTUy0zMTMuCitvIEFkZGVkIHN1cHBvcnQgZm9yIHBhcmFsbGVsIGNvbXByZXNzaW9uLiBUaGlzIGxvdy1sZXZlbCBBUEkgYWxsb3dzCisgIGEgY2xpZW50IHRvIGJ1aWxkIGEgemlwL2phciBmaWxlIGJ5IHVzaW5nIHRoZSBjbGFzcworICBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcC5QYXJhbGxlbFNjYXR0ZXJaaXBDcmVhdG9yLgorCisgIFppcCBkb2N1bWVudGF0aW9uIHVwZGF0ZWQgd2l0aCBmdXJ0aGVyIG5vdGVzIGFib3V0IHBhcmFsbGVsIGZlYXR1cmVzLgorCisgIFBsZWFzZSBub3RlIHRoYXQgc29tZSBhc3BlY3RzIG9mIGphciBjcmVhdGlvbiBuZWVkIHRvIGJlCisgIGhhbmRsZWQgYnkgY2xpZW50IGNvZGUgYW5kIGlzIG5vdCBwYXJ0IG9mIGNvbW1vbnMtY29tcHJlc3MgZm9yIHRoaXMKKyAgcmVsZWFzZS4KKyAgSXNzdWU6IENPTVBSRVNTLTI5Ni4gVGhhbmtzIHRvIEtyaXN0aWFuIFJvc2Vudm9sZC4KK28gQ3V0IG92ZXJhbGwgb2JqZWN0IGluc3RhbnRpYXRpb24gaW4gaGFsZiBieSBjaGFuZ2luZyBmaWxlCisgIGhlYWRlciBnZW5lcmF0aW9uIGFsZ29yaXRobSwgZm9yIGEgMTAtMTUgcGVyY2VudCBwZXJmb3JtYW5jZQorICBpbXByb3ZlbWVudC4KKworICBBbHNvIGV4dHJhY3RlZCB0d28gcHJpdmF0ZSBtZXRob2RzIGNyZWF0ZUxvY2FsRmlsZUhlYWRlcgorICBhbmQgY3JlYXRlQ2VudHJhbEZpbGVIZWFkZXIgaW4gWmlwQXJjaGl2ZU91dHB1dFN0cmVhbS4KKyAgVGhlc2UgbWF5IGhhdmUgc29tZSBpbnRlcmVzdGluZyBhZGRpdGlvbmFsIHVzYWdlcyBpbiB0aGUKKyAgbmVhciBmdXR1cmUuIFRoYW5rcyB0byBLcmlzdGlhbiBSb3NlbnZvbGQuCitvIE5ldyBtZXRob2RzIGluIFppcEFyY2hpdmVPdXRwdXRTdHJlYW0gYW5kIFppcEZpbGUgYWxsb3dzCisgIGVudHJpZXMgdG8gYmUgY29waWVkIGZyb20gb25lIGFyY2hpdmUgdG8gYW5vdGhlciB3aXRob3V0CisgIGhhdmluZyB0byByZS1jb21wcmVzcyB0aGVtLgorICBJc3N1ZTogQ09NUFJFU1MtMjk1LiBUaGFua3MgdG8gS3Jpc3RpYW4gUm9zZW52b2xkLgorCitGaXhlZCBCdWdzOgorbyBUYXJBcmNoaXZlSW5wdXRTdHJlYW0gY2FuIG5vdyByZWFkIGVudHJpZXMgd2l0aCBncm91cCBvcgorICB1c2VyIGlkcyA+IDB4ODAwMDAwMDAuCisgIElzc3VlOiBDT01QUkVTUy0zMTQuCitvIFRhckFyY2hpdmVPdXRwdXRTdHJlYW0gY2FuIG5vdyB3cml0ZSBlbnRyaWVzIHdpdGggZ3JvdXAgb3IKKyAgdXNlciBpZHMgPiAweDgwMDAwMDAwLgorICBJc3N1ZTogQ09NUFJFU1MtMzE1LgorbyBUYXJBcmNoaXZlRW50cnkncyBjb25zdHJ1Y3RvciB3aXRoIGEgRmlsZSBhbmQgYSBTdHJpbmcgYXJnCisgIGRpZG4ndCBub3JtYWxpemUgdGhlIG5hbWUuCisgIElzc3VlOiBDT01QUkVTUy0zMTIuCitvIFppcEVuY29kaW5nSGVscGVyIG5vIGxvbmdlciByZWFkcyBzeXN0ZW0gcHJvcGVydGllcyBkaXJlY3RseQorICB0byBkZXRlcm1pbmUgdGhlIGRlZmF1bHQgY2hhcnNldC4KKyAgSXNzdWU6IENPTVBSRVNTLTMwOC4KK28gQlppcDJDb21wcmVzc29ySW5wdXRTdHJlYW0jcmVhZCB3b3VsZCByZXR1cm4gLTEgd2hlbiBhc2tlZCB0bworICByZWFkIDAgYnl0ZXMuCisgIElzc3VlOiBDT01QUkVTUy0zMDkuCitvIEFyY2hpdmVTdHJlYW1GYWN0b3J5IGZhaWxzIHRvIHBhc3Mgb24gdGhlIGVuY29kaW5nIHdoZW4gY3JlYXRpbmcKKyAgc29tZSBzdHJlYW1zLgorICAgICogQXJqQXJjaGl2ZUlucHV0U3RyZWFtCisgICAgKiBDcGlvQXJjaGl2ZUlucHV0U3RyZWFtCisgICAgKiBEdW1wQXJjaGl2ZUlucHV0U3RyZWFtCisgICAgKiBKYXJBcmNoaXZlSW5wdXRTdHJlYW0KKyAgICAqIFRhckFyY2hpdmVJbnB1dFN0cmVhbQorICAgICogSmFyQXJjaGl2ZU91dHB1dFN0cmVhbQorICBJc3N1ZTogQ09NUFJFU1MtMzA2LgorbyBSZXN0b3JlIGltbXV0YWJpbGl0eS90aHJlYWQtc2FmZXR5IHRvIEFyY2hpdmVTdHJlYW1GYWN0b3J5LgorICBUaGUgY2xhc3MgaXMgbm93IGltbXV0YWJsZSBwcm92aWRlZCB0aGF0IHRoZSBtZXRob2Qgc2V0RW50cnlFbmNvZGluZworICBpcyBub3QgdXNlZC4gVGhlIGNsYXNzIGlzIHRocmVhZC1zYWZlLgorICBJc3N1ZTogQ09NUFJFU1MtMzAyLgorbyBSZXN0b3JlIGltbXV0YWJpbGl0eS90aHJlYWQtc2FmZXR5IHRvIENvbXByZXNzb3JTdHJlYW1GYWN0b3J5LgorICBUaGUgY2xhc3MgaXMgbm93IGltbXV0YWJsZSBwcm92aWRlZCB0aGF0IHRoZSBtZXRob2QKKyAgc2V0RGVjb21wcmVzc0NvbmNhdGVuYXRlZCBpcyBub3QgdXNlZC4gIFRoZSBjbGFzcyBpcyB0aHJlYWQtc2FmZS4KKyAgSXNzdWU6IENPTVBSRVNTLTMwMy4KK28gWmlwRmlsZSBsb2dzIGEgd2FybmluZyBpbiBpdHMgZmluYWxpemVyIHdoZW4gaXRzIGNvbnN0cnVjdG9yCisgIGhhcyB0aHJvd24gYW4gZXhjZXB0aW9uIHJlYWRpbmcgdGhlIGZpbGUgLSBmb3IgZXhhbXBsZSBpZiB0aGUKKyAgZmlsZSBkb2Vzbid0IGV4aXN0LgorICBJc3N1ZTogQ09NUFJFU1MtMjk3LgorbyBJbXByb3ZlZCBlcnJvciBtZXNzYWdlIHdoZW4gdGFyIGVuY291bnRlcnMgYSBncm91cElkIHRoYXQgaXMKKyAgdG9vIGJpZyB0byB3cml0ZSB3aXRob3V0IHVzaW5nIHRoZSBTVEFSIG9yIFBPU0lYIGZvcm1hdC4KKyAgSXNzdWU6IENPTVBSRVNTLTI5MC4gVGhhbmtzIHRvIEtyaXN0aWFuIFJvc2Vudm9sZC4KK28gU2V2ZW5aRmlsZSBub3cgdGhyb3dzIHRoZSBzcGVjaWZpYyBQYXNzd29yZFJlcXVpcmVkRXhjZXB0aW9uCisgIHdoZW4gaXQgZW5jb3VudGVycyBhbiBlbmNyeXB0ZWQgc3RyZWFtIGJ1dCBubyBwYXNzd29yZCBoYXMKKyAgYmVlbiBzcGVjaWZpZWQuCisgIElzc3VlOiBDT01QUkVTUy0yOTguCisKK0NoYW5nZXM6CitvIE1vdmVkIHRoZSBwYWNrYWdlCisgIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy56Ll9pbnRlcm5hbF8gdG8KKyAgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLmx6dyBhbmQgbWFkZSBpdCBwYXJ0CisgIG9mIHRoZSBBUEkgdGhhdCBpcyBvZmZpY2lhbGx5IHN1cHBvcnRlZC4gIFRoaXMgd2lsbCBicmVhaworICBleGlzdGluZyBjb2RlIHRoYXQgdXNlcyB0aGUgb2xkIHBhY2thZ2UuIFRoYW5rcyB0byBEYW1qYW4gSm92YW5vdmljLgorCitGb3IgY29tcGxldGUgaW5mb3JtYXRpb24gb24gQXBhY2hlIENvbW1vbnMgQ29tcHJlc3MsIGluY2x1ZGluZyBpbnN0cnVjdGlvbnMKK29uIGhvdyB0byBzdWJtaXQgYnVnIHJlcG9ydHMsIHBhdGNoZXMsIG9yIHN1Z2dlc3Rpb25zIGZvciBpbXByb3ZlbWVudCwKK3NlZSB0aGUgQXBhY2hlIENvbW1vbnMgQ29tcHJlc3Mgd2Vic2l0ZToKKworaHR0cHM6Ly9jb21tb25zLmFwYWNoZS5vcmcvY29tcHJlc3MvCisKK09sZCBSZWxlYXNlIE5vdGVzCis9PT09PT09PT09PT09PT09PQorCitSZWxlYXNlIDEuOQorLS0tLS0tLS0tLS0KKworTmV3IGZlYXR1cmVzOgorbyBBZGRlZCBzdXBwb3J0IGZvciBERUZMQVRFIHN0cmVhbXMgd2l0aG91dCBhbnkgZ3ppcCBmcmFtaW5nLgorICBJc3N1ZTogQ09NUFJFU1MtMjYzLgorICBUaGFua3MgdG8gTWF0dGhpYXMgU3RldmVucy4KKworRml4ZWQgQnVnczoKK28gV2hlbiByZWFkaW5nIDd6IGZpbGVzIHVua25vd24gZmlsZSBwcm9wZXJ0aWVzIGFuZCBwcm9wZXJ0aWVzIG9mIHR5cGUKKyAga0R1bW15IGFyZSBub3cgaWdub3JlZC4KKyAgSXNzdWU6IENPTVBSRVNTLTI4Ny4KK28gRXhwYW5kaW5nIDd6IGFyY2hpdmVzIHVzaW5nIExaTUEgY29tcHJlc3Npb24gY291bGQgY2F1c2UgYW4KKyAgRU9GRXhjZXB0aW9uLgorICBJc3N1ZTogQ09NUFJFU1MtMjg2LgorbyBMb25nLU5hbWUgYW5kIC1saW5rIG9yIFBBWC1oZWFkZXIgZW50cmllcyBpbiBUQVIgYXJjaGl2ZXMgYWx3YXlzIGhhZAorICB0aGUgY3VycmVudCB0aW1lIGFzIGxhc3QgbW9kZmljYXRpb24gdGltZSwgY3JlYXRpbmcgYXJjaGl2ZXMgdGhhdAorICBhcmUgZGlmZmVyZW50IGF0IHRoZSBieXRlIGxldmVsIGVhY2ggdGltZSBhbiBhcmNoaXZlIHdhcyBidWlsdC4KKyAgSXNzdWU6IENPTVBSRVNTLTI4OS4KKyAgVGhhbmtzIHRvIEJvYiBSb2JlcnRzb24uCisKK0NoYW5nZXM6CitvIENoZWNraW5nIGZvciBYWiBmb3IgSmF2YSBtYXkgYmUgZXhwZW5zaXZlLiAgVGhlIHJlc3VsdCB3aWxsIG5vdyBiZQorICBjYWNoZWQgb3V0c2lkZSBvZiBhbiBPU0dpIGVudmlyb25tZW50LiAgWW91IGNhbiB1c2UgdGhlIG5ldworICBYWlV0aWxzI3NldENhY2hlWFpBdmFpbGFiaWxpdHkgdG8gb3ZlcnJyaWRlIHRoaXMgZGVmYXVsdCBiZWhhdmlvci4KKyAgSXNzdWU6IENPTVBSRVNTLTI4NS4KKworUmVsZWFzZSAxLjguMQorLS0tLS0tLS0tLS0tLQorCitOZXcgZmVhdHVyZXM6CitvIENPTVBSRVNTLTI3MjogIENvbXByZXNzb3JTdHJlYW1GYWN0b3J5IGNhbiBub3cgYXV0by1kZXRlY3QgVW5peCBjb21wcmVzcworICAgICAgICAgICAgICAgICAoIi5aIikgc3RyZWFtcy4KKworRml4ZWQgQnVnczoKK28gQ09NUFJFU1MtMjcwOiAgVGhlIHNuYXBweSwgYXIgYW5kIHRhciBpbnB1dHN0cmVhbXMgbWlnaHQgZmFpbCB0byByZWFkIGZyb20gYQorICAgICAgICAgICAgICAgICBub24tYnVmZmVyZWQgc3RyZWFtIGluIGNlcnRhaW4gY2FzZXMuCitvIENPTVBSRVNTLTI3NzogIElPVXRpbHMjc2tpcCBtaWdodCBza2lwIGZld2VyIGJ5dGVzIHRoYW4gcmVxdWVzdGVkIGV2ZW4gdGhvdWdoCisgICAgICAgICAgICAgICAgIG1vcmUgY291bGQgYmUgcmVhZCBmcm9tIHRoZSBzdHJlYW0uCitvIENPTVBSRVNTLTI3NjogIEFyY2hpdmVTdHJlYW1zIG5vdyB2YWxpZGF0ZSB0aGVyZSBpcyBhIGN1cnJlbnQgZW50cnkgYmVmb3JlCisgICAgICAgICAgICAgICAgIHJlYWRpbmcgb3Igd3JpdGluZyBlbnRyeSBkYXRhLgorbyBBcmpBcmNoaXZlSW5wdXRTdHJlYW0jY2FuUmVhZEVudHJ5RGF0YSB0ZXN0ZWQgdGhlIGN1cnJlbnQKKyAgICAgICAgICAgICAgICAgZW50cnkgb2YgdGhlIHN0cmVhbSByYXRoZXIgdGhhbiBpdHMgYXJndW1lbnQuCitvIENPTVBSRVNTLTI3NDogIENoYW5nZVNldCNkZWxldGUgYW5kIGRlbGV0ZURpciBub3cgcHJvcGVybHkgZGVhbCB3aXRoIHVubmFtZWQKKyAgICAgICAgICAgICAgICAgZW50cmllcy4KK28gQ09NUFJFU1MtMjczOiAgQWRkZWQgYSBmZXcgbnVsbCBjaGVja3MgdG8gaW1wcm92ZSByb2J1c3RuZXNzLgorbyBDT01QUkVTUy0yNzg6ICBUYXJBcmNoaXZlSW5wdXRTdHJlYW0gZmFpbGVkIHRvIHJlYWQgYXJjaGl2ZXMgd2l0aCBlbXB0eQorICAgICAgICAgICAgICAgICBnaWQvdWlkIGZpZWxkcy4KK28gQ09NUFJFU1MtMjc5OiAgVGFyQXJjaGl2ZUlucHV0U3RyZWFtIG5vdyBhZ2FpbiB0aHJvd3MgYW4gZXhjZXB0aW9uIHdoZW4gaXQKKyAgICAgICAgICAgICAgICAgZW5jb3VudGVycyBhIHRydW5jYXRlZCBhcmNoaXZlIHdoaWxlIHJlYWRpbmcgZnJvbSB0aGUgbGFzdAorICAgICAgICAgICAgICAgICBlbnRyeS4KK28gQ09NUFJFU1MtMjgwOiAgQWRhcHRlZCBUYXJBcmNoaXZlSW5wdXRTdHJlYW0jc2tpcCB0byB0aGUgbW9kaWZpZWQKKyAgICAgICAgICAgICAgICAgSU9VdGlscyNza2lwIG1ldGhvZC4gVGhhbmtzIHRvIEJFTFVHQSBCRUhSLgorCitDaGFuZ2VzOgorbyBUaGUgZGVwZW5kZW5jeSBvbiBvcmcudHVrYWFuaTp4eiBpcyBub3cgbWFya2VkIGFzIG9wdGlvbmFsLgorCitSZWxlYXNlIDEuOAorLS0tLS0tLS0tLS0KKworTmV3IGZlYXR1cmVzOgorbyBHemlwQ29tcHJlc3NvcklucHV0U3RyZWFtIG5vdyBwcm92aWRlcyBhY2Nlc3MgdG8gdGhlIHNhbWUKKyAgbWV0YWRhdGEgdGhhdCBjYW4gYmUgcHJvdmlkZWQgdmlhIEd6aXBQYXJhbWV0ZXJzIHdoZW4gd3JpdGluZworICBhIGd6aXAgc3RyZWFtLgorICBJc3N1ZTogQ09NUFJFU1MtMjYwLgorbyBTZXZlblpPdXRwdXRGaWxlIG5vdyBzdXBwb3J0cyBjaGFpbmluZyBtdWx0aXBsZQorICBjb21wcmVzc2lvbi9lbmNyeXB0aW9uL2ZpbHRlciBtZXRob2RzIGFuZCBwYXNzaW5nIG9wdGlvbnMgdG8KKyAgdGhlIG1ldGhvZHMuCisgIElzc3VlOiBDT01QUkVTUy0yNjYuCitvIFRoZSAoY29tcHJlc3Npb24pIG1ldGhvZChzKSBjYW4gbm93IGJlIHNwZWNpZmllZCBwZXIgZW50cnkgaW4KKyAgU2V2ZW5aT3V0cHV0RmlsZS4KKyAgSXNzdWU6IENPTVBSRVNTLTI2MS4KK28gU2V2ZW5aQXJjaGl2ZUVudHJ5ICJrbm93cyIgd2hpY2ggbWV0aG9kKHMpIGhhdmUgYmVlbiB1c2VkIHRvCisgIHdyaXRlIGl0IHRvIHRoZSBhcmNoaXZlLgorICBJc3N1ZTogQ09NUFJFU1MtMjU4LgorbyBUaGUgN3ogcGFja2FnZSBub3cgc3VwcG9ydHMgdGhlIGRlbHRhIGZpbHRlciBhcyBtZXRob2QuCitvIFRoZSA3eiBwYWNrYWdlIG5vdyBzdXBwb3J0cyBCQ0ogZmlsdGVycyBmb3Igc2V2ZXJhbCBwbGF0Zm9ybXMuCisgIFlvdSB3aWxsIG5lZWQgYSB2ZXJzaW9uID49IDEuNSBvZiBYWiBmb3IgSmF2YSB0byByZWFkIGFyY2hpdmVzCisgIHVzaW5nIEJDSiwgdGhvdWdoLgorICBJc3N1ZTogQ09NUFJFU1MtMjU3LgorCitGaXhlZCBCdWdzOgorbyBCWmlwMkNvbXByZXNzb3JJbnB1dFN0cmVhbSByZWFkIGZld2VyIGJ5dGVzIHRoYW4gcG9zc2libGUgZnJvbQorICBhIHRydW5jYXRlZCBzdHJlYW0uCisgIElzc3VlOiBDT01QUkVTUy0yNTMuCitvIFNldmVuWkZpbGUgZmFpbGVkIGNsYWltaW5nIHRoZSBkaWN0aW9uYXJ5IHdhcyB0b28gbGFyZ2Ugd2hlbgorICBhcmNoaXZlcyB1c2VkIExaTUEgY29tcHJlc3Npb24gZm9yIGhlYWRlcnMgYW5kIGNvbnRlbnQgYW5kCisgIGNlcnRhaW4gbm9uLWRlZmF1bHQgZGljdGlvbmFyeSBzaXplcy4KKyAgSXNzdWU6IENPTVBSRVNTLTI1My4KK28gQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkuY3JlYXRlQ29tcHJlc3NvcklucHV0U3RyZWFtIHdpdGgKKyAgZXhwbGljaXQgY29tcHJlc3Npb24gZGlkIG5vdCBob25vciBkZWNvbXByZXNzQ29uY2F0ZW5hdGVkCisgIElzc3VlOiBDT01QUkVTUy0yNTkuCitvIFRhckFyY2hpdmVJbnB1dFN0cmVhbSB3aWxsIG5vdyByZWFkIGFyY2hpdmVzIGNyZWF0ZWQgYnkgdGFyCisgIGltcGxlbWVudGF0aW9ucyB0aGF0IGVuY29kZSBiaWcgbnVtYmVycyBieSBub3QgYWRkaW5nIGEKKyAgdHJhaWxpbmcgTlVMLgorICBJc3N1ZTogQ09NUFJFU1MtMjYyLgorbyBaaXBBcmNoaXZlSW5wdXRTdHJlYW0gd291bGQgcmV0dXJuIE5VTCBieXRlcyBmb3IgdGhlIGZpcnN0IDUxMgorICBieXRlcyBvZiBhIFNUT1JFRCBlbnRyeSBpZiBpdCB3YXMgdGhlIHZlcnkgZmlyc3QgZW50cnkgb2YgdGhlCisgIGFyY2hpdmUuCisgIElzc3VlOiBDT01QUkVTUy0yNjQuCitvIFdoZW4gd3JpdGluZyBQQVgvUE9TSVggaGVhZGVycyBmb3IgVEFSIGVudHJpZXMgd2l0aAorICBiYWNrc2xhc2hlcyBvciBjZXJ0YWluIG5vbi1BU0NJSSBjaGFyYWN0ZXJzIGluIHRoZWlyIG5hbWUKKyAgVGFyQXJjaGl2ZU91dHB1dFN0cmVhbSBjb3VsZCBmYWlsLgorICBJc3N1ZTogQ09NUFJFU1MtMjY1LgorbyBBcmNoaXZlU3RyZWFtRmFjdG9yeSBub3cgdGhyb3dzIGEgU3RyZWFtaW5nTm90U3VwcG9ydGVkIC0gYQorICBuZXcgc3ViY2xhc3Mgb2YgQXJjaGl2ZUV4Y2VwdGlvbiAtIGlmIGl0IGlzIGFza2VkIHRvIHJlYWQgZnJvbQorICBvciB3cml0ZSB0byBhIHN0cmVhbSBhbmQgQ29tbW9ucyBDb21wcmVzcyBkb2Vzbid0IHN1cHBvcnQKKyAgc3RyZWFtaW5nIGZvciB0aGUgZm9ybWF0LiAgVGhpcyBjdXJyZW50bHkgb25seSBhcHBsaWVzIHRvIHRoZQorICA3eiBmb3JtYXQuCisgIElzc3VlOiBDT01QUkVTUy0yNjcuCisKK1JlbGVhc2UgMS43CistLS0tLS0tLS0tLQorCitOZXcgZmVhdHVyZXM6CitvIFJlYWQtT25seSBzdXBwb3J0IGZvciBTbmFwcHkgY29tcHJlc3Npb24uCisgIElzc3VlOiBDT01QUkVTUy0xNDcuIFRoYW5rcyB0byBCRUxVR0EgQkVIUi4KK28gUmVhZC1Pbmx5IHN1cHBvcnQgZm9yIC5aIGNvbXByZXNzZWQgZmlsZXMuCisgIElzc3VlOiBDT01QUkVTUy0yNDMuIFRoYW5rcyB0byBEYW1qYW4gSm92YW5vdmljLgorbyBaaXBGaWxlIGFuZCBaaXBBcmNoaXZlSW5wdXRTdHJlYW0gbm93IHN1cHBvcnQgcmVhZGluZyBlbnRyaWVzCisgIGNvbXByZXNzZWQgdXNpbmcgdGhlIFNIUklOS0lORyBtZXRob2QuIFRoYW5rcyB0byBEYW1qYW4gSm92YW5vdmljLgorbyBHemlwQ29tcHJlc3Nvck91dHB1dFN0cmVhbSBub3cgc3VwcG9ydHMgc2V0dGluZyB0aGUgY29tcHJlc3Npb24KKyAgbGV2ZWwgYW5kIHRoZSBoZWFkZXIgbWV0YWRhdGEgKGZpbGVuYW1lLCBjb21tZW50LCBtb2RpZmljYXRpb24gdGltZSwKKyAgb3BlcmF0aW5nIHN5c3RlbSBhbmQgZXh0cmEgZmxhZ3MpCisgIElzc3VlOiBDT01QUkVTUy0yNTAuIFRoYW5rcyB0byBFbW1hbnVlbCBCb3VyZy4KK28gWmlwRmlsZSBhbmQgWmlwQXJjaGl2ZUlucHV0U3RyZWFtIG5vdyBzdXBwb3J0IHJlYWRpbmcgZW50cmllcworICBjb21wcmVzc2VkIHVzaW5nIHRoZSBJTVBMT0RFIG1ldGhvZC4KKyAgSXNzdWU6IENPTVBSRVNTLTExNS4gVGhhbmtzIHRvIEVtbWFudWVsIEJvdXJnLgorbyBaaXBGaWxlIGFuZCB0aGUgN3ogZmlsZSBjbGFzc2VzIG5vdyBpbXBsZW1lbnQgQ2xvc2VhYmxlIGFuZCBjYW4gYmUKKyAgdXNlZCBpbiB0cnktd2l0aC1yZXNvdXJjZXMgY29uc3RydWN0cy4KKworRml4ZWQgQnVnczoKK28gU2V2ZW5aT3V0cHV0RmlsZSNjbG9zZUFyY2hpdmVFbnRyeSB0aHJvd3MgYW4gZXhjZXB0aW9uIHdoZW4gdXNpbmcKKyAgTFpNQTIgY29tcHJlc3Npb24gb24gSmF2YTguICBJc3N1ZTogQ09NUFJFU1MtMjQxLgorbyA3eiByZWFkaW5nIG9mIGJpZyA2NGJpdCB2YWx1ZXMgY291bGQgYmUgd3JvbmcuCisgIElzc3VlOiBDT01QUkVTUy0yNDQuIFRoYW5rcyB0byBOaWNvIEtydWJlci4KK28gVGFyQXJjaGl2ZUlucHV0U3RyZWFtIGNvdWxkIGZhaWwgdG8gcmVhZCBhbiBhcmNoaXZlIGNvbXBsZXRlbHkuCisgIElzc3VlOiBDT01QUkVTUy0yNDUuCitvIFRoZSB0aW1lLXNldHRlcnMgaW4gWDU0NTVfRXh0ZW5kZWRUaW1lc3RhbXAgbm93IHNldCB0aGUKKyAgY29ycmVzcG9uZGluZyBmbGFncyBleHBsaWNpdGx5IC0gaS5lLiB0aGV5IHNldCB0aGUgYml0IGlmIHRoZSB2YWx1cworICBpcyBub3QtbnVsbCBhbmQgcmVzZXQgaXQgb3RoZXJ3aXNlLiAgVGhpcyBtYXkgY2F1c2UKKyAgaW5jb21wYXRpYmlsaXRpZXMgaWYgeW91IHVzZSBzZXRGbGFncyB0byB1bnNldCBhIGJpdCBhbmQgbGF0ZXIgc2V0CisgIHRoZSB0aW1lIHRvIGEgbm9uLW51bGwgdmFsdWUgLSB0aGUgZmxhZyB3aWxsIG5vdyBiZSBzZXQuCisgIElzc3VlOiBDT01QUkVTUy0yNDIuCitvIFNldmVuWk91dHB1dEZpbGUgd291bGQgY3JlYXRlIGludmFsaWQgYXJjaGl2ZXMgaWYgbW9yZSB0aGFuIHNpeAorICBlbXB0eSBmaWxlcyBvciBkaXJlY3RvcmllcyB3ZXJlIGluY2x1ZGVkLiAgSXNzdWU6IENPTVBSRVNTLTI1Mi4KKworUmVsZWFzZSAxLjYKKy0tLS0tLS0tLS0tCisKK1ZlcnNpb24gMS42IGludHJvZHVjZXMgY2hhbmdlcyB0byB0aGUgaW50ZXJuYWwgQVBJIG9mIHRoZSB0YXIgcGFja2FnZSB0aGF0CiticmVhayBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSBpbiB0aGUgZm9sbG93aW5nIHJhcmUgY2FzZXMuICBUaGlzIHZlcnNpb24KK3JlbW92ZXMgdGhlIHBhY2thZ2UgcHJpdmF0ZSBUYXJCdWZmZXIgY2xhc3MgYWxvbmcgd2l0aCB0aGUgcHJvdGVjdGVkICJidWZmZXIiCittZW1iZXJzIGluIFRhckFyY2hpdmVJbnB1dFN0cmVhbSBhbmQgVGFyQXJjaGl2ZU91dHB1dFN0cmVhbS4gIFRoaXMgY2hhbmdlIHdpbGwKK29ubHkgYWZmZWN0IHlvdSBpZiB5b3UgaGF2ZSBjcmVhdGVkIGEgc3ViY2xhc3Mgb2Ygb25lIG9mIHRoZSBzdHJlYW0gY2xhc3NlcworYW5kIGFjY2Vzc2VkIHRoZSBidWZmZXIgbWVtYmVyIG9yIGRpcmVjdGx5IHVzZWQgdGhlIFRhckJ1ZmZlciBjbGFzcy4KKworQ2hhbmdlcyBpbiB0aGlzIHZlcnNpb24gaW5jbHVkZToKKworTmV3IGZlYXR1cmVzOgorbyBBZGRlZCBzdXBwb3J0IGZvciA3eiBhcmNoaXZlcy4gIE1vc3QgY29tcHJlc3Npb24gYWxnb3JpdGhtcworICBjYW4gYmUgcmVhZCBhbmQgd3JpdHRlbiwgTFpNQSBhbmQgZW5jcnlwdGlvbiBhcmUgb25seQorICBzdXBwb3J0ZWQgd2hlbiByZWFkaW5nLiAgSXNzdWU6IENPTVBSRVNTLTU0LiBUaGFua3MgdG8gRGFtamFuIEpvdmFub3ZpYy4KK28gQWRkZWQgcmVhZC1vbmx5IHN1cHBvcnQgZm9yIEFSSiBhcmNoaXZlcyB0aGF0IGRvbid0IHVzZQorICBjb21wcmVzc2lvbi4gIElzc3VlOiBDT01QUkVTUy0yMjYuIFRoYW5rcyB0byBEYW1qYW4gSm92YW5vdmljLgorbyBEdW1wQXJjaGl2ZUlucHV0U3RyZWFtIG5vdyBzdXBwb3J0cyBhbiBlbmNvZGluZyBwYXJhbWV0ZXIgdGhhdAorICBjYW4gYmUgdXNlZCB0byBzcGVjaWZ5IHRoZSBlbmNvZGluZyBvZiBmaWxlIG5hbWVzLgorbyBUaGUgQ1BJTyBzdHJlYW1zIG5vdyBzdXBwb3J0IGFuIGVuY29kaW5nIHBhcmFtZXRlciB0aGF0IGNhbiBiZQorICB1c2VkIHRvIHNwZWNpZnkgdGhlIGVuY29kaW5nIG9mIGZpbGUgbmFtZXMuCitvIFJlYWQtb25seSBzdXBwb3J0IGZvciBMWk1BIHN0YW5kYWxvbmUgY29tcHJlc3Npb24gaGFzIGJlZW4gYWRkZWQuCisgIElzc3VlOiBDT01QUkVTUy0xMTEuCisKK0ZpeGVkIEJ1Z3M6CitvIFRhckJ1ZmZlci50cnlUb0NvbnN1bWVTZWNvbmRFT0ZSZWNvcmQgY291bGQgdGhyb3cgYQorICBOdWxsUG9pbnRlckV4Y2VwdGlvbiAgSXNzdWU6IENPTVBSRVNTLTIyMy4gVGhhbmtzIHRvIEplcmVteSBHdXN0aWUuCitvIFBhcnNpbmcgb2YgemlwNjQgZXh0cmEgZmllbGRzIGhhcyBiZWNvbWUgbW9yZSBsZW5pZW50IGluIG9yZGVyCisgIHRvIGJlIGFibGUgdG8gcmVhZCBhcmNoaXZlcyBjcmVhdGVkIGJ5IERvdE5ldFppcCBhbmQgbWF5YmUKKyAgb3RoZXIgYXJjaGl2ZXJzIGFzIHdlbGwuICBJc3N1ZTogQ09NUFJFU1MtMjI4LgorbyBUQVIgd2lsbCBub3cgcHJvcGVybHkgcmVhZCB0aGUgbmFtZXMgb2Ygc3ltYm9saWMgbGlua3Mgd2l0aAorICBsb25nIG5hbWVzIHRoYXQgdXNlIHRoZSBHTlUgdmFyaWFudCB0byBzcGVjaWZ5IHRoZSBsb25nIGZpbGUKKyAgbmFtZS4gIElzc3VlOiBDT01QUkVTUy0yMjkuIFRoYW5rcyB0byBDaHJpc3RvcGggR3lzaW4uCitvIFppcEZpbGUjZ2V0SW5wdXRTdHJlYW0gY291bGQgcmV0dXJuIG51bGwgaWYgdGhlIGFyY2hpdmUKKyAgY29udGFpbmVkIGR1cGxpY2F0ZSBlbnRyaWVzLgorICBUaGUgY2xhc3Mgbm93IGFsc28gcHJvdmlkZXMgdHdvIG5ldyBtZXRob2RzIHRvIG9idGFpbiBhbGwKKyAgZW50cmllcyBvZiBhIGdpdmVuIG5hbWUgcmF0aGVyIHRoYW4ganVzdCB0aGUgZmlyc3Qgb25lLgorICBJc3N1ZTogQ09NUFJFU1MtMjI3LgorbyBDcGlvQXJjaGl2ZUlucHV0U3RyZWFtIGZhaWxlZCB0byByZWFkIGFyY2hpdmVzIGNyZWF0ZWQgYnkKKyAgUmVkbGluZSBSUE0uICBJc3N1ZTogQ09NUFJFU1MtMjM2LiBUaGFua3MgdG8gQW5kcmV3IER1ZmZ5LgorbyBUYXJBcmNoaXZlT3V0cHV0U3RyZWFtIG5vdyBwcm9wZXJseSBoYW5kbGVzIGxpbmsgbmFtZXMgdGhhdAorICBhcmUgdG9vIGxvbmcgdG8gZml0IGludG8gYSB0cmFkaXRpb25hbCBUQVIgaGVhZGVyLiAgSXNzdWU6CisgIENPTVBSRVNTLTIzNy4gVGhhbmtzIHRvIEVtbWFudWVsIEJvdXJnLgorbyBUaGUgYXV0by1kZXRlY3RpbmcgY3JlYXRlKklucHV0U3RyZWFtIG1ldGhvZHMgb2YgQXJjaGl2ZSBhbmQKKyAgQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkgY291bGQgZmFpbCB0byBkZXRlY3QgdGhlIGZvcm1hdCBvZgorICBibG9ja2luZyBpbnB1dCBzdHJlYW1zLiAgSXNzdWU6IENPTVBSRVNTLTIzOS4KKworQ2hhbmdlczoKK28gUmVhZGFiaWx0eSBwYXRjaCB0byBUYXJBcmNoaXZlSW5wdXRTdHJlYW0uICBJc3N1ZToKKyAgQ09NUFJFU1MtMjMyLiBUaGFua3MgdG8gQkVMVUdBIEJFSFIuCitvIFBlcmZvcm1hbmNlIGltcHJvdmVtZW50cyB0byBUYXJBcmNoaXZlSW5wdXRTdHJlYW0sIGluCisgIHBhcnRpY3VsYXIgdG8gdGhlIHNraXAgbWV0aG9kLiAgSXNzdWU6IENPTVBSRVNTLTIzNC4gVGhhbmtzIHRvCisgIEJFTFVHQSBCRUhSLgorCitSZWxlYXNlIDEuNQorLS0tLS0tLS0tLS0KKworTmV3IGZlYXR1cmVzOgorCitvIENvbXByZXNzb3JTdHJlYW1GYWN0b3J5IGhhcyBhbiBvcHRpb24gdG8gY3JlYXRlIGRlY29tcHJlc3NpbmcKKyAgc3RyZWFtcyB0aGF0IGRlY29tcHJlc3MgdGhlIGZ1bGwgaW5wdXQgZm9yIGZvcm1hdHMgdGhhdCBzdXBwb3J0CisgIG11bHRpcGxlIGNvbmNhdGVuYXRlZCBzdHJlYW1zLgorICBJc3N1ZTogQ09NUFJFU1MtMjIwLgorCitGaXhlZCBCdWdzOgorCitvIFR5cG8gaW4gQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkgSmF2YWRvYworICBJc3N1ZTogQ09NUFJFU1MtMjE4LgorICBUaGFua3MgdG8gR2lsaS4KK28gQXJjaGl2ZVN0cmVhbUZhY3RvcnkncyB0YXIgc3RyZWFtIGRldGVjdGlvbiBjcmVhdGVkIGZhbHNlIHBvc2l0aXZlcworICBmb3IgQUlGRiBmaWxlcy4KKyAgSXNzdWU6IENPTVBSRVNTLTE5MS4KKyAgVGhhbmtzIHRvIEp1a2thIFppdHRpbmcuCitvIFhaIGZvciBKYXZhIGRpZG4ndCBwcm92aWRlIGFuIE9TR2kgYnVuZGxlLiAgQ29tcHJlc3MnIGRlcGVuZGVuY3kgb24KKyAgaXQgaGFzIG5vdyBiZWVuIG1hcmtlZCBvcHRpb25hbCBzbyBDb21wcmVzcyBpdHNlbGYgY2FuIHN0aWxsIGJlIHVzZWQKKyAgaW4gYW4gT1NHaSBjb250ZXh0LgorICBJc3N1ZTogQ09NUFJFU1MtMTk5LgorICBUaGFua3MgdG8gSnVra2EgWml0dGluZy4KK28gV2hlbiBzcGVjaWZ5aW5nIHRoZSBlbmNvZGluZyBleHBsaWNpdGx5IFRhckFyY2hpdmVPdXRwdXRTdHJlYW0gd291bGQKKyAgd3JpdGUgdW5yZWFkYWJsZSBuYW1lcyBpbiBHTlUgbW9kZSBvciBldmVuIGNhdXNlIGVycm9ycyBpbiBQT1NJWAorICBtb2RlIGZvciBmaWxlIG5hbWVzIGxvbmdlciB0aGFuIDY2IGNoYXJhY3RlcnMuCisgIElzc3VlOiBDT01QUkVTUy0yMDAuCisgIFRoYW5rcyB0byBDaHJpc3RpYW4gU2NobGljaHRoZXJsZS4KK28gV3JpdGluZyBUQVIgUEFYIGhlYWRlcnMgZmFpbGVkIGlmIHRoZSBnZW5lcmF0ZWQgZW50cnkgbmFtZSBlbmRlZAorICB3aXRoIGEgIi8iLgorICBJc3N1ZTogQ09NUFJFU1MtMjAzLgorbyBaaXBBcmNoaXZlSW5wdXRTdHJlYW0gc29tZXRpbWVzIGZhaWxlZCB0byBwcm92aWRlIGlucHV0IHRvIHRoZQorICBJbmZsYXRlciB3aGVuIGl0IG5lZWRlZCBpdCwgbGVhZGluZyB0byByZWFkcyByZXR1cm5pbmcgMC4KKyAgSXNzdWU6IENPTVBSRVNTLTE4OS4KKyAgVGhhbmtzIHRvIERhbmllbCBMb3dlLgorbyBUYXJBcmNoaXZlSW5wdXRTdHJlYW0gaWdub3JlZCB0aGUgZW5jb2RpbmcgZm9yIEdOVSBsb25nIG5hbWUKKyAgZW50cmllcy4KKyAgSXNzdWU6IENPTVBSRVNTLTIxMi4KK28gVGFyQXJjaGl2ZUlucHV0U3RyZWFtIGNvdWxkIGxlYXZlIHRoZSBzZWNvbmQgRU9GIHJlY29yZCBpbnNpZGUgdGhlCisgIHN0cmVhbSBpdCBoYWQganVzdCBmaW5pc2hlZCByZWFkaW5nLgorICBJc3N1ZTogQ09NUFJFU1MtMjA2LgorICBUaGFua3MgdG8gUGV0ZXIgRGUgTWFleWVyLgorbyBEdW1wQXJjaGl2ZUlucHV0U3RyZWFtIG5vIGxvbmdlciBpbXBsaWNpdGx5IGNsb3NlcyB0aGUgb3JpZ2luYWwKKyAgaW5wdXQgc3RyZWFtIHdoZW4gaXQgcmVhY2hlcyB0aGUgZW5kIG9mIHRoZSBhcmNoaXZlLgorbyBaaXBBcmNoaXZlSW5wdXRTdHJlYW0gbm93IGNvbnN1bWVzIHRoZSByZW1haW5kZXIgb2YgdGhlIGFyY2hpdmUgd2hlbgorICBnZXROZXh0WmlwRW50cnkgcmV0dXJucyBudWxsLgorbyBVbml0IHRlc3RzIGNvdWxkIGZhaWwgaWYgdGhlIHNvdXJjZSB0cmVlIHdhcyBjaGVja2VkIG91dCB0byBhCisgIGRpcmVjdG9yeSB0cmVlIGNvbnRhaW5pZ24gc3BhY2VzLgorICBJc3N1ZTogQ09NUFJFU1MtMjA1LgorICBUaGFua3MgdG8gRGFuaWVsIExvd2UuCitvIEZpeGVkIGEgcG90ZW50aWFsIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB3aGVuIHJlYWRpbmcgU1RPUkVECisgIGVudHJpZXMgZnJvbSBaaXBBcmNoaXZlSW5wdXRTdHJlYW0uCisgIElzc3VlOiBDT01QUkVTUy0yMTkuCitvIENvbXByZXNzb3JTdHJlYW1GYWN0b3J5IGNhbiBub3cgYmUgdXNlZCB3aXRob3V0IFhaIGZvciBKYXZhIGJlaW5nCisgIGF2YWlsYWJsZS4KKyAgSXNzdWU6IENPTVBSRVNTLTIyMS4KKworQ2hhbmdlczoKKworbyBJbXByb3ZlZCBleGNlcHRpb24gbWVzc2FnZSBpZiBhIHppcCBhcmNoaXZlIGNhbm5vdCBiZSByZWFkIGJlY2F1c2UKKyAgb2YgYW4gdW5zdXBwb3J0ZWQgY29tcHJlc3Npb24gbWV0aG9kLgorICBJc3N1ZTogQ09NUFJFU1MtMTg4LgorICBUaGFua3MgdG8gSGFyYWxkIEt1aG4uCitvIEFyY2hpdmVTdHJlYW1GYWN0b3J5IGhhcyBhIHNldHRpbmcgZm9yIGZpbGUgbmFtZSBlbmNvZGluZyB0aGF0IHNldHMKKyAgdXAgZW5jb2RpbmcgZm9yIFpJUCBhbmQgVEFSIHN0cmVhbXMuCisgIElzc3VlOiBDT01QUkVTUy0xOTIuCisgIFRoYW5rcyB0byBKdWtrYSBaaXR0aW5nLgorbyBUYXJBcmNoaXZlRW50cnkgbm93IGhhcyBhIG1ldGhvZCB0byB2ZXJpZnkgaXRzIGNoZWNrc3VtLgorICBJc3N1ZTogQ09NUFJFU1MtMTkxLgorICBUaGFua3MgdG8gSnVra2EgWml0dGluZy4KK28gU3BsaXQvc3Bhbm5lZCBaSVAgYXJjaGl2ZXMgYXJlIG5vdyBwcm9wZXJseSBkZXRlY3RlZCBieQorICBBcmNoaXZlU3RyZWFtRmFjdG9yeSBidXQgd2lsbCBjYXVzZSBhbgorICBVbnN1cHBvcnRlZFppcEZlYXR1cmVFeGNlcHRpb24gd2hlbiByZWFkLgorbyBaaXBBcmNoaXZlSW5wdXRTdHJlYW0gbm93IHJlYWRzIGFyY2hpdmVzIHRoYXQgc3RhcnQgd2l0aCBhICJQSzAwIgorICBzaWduYXR1cmUuICBBcmNoaXZlcyB3aXRoIHRoaXMgc2lnbmF0dXJlcyBhcmUgY3JlYXRlZCB3aGVuIHRoZQorICBhcmNoaXZlciB3YXMgd2lsbGluZyB0byBzcGxpdCB0aGUgYXJjaGl2ZSBidXQgaW4gdGhlIGVuZCBvbmx5IG5lZWRlZAorICBhIHNpbmdsZSBzZWdtZW50IC0gc28gZGlkbid0IHNwbGl0IGFueXRoaW5nLgorICBJc3N1ZTogQ09NUFJFU1MtMjA4LgorbyBUYXJBcmNoaXZlRW50cnkgaGFzIGEgbmV3IGNvbnN0cnVjdG9yIHRoYXQgYWxsb3dzIHNldHRpbmcgbGlua0ZsYWcKKyAgYW5kIHByZXNlcnZlTGVhZGluZ1NsYXNoZXMgYXQgdGhlIHNhbWUgdGltZS4KKyAgSXNzdWU6IENPTVBSRVNTLTIwMS4KK28gQ2hhbmdlU2V0UGVyZm9ybWVyIGhhcyBhIG5ldyBwZXJmb3JtIG92ZXJsb2FkIHRoYXQgdXNlcyBhIFppcEZpbGUKKyAgaW5zdGFuY2UgYXMgaW5wdXQuCisgIElzc3VlOiBDT01QUkVTUy0xNTkuCitvIEdhcmJhZ2UgY29sbGVjdGlvbiBwcmVzc3VyZSBoYXMgYmVlbiByZWR1Y2VkIGJ5IHJldXNpbmcgdGVtcG9yYXJ5CisgIGJ5dGUgYXJyYXlzIGluIGNsYXNzZXMuCisgIElzc3VlOiBDT01QUkVTUy0xNzIuCisgIFRoYW5rcyB0byBUaG9tYXMgTWFpci4KK28gQ2FuIG5vdyBoYW5kbGUgemlwIGV4dHJhIGZpZWxkIDB4NTQ1NSAtIEV4dGVuZGVkIFRpbWVzdGFtcC4KKyAgSXNzdWU6IENPTVBSRVNTLTIxMC4KKyAgVGhhbmtzIHRvIEp1bGl1cyBEYXZpZXMuCitvIGhhbmRsZSB6aXAgZXh0cmEgZmllbGQgMHg3ODc1IC0gSW5mbyBaaXAgTmV3IFVuaXggRXh0cmEgRmllbGQuCisgIElzc3VlOiBDT01QUkVTUy0yMTEuCisgIFRoYW5rcyB0byBKdWxpdXMgRGF2aWVzLgorbyBaaXBTaG9ydCwgWmlwTG9uZywgWmlwRWlnaHRCeXRlSW50ZWdlciBzaG91bGQgaW1wbGVtZW50IFNlcmlhbGl6YWJsZQorICBJc3N1ZTogQ09NUFJFU1MtMjEzLgorICBUaGFua3MgdG8gSnVsaXVzIERhdmllcy4KK28gYmV0dGVyIHN1cHBvcnQgZm9yIHVuaXggc3ltbGlua3MgaW4gWmlwRmlsZSBlbnRyaWVzLgorICBJc3N1ZTogQ09NUFJFU1MtMjE0LgorICBUaGFua3MgdG8gSnVsaXVzIERhdmllcy4KK28gWmlwRmlsZSdzIGluaXRpYWxpemF0aW9uIGhhcyBiZWVuIGltcHJvdmVkIGZvciBub24tWmlwNjQgYXJjaGl2ZXMuCisgIElzc3VlOiBDT01QUkVTUy0yMTUuCisgIFRoYW5rcyB0byBSb2JpbiBQb3dlci4KK28gVXBkYXRlZCBYWiBmb3IgSmF2YSBkZXBlbmRlbmN5IHRvIDEuMiBhcyB0aGlzIHZlcnNpb24gcHJvdmlkZXMKKyAgcHJvcGVyIE9TR2kgbWFuaWZlc3QgYXR0cmlidXRlcy4KKworUmVsZWFzZSAxLjQuMQorLS0tLS0tLS0tLS0tLQorCitUaGlzIGlzIGEgc2VjdXJpdHkgYnVnZml4IHJlbGVhc2UsIHNlZQoraHR0cHM6Ly9jb21tb25zLmFwYWNoZS5vcmcvcHJvcGVyL2NvbW1vbnMtY29tcHJlc3Mvc2VjdXJpdHkuaHRtbCNGaXhlZF9pbl9BcGFjaGVfQ29tbW9uc19Db21wcmVzc18xLjQuMQorCitGaXhlZCBCdWdzOgorCitvIFBvcnRlZCBsaWJiemlwMidzIGZhbGxiYWNrIHNvcnQgYWxnb3JpdGhtIHRvCisgIEJaaXAyQ29tcHJlc3Nvck91dHB1dFN0cmVhbSB0byBzcGVlZCB1cCBjb21wcmVzc2lvbiBpbiBjZXJ0YWluCisgIGVkZ2UgY2FzZXMuCisKK1JlbGVhc2UgMS40CistLS0tLS0tLS0tLQorCitOZXcgZmVhdHVyZXM6CitvIENPTVBSRVNTLTE1NjogIFN1cHBvcnQgZm9yIHRoZSBYWiBmb3JtYXQgaGFzIGJlZW4gYWRkZWQuCisKK0ZpeGVkIEJ1Z3M6CitvIENPTVBSRVNTLTE4MzogIFRoZSB0YXIgcGFja2FnZSBub3cgYWxsb3dzIHRoZSBlbmNvZGluZyBvZiBmaWxlIG5hbWVzIHRvIGJlCisgICAgICAgICAgICAgICAgIHNwZWNpZmllZCBhbmQgY2FuIG9wdGlvbmFsbHkgdXNlIFBBWCBleHRlbnNpb24gaGVhZGVycyB0bworICAgICAgICAgICAgICAgICB3cml0ZSBub24tQVNDSUkgZmlsZSBuYW1lcy4KKyAgICAgICAgICAgICAgICAgVGhlIHN0cmVhbSBjbGFzc2VzIG5vdyB3cml0ZSAob3IgZXhwZWN0IHRvIHJlYWQpIGFyY2hpdmVzIHRoYXQKKyAgICAgICAgICAgICAgICAgdXNlIHRoZSBwbGF0Zm9ybSdzIG5hdGl2ZSBlbmNvZGluZyBmb3IgZmlsZSBuYW1lcy4gIEFwYWNoZQorICAgICAgICAgICAgICAgICBDb21tb25zIENvbXByZXNzIDEuMyB1c2VkIHRvIHN0cmlwIGV2ZXJ5dGhpbmcgYnV0IHRoZSBsb3dlcgorICAgICAgICAgICAgICAgICBlaWdodCBiaXRzIG9mIGVhY2ggY2hhcmFjdGVyIHdoaWNoIGVmZmVjdGl2ZWx5IG9ubHkgd29ya2VkIGZvcgorICAgICAgICAgICAgICAgICBBU0NJSSBhbmQgSVNPLTg4NTktMSBmaWxlIG5hbWVzLgorICAgICAgICAgICAgICAgICBUaGlzIG5ldyBkZWZhdWx0IGJlaGF2aW9yIGlzIGEgYnJlYWtpbmcgY2hhbmdlLgorbyBDT01QUkVTUy0xODQ6ICBUYXJBcmNoaXZlSW5wdXRTdHJlYW0gZmFpbGVkIHRvIHBhcnNlIFBBWCBoZWFkZXJzIHRoYXQKKyAgICAgICAgICAgICAgICAgY29udGFpbmVkIG5vbi1BU0NJSSBjaGFyYWN0ZXJzLgorbyBDT01QUkVTUy0xNzg6ICBUYXJBcmNoaXZlSW5wdXRTdHJlYW0gdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpbnN0ZWFkIG9mIElPRXhjZXB0aW9uCitvIENPTVBSRVNTLTE3OTogIFRhclV0aWxzLmZvcm1hdExvbmdPY3RhbE9yQmluYXJ5Qnl0ZXMoKSBhc3N1bWVzIHRoZSBmaWVsZCB3aWxsIGJlIDEyIGJ5dGVzIGxvbmcKK28gQ09NUFJFU1MtMTc1OiAgR05VIFRhciBzb21ldGltZXMgdXNlcyBiaW5hcnkgZW5jb2RpbmcgZm9yIFVJRCBhbmQgR0lECitvIENPTVBSRVNTLTE3MTogIEFyY2hpdmVTdHJlYW1GYWN0b3J5LmNyZWF0ZUFyY2hpdmVJbnB1dFN0cmVhbSB3b3VsZCBjbGFpbQorICAgICAgICAgICAgICAgICBzaG9ydCB0ZXh0IGZpbGVzIHdlcmUgVEFSIGFyY2hpdmVzLgorbyBDT01QUkVTUy0xNjQ6ICBaaXBGaWxlIGRpZG4ndCB3b3JrIHByb3Blcmx5IGZvciBhcmNoaXZlcyB1c2luZyB1bmljb2RlIGV4dHJhCisgICAgICAgICAgICAgICAgIGZpZWxkcyByYXRoZXIgdGhhbiBVVEYtOCBmaWxlbmFtZXMgYW5kIHRoZSBFRlMtRmxhZy4KK28gQ09NUFJFU1MtMTY5OiAgRm9yIGNvcnJ1cHQgYXJjaGl2ZXMgWmlwRmlsZSB3b3VsZCB0aHJvdyBhIFJ1bnRpbWVFeGNlcHRpb24gaW4KKyAgICAgICAgICAgICAgICAgc29tZSBjYXNlcyBhbmQgYW4gSU9FeGNlcHRpb24gaW4gb3RoZXJzLiAgSXQgd2lsbCBub3cKKyAgICAgICAgICAgICAgICAgY29uc2lzdGVudGx5IHRocm93IGFuIElPRXhjZXB0aW9uLgorCitDaGFuZ2VzOgorbyBDT01QUkVTUy0xODI6ICBUaGUgdGFyIHBhY2thZ2UgY2FuIG5vdyB3cml0ZSBhcmNoaXZlcyB0aGF0IHVzZSBzdGFyL0dOVS9CU0QKKyAgICAgICAgICAgICAgICAgZXh0ZW5zaW9ucyBvciB1c2UgdGhlIFBPU0lYL1BBWCB2YXJpYW50IHRvIHN0b3JlIG51bWVyaWMKKyAgICAgICAgICAgICAgICAgdmFsdWVzIHRoYXQgZG9uJ3QgZml0IGludG8gdGhlIHRyYWRpdGlvbmFsIGhlYWRlciBmaWVsZHMuCitvIENPTVBSRVNTLTE4MTogIEFkZGVkIGEgd29ya2Fyb3VuZCBmb3IgYSBCdWcgc29tZSB0YXIgaW1wbGVtZW50YXRpb25zIHRoYXQgYWRkCisgICAgICAgICAgICAgICAgIGEgTlVMIGJ5dGUgYXMgZmlyc3QgYnl0ZSBpbiBudW1lcmljIGhlYWRlciBmaWVsZHMuCitvIENPTVBSRVNTLTE3NjogIEFkZGVkIGEgd29ya2Fyb3VuZCBmb3IgYSBCdWcgaW4gV2luWklQIHdoaWNoIHVzZXMgYmFja3NsYXNoZXMKKyAgICAgICAgICAgICAgICAgYXMgcGF0aCBzZXBhcmF0b3JzIGluIFVuaWNvZGUgRXh0cmEgRmllbGRzLgorbyBDT01QUkVTUy0xMzE6ICBBcnJheU91dE9mQm91bmRzIHdoaWxlIGRlY29tcHJlc3NpbmcgYnoyLiBBZGRlZCB0ZXN0IGNhc2UgLSBjb2RlIGFscmVhZHkgc2VlbXMgdG8gaGF2ZSBiZWVuIGZpeGVkLgorbyBDT01QUkVTUy0xNDY6ICBCWmlwMkNvbXByZXNzb3JJbnB1dFN0cmVhbSBub3cgb3B0aW9uYWxseSBzdXBwb3J0cyByZWFkaW5nIG9mCisgICAgICAgICAgICAgICAgIGNvbmNhdGVuYXRlZCAuYnoyIGZpbGVzLgorbyBDT01QUkVTUy0xNTQ6ICBHWmlwQ29tcHJlc3NvcklucHV0U3RyZWFtIG5vdyBvcHRpb25hbGx5IHN1cHBvcnRzIHJlYWRpbmcgb2YKKyAgICAgICAgICAgICAgICAgY29uY2F0ZW5hdGVkIC5neiBmaWxlcy4KK28gQ09NUFJFU1MtMTY6ICBUaGUgdGFyIHBhY2thZ2UgY2FuIG5vdyByZWFkIGFyY2hpdmVzIHRoYXQgdXNlIHN0YXIvR05VL0JTRAorICAgICAgICAgICAgICAgICBleHRlbnNpb25zIGZvciBmaWxlcyB0aGF0IGFyZSBsb25nZXIgdGhhbiA4IEdCeXRlIGFzIHdlbGwgYXMKKyAgICAgICAgICAgICAgICAgYXJjaGl2ZXMgdGhhdCB1c2UgdGhlIFBPU0lYL1BBWCB2YXJpYW50LgorbyBDT01QUkVTUy0xNjU6ICBUaGUgdGFyIHBhY2thZ2UgY2FuIG5vdyB3cml0ZSBhcmNoaXZlcyB0aGF0IHVzZSBzdGFyL0dOVS9CU0QKKyAgICAgICAgICAgICAgICAgZXh0ZW5zaW9ucyBmb3IgZmlsZXMgdGhhdCBhcmUgbG9uZ2VyIHRoYW4gOCBHQnl0ZSBhcyB3ZWxsIGFzCisgICAgICAgICAgICAgICAgIGFyY2hpdmVzIHRoYXQgdXNlIHRoZSBQT1NJWC9QQVggdmFyaWFudC4KK28gQ09NUFJFU1MtMTY2OiAgVGhlIHRhciBwYWNrYWdlIGNhbiBub3cgdXNlIHRoZSBQT1NJWC9QQVggdmFyaWFudCBmb3Igd3JpdGluZworICAgICAgICAgICAgICAgICBlbnRyaWVzIHdpdGggbmFtZXMgbG9uZ2VyIHRoYW4gMTAwIGNoYXJhY3RlcnMuCisKK1JlbGVhc2UgMS4zCistLS0tLS0tLS0tLQorCitDb21tb25zIENvbXByZXNzIDEuMyBpcyB0aGUgZmlyc3QgdmVyc2lvbiB0byByZXF1aXJlIEphdmE1IGF0IHJ1bnRpbWUuCisKK0NoYW5nZXMgaW4gdGhpcyB2ZXJzaW9uIGluY2x1ZGU6CisKK05ldyBmZWF0dXJlczoKK28gU3VwcG9ydCBmb3IgdGhlIFBhY2syMDAgZm9ybWF0IGhhcyBiZWVuIGFkZGVkLiAgSXNzdWU6IENPTVBSRVNTLTE0Mi4KK28gUmVhZC1vbmx5IHN1cHBvcnQgZm9yIHRoZSBmb3JtYXQgdXNlZCBieSB0aGUgVW5peCBkdW1wKDgpIHRvb2wKKyAgaGFzIGJlZW4gYWRkZWQuICBJc3N1ZTogQ09NUFJFU1MtMTMyLgorCitGaXhlZCBCdWdzOgorbyBCWmlwMkNvbXByZXNzb3JJbnB1dFN0cmVhbSdzIGdldEJ5dGVzUmVhZCBtZXRob2QgYWx3YXlzCisgIHJldHVybmVkIDAuCitvIFppcEFyY2hpdmVJbnB1dFN0cmVhbSBhbmQgWmlwQXJjaGl2ZU91dHB1dFN0cmVhbSBjb3VsZCBsZWFrCisgIHJlc291cmNlcyBvbiBzb21lIEpES3MuICBJc3N1ZTogQ09NUFJFU1MtMTUyLgorbyBUYXJBcmNoaXZlT3V0cHV0U3RyZWFtJ3MgZ2V0Qnl0ZXNXcml0dGVuIG1ldGhvZCBkaWRuJ3QgY291bnQKKyAgY29ycmVjdGx5LiAgSXNzdWU6IENPTVBSRVNTLTE2MC4KKworQ2hhbmdlczoKK28gVGhlIFpJUCBwYWNrYWdlIG5vdyBzdXBwb3J0cyBaaXA2NCBleHRlbnNpb25zLiAgSXNzdWU6IENPTVBSRVNTLTM2LgorbyBUaGUgQVIgcGFja2FnZSBub3cgc3VwcG9ydHMgdGhlIEJTRCBkaWFsZWN0IG9mIHN0b3JpbmcgZmlsZQorICBuYW1lcyBsb25nZXIgdGhhbiAxNiBjaGFycyAoYm90aCByZWFkaW5nIGFuZCB3cml0aW5nKS4KKyAgSXNzdWU6IENPTVBSRVNTLTE0NC4KKworUmVsZWFzZSAxLjIKKy0tLS0tLS0tLS0tCisKK05ldyBmZWF0dXJlczoKK28gQ09NUFJFU1MtMTIzOiAgWmlwQXJjaGl2ZUVudHJ5IGhhcyBhIG5ldyBtZXRob2QgZ2V0UmF3TmFtZSB0aGF0IHByb3ZpZGVzIHRoZQorICAgICAgICBvcmlnaW5hbCBieXRlcyB0aGF0IG1hZGUgdXAgdGhlIG5hbWUuICBUaGlzIG1heSBhbGxvdyB1c2VyCisgICAgICAgIGNvZGUgdG8gZGV0ZWN0IHRoZSBlbmNvZGluZy4KK28gQ09NUFJFU1MtMTIyOiAgVGFyQXJjaGl2ZUVudHJ5IHByb3ZpZGVzIGFjY2VzcyB0byB0aGUgZmxhZ3MgdGhhdCBkZXRlcm1pbmUKKyAgICAgICAgd2hldGhlciBpdCBpcyBhbiBhcmNoaXZlZCBzeW1ib2xpYyBsaW5rLCBwaXBlIG9yIG90aGVyCisgICAgICAgICJ1bmNvbW1vbiIgZmlsZSBzeXN0ZW0gb2JqZWN0LgorCitGaXhlZCBCdWdzOgorbyBDT01QUkVTUy0xMjk6ICBaaXBBcmNoaXZlSW5wdXRTdHJlYW0gY291bGQgZmFpbCB3aXRoIGEgIlRydW5jYXRlZCBaSVAiIGVycm9yCisgICAgICAgIG1lc3NhZ2UgZm9yIGVudHJpZXMgYmV0d2VlbiAyIEdCeXRlIGFuZCA0IEdCeXRlIGluIHNpemUuCitvIENPTVBSRVNTLTE0NTogIFRhckFyY2hpdmVJbnB1dFN0cmVhbSBub3cgZGV0ZWN0cyBzcGFyc2UgZW50cmllcyB1c2luZyB0aGUKKyAgICAgICAgb2xkZ251IGZvcm1hdCBhbmQgcHJvcGVybHkgcmVwb3J0cyBpdCBjYW5ub3QgZXh0cmFjdCB0aGVpcgorICAgICAgICBjb250ZW50cy4KK28gQ09NUFJFU1MtMTMwOiAgVGhlIEphdmFkb2MgZm9yIFppcEFyY2hpdmVJbnB1dFN0cmVhbSNza2lwIG5vdyBtYXRjaGVzIHRoZQorICAgICAgICBpbXBsZW1lbnRhdGlvbiwgdGhlIGNvZGUgaGFzIGJlZW4gbWFkZSBtb3JlIGRlZmVuc2l2ZS4KK28gQ09NUFJFU1MtMTQwOiAgQXJBcmNoaXZlSW5wdXRTdHJlYW0gZmFpbHMgaWYgZW50cmllcyBjb250YWluIG9ubHkgYmxhbmtzIGZvcgorICAgICAgICB1c2VySWQgb3IgZ3JvdXBJZC4gVGhhbmtzIHRvIFRyZWprYXouCitvIENPTVBSRVNTLTEzOTogIFppcEZpbGUgbWF5IGxlYWsgcmVzb3VyY2VzIG9uIHNvbWUgSkRLcy4KK28gQ09NUFJFU1MtMTI1OiAgQlppcDJDb21wcmVzc29ySW5wdXRTdHJlYW0gdGhyb3dzIElPRXhjZXB0aW9uIGlmCisgICAgICAgIHVuZGVybHlpbmcgc3RyZWFtIHJldHVybnMgYXZhaWxhYmxlKCkgPT0gMC4KKyAgICAgICAgUmVtb3ZlZCB0aGUgY2hlY2suCitvIENPTVBSRVNTLTEyNzogIENhbGxpbmcgY2xvc2UoKSBvbiBpbnB1dFN0cmVhbSByZXR1cm5lZCBieQorICAgICAgICBDb21wcmVzc29yU3RyZWFtRmFjdG9yeS5jcmVhdGVDb21wcmVzc29ySW5wdXRTdHJlYW0oKQorICAgICAgICBkb2VzIG5vdCBjbG9zZSB0aGUgdW5kZXJseWluZyBpbnB1dCBzdHJlYW0uCitvIENPTVBSRVNTLTExOTogIFRhckFyY2hpdmVPdXRwdXRTdHJlYW0jZmluaXNoIG5vdyB3cml0ZXMgYWxsIGJ1ZmZlcmVkCisgICAgICAgIGRhdGEgdG8gdGhlIHN0cmVhbQorCitDaGFuZ2VzOgorbyBaaXBGaWxlIG5vdyBpbXBsZW1lbnRzIGZpbmFsaXplIHdoaWNoIGNsb3NlcyB0aGUgdW5kZXJseWluZworICAgICAgICBmaWxlLgorbyBDT01QUkVTUy0xMTc6ICBDZXJ0YWluIHRhciBmaWxlcyBub3QgcmVjb2duaXNlZCBieQorICAgICAgICBBcmNoaXZlU3RyZWFtRmFjdG9yeS4KKworUmVsZWFzZSAxLjEKKy0tLS0tLS0tLS0tCisKK05ldyBmZWF0dXJlczoKK28gQ09NUFJFU1MtMTA4OiAgQ29tbWFuZC1saW5lIGludGVyZmFjZSB0byBsaXN0IGFyY2hpdmUgY29udGVudHMuCisgICAgICAgVXNhZ2U6IGphdmEgLWphciBjb21tb25zLWNvbXByZXNzLW4ubS5qYXIgYXJjaGl2ZS1uYW1lIFt6aXB8dGFyfGV0Y10KK28gQ09NUFJFU1MtMTA5OiAgVGFyIGltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgUGF4IGhlYWRlcnMKKyAgICAgICBBZGRlZCBzdXBwb3J0IGZvciByZWFkaW5nIHBheCBoZWFkZXJzLgorICAgICAgIE5vdGU6IGRvZXMgbm90IHN1cHBvcnQgZ2xvYmFsIHBheCBoZWFkZXJzCitvIENPTVBSRVNTLTEwMzogIFppcEFyY2hpdmVJbnB1dFN0cmVhbSBjYW4gb3B0aW9uYWxseSBleHRyYWN0IGRhdGEgdGhhdCB1c2VkCisgICAgICAgIHRoZSBTVE9SRUQgY29tcHJlc3Npb24gbWV0aG9kIGFuZCBhIGRhdGEgZGVzY3JpcHRvci4KKyAgICAgICAgRG9pbmcgc28gaW4gYSBzdHJlYW0gaXMgbm90IHNhZmUgaW4gZ2VuZXJhbCwgc28geW91IGhhdmUgdG8KKyAgICAgICAgZXhwbGljaXRseSBlbmFibGUgdGhlIGZlYXR1cmUuICBCeSBkZWZhdWx0IHRoZSBzdHJlYW0gd2lsbAorICAgICAgICB0aHJvdyBhbiBleGNlcHRpb24gaWYgaXQgZW5jb3VudGVycyBzdWNoIGFuIGVudHJ5LgorbyBDT01QUkVTUy05ODogIFRoZSBaSVAgY2xhc3NlcyB3aWxsIHRocm93IHNwZWNpYWxpemVkIGV4Y2VwdGlvbnMgaWYgYW55CisgICAgICAgIGF0dGVtcHQgaXMgbWFkZSB0byByZWFkIG9yIHdyaXRlIGRhdGEgdGhhdCB1c2VzIHppcCBmZWF0dXJlcworICAgICAgICBub3Qgc3VwcG9ydGVkICh5ZXQpLgorbyBDT01QUkVTUy05OTogIFppcEZpbGUjZ2V0RW50cmllcyByZXR1cm5zIGVudHJpZXMgaW4gYSBwcmVkaWN0YWJsZSBvcmRlciAtCisgICAgICAgIHRoZSBvcmRlciB0aGV5IGFwcGVhciBpbnNpZGUgdGhlIGNlbnRyYWwgZGlyZWN0b3J5LgorICAgICAgICBBIG5ldyBtZXRob2QgZ2V0RW50cmllc0luUGh5c2ljYWxPcmRlciByZXR1cm5zIGVudHJpZXMgaW4KKyAgICAgICAgb3JkZXIgb2YgdGhlIGVudHJ5IGRhdGEsIGkuZS4gdGhlIG9yZGVyIFppcEFyY2hpdmVJbnB1dFN0cmVhbQorICAgICAgICB3b3VsZCBzZWUuCitvIFRoZSBBcmNoaXZlKlN0cmVhbSBhbmQgWmlwRmlsZSBjbGFzc2VzIG5vdyBoYXZlCisgICAgICAgIGNhbihSZWFkfFdyaXRlKUVudHJ5RGF0YSBtZXRob2RzIHRoYXQgY2FuIGJlIHVzZWQgdG8gY2hlY2sKKyAgICAgICAgd2hldGhlciBhIGdpdmVuIGVudHJ5J3MgZGF0YSBjYW4gYmUgcmVhZC93cml0dGVuLgorICAgICAgICBUaGUgbWV0aG9kIGN1cnJlbnRseSByZXR1cm5zIGZhbHNlIGZvciBaSVAgYXJjaGl2ZXMgaWYgYW4KKyAgICAgICAgZW50cnkgdXNlcyBhbiB1bnN1cHBvcnRlZCBjb21wcmVzc2lvbiBtZXRob2Qgb3IgZW5jcnlwdGlvbi4KK28gQ09NUFJFU1MtODk6ICBUaGUgWklQIGNsYXNzZXMgbm93IGRldGVjdCBlbmNyeXB0ZWQgZW50cmllcy4KK28gQ09NUFJFU1MtOTc6ICBBZGRlZCBhdXRvZGV0ZWN0aW9uIG9mIGNvbXByZXNzaW9uIGZvcm1hdCB0bworICAgICAgICBDb21wcmVzc29yU3RyZWFtRmFjdG9yeS4KK28gQ09NUFJFU1MtOTU6ICBJbXByb3ZlIEV4Y2VwdGlvbk1lc3NhZ2VzIGluIEFyY2hpdmVTdHJlYW1GYWN0b3J5IFRoYW5rcyB0byBKb2VyZyBCZWxsbWFubi4KK28gQSBuZXcgY29uc3RydWN0b3Igb2YgVGFyQXJjaGl2ZUVudHJ5IGNhbiBjcmVhdGUgZW50cmllcyB3aXRoCisgICAgICAgIG5hbWVzIHRoYXQgc3RhcnQgd2l0aCBzbGFzaGVzIC0gdGhlIGRlZmF1bHQgaXMgdG8gc3RyaXAKKyAgICAgICAgbGVhZGluZyBzbGFzaGVzIGluIG9yZGVyIHRvIGNyZWF0ZSByZWxhdGl2ZSBwYXRoIG5hbWVzLgorbyBBcmNoaXZlRW50cnkgbm93IGhhcyBhIGdldExhc3RNb2RpZmllZERhdGUgbWV0aG9kLgorbyBDT01QUkVTUy03ODogIEFkZCBhIEJaaXAyVXRpbHMgY2xhc3MgbW9kZWxsZWQgYWZ0ZXIgR1ppcFV0aWxzIFRoYW5rcyB0byBKdWtrYSBaaXR0aW5nLgorCitGaXhlZCBCdWdzOgorbyBDT01QUkVTUy03MjogIE1vdmUgYWNrbm93bGVkZ2VtZW50cyBmcm9tIE5PVElDRSB0byBSRUFETUUKK28gQ09NUFJFU1MtMTEzOiAgVGFyQXJjaGl2ZUVudHJ5LnBhcnNlVGFySGVhZGVyKCkgaW5jbHVkZXMgdGhlIHRyYWlsaW5nIHNwYWNlL05VTCB3aGVuIHBhcnNpbmcgdGhlIG9jdGFsIHNpemUKK28gQ09NUFJFU1MtMTE4OiAgVGFyVXRpbHMucGFyc2VOYW1lIGRvZXMgbm90IHByb3Blcmx5IGhhbmRsZSBjaGFyYWN0ZXJzIG91dHNpZGUgdGhlIHJhbmdlIDAtMTI3CitvIENPTVBSRVNTLTEwNzogIEFyY2hpdmVTdHJlYW1GYWN0b3J5IGRvZXMgbm90IHJlY29nbmlzZSB0YXIgZmlsZXMgY3JlYXRlZCBieSBBbnQKK28gQ09NUFJFU1MtMTEwOiAgU3VwcG9ydCAidXN0YXIiIHByZWZpeCBmaWVsZCwgd2hpY2ggaXMgdXNlZCB3aGVuIGZpbGUgcGF0aHMgYXJlIGxvbmdlcgorICAgICAgIHRoYW4gMTAwIGNoYXJhY3RlcnMuCitvIENPTVBSRVNTLTEwMDogIFppcEFyY2hpdmVJbnB1dFN0cmVhbSB3aWxsIHRocm93IGFuIGV4Y2VwdGlvbiBpZiBpdCBkZXRlY3RzIGFuCisgICAgICAgIGVudHJ5IHRoYXQgdXNlcyBhIGRhdGEgZGVzY3JpcHRvciBmb3IgYSBTVE9SRUQgZW50cnkgc2luY2UgaXQKKyAgICAgICAgY2Fubm90IHJlbGlhYmx5IGZpbmQgdGhlIGVuZCBvZiBkYXRhIGZvciB0aGlzICJjb21wcmVzc2lvbiIKKyAgICAgICAgbWV0aG9kLgorbyBDT01QUkVTUy0xMDE6ICBaaXBBcmNoaXZlSW5wdXRTdHJlYW0gc2hvdWxkIG5vdyBwcm9wZXJseSByZWFkIGFyY2hpdmVzIHRoYXQKKyAgICAgICAgdXNlIGRhdGEgZGVzY3JpcHRvcnMgYnV0IHdpdGhvdXQgdGhlICJ1bm9mZmljaWFsIiBzaWduYXR1cmUuCitvIENPTVBSRVNTLTc0OiAgWmlwQXJjaGl2ZUlucHV0U3RyZWFtIGZhaWxlZCB0byB1cGRhdGUgdGhlIG51bWJlciBvZiBieXRlcworICAgICAgICByZWFkIHByb3Blcmx5LgorbyBBcmNoaXZlSW5wdXRTdHJlYW0gaGFzIGEgbmV3IG1ldGhvZCBnZXRCeXRlc1JlYWQgdGhhdCBzaG91bGQKKyAgICAgICAgYmUgcHJlZmVycmVkIG92ZXIgZ2V0Q291bnQgc2luY2UgdGhlIGxhdGVyIG1heSB0cnVuY2F0ZSB0aGUKKyAgICAgICAgbnVtYmVyIG9mIGJ5dGVzIHJlYWQgZm9yIGJpZyBhcmNoaXZlcy4KK28gQ09NUFJFU1MtODU6ICBUaGUgY3BpbyBhcmNoaXZlcyBjcmVhdGVkIGJ5IENwaW9BcmNoaXZlT3V0cHV0U3RyZWFtIGNvdWxkbid0CisgICAgICAgIGJlIHJlYWQgYnkgbWFueSBleGlzdGluZyBuYXRpdmUgaW1wbGVtZW50YXRpb25zIGJlY2F1c2UgdGhlCisgICAgICAgIGFyY2hpdmVzIGNvbnRhaW5lZCBtdWx0aXBsZSBlbnRyaWVzIHdpdGggdGhlIHNhbWUgaW5vZGUvZGV2aWNlCisgICAgICAgIGNvbWJpbmF0aW9ucyBhbmQgd2VyZW4ndCBwYWRkZWQgdG8gYSBibG9ja3NpemUgb2YgNTEyIGJ5dGVzLgorbyBDT01QUkVTUy03MzogIFppcEFyY2hpdmVFbnRyeSwgWmlwRmlsZSBhbmQgWmlwQXJjaGl2ZUlucHV0U3RyZWFtIGFyZSBub3cKKyAgICAgICAgbW9yZSBsZW5pZW50IHdoZW4gcGFyc2luZyBleHRyYSBmaWVsZHMuCitvIENPTVBSRVNTLTgyOiAgY3BpbyBpcyB0ZXJyaWJseSBzbG93LgorICAgICAgICBEb2N1bWVudGVkIHRoYXQgYnVmZmVyZWQgc3RyZWFtcyBhcmUgbmVlZGVkIGZvciBwZXJmb3JtYW5jZQorbyBJbXByb3ZlZCBleGNlcHRpb24gbWVzc2FnZSBpZiB0aGUgZXh0cmEgZmllbGQgZGF0YSBpbiBaSVAKKyAgICAgICAgYXJjaGl2ZXMgY2Fubm90IGJlIHBhcnNlZC4KK28gQ09NUFJFU1MtMTc6ICBUYXIgZm9ybWF0IHVuc3BlY2lmaWVkIC0gY3VycmVudCBzdXBwb3J0IGRvY3VtZW50ZWQuCitvIENPTVBSRVNTLTk0OiAgWmlwQXJjaGl2ZUVudHJ5J3MgZXF1YWxzIG1ldGhvZCB3YXMgYnJva2VuIGZvciBlbnRyaWVzIGNyZWF0ZWQKKyAgICAgICAgd2l0aCB0aGUgU3RyaW5nLWFyZyBjb25zdHJ1Y3Rvci4gIFRoaXMgbGVhZCB0byBicm9rZW4gWklQCisgICAgICAgIGFyY2hpdmVzIGlmIHR3byBkaWZmZXJlbnQgZW50cmllcyBoYWQgdGhlIHNhbWUgaGFzaCBjb2RlLiBUaGFua3MgdG8gQW5vbiBEZXZzLgorbyBDT01QUkVTUy04NzogIFppcEFyY2hpdmVJbnB1dFN0cmVhbSBjb3VsZCByZXBlYXRlZGx5IHJldHVybiAwIG9uIHJlYWQoKSB3aGVuCisgICAgICAgIHRoZSBhcmNoaXZlIHdhcyB0cnVuY2F0ZWQuIFRoYW5rcyB0byBBbnRvbmkgTXlsa2EuCitvIENPTVBSRVNTLTg2OiAgVGFyIGFyY2hpdmUgZW50cmllcyBob2xkaW5nIHRoZSBmaWxlIG5hbWUgZm9yIG5hbWVzIGxvbmdlcgorICAgICAgICB0aGFuIDEwMCBjaGFyYWN0ZXJzIGluIEdOVSBsb25nZmlsZSBtb2RlIGRpZG4ndCBwcm9wZXJseQorICAgICAgICBzcGVjaWZ5IHRoZXknZCBiZSB1c2luZyB0aGUgIm9sZGdudSIgZXh0ZW5zaW9uLgorbyBDT01QUkVTUy04MzogIERlbGVnYXRlIGFsbCByZWFkIGFuZCB3cml0ZSBtZXRob2RzIGluIEdaaXAgc3RyZWFtIGluIG9yZGVyIHRvCisgICAgICAgIHNwZWVkIHVwIG9wZXJhdGlvbnMuCitvIFRoZSBhciBhbmQgY3BpbyBzdHJlYW1zIG5vdyBwcm9wZXJseSByZWFkIGFuZCB3cml0ZSBsYXN0CisgICAgICAgIG1vZGlmaWVkIHRpbWVzLgorbyBDT01QUkVTUy04MTogIFRhck91dHB1dFN0cmVhbSBjYW4gbGVhdmUgZ2FyYmFnZSBhdCB0aGUgZW5kIG9mIHRoZSBhcmNoaXZlCisKK0NoYW5nZXM6CitvIENPTVBSRVNTLTExMjogIEFyQXJjaGl2ZUlucHV0U3RyZWFtIGRvZXMgbm90IGhhbmRsZSBHTlUgZXh0ZW5kZWQgZmlsZW5hbWUgcmVjb3JkcyAoLy8pCitvIENPTVBSRVNTLTEwNTogIERvY3VtZW50IHRoYXQgdGhlIG5hbWUgb2YgYW4gWmlwQXJjaGl2ZUVudHJ5IGRldGVybWluZXMgd2hldGhlcgorICAgICAgIGFuIGVudHJ5IGlzIGNvbnNpZGVyZWQgYSBkaXJlY3Rvcnkgb3Igbm90LgorICAgICAgIElmIHlvdSBkb24ndCB1c2UgdGhlIGNvbnN0cnVjdG9yIHdpdGggdGhlIEZpbGUgYXJndW1lbnQgdGhlIGVudHJ5J3MKKyAgICAgICAgbmFtZSBtdXN0IGVuZCBpbiBhICIvIiBpbiBvcmRlciBmb3IgdGhlIGVudHJ5IHRvIGJlIGtub3duIGFzIGEgZGlyZWN0b3J5LgorbyBDT01QUkVTUy03OTogIE1vdmUgRE9TL0phdmEgdGltZSBjb252ZXJzaW9ucyBpbnRvIFppcCB1dGlsaXR5IGNsYXNzLgorbyBDT01QUkVTUy03NTogIFppcEFyY2hpdmVJbnB1dFN0cmVhbSBkb2VzIG5vdCBzaG93IGxvY2F0aW9uIGluIGZpbGUKKyAgICAgICB3aGVyZSBhIHByb2JsZW0gb2NjdXJyZWQuCisKZGlmZiAtLWdpdCBhL2ZpbmRidWdzLWV4Y2x1ZGUtZmlsdGVyLnhtbCBiL2ZpbmRidWdzLWV4Y2x1ZGUtZmlsdGVyLnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kNjNmZTE1Ci0tLSAvZGV2L251bGwKKysrIGIvZmluZGJ1Z3MtZXhjbHVkZS1maWx0ZXIueG1sCkBAIC0wLDAgKzEsMjA3IEBACis8P3htbCB2ZXJzaW9uPSIxLjAiPz4KKzwhLS0KKyAgIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAgIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisKKyAgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKworICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAgIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCistLT4KKworPCEtLQorICBUaGlzIGZpbGUgY29udGFpbnMgc29tZSBmYWxzZSBwb3NpdGl2ZSBidWdzIGRldGVjdGVkIGJ5IGZpbmRidWdzLiBUaGVpcgorICBmYWxzZSBwb3NpdGl2ZSBuYXR1cmUgaGFzIGJlZW4gYW5hbHl6ZWQgaW5kaXZpZHVhbGx5IGFuZCB0aGV5IGhhdmUgYmVlbgorICBwdXQgaGVyZSB0byBpbnN0cnVjdCBmaW5kYnVncyBpdCBtdXN0IGlnbm9yZSB0aGVtLgorLS0+Cis8RmluZEJ1Z3NGaWx0ZXI+CisKKyAgPCEtLSBSZWFzb246IFJlZmVyZW5jZXMgdG8gU3lzdGVtLm91dC9lcnIgPT0gLS0+CisgIDxNYXRjaD4KKyAgICA8Q2xhc3MgbmFtZT0ib3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5MaXN0ZXIiIC8+CisgICAgPE9yPgorICAgICAgPE1ldGhvZCBuYW1lPSJtYWluIiAvPgorICAgICAgPE1ldGhvZCBuYW1lPSJ1c2FnZSIgLz4KKyAgICA8L09yPgorICAgIDxCdWcgcGF0dGVybj0iTlBfQUxXQVlTX05VTEwiIC8+CisgIDwvTWF0Y2g+CisgIDxNYXRjaD4KKyAgICA8Q2xhc3MgbmFtZT0ib3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXAuWmlwRmlsZSIgLz4KKyAgICA8TWV0aG9kIG5hbWU9ImZpbmFsaXplIiAvPgorICAgIDxCdWcgcGF0dGVybj0iTlBfQUxXQVlTX05VTEwiIC8+CisgIDwvTWF0Y2g+CisgIDxNYXRjaD4KKyAgICA8Q2xhc3MgbmFtZT0ib3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5kdW1wLkR1bXBBcmNoaXZlVXRpbCIgLz4KKyAgICA8TWV0aG9kIG5hbWU9ImR1bXBCbG9jayIgLz4KKyAgICA8QnVnIHBhdHRlcm49Ik5QX0FMV0FZU19OVUxMIiAvPgorICA8L01hdGNoPgorCisgIDwhLS0gUmVhc29uOiBmYWxsdGhyb3VnaCBpcyBpbnRlbmRlZCAtLT4KKyAgPE1hdGNoPgorICAgIDxDbGFzcyBuYW1lPSJvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcC5FeHRyYUZpZWxkVXRpbHMiIC8+CisgICAgPE1ldGhvZCBuYW1lPSJwYXJzZSIgLz4KKyAgICA8QnVnIHBhdHRlcm49IlNGX1NXSVRDSF9GQUxMVEhST1VHSCIgLz4KKyAgPC9NYXRjaD4KKyAgPE1hdGNoPgorICAgIDxDbGFzcyBuYW1lPSJvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMubHo0LkJsb2NrTFo0Q29tcHJlc3NvcklucHV0U3RyZWFtIiAvPgorICAgIDxNZXRob2QgbmFtZT0icmVhZCIgLz4KKyAgICA8QnVnIHBhdHRlcm49IlNGX1NXSVRDSF9GQUxMVEhST1VHSCIgLz4KKyAgPC9NYXRjaD4KKworICA8IS0tIFJlYXNvbjogZmllbGRzIHVudXNlZCBhcyBkb2N1bWVudGVkIC0tPgorICA8TWF0Y2g+CisgICAgPENsYXNzIG5hbWU9Im9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuamFyLkphckFyY2hpdmVFbnRyeSIgLz4KKyAgICA8T3I+CisgICAgICA8RmllbGQgbmFtZT0iY2VydGlmaWNhdGVzIi8+CisgICAgICA8RmllbGQgbmFtZT0ibWFuaWZlc3RBdHRyaWJ1dGVzIi8+CisgICAgPC9Pcj4KKyAgICA8QnVnIHBhdHRlcm49IlVXRl9OVUxMX0ZJRUxEIiAvPgorICA8L01hdGNoPgorICA8TWF0Y2g+CisgICAgPENsYXNzIG5hbWU9Im9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuZHVtcC5EdW1wQXJjaGl2ZUVudHJ5IiAvPgorICAgIDxGaWVsZCBuYW1lPSJzdW1tYXJ5Ii8+CisgICAgPEJ1ZyBwYXR0ZXJuPSJVV0ZfTlVMTF9GSUVMRCIgLz4KKyAgPC9NYXRjaD4KKyAgPE1hdGNoPgorICAgIDxDbGFzcyBuYW1lPSJvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnNldmVuei5Gb2xkZXIiIC8+CisgICAgPE9yPgorICAgICAgPEZpZWxkIG5hbWU9InRvdGFsSW5wdXRTdHJlYW1zIi8+CisgICAgPC9Pcj4KKyAgICA8QnVnIHBhdHRlcm49IlVSRl9VTlJFQURfRklFTEQiIC8+CisgIDwvTWF0Y2g+CisKKyAgPCEtLSBSZWFzb246IGV4Y2VwdGlvbiBpbiBjbG9zZSBzd2FsbG93ZWQgaW4gb3JkZXIgdG8gcmUtdGhyb3cgb3JpZ2luYWwgaW4gY2FsbGVyIC0tPgorICA8TWF0Y2g+CisgICAgPENsYXNzIG5hbWU9Im9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5JT1V0aWxzIiAvPgorICAgIDxNZXRob2QgbmFtZT0iY2xvc2VRdWlldGx5IiAvPgorICAgIDxCdWcgcGF0dGVybj0iREVfTUlHSFRfSUdOT1JFIiAvPgorICA8L01hdGNoPgorCisgIDwhLS0gUmVhc29uOiBza2lwKExvbmcuTUFYX1ZBTFVFKSBjYWxsZWQgdG8gZHJhaW4gc3RyZWFtIGNvbXBsZXRlbHksCisgICAgICAgdGhlIGNsYXNzIG92ZXJyaWRlcyBza2lwIHRvIGVuc3VyZSBpdCByZWFkcyB0aGUgZnVsbCBhbW91bnQKKyAgICAgICB1bnRpbCBFT0YgaXMgcmVhY2hlZCAtLT4KKyAgPE1hdGNoPgorICAgIDxDbGFzcyBuYW1lPSJvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcC5aaXBBcmNoaXZlSW5wdXRTdHJlYW0iIC8+CisgICAgPE1ldGhvZCBuYW1lPSJjbG9zZUVudHJ5IiAvPgorICAgIDxCdWcgcGF0dGVybj0iU1JfTk9UX0NIRUNLRUQiIC8+CisgIDwvTWF0Y2g+CisgIDxNYXRjaD4KKyAgICA8Q2xhc3MgbmFtZT0ib3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy50YXIuVGFyQXJjaGl2ZUlucHV0U3RyZWFtIiAvPgorICAgIDxNZXRob2QgbmFtZT0iZ2V0TmV4dFRhckVudHJ5IiAvPgorICAgIDxCdWcgcGF0dGVybj0iU1JfTk9UX0NIRUNLRUQiIC8+CisgIDwvTWF0Y2g+CisKKyAgPCEtLSBSZWFzb246IHRyeWluZyB0byBkZWxldGUgYSB0ZW1wb3JhcnkgZmlsZSB0aGF0IGhhcyBkZWxldGVPbkV4aXQgc2V0CisgICAgICAgYW55d2F5IC0tPgorICA8TWF0Y2g+CisgICAgPENsYXNzIG5hbWU9Im9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5wYWNrMjAwLlBhY2syMDBVdGlscyIgLz4KKyAgICA8TWV0aG9kIG5hbWU9Im5vcm1hbGl6ZSIgLz4KKyAgICA8QnVnIHBhdHRlcm49IlJWX1JFVFVSTl9WQUxVRV9JR05PUkVEX0JBRF9QUkFDVElDRSIgLz4KKyAgPC9NYXRjaD4KKyAgPE1hdGNoPgorICAgIDxDbGFzcyBuYW1lPSJvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMucGFjazIwMC5UZW1wRmlsZUNhY2hpbmdTdHJlYW1CcmlkZ2UkMSIgLz4KKyAgICA8TWV0aG9kIG5hbWU9ImNsb3NlIiAvPgorICAgIDxCdWcgcGF0dGVybj0iUlZfUkVUVVJOX1ZBTFVFX0lHTk9SRURfQkFEX1BSQUNUSUNFIiAvPgorICA8L01hdGNoPgorCisgIDwhLS0gUmVhc29uOiBJdCBpcyB0aGUgUGFjazIwMCpTdHJlYW0gdGhhdCdzIGdvaW5nIHRvIGNsb3NlIGl0LiAtLT4KKyAgPE1hdGNoPgorICAgIDxDbGFzcyBuYW1lPSJvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMucGFjazIwMC5UZW1wRmlsZUNhY2hpbmdTdHJlYW1CcmlkZ2UkMSIgLz4KKyAgICA8TWV0aG9kIG5hbWU9IiZsdDtpbml0Jmd0OyIgLz4KKyAgICA8QnVnIHBhdHRlcm49Ik9CTF9VTlNBVElTRklFRF9PQkxJR0FUSU9OIiAvPgorICA8L01hdGNoPgorCisgIDwhLS0gUmVhc29uOiB0aGUgY29udHJhY3QgaXMgdG8gdXNlIGRlZmF1bHQgZW5jb2RpbmcgKHVubGVzcyB0b2xkIG90aGVyd2lzZSkgLS0+CisgIDxNYXRjaD4KKyAgICA8Q2xhc3MgbmFtZT0ib3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5hcmouQXJqQXJjaGl2ZUlucHV0U3RyZWFtIiAvPgorICAgIDxNZXRob2QgbmFtZT0icmVhZFN0cmluZyIgLz4KKyAgICA8QnVnIHBhdHRlcm49IkRNX0RFRkFVTFRfRU5DT0RJTkciIC8+CisgIDwvTWF0Y2g+CisgIDxNYXRjaD4KKyAgICA8Q2xhc3MgbmFtZT0ib3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXAuQXNpRXh0cmFGaWVsZCIgLz4KKyAgICA8T3I+CisgICAgICA8TWV0aG9kIG5hbWU9ImdldExvY2FsRmlsZURhdGFEYXRhIiAvPgorICAgICAgPE1ldGhvZCBuYW1lPSJnZXRMb2NhbEZpbGVEYXRhTGVuZ3RoIiAvPgorICAgICAgPE1ldGhvZCBuYW1lPSJwYXJzZUZyb21Mb2NhbEZpbGVEYXRhIiAvPgorICAgIDwvT3I+CisgICAgPEJ1ZyBwYXR0ZXJuPSJETV9ERUZBVUxUX0VOQ09ESU5HIiAvPgorICA8L01hdGNoPgorICA8TWF0Y2g+CisgICAgPENsYXNzIG5hbWU9Im9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwLkZhbGxiYWNrWmlwRW5jb2RpbmciIC8+CisgICAgPE9yPgorICAgICAgPE1ldGhvZCBuYW1lPSJkZWNvZGUiIC8+CisgICAgICA8TWV0aG9kIG5hbWU9ImVuY29kZSIgLz4KKyAgICA8L09yPgorICAgIDxCdWcgcGF0dGVybj0iRE1fREVGQVVMVF9FTkNPRElORyIgLz4KKyAgPC9NYXRjaD4KKworICA8IS0tIFJlYXNvbjogZGVmYXVsdCBlbmNvZGluZyBpcyBnb29kIGVub3VnaCBmb3IgZXhjZXB0aW9uIG1lc3NhZ2UgLS0+CisgIDxNYXRjaD4KKyAgICA8Q2xhc3MgbmFtZT0ib3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy50YXIuVGFyVXRpbHMiIC8+CisgICAgPE1ldGhvZCBuYW1lPSJleGNlcHRpb25NZXNzYWdlIiAvPgorICAgIDxCdWcgcGF0dGVybj0iRE1fREVGQVVMVF9FTkNPRElORyIgLz4KKyAgPC9NYXRjaD4KKworICA8IS0tIFJlYXNvbjogdW5yb2xsZWQgbG9vcCwgYWxsIHBvc3NpYmxlIGNhc2VzIGFyZSBjb3ZlcmVkIC0tPgorICA8TWF0Y2g+CisgICAgPENsYXNzIG5hbWU9Im9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5zbmFwcHkuUHVyZUphdmFDcmMzMkMiIC8+CisgICAgPE1ldGhvZCBuYW1lPSJ1cGRhdGUiIC8+CisgICAgPEJ1ZyBwYXR0ZXJuPSJTRl9TV0lUQ0hfTk9fREVGQVVMVCIgLz4KKyAgPC9NYXRjaD4KKworICA8IS0tIFJlYXNvbjogY2xhc3Mgb25seSBhZGRzIHVudXNlZCBhbHdheXMtbnVsbCBmaWVsZHMgYW5kIHN1cGVyY2xhc3MnIGVxdWFscyBpcyBzdWZmaWNpZW50IC0tPgorICA8TWF0Y2g+CisgICAgPENsYXNzIG5hbWU9Im9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuamFyLkphckFyY2hpdmVFbnRyeSIgLz4KKyAgICA8TWV0aG9kIG5hbWU9ImVxdWFscyIgLz4KKyAgICA8QnVnIHBhdHRlcm49IkVRX0RPRVNOVF9PVkVSUklERV9FUVVBTFMiIC8+CisgIDwvTWF0Y2g+CisgIAorICA8IS0tIFJlYXNvbjogZmFpbHVyZSB0byBkZWxldGUgYSBmaWxlIHRoYXQgbWF5IG5vdCBleGlzdC4gQW5kIHdlIHJlYWxseSBkb24ndCBjYXJlIHRoYXQgbXVjaCBlaXRoZXIgLS0+CisgIDxNYXRjaD4KKyAgICA8Q2xhc3MgbmFtZT0ib3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnBhcmFsbGVsLkZpbGVCYXNlZFNjYXR0ZXJHYXRoZXJCYWNraW5nU3RvcmUiIC8+CisgICAgPE1ldGhvZCBuYW1lPSJjbG9zZSIgLz4KKyAgICA8QnVnIHBhdHRlcm49IlJWX1JFVFVSTl9WQUxVRV9JR05PUkVEX0JBRF9QUkFDVElDRSIgLz4KKyAgPC9NYXRjaD4KKworICA8IS0tIFJlYXNvbjogbmVzdGVkIGNvZGUgY2FuIHRocm93IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZgorICAgICAgIHN0cmVhbSBpcyBub3QgYSBUQVIgc3RyZWFtIC0tPgorICA8TWF0Y2g+CisgICAgPENsYXNzIG5hbWU9Im9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZVN0cmVhbUZhY3RvcnkiIC8+CisgICAgPE1ldGhvZCBuYW1lPSJjcmVhdGVBcmNoaXZlSW5wdXRTdHJlYW0iIC8+CisgICAgPEJ1ZyBwYXR0ZXJuPSJSRUNfQ0FUQ0hfRVhDRVBUSU9OIiAvPgorICA8L01hdGNoPgorICAKKyAgPCEtLSB0aGUgY2xhc3Mgd2FudHMgdG8gYWxsb3cgb3V0c2lkZSBhY2Nlc3MgdG8gdGhlIGFycmF5LCBqdXN0IGxpa2UKKyAgICAgICBCeXRlQnVmZmVyLndyYXAgZG9lcyAtLT4KKyAgPE1hdGNoPgorICAgIDxDbGFzcyBuYW1lPSJvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuU2Vla2FibGVJbk1lbW9yeUJ5dGVDaGFubmVsIiAvPgorICAgIDxNZXRob2QgbmFtZT0iYXJyYXkiIC8+CisgICAgPEJ1ZyBwYXR0ZXJuPSJFSV9FWFBPU0VfUkVQIiAvPgorICA8L01hdGNoPgorICA8TWF0Y2g+CisgICAgPENsYXNzIG5hbWU9Im9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5TZWVrYWJsZUluTWVtb3J5Qnl0ZUNoYW5uZWwiIC8+CisgICAgPE1ldGhvZCBuYW1lPSImbHQ7aW5pdCZndDsiIC8+CisgICAgPEJ1ZyBwYXR0ZXJuPSJFSV9FWFBPU0VfUkVQMiIgLz4KKyAgPC9NYXRjaD4KKworICA8IS0tIHRoZSBhcnJheSBpcyBleHBvc2VkIGRlbGliZXJhdGVseSB0byBpbXByb3ZlIHBlcmZvcm1hbmNlIGFuZCBpdAorICAgICAgIGlzIGRvY3VtZW50ZWQgdGhhdCB3YXkgLS0+CisgIDxNYXRjaD4KKyAgICA8Q2xhc3MgbmFtZT0ib3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLmx6NzdzdXBwb3J0LkxaNzdDb21wcmVzc29yJExpdGVyYWxCbG9jayIgLz4KKyAgICA8TWV0aG9kIG5hbWU9ImdldERhdGEiIC8+CisgICAgPEJ1ZyBwYXR0ZXJuPSJFSV9FWFBPU0VfUkVQIiAvPgorICA8L01hdGNoPgorICA8TWF0Y2g+CisgICAgPENsYXNzIG5hbWU9Im9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5sejc3c3VwcG9ydC5MWjc3Q29tcHJlc3NvciRMaXRlcmFsQmxvY2siIC8+CisgICAgPE1ldGhvZCBuYW1lPSImbHQ7aW5pdCZndDsiIC8+CisgICAgPEJ1ZyBwYXR0ZXJuPSJFSV9FWFBPU0VfUkVQMiIgLz4KKyAgPC9NYXRjaD4KKworPC9GaW5kQnVnc0ZpbHRlcj4KZGlmZiAtLWdpdCBhL212bncgYi9tdm53Cm5ldyBmaWxlIG1vZGUgMTAwNzU1CmluZGV4IDAwMDAwMDAuLjViZjI1MWMKLS0tIC9kZXYvbnVsbAorKysgYi9tdm53CkBAIC0wLDAgKzEsMjI1IEBACisjIS9iaW4vc2gKKyMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorIyBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisjIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorIyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorIyByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisjIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyMgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorIyB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisjCisjICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorIworIyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisjIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisjICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorIyBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyMgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworIyB1bmRlciB0aGUgTGljZW5zZS4KKyMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyMgTWF2ZW4yIFN0YXJ0IFVwIEJhdGNoIHNjcmlwdAorIworIyBSZXF1aXJlZCBFTlYgdmFyczoKKyMgLS0tLS0tLS0tLS0tLS0tLS0tCisjICAgSkFWQV9IT01FIC0gbG9jYXRpb24gb2YgYSBKREsgaG9tZSBkaXIKKyMKKyMgT3B0aW9uYWwgRU5WIHZhcnMKKyMgLS0tLS0tLS0tLS0tLS0tLS0KKyMgICBNMl9IT01FIC0gbG9jYXRpb24gb2YgbWF2ZW4yJ3MgaW5zdGFsbGVkIGhvbWUgZGlyCisjICAgTUFWRU5fT1BUUyAtIHBhcmFtZXRlcnMgcGFzc2VkIHRvIHRoZSBKYXZhIFZNIHdoZW4gcnVubmluZyBNYXZlbgorIyAgICAgZS5nLiB0byBkZWJ1ZyBNYXZlbiBpdHNlbGYsIHVzZQorIyAgICAgICBzZXQgTUFWRU5fT1BUUz0tWGRlYnVnIC1YcnVuamR3cDp0cmFuc3BvcnQ9ZHRfc29ja2V0LHNlcnZlcj15LHN1c3BlbmQ9eSxhZGRyZXNzPTgwMDAKKyMgICBNQVZFTl9TS0lQX1JDIC0gZmxhZyB0byBkaXNhYmxlIGxvYWRpbmcgb2YgbWF2ZW5yYyBmaWxlcworIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2lmIFsgLXogIiRNQVZFTl9TS0lQX1JDIiBdIDsgdGhlbgorCisgIGlmIFsgLWYgL2V0Yy9tYXZlbnJjIF0gOyB0aGVuCisgICAgLiAvZXRjL21hdmVucmMKKyAgZmkKKworICBpZiBbIC1mICIkSE9NRS8ubWF2ZW5yYyIgXSA7IHRoZW4KKyAgICAuICIkSE9NRS8ubWF2ZW5yYyIKKyAgZmkKKworZmkKKworIyBPUyBzcGVjaWZpYyBzdXBwb3J0LiAgJHZhciBfbXVzdF8gYmUgc2V0IHRvIGVpdGhlciB0cnVlIG9yIGZhbHNlLgorY3lnd2luPWZhbHNlOworZGFyd2luPWZhbHNlOworbWluZ3c9ZmFsc2UKK2Nhc2UgImB1bmFtZWAiIGluCisgIENZR1dJTiopIGN5Z3dpbj10cnVlIDs7CisgIE1JTkdXKikgbWluZ3c9dHJ1ZTs7CisgIERhcndpbiopIGRhcndpbj10cnVlCisgICAgIyBVc2UgL3Vzci9saWJleGVjL2phdmFfaG9tZSBpZiBhdmFpbGFibGUsIG90aGVyd2lzZSBmYWxsIGJhY2sgdG8gL0xpYnJhcnkvSmF2YS9Ib21lCisgICAgIyBTZWUgaHR0cHM6Ly9kZXZlbG9wZXIuYXBwbGUuY29tL2xpYnJhcnkvbWFjL3FhL3FhMTE3MC9faW5kZXguaHRtbAorICAgIGlmIFsgLXogIiRKQVZBX0hPTUUiIF07IHRoZW4KKyAgICAgIGlmIFsgLXggIi91c3IvbGliZXhlYy9qYXZhX2hvbWUiIF07IHRoZW4KKyAgICAgICAgZXhwb3J0IEpBVkFfSE9NRT0iYC91c3IvbGliZXhlYy9qYXZhX2hvbWVgIgorICAgICAgZWxzZQorICAgICAgICBleHBvcnQgSkFWQV9IT01FPSIvTGlicmFyeS9KYXZhL0hvbWUiCisgICAgICBmaQorICAgIGZpCisgICAgOzsKK2VzYWMKKworaWYgWyAteiAiJEpBVkFfSE9NRSIgXSA7IHRoZW4KKyAgaWYgWyAtciAvZXRjL2dlbnRvby1yZWxlYXNlIF0gOyB0aGVuCisgICAgSkFWQV9IT01FPWBqYXZhLWNvbmZpZyAtLWpyZS1ob21lYAorICBmaQorZmkKKworaWYgWyAteiAiJE0yX0hPTUUiIF0gOyB0aGVuCisgICMjIHJlc29sdmUgbGlua3MgLSAkMCBtYXkgYmUgYSBsaW5rIHRvIG1hdmVuJ3MgaG9tZQorICBQUkc9IiQwIgorCisgICMgbmVlZCB0aGlzIGZvciByZWxhdGl2ZSBzeW1saW5rcworICB3aGlsZSBbIC1oICIkUFJHIiBdIDsgZG8KKyAgICBscz1gbHMgLWxkICIkUFJHImAKKyAgICBsaW5rPWBleHByICIkbHMiIDogJy4qLT4gXCguKlwpJCdgCisgICAgaWYgZXhwciAiJGxpbmsiIDogJy8uKicgPiAvZGV2L251bGw7IHRoZW4KKyAgICAgIFBSRz0iJGxpbmsiCisgICAgZWxzZQorICAgICAgUFJHPSJgZGlybmFtZSAiJFBSRyJgLyRsaW5rIgorICAgIGZpCisgIGRvbmUKKworICBzYXZlZGRpcj1gcHdkYAorCisgIE0yX0hPTUU9YGRpcm5hbWUgIiRQUkciYC8uLgorCisgICMgbWFrZSBpdCBmdWxseSBxdWFsaWZpZWQKKyAgTTJfSE9NRT1gY2QgIiRNMl9IT01FIiAmJiBwd2RgCisKKyAgY2QgIiRzYXZlZGRpciIKKyAgIyBlY2hvIFVzaW5nIG0yIGF0ICRNMl9IT01FCitmaQorCisjIEZvciBDeWd3aW4sIGVuc3VyZSBwYXRocyBhcmUgaW4gVU5JWCBmb3JtYXQgYmVmb3JlIGFueXRoaW5nIGlzIHRvdWNoZWQKK2lmICRjeWd3aW4gOyB0aGVuCisgIFsgLW4gIiRNMl9IT01FIiBdICYmCisgICAgTTJfSE9NRT1gY3lncGF0aCAtLXVuaXggIiRNMl9IT01FImAKKyAgWyAtbiAiJEpBVkFfSE9NRSIgXSAmJgorICAgIEpBVkFfSE9NRT1gY3lncGF0aCAtLXVuaXggIiRKQVZBX0hPTUUiYAorICBbIC1uICIkQ0xBU1NQQVRIIiBdICYmCisgICAgQ0xBU1NQQVRIPWBjeWdwYXRoIC0tcGF0aCAtLXVuaXggIiRDTEFTU1BBVEgiYAorZmkKKworIyBGb3IgTWlnd24sIGVuc3VyZSBwYXRocyBhcmUgaW4gVU5JWCBmb3JtYXQgYmVmb3JlIGFueXRoaW5nIGlzIHRvdWNoZWQKK2lmICRtaW5ndyA7IHRoZW4KKyAgWyAtbiAiJE0yX0hPTUUiIF0gJiYKKyAgICBNMl9IT01FPSJgKGNkICIkTTJfSE9NRSI7IHB3ZClgIgorICBbIC1uICIkSkFWQV9IT01FIiBdICYmCisgICAgSkFWQV9IT01FPSJgKGNkICIkSkFWQV9IT01FIjsgcHdkKWAiCisgICMgVE9ETyBjbGFzc3BhdGg/CitmaQorCitpZiBbIC16ICIkSkFWQV9IT01FIiBdOyB0aGVuCisgIGphdmFFeGVjdXRhYmxlPSJgd2hpY2ggamF2YWNgIgorICBpZiBbIC1uICIkamF2YUV4ZWN1dGFibGUiIF0gJiYgISBbICJgZXhwciBcIiRqYXZhRXhlY3V0YWJsZVwiIDogJ1woW14gXSpcKSdgIiA9ICJubyIgXTsgdGhlbgorICAgICMgcmVhZGxpbmsoMSkgaXMgbm90IGF2YWlsYWJsZSBhcyBzdGFuZGFyZCBvbiBTb2xhcmlzIDEwLgorICAgIHJlYWRMaW5rPWB3aGljaCByZWFkbGlua2AKKyAgICBpZiBbICEgYGV4cHIgIiRyZWFkTGluayIgOiAnXChbXiBdKlwpJ2AgPSAibm8iIF07IHRoZW4KKyAgICAgIGlmICRkYXJ3aW4gOyB0aGVuCisgICAgICAgIGphdmFIb21lPSJgZGlybmFtZSBcIiRqYXZhRXhlY3V0YWJsZVwiYCIKKyAgICAgICAgamF2YUV4ZWN1dGFibGU9ImBjZCBcIiRqYXZhSG9tZVwiICYmIHB3ZCAtUGAvamF2YWMiCisgICAgICBlbHNlCisgICAgICAgIGphdmFFeGVjdXRhYmxlPSJgcmVhZGxpbmsgLWYgXCIkamF2YUV4ZWN1dGFibGVcImAiCisgICAgICBmaQorICAgICAgamF2YUhvbWU9ImBkaXJuYW1lIFwiJGphdmFFeGVjdXRhYmxlXCJgIgorICAgICAgamF2YUhvbWU9YGV4cHIgIiRqYXZhSG9tZSIgOiAnXCguKlwpL2JpbidgCisgICAgICBKQVZBX0hPTUU9IiRqYXZhSG9tZSIKKyAgICAgIGV4cG9ydCBKQVZBX0hPTUUKKyAgICBmaQorICBmaQorZmkKKworaWYgWyAteiAiJEpBVkFDTUQiIF0gOyB0aGVuCisgIGlmIFsgLW4gIiRKQVZBX0hPTUUiICBdIDsgdGhlbgorICAgIGlmIFsgLXggIiRKQVZBX0hPTUUvanJlL3NoL2phdmEiIF0gOyB0aGVuCisgICAgICAjIElCTSdzIEpESyBvbiBBSVggdXNlcyBzdHJhbmdlIGxvY2F0aW9ucyBmb3IgdGhlIGV4ZWN1dGFibGVzCisgICAgICBKQVZBQ01EPSIkSkFWQV9IT01FL2pyZS9zaC9qYXZhIgorICAgIGVsc2UKKyAgICAgIEpBVkFDTUQ9IiRKQVZBX0hPTUUvYmluL2phdmEiCisgICAgZmkKKyAgZWxzZQorICAgIEpBVkFDTUQ9ImB3aGljaCBqYXZhYCIKKyAgZmkKK2ZpCisKK2lmIFsgISAteCAiJEpBVkFDTUQiIF0gOyB0aGVuCisgIGVjaG8gIkVycm9yOiBKQVZBX0hPTUUgaXMgbm90IGRlZmluZWQgY29ycmVjdGx5LiIgPiYyCisgIGVjaG8gIiAgV2UgY2Fubm90IGV4ZWN1dGUgJEpBVkFDTUQiID4mMgorICBleGl0IDEKK2ZpCisKK2lmIFsgLXogIiRKQVZBX0hPTUUiIF0gOyB0aGVuCisgIGVjaG8gIldhcm5pbmc6IEpBVkFfSE9NRSBlbnZpcm9ubWVudCB2YXJpYWJsZSBpcyBub3Qgc2V0LiIKK2ZpCisKK0NMQVNTV09STERTX0xBVU5DSEVSPW9yZy5jb2RlaGF1cy5wbGV4dXMuY2xhc3N3b3JsZHMubGF1bmNoZXIuTGF1bmNoZXIKKworIyB0cmF2ZXJzZXMgZGlyZWN0b3J5IHN0cnVjdHVyZSBmcm9tIHByb2Nlc3Mgd29yayBkaXJlY3RvcnkgdG8gZmlsZXN5c3RlbSByb290CisjIGZpcnN0IGRpcmVjdG9yeSB3aXRoIC5tdm4gc3ViZGlyZWN0b3J5IGlzIGNvbnNpZGVyZWQgcHJvamVjdCBiYXNlIGRpcmVjdG9yeQorZmluZF9tYXZlbl9iYXNlZGlyKCkgeworCisgIGlmIFsgLXogIiQxIiBdCisgIHRoZW4KKyAgICBlY2hvICJQYXRoIG5vdCBzcGVjaWZpZWQgdG8gZmluZF9tYXZlbl9iYXNlZGlyIgorICAgIHJldHVybiAxCisgIGZpCisKKyAgYmFzZWRpcj0iJDEiCisgIHdkaXI9IiQxIgorICB3aGlsZSBbICIkd2RpciIgIT0gJy8nIF0gOyBkbworICAgIGlmIFsgLWQgIiR3ZGlyIi8ubXZuIF0gOyB0aGVuCisgICAgICBiYXNlZGlyPSR3ZGlyCisgICAgICBicmVhaworICAgIGZpCisgICAgIyB3b3JrYXJvdW5kIGZvciBKQkVBUC04OTM3IChvbiBTb2xhcmlzIDEwL1NwYXJjKQorICAgIGlmIFsgLWQgIiR7d2Rpcn0iIF07IHRoZW4KKyAgICAgIHdkaXI9YGNkICIkd2Rpci8uLiI7IHB3ZGAKKyAgICBmaQorICAgICMgZW5kIG9mIHdvcmthcm91bmQKKyAgZG9uZQorICBlY2hvICIke2Jhc2VkaXJ9IgorfQorCisjIGNvbmNhdGVuYXRlcyBhbGwgbGluZXMgb2YgYSBmaWxlCitjb25jYXRfbGluZXMoKSB7CisgIGlmIFsgLWYgIiQxIiBdOyB0aGVuCisgICAgZWNobyAiJCh0ciAtcyAnXG4nICcgJyA8ICIkMSIpIgorICBmaQorfQorCitCQVNFX0RJUj1gZmluZF9tYXZlbl9iYXNlZGlyICIkKHB3ZCkiYAoraWYgWyAteiAiJEJBU0VfRElSIiBdOyB0aGVuCisgIGV4aXQgMTsKK2ZpCisKK2V4cG9ydCBNQVZFTl9QUk9KRUNUQkFTRURJUj0ke01BVkVOX0JBU0VESVI6LSIkQkFTRV9ESVIifQorZWNobyAkTUFWRU5fUFJPSkVDVEJBU0VESVIKK01BVkVOX09QVFM9IiQoY29uY2F0X2xpbmVzICIkTUFWRU5fUFJPSkVDVEJBU0VESVIvLm12bi9qdm0uY29uZmlnIikgJE1BVkVOX09QVFMiCisKKyMgRm9yIEN5Z3dpbiwgc3dpdGNoIHBhdGhzIHRvIFdpbmRvd3MgZm9ybWF0IGJlZm9yZSBydW5uaW5nIGphdmEKK2lmICRjeWd3aW47IHRoZW4KKyAgWyAtbiAiJE0yX0hPTUUiIF0gJiYKKyAgICBNMl9IT01FPWBjeWdwYXRoIC0tcGF0aCAtLXdpbmRvd3MgIiRNMl9IT01FImAKKyAgWyAtbiAiJEpBVkFfSE9NRSIgXSAmJgorICAgIEpBVkFfSE9NRT1gY3lncGF0aCAtLXBhdGggLS13aW5kb3dzICIkSkFWQV9IT01FImAKKyAgWyAtbiAiJENMQVNTUEFUSCIgXSAmJgorICAgIENMQVNTUEFUSD1gY3lncGF0aCAtLXBhdGggLS13aW5kb3dzICIkQ0xBU1NQQVRIImAKKyAgWyAtbiAiJE1BVkVOX1BST0pFQ1RCQVNFRElSIiBdICYmCisgICAgTUFWRU5fUFJPSkVDVEJBU0VESVI9YGN5Z3BhdGggLS1wYXRoIC0td2luZG93cyAiJE1BVkVOX1BST0pFQ1RCQVNFRElSImAKK2ZpCisKK1dSQVBQRVJfTEFVTkNIRVI9b3JnLmFwYWNoZS5tYXZlbi53cmFwcGVyLk1hdmVuV3JhcHBlck1haW4KKworZXhlYyAiJEpBVkFDTUQiIFwKKyAgJE1BVkVOX09QVFMgXAorICAtY2xhc3NwYXRoICIkTUFWRU5fUFJPSkVDVEJBU0VESVIvLm12bi93cmFwcGVyL21hdmVuLXdyYXBwZXIuamFyIiBcCisgICItRG1hdmVuLmhvbWU9JHtNMl9IT01FfSIgIi1EbWF2ZW4ubXVsdGlNb2R1bGVQcm9qZWN0RGlyZWN0b3J5PSR7TUFWRU5fUFJPSkVDVEJBU0VESVJ9IiBcCisgICR7V1JBUFBFUl9MQVVOQ0hFUn0gJE1BVkVOX0NPTkZJRyAiJEAiCmRpZmYgLS1naXQgYS9tdm53LmNtZCBiL212bncuY21kCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAxOWJkNzQKLS0tIC9kZXYvbnVsbAorKysgYi9tdm53LmNtZApAQCAtMCwwICsxLDE0MyBAQAorQFJFTSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCitAUkVNIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKK0BSRU0gb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCitAUkVNIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCitAUkVNIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKK0BSRU0gdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorQFJFTSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCitAUkVNIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKK0BSRU0KK0BSRU0gICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCitAUkVNCitAUkVNIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKK0BSRU0gc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KK0BSRU0gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCitAUkVNIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorQFJFTSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCitAUkVNIHVuZGVyIHRoZSBMaWNlbnNlLgorQFJFTSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK0BSRU0gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorQFJFTSBNYXZlbjIgU3RhcnQgVXAgQmF0Y2ggc2NyaXB0CitAUkVNCitAUkVNIFJlcXVpcmVkIEVOViB2YXJzOgorQFJFTSBKQVZBX0hPTUUgLSBsb2NhdGlvbiBvZiBhIEpESyBob21lIGRpcgorQFJFTQorQFJFTSBPcHRpb25hbCBFTlYgdmFycworQFJFTSBNMl9IT01FIC0gbG9jYXRpb24gb2YgbWF2ZW4yJ3MgaW5zdGFsbGVkIGhvbWUgZGlyCitAUkVNIE1BVkVOX0JBVENIX0VDSE8gLSBzZXQgdG8gJ29uJyB0byBlbmFibGUgdGhlIGVjaG9pbmcgb2YgdGhlIGJhdGNoIGNvbW1hbmRzCitAUkVNIE1BVkVOX0JBVENIX1BBVVNFIC0gc2V0IHRvICdvbicgdG8gd2FpdCBmb3IgYSBrZXkgc3Ryb2tlIGJlZm9yZSBlbmRpbmcKK0BSRU0gTUFWRU5fT1BUUyAtIHBhcmFtZXRlcnMgcGFzc2VkIHRvIHRoZSBKYXZhIFZNIHdoZW4gcnVubmluZyBNYXZlbgorQFJFTSAgICAgZS5nLiB0byBkZWJ1ZyBNYXZlbiBpdHNlbGYsIHVzZQorQFJFTSBzZXQgTUFWRU5fT1BUUz0tWGRlYnVnIC1YcnVuamR3cDp0cmFuc3BvcnQ9ZHRfc29ja2V0LHNlcnZlcj15LHN1c3BlbmQ9eSxhZGRyZXNzPTgwMDAKK0BSRU0gTUFWRU5fU0tJUF9SQyAtIGZsYWcgdG8gZGlzYWJsZSBsb2FkaW5nIG9mIG1hdmVucmMgZmlsZXMKK0BSRU0gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitAUkVNIEJlZ2luIGFsbCBSRU0gbGluZXMgd2l0aCAnQCcgaW4gY2FzZSBNQVZFTl9CQVRDSF9FQ0hPIGlzICdvbicKK0BlY2hvIG9mZgorQFJFTSBlbmFibGUgZWNob2luZyBteSBzZXR0aW5nIE1BVkVOX0JBVENIX0VDSE8gdG8gJ29uJworQGlmICIlTUFWRU5fQkFUQ0hfRUNITyUiID09ICJvbiIgIGVjaG8gJU1BVkVOX0JBVENIX0VDSE8lCisKK0BSRU0gc2V0ICVIT01FJSB0byBlcXVpdmFsZW50IG9mICRIT01FCitpZiAiJUhPTUUlIiA9PSAiIiAoc2V0ICJIT01FPSVIT01FRFJJVkUlJUhPTUVQQVRIJSIpCisKK0BSRU0gRXhlY3V0ZSBhIHVzZXIgZGVmaW5lZCBzY3JpcHQgYmVmb3JlIHRoaXMgb25lCitpZiBub3QgIiVNQVZFTl9TS0lQX1JDJSIgPT0gIiIgZ290byBza2lwUmNQcmUKK0BSRU0gY2hlY2sgZm9yIHByZSBzY3JpcHQsIG9uY2Ugd2l0aCBsZWdhY3kgLmJhdCBlbmRpbmcgYW5kIG9uY2Ugd2l0aCAuY21kIGVuZGluZworaWYgZXhpc3QgIiVIT01FJVxtYXZlbnJjX3ByZS5iYXQiIGNhbGwgIiVIT01FJVxtYXZlbnJjX3ByZS5iYXQiCitpZiBleGlzdCAiJUhPTUUlXG1hdmVucmNfcHJlLmNtZCIgY2FsbCAiJUhPTUUlXG1hdmVucmNfcHJlLmNtZCIKKzpza2lwUmNQcmUKKworQHNldGxvY2FsCisKK3NldCBFUlJPUl9DT0RFPTAKKworQFJFTSBUbyBpc29sYXRlIGludGVybmFsIHZhcmlhYmxlcyBmcm9tIHBvc3NpYmxlIHBvc3Qgc2NyaXB0cywgd2UgdXNlIGFub3RoZXIgc2V0bG9jYWwKK0BzZXRsb2NhbAorCitAUkVNID09PT0gU1RBUlQgVkFMSURBVElPTiA9PT09CitpZiBub3QgIiVKQVZBX0hPTUUlIiA9PSAiIiBnb3RvIE9rSkhvbWUKKworZWNoby4KK2VjaG8gRXJyb3I6IEpBVkFfSE9NRSBub3QgZm91bmQgaW4geW91ciBlbnZpcm9ubWVudC4gPiYyCitlY2hvIFBsZWFzZSBzZXQgdGhlIEpBVkFfSE9NRSB2YXJpYWJsZSBpbiB5b3VyIGVudmlyb25tZW50IHRvIG1hdGNoIHRoZSA+JjIKK2VjaG8gbG9jYXRpb24gb2YgeW91ciBKYXZhIGluc3RhbGxhdGlvbi4gPiYyCitlY2hvLgorZ290byBlcnJvcgorCis6T2tKSG9tZQoraWYgZXhpc3QgIiVKQVZBX0hPTUUlXGJpblxqYXZhLmV4ZSIgZ290byBpbml0CisKK2VjaG8uCitlY2hvIEVycm9yOiBKQVZBX0hPTUUgaXMgc2V0IHRvIGFuIGludmFsaWQgZGlyZWN0b3J5LiA+JjIKK2VjaG8gSkFWQV9IT01FID0gIiVKQVZBX0hPTUUlIiA+JjIKK2VjaG8gUGxlYXNlIHNldCB0aGUgSkFWQV9IT01FIHZhcmlhYmxlIGluIHlvdXIgZW52aXJvbm1lbnQgdG8gbWF0Y2ggdGhlID4mMgorZWNobyBsb2NhdGlvbiBvZiB5b3VyIEphdmEgaW5zdGFsbGF0aW9uLiA+JjIKK2VjaG8uCitnb3RvIGVycm9yCisKK0BSRU0gPT09PSBFTkQgVkFMSURBVElPTiA9PT09CisKKzppbml0CisKK0BSRU0gRmluZCB0aGUgcHJvamVjdCBiYXNlIGRpciwgaS5lLiB0aGUgZGlyZWN0b3J5IHRoYXQgY29udGFpbnMgdGhlIGZvbGRlciAiLm12biIuCitAUkVNIEZhbGxiYWNrIHRvIGN1cnJlbnQgd29ya2luZyBkaXJlY3RvcnkgaWYgbm90IGZvdW5kLgorCitzZXQgTUFWRU5fUFJPSkVDVEJBU0VESVI9JU1BVkVOX0JBU0VESVIlCitJRiBOT1QgIiVNQVZFTl9QUk9KRUNUQkFTRURJUiUiPT0iIiBnb3RvIGVuZERldGVjdEJhc2VEaXIKKworc2V0IEVYRUNfRElSPSVDRCUKK3NldCBXRElSPSVFWEVDX0RJUiUKKzpmaW5kQmFzZURpcgorSUYgRVhJU1QgIiVXRElSJSJcLm12biBnb3RvIGJhc2VEaXJGb3VuZAorY2QgLi4KK0lGICIlV0RJUiUiPT0iJUNEJSIgZ290byBiYXNlRGlyTm90Rm91bmQKK3NldCBXRElSPSVDRCUKK2dvdG8gZmluZEJhc2VEaXIKKworOmJhc2VEaXJGb3VuZAorc2V0IE1BVkVOX1BST0pFQ1RCQVNFRElSPSVXRElSJQorY2QgIiVFWEVDX0RJUiUiCitnb3RvIGVuZERldGVjdEJhc2VEaXIKKworOmJhc2VEaXJOb3RGb3VuZAorc2V0IE1BVkVOX1BST0pFQ1RCQVNFRElSPSVFWEVDX0RJUiUKK2NkICIlRVhFQ19ESVIlIgorCis6ZW5kRGV0ZWN0QmFzZURpcgorCitJRiBOT1QgRVhJU1QgIiVNQVZFTl9QUk9KRUNUQkFTRURJUiVcLm12blxqdm0uY29uZmlnIiBnb3RvIGVuZFJlYWRBZGRpdGlvbmFsQ29uZmlnCisKK0BzZXRsb2NhbCBFbmFibGVFeHRlbnNpb25zIEVuYWJsZURlbGF5ZWRFeHBhbnNpb24KK2ZvciAvRiAidXNlYmFja3EgZGVsaW1zPSIgJSVhIGluICgiJU1BVkVOX1BST0pFQ1RCQVNFRElSJVwubXZuXGp2bS5jb25maWciKSBkbyBzZXQgSlZNX0NPTkZJR19NQVZFTl9QUk9QUz0hSlZNX0NPTkZJR19NQVZFTl9QUk9QUyEgJSVhCitAZW5kbG9jYWwgJiBzZXQgSlZNX0NPTkZJR19NQVZFTl9QUk9QUz0lSlZNX0NPTkZJR19NQVZFTl9QUk9QUyUKKworOmVuZFJlYWRBZGRpdGlvbmFsQ29uZmlnCisKK1NFVCBNQVZFTl9KQVZBX0VYRT0iJUpBVkFfSE9NRSVcYmluXGphdmEuZXhlIgorCitzZXQgV1JBUFBFUl9KQVI9IiVNQVZFTl9QUk9KRUNUQkFTRURJUiVcLm12blx3cmFwcGVyXG1hdmVuLXdyYXBwZXIuamFyIgorc2V0IFdSQVBQRVJfTEFVTkNIRVI9b3JnLmFwYWNoZS5tYXZlbi53cmFwcGVyLk1hdmVuV3JhcHBlck1haW4KKworJU1BVkVOX0pBVkFfRVhFJSAlSlZNX0NPTkZJR19NQVZFTl9QUk9QUyUgJU1BVkVOX09QVFMlICVNQVZFTl9ERUJVR19PUFRTJSAtY2xhc3NwYXRoICVXUkFQUEVSX0pBUiUgIi1EbWF2ZW4ubXVsdGlNb2R1bGVQcm9qZWN0RGlyZWN0b3J5PSVNQVZFTl9QUk9KRUNUQkFTRURJUiUiICVXUkFQUEVSX0xBVU5DSEVSJSAlTUFWRU5fQ09ORklHJSAlKgoraWYgRVJST1JMRVZFTCAxIGdvdG8gZXJyb3IKK2dvdG8gZW5kCisKKzplcnJvcgorc2V0IEVSUk9SX0NPREU9MQorCis6ZW5kCitAZW5kbG9jYWwgJiBzZXQgRVJST1JfQ09ERT0lRVJST1JfQ09ERSUKKworaWYgbm90ICIlTUFWRU5fU0tJUF9SQyUiID09ICIiIGdvdG8gc2tpcFJjUG9zdAorQFJFTSBjaGVjayBmb3IgcG9zdCBzY3JpcHQsIG9uY2Ugd2l0aCBsZWdhY3kgLmJhdCBlbmRpbmcgYW5kIG9uY2Ugd2l0aCAuY21kIGVuZGluZworaWYgZXhpc3QgIiVIT01FJVxtYXZlbnJjX3Bvc3QuYmF0IiBjYWxsICIlSE9NRSVcbWF2ZW5yY19wb3N0LmJhdCIKK2lmIGV4aXN0ICIlSE9NRSVcbWF2ZW5yY19wb3N0LmNtZCIgY2FsbCAiJUhPTUUlXG1hdmVucmNfcG9zdC5jbWQiCis6c2tpcFJjUG9zdAorCitAUkVNIHBhdXNlIHRoZSBzY3JpcHQgaWYgTUFWRU5fQkFUQ0hfUEFVU0UgaXMgc2V0IHRvICdvbicKK2lmICIlTUFWRU5fQkFUQ0hfUEFVU0UlIiA9PSAib24iIHBhdXNlCisKK2lmICIlTUFWRU5fVEVSTUlOQVRFX0NNRCUiID09ICJvbiIgZXhpdCAlRVJST1JfQ09ERSUKKworZXhpdCAvQiAlRVJST1JfQ09ERSUKZGlmZiAtLWdpdCBhL3BtZC1ydWxlc2V0LnhtbCBiL3BtZC1ydWxlc2V0LnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44YWQxMTUzCi0tLSAvZGV2L251bGwKKysrIGIvcG1kLXJ1bGVzZXQueG1sCkBAIC0wLDAgKzEsMzQgQEAKKzw/eG1sIHZlcnNpb249IjEuMCI/PgorPCEtLQorCisgICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAgIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAgICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorCisgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisKKyAgIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAgIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAgIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAgIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorCistLT4KKzxydWxlc2V0IG5hbWU9ImNvbXByZXNzIgorICAgIHhtbG5zPSJodHRwOi8vcG1kLnNmLm5ldC9ydWxlc2V0LzEuMC4wIgorICAgIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiCisgICAgeHNpOnNjaGVtYUxvY2F0aW9uPSJodHRwOi8vcG1kLnNmLm5ldC9ydWxlc2V0LzEuMC4wIGh0dHA6Ly9wbWQuc2YubmV0L3J1bGVzZXRfeG1sX3NjaGVtYS54c2QiCisgICAgeHNpOm5vTmFtZXNwYWNlU2NoZW1hTG9jYXRpb249Imh0dHA6Ly9wbWQuc2YubmV0L3J1bGVzZXRfeG1sX3NjaGVtYS54c2QiPgorICA8ZGVzY3JpcHRpb24+U3RhbmRhcmQgUnVsZXNldCBidXQgZXhjbHVkaW5nIHRoZSAibm8gb2N0YWwKKyAgICBjb25zdGFudHMiIHJ1bGU8L2Rlc2NyaXB0aW9uPgorICA8cnVsZSByZWY9InJ1bGVzZXRzL2phdmEvYmFzaWMueG1sIj4KKyAgICA8ZXhjbHVkZSBuYW1lPSJBdm9pZFVzaW5nT2N0YWxWYWx1ZXMiLz4KKyAgPC9ydWxlPgorICA8cnVsZSByZWY9InJ1bGVzZXRzL2phdmEvZmluYWxpemVycy54bWwiLz4KKyAgPHJ1bGUgcmVmPSJydWxlc2V0cy9qYXZhL2ltcG9ydHMueG1sIi8+CisgIDxydWxlIHJlZj0icnVsZXNldHMvamF2YS91bnVzZWRjb2RlLnhtbCIvPgorICA8cnVsZSByZWY9InJ1bGVzZXRzL2phdmEvYnJhY2VzLnhtbCIvPgorPC9ydWxlc2V0PgpkaWZmIC0tZ2l0IGEvcG9tLnhtbCBiL3BvbS54bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDdkN2M0NAotLS0gL2Rldi9udWxsCisrKyBiL3BvbS54bWwKQEAgLTAsMCArMSw1NDEgQEAKKzw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04Ij8+Cis8IS0tCisgICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAgIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAgICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorCisgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisKKyAgIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAgIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAgIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAgIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorLS0+Cis8cHJvamVjdCB4bWxucz0iaHR0cDovL21hdmVuLmFwYWNoZS5vcmcvUE9NLzQuMC4wIiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4c2k6c2NoZW1hTG9jYXRpb249Imh0dHA6Ly9tYXZlbi5hcGFjaGUub3JnL1BPTS80LjAuMCBodHRwOi8vbWF2ZW4uYXBhY2hlLm9yZy9tYXZlbi12NF8wXzAueHNkIj4KKyAgPG1vZGVsVmVyc2lvbj40LjAuMDwvbW9kZWxWZXJzaW9uPgorICA8cGFyZW50PgorICAgIDxncm91cElkPm9yZy5hcGFjaGUuY29tbW9uczwvZ3JvdXBJZD4KKyAgICA8YXJ0aWZhY3RJZD5jb21tb25zLXBhcmVudDwvYXJ0aWZhY3RJZD4KKyAgICA8dmVyc2lvbj40NzwvdmVyc2lvbj4KKyAgPC9wYXJlbnQ+CisKKyAgPGFydGlmYWN0SWQ+Y29tbW9ucy1jb21wcmVzczwvYXJ0aWZhY3RJZD4KKyAgPHZlcnNpb24+MS4xOS1TTkFQU0hPVDwvdmVyc2lvbj4KKyAgPG5hbWU+QXBhY2hlIENvbW1vbnMgQ29tcHJlc3M8L25hbWU+CisgIDx1cmw+aHR0cHM6Ly9jb21tb25zLmFwYWNoZS5vcmcvcHJvcGVyL2NvbW1vbnMtY29tcHJlc3MvPC91cmw+CisgIDwhLS0gVGhlIGRlc2NyaXB0aW9uIGlzIG5vdCBpbmRlbnRlZCB0byBtYWtlIGl0IGxvb2sgYmV0dGVyIGluIHRoZSByZWxlYXNlIG5vdGVzIC0tPgorICA8ZGVzY3JpcHRpb24+CitBcGFjaGUgQ29tbW9ucyBDb21wcmVzcyBzb2Z0d2FyZSBkZWZpbmVzIGFuIEFQSSBmb3Igd29ya2luZyB3aXRoCitjb21wcmVzc2lvbiBhbmQgYXJjaGl2ZSBmb3JtYXRzLiAgVGhlc2UgaW5jbHVkZTogYnppcDIsIGd6aXAsIHBhY2syMDAsCitsem1hLCB4eiwgU25hcHB5LCB0cmFkaXRpb25hbCBVbml4IENvbXByZXNzLCBERUZMQVRFLCBERUZMQVRFNjQsIExaNCwKK0Jyb3RsaSwgWnN0YW5kYXJkIGFuZCBhciwgY3BpbywgamFyLCB0YXIsIHppcCwgZHVtcCwgN3osIGFyai4KKyAgPC9kZXNjcmlwdGlvbj4KKworICA8cHJvcGVydGllcz4KKyAgICA8bWF2ZW4uY29tcGlsZXIuc291cmNlPjEuNzwvbWF2ZW4uY29tcGlsZXIuc291cmNlPgorICAgIDxtYXZlbi5jb21waWxlci50YXJnZXQ+MS43PC9tYXZlbi5jb21waWxlci50YXJnZXQ+CisgICAgPGNvbW1vbnMuY29tcG9uZW50aWQ+Y29tcHJlc3M8L2NvbW1vbnMuY29tcG9uZW50aWQ+CisgICAgPGNvbW1vbnMubW9kdWxlLm5hbWU+b3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzPC9jb21tb25zLm1vZHVsZS5uYW1lPgorICAgIDxjb21tb25zLmppcmEuaWQ+Q09NUFJFU1M8L2NvbW1vbnMuamlyYS5pZD4KKyAgICA8Y29tbW9ucy5qaXJhLnBpZD4xMjMxMDkwNDwvY29tbW9ucy5qaXJhLnBpZD4KKyAgICA8IS0tIGNvbmZpZ3VyYXRpb24gYml0cyBmb3IgY3V0dGluZyBhIHJlbGVhc2UgY2FuZGlkYXRlIC0tPgorICAgIDxjb21tb25zLnJlbGVhc2UudmVyc2lvbj4ke3Byb2plY3QudmVyc2lvbn08L2NvbW1vbnMucmVsZWFzZS52ZXJzaW9uPgorICAgIDxjb21tb25zLnJjLnZlcnNpb24+UkMxPC9jb21tb25zLnJjLnZlcnNpb24+CisgICAgPHBvd2VybW9jay52ZXJzaW9uPjEuNy4zPC9wb3dlcm1vY2sudmVyc2lvbj4KKyAgICA8Y29tbW9ucy5wbWQtcGx1Z2luLnZlcnNpb24+My44PC9jb21tb25zLnBtZC1wbHVnaW4udmVyc2lvbj4KKworICAgIDxjb21tb25zLm1hbmlmZXN0bG9jYXRpb24+JHtwcm9qZWN0LmJ1aWxkLm91dHB1dERpcmVjdG9yeX0vTUVUQS1JTkY8L2NvbW1vbnMubWFuaWZlc3Rsb2NhdGlvbj4KKyAgICA8Y29tbW9ucy5tYW5pZmVzdGZpbGU+JHtjb21tb25zLm1hbmlmZXN0bG9jYXRpb259L01BTklGRVNULk1GPC9jb21tb25zLm1hbmlmZXN0ZmlsZT4KKyAgICA8Y29tbW9ucy5vc2dpLmltcG9ydD4KKyAgICAgIG9yZy50dWthYW5pLnh6O3Jlc29sdXRpb246PW9wdGlvbmFsLAorICAgICAgb3JnLmJyb3RsaS5kZWM7cmVzb2x1dGlvbjo9b3B0aW9uYWwsCisgICAgICBjb20uZ2l0aHViLmx1YmVuLnpzdGQ7cmVzb2x1dGlvbjo9b3B0aW9uYWwsCisgICAgICBqYXZheC5jcnlwdG8uKjtyZXNvbHV0aW9uOj1vcHRpb25hbCwKKyAgICAgICoKKyAgICA8L2NvbW1vbnMub3NnaS5pbXBvcnQ+CisKKyAgICA8IS0tIG9ubHkgc2hvdyBpc3N1ZXMgb2YgdGhlIGN1cnJlbnQgdmVyc2lvbiAtLT4KKyAgICA8Y29tbW9ucy5jaGFuZ2VzLm9ubHlDdXJyZW50VmVyc2lvbj50cnVlPC9jb21tb25zLmNoYW5nZXMub25seUN1cnJlbnRWZXJzaW9uPgorCisgICAgPCEtLSBnZW5lcmF0ZSByZXBvcnQgZXZlbiBpZiB0aGVyZSBhcmUgYmluYXJ5IGluY29tcGF0aWJsZSBjaGFuZ2VzIC0tPgorICAgIDxjb21tb25zLmphcGljbXAuYnJlYWtCdWlsZE9uQmluYXJ5SW5jb21wYXRpYmxlTW9kaWZpY2F0aW9ucz5mYWxzZTwvY29tbW9ucy5qYXBpY21wLmJyZWFrQnVpbGRPbkJpbmFyeUluY29tcGF0aWJsZU1vZGlmaWNhdGlvbnM+CisgICAgPCEtLSAwLjEyLjAgZGllcyB3aXRoIGEgTnVsbFBvaW50ZXJFeGNlcHRpb24gLS0+CisgICAgPGNvbW1vbnMuamFwaWNtcC52ZXJzaW9uPjAuMTEuMTwvY29tbW9ucy5qYXBpY21wLnZlcnNpb24+CisKKyAgICA8IS0tIGRlZmluaXRpb24gdXNlcyBjb21tb25zLmNvbXBvbmVudElkIHN0YXJ0aW5nIHdpdGggcGFyZW50IDQ3LAorICAgICAgICAgdGhpcyBkb2Vzbid0IHdvcmsgZm9yIHVzIC0tPgorICAgIDxjb21tb25zLnNjbVB1YlVybD5odHRwczovL3N2bi5hcGFjaGUub3JnL3JlcG9zL2luZnJhL3dlYnNpdGVzL3Byb2R1Y3Rpb24vY29tbW9ucy9jb250ZW50L3Byb3Blci8ke3Byb2plY3QuYXJ0aWZhY3RJZH08L2NvbW1vbnMuc2NtUHViVXJsPgorCisgICAgPHBheC5leGFtLnZlcnNpb24+NC4xMS4wPC9wYXguZXhhbS52ZXJzaW9uPgorICAgIDxzbGY0ai52ZXJzaW9uPjEuNy4yMTwvc2xmNGoudmVyc2lvbj4KKyAgPC9wcm9wZXJ0aWVzPgorCisgIDxpc3N1ZU1hbmFnZW1lbnQ+CisgICAgPHN5c3RlbT5qaXJhPC9zeXN0ZW0+CisgICAgPHVybD5odHRwczovL2lzc3Vlcy5hcGFjaGUub3JnL2ppcmEvYnJvd3NlL0NPTVBSRVNTPC91cmw+CisgIDwvaXNzdWVNYW5hZ2VtZW50PgorCisgIDxkZXBlbmRlbmNpZXM+CisgICAgPGRlcGVuZGVuY3k+CisgICAgICA8Z3JvdXBJZD5qdW5pdDwvZ3JvdXBJZD4KKyAgICAgIDxhcnRpZmFjdElkPmp1bml0PC9hcnRpZmFjdElkPgorICAgICAgPHZlcnNpb24+NC4xMjwvdmVyc2lvbj4KKyAgICAgIDxzY29wZT50ZXN0PC9zY29wZT4KKyAgICA8L2RlcGVuZGVuY3k+CisgICAgPGRlcGVuZGVuY3k+CisgICAgICA8Z3JvdXBJZD5jb20uZ2l0aHViLmx1YmVuPC9ncm91cElkPgorICAgICAgPGFydGlmYWN0SWQ+enN0ZC1qbmk8L2FydGlmYWN0SWQ+CisgICAgICA8dmVyc2lvbj4xLjMuMy0zPC92ZXJzaW9uPgorICAgICAgPG9wdGlvbmFsPnRydWU8L29wdGlvbmFsPgorICAgIDwvZGVwZW5kZW5jeT4KKyAgICA8ZGVwZW5kZW5jeT4KKyAgICAgIDxncm91cElkPm9yZy5icm90bGk8L2dyb3VwSWQ+CisgICAgICA8YXJ0aWZhY3RJZD5kZWM8L2FydGlmYWN0SWQ+CisgICAgICA8dmVyc2lvbj4wLjEuMjwvdmVyc2lvbj4KKyAgICAgIDxvcHRpb25hbD50cnVlPC9vcHRpb25hbD4KKyAgICA8L2RlcGVuZGVuY3k+CisgICAgPGRlcGVuZGVuY3k+CisgICAgICA8Z3JvdXBJZD5vcmcudHVrYWFuaTwvZ3JvdXBJZD4KKyAgICAgIDxhcnRpZmFjdElkPnh6PC9hcnRpZmFjdElkPgorICAgICAgPHZlcnNpb24+MS44PC92ZXJzaW9uPgorICAgICAgPG9wdGlvbmFsPnRydWU8L29wdGlvbmFsPgorICAgIDwvZGVwZW5kZW5jeT4KKyAgICA8ZGVwZW5kZW5jeT4KKyAgICAgIDxncm91cElkPm9yZy5wb3dlcm1vY2s8L2dyb3VwSWQ+CisgICAgICA8YXJ0aWZhY3RJZD5wb3dlcm1vY2stbW9kdWxlLWp1bml0NDwvYXJ0aWZhY3RJZD4KKyAgICAgIDx2ZXJzaW9uPiR7cG93ZXJtb2NrLnZlcnNpb259PC92ZXJzaW9uPgorICAgICAgPHNjb3BlPnRlc3Q8L3Njb3BlPgorICAgIDwvZGVwZW5kZW5jeT4KKyAgICA8ZGVwZW5kZW5jeT4KKyAgICAgIDxncm91cElkPm9yZy5wb3dlcm1vY2s8L2dyb3VwSWQ+CisgICAgICA8YXJ0aWZhY3RJZD5wb3dlcm1vY2stYXBpLW1vY2tpdG88L2FydGlmYWN0SWQ+CisgICAgICA8dmVyc2lvbj4ke3Bvd2VybW9jay52ZXJzaW9ufTwvdmVyc2lvbj4KKyAgICAgIDxzY29wZT50ZXN0PC9zY29wZT4KKyAgICA8L2RlcGVuZGVuY3k+CisKKyAgICA8IS0tIGludGVncmF0aW9uIHRlc3QgdmVyaWZpeWluZyBPU0dpIGJ1bmRsZSB3b3JrcyAtLT4KKyAgICA8ZGVwZW5kZW5jeT4KKyAgICAgIDxncm91cElkPm9yZy5vcHM0ai5wYXguZXhhbTwvZ3JvdXBJZD4KKyAgICAgIDxhcnRpZmFjdElkPnBheC1leGFtLWNvbnRhaW5lci1uYXRpdmU8L2FydGlmYWN0SWQ+CisgICAgICA8dmVyc2lvbj4ke3BheC5leGFtLnZlcnNpb259PC92ZXJzaW9uPgorICAgICAgPHNjb3BlPnRlc3Q8L3Njb3BlPgorICAgIDwvZGVwZW5kZW5jeT4KKyAgICA8ZGVwZW5kZW5jeT4KKyAgICAgIDxncm91cElkPm9yZy5vcHM0ai5wYXguZXhhbTwvZ3JvdXBJZD4KKyAgICAgIDxhcnRpZmFjdElkPnBheC1leGFtLWp1bml0NDwvYXJ0aWZhY3RJZD4KKyAgICAgIDx2ZXJzaW9uPiR7cGF4LmV4YW0udmVyc2lvbn08L3ZlcnNpb24+CisgICAgICA8c2NvcGU+dGVzdDwvc2NvcGU+CisgICAgPC9kZXBlbmRlbmN5PgorICAgIDxkZXBlbmRlbmN5PgorICAgICAgPGdyb3VwSWQ+b3JnLm9wczRqLnBheC5leGFtPC9ncm91cElkPgorICAgICAgPGFydGlmYWN0SWQ+cGF4LWV4YW0tY208L2FydGlmYWN0SWQ+CisgICAgICA8dmVyc2lvbj4ke3BheC5leGFtLnZlcnNpb259PC92ZXJzaW9uPgorICAgICAgPHNjb3BlPnRlc3Q8L3Njb3BlPgorICAgIDwvZGVwZW5kZW5jeT4KKyAgICA8ZGVwZW5kZW5jeT4KKyAgICAgIDxncm91cElkPm9yZy5vcHM0ai5wYXguZXhhbTwvZ3JvdXBJZD4KKyAgICAgIDxhcnRpZmFjdElkPnBheC1leGFtLWxpbmstbXZuPC9hcnRpZmFjdElkPgorICAgICAgPHZlcnNpb24+JHtwYXguZXhhbS52ZXJzaW9ufTwvdmVyc2lvbj4KKyAgICAgIDxzY29wZT50ZXN0PC9zY29wZT4KKyAgICA8L2RlcGVuZGVuY3k+CisgICAgPGRlcGVuZGVuY3k+CisgICAgICA8Z3JvdXBJZD5vcmcuYXBhY2hlLmZlbGl4PC9ncm91cElkPgorICAgICAgPGFydGlmYWN0SWQ+b3JnLmFwYWNoZS5mZWxpeC5mcmFtZXdvcms8L2FydGlmYWN0SWQ+CisgICAgICA8dmVyc2lvbj41LjYuMTA8L3ZlcnNpb24+CisgICAgICA8c2NvcGU+dGVzdDwvc2NvcGU+CisgICAgPC9kZXBlbmRlbmN5PgorICAgIDxkZXBlbmRlbmN5PgorICAgICAgPGdyb3VwSWQ+amF2YXguaW5qZWN0PC9ncm91cElkPgorICAgICAgPGFydGlmYWN0SWQ+amF2YXguaW5qZWN0PC9hcnRpZmFjdElkPgorICAgICAgPHZlcnNpb24+MTwvdmVyc2lvbj4KKyAgICAgIDxzY29wZT50ZXN0PC9zY29wZT4KKyAgICA8L2RlcGVuZGVuY3k+CisgICAgPGRlcGVuZGVuY3k+CisgICAgICA8Z3JvdXBJZD5vcmcuc2xmNGo8L2dyb3VwSWQ+CisgICAgICA8YXJ0aWZhY3RJZD5zbGY0ai1hcGk8L2FydGlmYWN0SWQ+CisgICAgICA8dmVyc2lvbj4ke3NsZjRqLnZlcnNpb259PC92ZXJzaW9uPgorICAgICAgPHNjb3BlPnRlc3Q8L3Njb3BlPgorICAgIDwvZGVwZW5kZW5jeT4gICAgCisKKyAgICA8ZGVwZW5kZW5jeT4KKyAgICAgIDxncm91cElkPm9yZy5vc2dpPC9ncm91cElkPgorICAgICAgPGFydGlmYWN0SWQ+b3JnLm9zZ2kuY29yZTwvYXJ0aWZhY3RJZD4KKyAgICAgIDx2ZXJzaW9uPjYuMC4wPC92ZXJzaW9uPgorICAgICAgPHNjb3BlPnByb3ZpZGVkPC9zY29wZT4KKyAgICA8L2RlcGVuZGVuY3k+CisgIDwvZGVwZW5kZW5jaWVzPgorCisgIDxkZXZlbG9wZXJzPgorICAgIDxkZXZlbG9wZXI+CisgICAgICA8bmFtZT5Ub3JzdGVuIEN1cmR0PC9uYW1lPgorICAgICAgPGlkPnRjdXJkdDwvaWQ+CisgICAgICA8ZW1haWw+dGN1cmR0IGF0IGFwYWNoZS5vcmc8L2VtYWlsPgorICAgIDwvZGV2ZWxvcGVyPgorICAgIDxkZXZlbG9wZXI+CisgICAgICA8bmFtZT5TdGVmYW4gQm9kZXdpZzwvbmFtZT4KKyAgICAgIDxpZD5ib2Rld2lnPC9pZD4KKyAgICAgIDxlbWFpbD5ib2Rld2lnIGF0IGFwYWNoZS5vcmc8L2VtYWlsPgorICAgIDwvZGV2ZWxvcGVyPgorICAgIDxkZXZlbG9wZXI+CisgICAgICA8bmFtZT5TZWJhc3RpYW4gQmF6bGV5PC9uYW1lPgorICAgICAgPGlkPnNlYmI8L2lkPgorICAgICAgPGVtYWlsPnNlYmIgYXQgYXBhY2hlLm9yZzwvZW1haWw+CisgICAgPC9kZXZlbG9wZXI+CisgICAgPGRldmVsb3Blcj4KKyAgICAgIDxuYW1lPkNocmlzdGlhbiBHcm9ibWVpZXI8L25hbWU+CisgICAgICA8aWQ+Z3JvYm1laWVyPC9pZD4KKyAgICAgIDxlbWFpbD5ncm9ibWVpZXIgYXQgYXBhY2hlLm9yZzwvZW1haWw+CisgICAgPC9kZXZlbG9wZXI+CisgICAgPGRldmVsb3Blcj4KKyAgICAgIDxuYW1lPkp1bGl1cyBEYXZpZXM8L25hbWU+CisgICAgICA8aWQ+anVsaXVzPC9pZD4KKyAgICAgIDxlbWFpbD5qdWxpdXMgYXQgYXBhY2hlLm9yZzwvZW1haWw+CisgICAgPC9kZXZlbG9wZXI+CisgICAgPGRldmVsb3Blcj4KKyAgICAgIDxuYW1lPkRhbWphbiBKb3Zhbm92aWM8L25hbWU+CisgICAgICA8aWQ+ZGFtamFuPC9pZD4KKyAgICAgIDxlbWFpbD5kYW1qYW4gYXQgYXBhY2hlLm9yZzwvZW1haWw+CisgICAgPC9kZXZlbG9wZXI+CisgICAgPGRldmVsb3Blcj4KKyAgICAgIDxuYW1lPkVtbWFudWVsIEJvdXJnPC9uYW1lPgorICAgICAgPGlkPmVib3VyZzwvaWQ+CisgICAgICA8ZW1haWw+ZWJvdXJnIGF0IGFwYWNoZS5vcmc8L2VtYWlsPgorICAgIDwvZGV2ZWxvcGVyPgorICAgIDxkZXZlbG9wZXI+CisgICAgICA8bmFtZT5HYXJ5IEdyZWdvcnk8L25hbWU+CisgICAgICA8aWQ+Z2dyZWdvcnk8L2lkPgorICAgICAgPGVtYWlsPmdncmVnb3J5IGF0IGFwYWNoZS5vcmc8L2VtYWlsPgorICAgIDwvZGV2ZWxvcGVyPgorICAgIDxkZXZlbG9wZXI+CisgICAgICA8bmFtZT5Sb2IgVG9tcGtpbnM8L25hbWU+CisgICAgICA8aWQ+Y2h0b21wa2k8L2lkPgorICAgICAgPGVtYWlsPmNodG9tcGtpIGF0IGFwYWNoZS5vcmc8L2VtYWlsPgorICAgIDwvZGV2ZWxvcGVyPgorICA8L2RldmVsb3BlcnM+CisKKyAgPGNvbnRyaWJ1dG9ycz4KKyAgICA8Y29udHJpYnV0b3I+CisgICAgICA8bmFtZT5Xb2xmZ2FuZyBHbGFzPC9uYW1lPgorICAgICAgPGVtYWlsPndvbGZnYW5nLmdsYXMgYXQgZXYtaS5hdDwvZW1haWw+CisgICAgPC9jb250cmlidXRvcj4KKyAgICA8Y29udHJpYnV0b3I+CisgICAgICA8bmFtZT5DaHJpc3RpYW4gS29obHNjaMO8dHRlPC9uYW1lPgorICAgICAgPGVtYWlsPmNrQG5ld3NjbHViLmRlPC9lbWFpbD4KKyAgICA8L2NvbnRyaWJ1dG9yPgorICAgIDxjb250cmlidXRvcj4KKyAgICAgIDxuYW1lPkJlYXIgR2lsZXM8L25hbWU+CisgICAgICA8ZW1haWw+YmdpbGVzQGNveW90ZXNvbmcuY29tPC9lbWFpbD4KKyAgICA8L2NvbnRyaWJ1dG9yPgorICAgIDxjb250cmlidXRvcj4KKyAgICAgIDxuYW1lPk1pY2hhZWwgS3VzczwvbmFtZT4KKyAgICAgIDxlbWFpbD5tYWlsIGF0IG1pY2hhZWwgbWludXMga3Vzcy5kZTwvZW1haWw+CisgICAgPC9jb250cmlidXRvcj4KKyAgICA8Y29udHJpYnV0b3I+CisgICAgICA8bmFtZT5MYXNzZSBDb2xsaW48L25hbWU+CisgICAgICA8ZW1haWw+bGFzc2UuY29sbGluQHR1a2Fhbmkub3JnPC9lbWFpbD4KKyAgICA8L2NvbnRyaWJ1dG9yPgorICAgIDxjb250cmlidXRvcj4KKyAgICAgIDxuYW1lPkpvaG4gS29kaXM8L25hbWU+CisgICAgPC9jb250cmlidXRvcj4KKyAgICA8Y29udHJpYnV0b3I+CisgICAgICA8bmFtZT5CRUxVR0EgQkVIUjwvbmFtZT4KKyAgICA8L2NvbnRyaWJ1dG9yPgorICAgIDxjb250cmlidXRvcj4KKwk8bmFtZT5TaW1vbiBTcGVybzwvbmFtZT4KKwk8ZW1haWw+c2VzdW5jZWR1QGdtYWlsLmNvbTwvZW1haWw+CisgICAgPC9jb250cmlidXRvcj4KKyAgICA8Y29udHJpYnV0b3I+CisgICAgICA8bmFtZT5NaWNoYWVsIEhhdXNlZ2dlcjwvbmFtZT4KKyAgICAgIDxlbWFpbD5oYXVzZWdnZXIubWljaGFlbEBnb29nbGVtYWlsLmNvbTwvZW1haWw+CisgICAgPC9jb250cmlidXRvcj4KKyAgPC9jb250cmlidXRvcnM+CisKKyAgPHNjbT4KKyAgICA8Y29ubmVjdGlvbj5zY206Z2l0Omh0dHBzOi8vZ2l0LXdpcC11cy5hcGFjaGUub3JnL3JlcG9zL2FzZi9jb21tb25zLWNvbXByZXNzLmdpdDwvY29ubmVjdGlvbj4KKyAgICA8ZGV2ZWxvcGVyQ29ubmVjdGlvbj5zY206Z2l0Omh0dHBzOi8vZ2l0LXdpcC11cy5hcGFjaGUub3JnL3JlcG9zL2FzZi9jb21tb25zLWNvbXByZXNzLmdpdDwvZGV2ZWxvcGVyQ29ubmVjdGlvbj4KKyAgICA8dXJsPmh0dHBzOi8vZ2l0LXdpcC11cy5hcGFjaGUub3JnL3JlcG9zL2FzZj9wPWNvbW1vbnMtY29tcHJlc3MuZ2l0PC91cmw+CisgIDwvc2NtPgorCisgIDxidWlsZD4KKyAgICA8cGx1Z2luTWFuYWdlbWVudD4KKyAgICAgIDxwbHVnaW5zPgorICAgICAgICA8IS0tIE92ZXJyaWRlIEphdmFkb2MgY29uZmlnIGluIHBhcmVudCBwb20gdG8gYWRkIEpDSVAgdGFncyAtLT4KKyAgICAgICAgPHBsdWdpbj4KKyAgICAgICAgICA8Z3JvdXBJZD5vcmcuYXBhY2hlLm1hdmVuLnBsdWdpbnM8L2dyb3VwSWQ+CisgICAgICAgICAgPGFydGlmYWN0SWQ+bWF2ZW4tamF2YWRvYy1wbHVnaW48L2FydGlmYWN0SWQ+CisgICAgICAgICAgPHZlcnNpb24+JHtjb21tb25zLmphdmFkb2MudmVyc2lvbn08L3ZlcnNpb24+CisgICAgICAgICAgPGNvbmZpZ3VyYXRpb24+IAorICAgICAgICAgICAgPHF1aWV0PnRydWU8L3F1aWV0PgorICAgICAgICAgICAgPHNvdXJjZT4ke21hdmVuLmNvbXBpbGVyLnNvdXJjZX08L3NvdXJjZT4KKyAgICAgICAgICAgIDxlbmNvZGluZz4ke2NvbW1vbnMuZW5jb2Rpbmd9PC9lbmNvZGluZz4KKyAgICAgICAgICAgIDxkb2NlbmNvZGluZz4ke2NvbW1vbnMuZG9jRW5jb2Rpbmd9PC9kb2NlbmNvZGluZz4KKyAgICAgICAgICAgIDxsaW5rc291cmNlPnRydWU8L2xpbmtzb3VyY2U+CisgICAgICAgICAgICA8bGlua3M+CisgICAgICAgICAgICAgIDxsaW5rPiR7Y29tbW9ucy5qYXZhZG9jLmphdmEubGlua308L2xpbms+CisgICAgICAgICAgICAgIDxsaW5rPiR7Y29tbW9ucy5qYXZhZG9jLmphdmFlZS5saW5rfTwvbGluaz4KKyAgICAgICAgICAgIDwvbGlua3M+CisgICAgICAgICAgICA8dGFncz4KKyAgICAgICAgICAgICAgPHRhZz4KKyAgICAgICAgICAgICAgICA8bmFtZT5JbW11dGFibGU8L25hbWU+CisgICAgICAgICAgICAgICAgPHBsYWNlbWVudD5hPC9wbGFjZW1lbnQ+CisgICAgICAgICAgICAgICAgPGhlYWQ+VGhpcyBjbGFzcyBpcyBpbW11dGFibGU8L2hlYWQ+CisgICAgICAgICAgICAgIDwvdGFnPgorICAgICAgICAgICAgICA8dGFnPgorICAgICAgICAgICAgICAgIDxuYW1lPk5vdFRocmVhZFNhZmU8L25hbWU+CisgICAgICAgICAgICAgICAgPHBsYWNlbWVudD5hPC9wbGFjZW1lbnQ+CisgICAgICAgICAgICAgICAgPGhlYWQ+VGhpcyBjbGFzcyBpcyBub3QgdGhyZWFkLXNhZmU8L2hlYWQ+CisgICAgICAgICAgICAgIDwvdGFnPgorICAgICAgICAgICAgICA8dGFnPgorICAgICAgICAgICAgICAgIDxuYW1lPlRocmVhZFNhZmU8L25hbWU+CisgICAgICAgICAgICAgICAgPHBsYWNlbWVudD5hPC9wbGFjZW1lbnQ+CisgICAgICAgICAgICAgICAgPGhlYWQ+VGhpcyBjbGFzcyBpcyB0aHJlYWQtc2FmZTwvaGVhZD4KKyAgICAgICAgICAgICAgPC90YWc+CisgICAgICAgICAgICA8L3RhZ3M+CisgICAgICAgICAgPC9jb25maWd1cmF0aW9uPiAKKyAgICAgICAgPC9wbHVnaW4+CisgICAgICAgIDxwbHVnaW4+CisgICAgICAgICAgPGdyb3VwSWQ+b3JnLmFwYWNoZS5yYXQ8L2dyb3VwSWQ+CisgICAgICAgICAgPGFydGlmYWN0SWQ+YXBhY2hlLXJhdC1wbHVnaW48L2FydGlmYWN0SWQ+CisgICAgICAgICAgPHZlcnNpb24+JHtjb21tb25zLnJhdC52ZXJzaW9ufTwvdmVyc2lvbj4KKyAgICAgICAgICA8Y29uZmlndXJhdGlvbj4KKyAgICAgICAgICAgIDxleGNsdWRlcz4KKyAgICAgICAgICAgICAgPCEtLSBmaWxlcyB1c2VkIGR1cmluZyB0ZXN0cyAtLT4KKyAgICAgICAgICAgICAgPGV4Y2x1ZGU+c3JjL3Rlc3QvcmVzb3VyY2VzLyoqPC9leGNsdWRlPgorICAgICAgICAgICAgICA8ZXhjbHVkZT4ucG1kPC9leGNsdWRlPgorICAgICAgICAgICAgICA8ZXhjbHVkZT4ucHJvamVjdGlsZTwvZXhjbHVkZT4KKyAgICAgICAgICAgICAgPGV4Y2x1ZGU+Lm12bi8qKjwvZXhjbHVkZT4KKyAgICAgICAgICAgIDwvZXhjbHVkZXM+CisgICAgICAgICAgPC9jb25maWd1cmF0aW9uPgorICAgICAgICA8L3BsdWdpbj4KKyAgICAgICAgPHBsdWdpbj4KKyAgICAgICAgICA8Z3JvdXBJZD5vcmcuZWx1ZGVyLmNvdmVyYWxsczwvZ3JvdXBJZD4KKyAgICAgICAgICA8YXJ0aWZhY3RJZD5jb3ZlcmFsbHMtbWF2ZW4tcGx1Z2luPC9hcnRpZmFjdElkPgorICAgICAgICAgIDxjb25maWd1cmF0aW9uPgorICAgICAgICAgICAgPGZhaWxPblNlcnZpY2VFcnJvcj5mYWxzZTwvZmFpbE9uU2VydmljZUVycm9yPgorICAgICAgICAgIDwvY29uZmlndXJhdGlvbj4KKyAgICAgICAgPC9wbHVnaW4+CisgICAgICAgIDxwbHVnaW4+CisgICAgICAgICAgPGdyb3VwSWQ+b3JnLmFwYWNoZS5mZWxpeDwvZ3JvdXBJZD4KKyAgICAgICAgICA8YXJ0aWZhY3RJZD5tYXZlbi1idW5kbGUtcGx1Z2luPC9hcnRpZmFjdElkPgorICAgICAgICAgIDx2ZXJzaW9uPiR7Y29tbW9ucy5mZWxpeC52ZXJzaW9ufTwvdmVyc2lvbj4KKyAgICAgICAgPC9wbHVnaW4+CisgICAgICAgIDwhLS0gb3ZlcnJpZGUgc2tpcCBwcm9wZXJ0eSBvZiBwYXJlbnQgcG9tLCBjYW4gYmUgcmVtb3ZlZCBvbmNlCisgICAgICAgICAgICAgd2UgYWRvcHQgcGFyZW50IDQ4KyAtLT4KKyAgICAgICAgPHBsdWdpbj4KKyAgICAgICAgICA8Z3JvdXBJZD5jb20uZ2l0aHViLnNpb203OS5qYXBpY21wPC9ncm91cElkPgorICAgICAgICAgIDxhcnRpZmFjdElkPmphcGljbXAtbWF2ZW4tcGx1Z2luPC9hcnRpZmFjdElkPgorICAgICAgICAgIDxjb25maWd1cmF0aW9uPgorICAgICAgICAgICAgPHNraXA+ZmFsc2U8L3NraXA+CisgICAgICAgICAgPC9jb25maWd1cmF0aW9uPgorICAgICAgICA8L3BsdWdpbj4KKyAgICAgIDwvcGx1Z2lucz4KKyAgICA8L3BsdWdpbk1hbmFnZW1lbnQ+CisgICAgPHBsdWdpbnM+CisgICAgICA8cGx1Z2luPgorICAgICAgICA8IS0tIGNyZWF0ZSB0aGUgc291cmNlIGFuZCBiaW5hcnkgYXNzZW1ibGllcyAtLT4KKyAgICAgICAgPGFydGlmYWN0SWQ+bWF2ZW4tYXNzZW1ibHktcGx1Z2luPC9hcnRpZmFjdElkPgorICAgICAgICA8Y29uZmlndXJhdGlvbj4KKyAgICAgICAgICA8ZGVzY3JpcHRvcnM+CisgICAgICAgICAgICA8ZGVzY3JpcHRvcj5zcmMvYXNzZW1ibHkvYmluLnhtbDwvZGVzY3JpcHRvcj4KKyAgICAgICAgICAgIDxkZXNjcmlwdG9yPnNyYy9hc3NlbWJseS9zcmMueG1sPC9kZXNjcmlwdG9yPgorICAgICAgICAgIDwvZGVzY3JpcHRvcnM+CisgICAgICAgICAgPHRhckxvbmdGaWxlTW9kZT5nbnU8L3RhckxvbmdGaWxlTW9kZT4KKyAgICAgICAgPC9jb25maWd1cmF0aW9uPgorICAgICAgPC9wbHVnaW4+CisgICAgICA8cGx1Z2luPgorICAgICAgICA8YXJ0aWZhY3RJZD5tYXZlbi1qYXItcGx1Z2luPC9hcnRpZmFjdElkPgorICAgICAgICA8Y29uZmlndXJhdGlvbj4KKyAgICAgICAgICA8YXJjaGl2ZT4KKyAgICAgICAgICAgIDxtYW5pZmVzdEVudHJpZXM+CisgICAgICAgICAgICAgIDxNYWluLUNsYXNzPm9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuTGlzdGVyPC9NYWluLUNsYXNzPgorICAgICAgICAgICAgICA8RXh0ZW5zaW9uLU5hbWU+b3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzPC9FeHRlbnNpb24tTmFtZT4KKyAgICAgICAgICAgICAgPEF1dG9tYXRpYy1Nb2R1bGUtTmFtZT4ke2NvbW1vbnMubW9kdWxlLm5hbWV9PC9BdXRvbWF0aWMtTW9kdWxlLU5hbWU+CisgICAgICAgICAgICA8L21hbmlmZXN0RW50cmllcz4KKyAgICAgICAgICA8L2FyY2hpdmU+CisgICAgICAgIDwvY29uZmlndXJhdGlvbj4KKyAgICAgIDwvcGx1Z2luPgorICAgICAgPHBsdWdpbj4KKyAgICAgICAgPGdyb3VwSWQ+b3JnLmFwYWNoZS5mZWxpeDwvZ3JvdXBJZD4KKyAgICAgICAgPGFydGlmYWN0SWQ+bWF2ZW4tYnVuZGxlLXBsdWdpbjwvYXJ0aWZhY3RJZD4KKyAgICAgICAgPGNvbmZpZ3VyYXRpb24+CisgICAgICAgICAgPG1hbmlmZXN0TG9jYXRpb24+JHtjb21tb25zLm1hbmlmZXN0bG9jYXRpb259PC9tYW5pZmVzdExvY2F0aW9uPgorICAgICAgICA8L2NvbmZpZ3VyYXRpb24+CisgICAgICA8L3BsdWdpbj4KKyAgICAgIDxwbHVnaW4+CisgICAgICAgIDxncm91cElkPm9yZy5hcGFjaGUubWF2ZW4ucGx1Z2luczwvZ3JvdXBJZD4KKyAgICAgICAgPGFydGlmYWN0SWQ+bWF2ZW4tc2NtLXB1Ymxpc2gtcGx1Z2luPC9hcnRpZmFjdElkPgorICAgICAgICA8Y29uZmlndXJhdGlvbj4KKyAgICAgICAgICA8aWdub3JlUGF0aHNUb0RlbGV0ZT4KKyAgICAgICAgICAgIDxpZ25vcmVQYXRoVG9EZWxldGU+amF2YWRvY3M8L2lnbm9yZVBhdGhUb0RlbGV0ZT4KKyAgICAgICAgICA8L2lnbm9yZVBhdGhzVG9EZWxldGU+CisgICAgICAgIDwvY29uZmlndXJhdGlvbj4KKyAgICAgIDwvcGx1Z2luPgorICAgICAgPHBsdWdpbj4KKyAgICAgICAgPGdyb3VwSWQ+b3JnLmFwYWNoZS5tYXZlbi5wbHVnaW5zPC9ncm91cElkPgorICAgICAgICA8YXJ0aWZhY3RJZD5tYXZlbi1wbWQtcGx1Z2luPC9hcnRpZmFjdElkPgorICAgICAgICA8dmVyc2lvbj4ke2NvbW1vbnMucG1kLXBsdWdpbi52ZXJzaW9ufTwvdmVyc2lvbj4KKyAgICAgIDwvcGx1Z2luPgorICAgICAgPHBsdWdpbj4KKyAgICAgICAgPGdyb3VwSWQ+b3JnLmFwYWNoZS5tYXZlbi5wbHVnaW5zPC9ncm91cElkPgorICAgICAgICA8YXJ0aWZhY3RJZD5tYXZlbi1hbnRydW4tcGx1Z2luPC9hcnRpZmFjdElkPgorICAgICAgICA8ZXhlY3V0aW9ucz4KKyAgICAgICAgICA8ZXhlY3V0aW9uPgorICAgICAgICAgICAgPHBoYXNlPnByb2Nlc3MtdGVzdC1yZXNvdXJjZXM8L3BoYXNlPgorICAgICAgICAgICAgPGNvbmZpZ3VyYXRpb24+CisgICAgICAgICAgICAgIDx0YXJnZXQ+CisgICAgICAgICAgICAgICAgPHVudGFyIHNyYz0iJHtiYXNlZGlyfS9zcmMvdGVzdC9yZXNvdXJjZXMvenN0ZC10ZXN0cy50YXIiCisgICAgICAgICAgICAgICAgICAgICAgIGRlc3Q9IiR7cHJvamVjdC5idWlsZC50ZXN0T3V0cHV0RGlyZWN0b3J5fSIKKyAgICAgICAgICAgICAgICAgICAgICAgLz4KKyAgICAgICAgICAgICAgPC90YXJnZXQ+CisgICAgICAgICAgICA8L2NvbmZpZ3VyYXRpb24+CisgICAgICAgICAgICA8Z29hbHM+CisgICAgICAgICAgICAgIDxnb2FsPnJ1bjwvZ29hbD4KKyAgICAgICAgICAgIDwvZ29hbHM+CisgICAgICAgICAgPC9leGVjdXRpb24+CisgICAgICAgIDwvZXhlY3V0aW9ucz4KKyAgICAgIDwvcGx1Z2luPgorICAgICAgPHBsdWdpbj4KKyAgICAgICAgPGFydGlmYWN0SWQ+bWF2ZW4tc3VyZWZpcmUtcGx1Z2luPC9hcnRpZmFjdElkPgorICAgICAgICA8Y29uZmlndXJhdGlvbj4KKyAgICAgICAgICA8c3lzdGVtUHJvcGVydHlWYXJpYWJsZXM+CisgICAgICAgICAgICA8cGF4LmV4YW0ua2FyYWYudmVyc2lvbj4ke2thcmFmLnZlcnNpb259PC9wYXguZXhhbS5rYXJhZi52ZXJzaW9uPgorICAgICAgICAgICAgPGNvbW1vbnMtY29tcHJlc3MudmVyc2lvbj4ke3Byb2plY3QudmVyc2lvbn08L2NvbW1vbnMtY29tcHJlc3MudmVyc2lvbj4KKyAgICAgICAgICA8L3N5c3RlbVByb3BlcnR5VmFyaWFibGVzPgorICAgICAgICA8L2NvbmZpZ3VyYXRpb24+CisgICAgICA8L3BsdWdpbj4KKyAgICA8L3BsdWdpbnM+CisgIDwvYnVpbGQ+CisKKyAgPHJlcG9ydGluZz4KKyAgICA8cGx1Z2lucz4KKyAgICAgIDxwbHVnaW4+CisgICAgICAgIDwhLS0gZ2VuZXJhdGUgdGhlIFBNRCByZXBvcnRzIC0tPgorICAgICAgICA8Z3JvdXBJZD5vcmcuYXBhY2hlLm1hdmVuLnBsdWdpbnM8L2dyb3VwSWQ+CisgICAgICAgIDxhcnRpZmFjdElkPm1hdmVuLXBtZC1wbHVnaW48L2FydGlmYWN0SWQ+CisgICAgICAgIDx2ZXJzaW9uPiR7Y29tbW9ucy5wbWQtcGx1Z2luLnZlcnNpb259PC92ZXJzaW9uPgorICAgICAgICA8Y29uZmlndXJhdGlvbj4KKyAgICAgICAgICA8bWluaW11bVRva2Vucz4yMDA8L21pbmltdW1Ub2tlbnM+CisgICAgICAgICAgPHRhcmdldEpkaz4ke21hdmVuLmNvbXBpbGVyLnNvdXJjZX08L3RhcmdldEpkaz4KKyAgICAgICAgICA8cnVsZXNldHM+CisgICAgICAgICAgICA8cnVsZXNldD4ke2Jhc2VkaXJ9L3BtZC1ydWxlc2V0LnhtbDwvcnVsZXNldD4KKyAgICAgICAgICA8L3J1bGVzZXRzPgorICAgICAgICA8L2NvbmZpZ3VyYXRpb24+CisgICAgICA8L3BsdWdpbj4KKyAgICAgIDwhLS0gT3ZlcnJpZGUgSmF2YWRvYyBjb25maWcgaW4gcGFyZW50IHBvbSB0byBhZGQgSkNJUCB0YWdzIC0tPgorICAgICAgPHBsdWdpbj4KKyAgICAgICAgPGdyb3VwSWQ+b3JnLmFwYWNoZS5tYXZlbi5wbHVnaW5zPC9ncm91cElkPgorICAgICAgICA8YXJ0aWZhY3RJZD5tYXZlbi1qYXZhZG9jLXBsdWdpbjwvYXJ0aWZhY3RJZD4KKyAgICAgICAgPGNvbmZpZ3VyYXRpb24+IAorICAgICAgICAgIDxxdWlldD50cnVlPC9xdWlldD4KKyAgICAgICAgICA8c291cmNlPiR7bWF2ZW4uY29tcGlsZXIuc291cmNlfTwvc291cmNlPgorICAgICAgICAgIDxlbmNvZGluZz4ke2NvbW1vbnMuZW5jb2Rpbmd9PC9lbmNvZGluZz4KKyAgICAgICAgICA8ZG9jZW5jb2Rpbmc+JHtjb21tb25zLmRvY0VuY29kaW5nfTwvZG9jZW5jb2Rpbmc+CisgICAgICAgICAgPGxpbmtzb3VyY2U+dHJ1ZTwvbGlua3NvdXJjZT4KKyAgICAgICAgICA8bGlua3M+CisgICAgICAgICAgICA8bGluaz4ke2NvbW1vbnMuamF2YWRvYy5qYXZhLmxpbmt9PC9saW5rPgorICAgICAgICAgICAgPGxpbms+JHtjb21tb25zLmphdmFkb2MuamF2YWVlLmxpbmt9PC9saW5rPgorICAgICAgICAgIDwvbGlua3M+CisgICAgICAgICAgPHRhZ3M+CisgICAgICAgICAgICA8dGFnPgorICAgICAgICAgICAgICA8bmFtZT5JbW11dGFibGU8L25hbWU+CisgICAgICAgICAgICAgIDxwbGFjZW1lbnQ+YTwvcGxhY2VtZW50PgorICAgICAgICAgICAgICA8aGVhZD5UaGlzIGNsYXNzIGlzIGltbXV0YWJsZTwvaGVhZD4KKyAgICAgICAgICAgIDwvdGFnPgorICAgICAgICAgICAgPHRhZz4KKyAgICAgICAgICAgICAgPG5hbWU+Tm90VGhyZWFkU2FmZTwvbmFtZT4KKyAgICAgICAgICAgICAgPHBsYWNlbWVudD5hPC9wbGFjZW1lbnQ+CisgICAgICAgICAgICAgIDxoZWFkPlRoaXMgY2xhc3MgaXMgbm90IHRocmVhZC1zYWZlPC9oZWFkPgorICAgICAgICAgICAgPC90YWc+CisgICAgICAgICAgICA8dGFnPgorICAgICAgICAgICAgICA8bmFtZT5UaHJlYWRTYWZlPC9uYW1lPgorICAgICAgICAgICAgICA8cGxhY2VtZW50PmE8L3BsYWNlbWVudD4KKyAgICAgICAgICAgICAgPGhlYWQ+VGhpcyBjbGFzcyBpcyB0aHJlYWQtc2FmZTwvaGVhZD4KKyAgICAgICAgICAgIDwvdGFnPgorICAgICAgICAgIDwvdGFncz4KKyAgICAgICAgPC9jb25maWd1cmF0aW9uPiAKKyAgICAgIDwvcGx1Z2luPgorICAgICAgPHBsdWdpbj4KKyAgICAgICAgPGdyb3VwSWQ+b3JnLmNvZGVoYXVzLm1vam88L2dyb3VwSWQ+CisgICAgICAgIDxhcnRpZmFjdElkPmZpbmRidWdzLW1hdmVuLXBsdWdpbjwvYXJ0aWZhY3RJZD4KKyAgICAgICAgPHZlcnNpb24+My4wLjU8L3ZlcnNpb24+CisgICAgICAgIDxjb25maWd1cmF0aW9uPgorICAgICAgICAgIDx0aHJlc2hvbGQ+Tm9ybWFsPC90aHJlc2hvbGQ+CisgICAgICAgICAgPGVmZm9ydD5EZWZhdWx0PC9lZmZvcnQ+CisgICAgICAgICAgPGV4Y2x1ZGVGaWx0ZXJGaWxlPiR7YmFzZWRpcn0vZmluZGJ1Z3MtZXhjbHVkZS1maWx0ZXIueG1sPC9leGNsdWRlRmlsdGVyRmlsZT4KKyAgICAgICA8L2NvbmZpZ3VyYXRpb24+CisgICAgICA8L3BsdWdpbj4KKyAgICA8L3BsdWdpbnM+CisgIDwvcmVwb3J0aW5nPgorCisgIDxwcm9maWxlcz4KKyAgICA8IS0tIEFkZCBsb25nIHJ1bm5pbmcgdGVzdHMgYXMgKiovKklULmphdmEgLS0+CisgICAgPHByb2ZpbGU+CisgICAgICA8aWQ+cnVuLXppcGl0PC9pZD4KKyAgICAgIDxidWlsZD4KKyAgICAgICAgPHBsdWdpbnM+CisgICAgICAgICAgPHBsdWdpbj4KKyAgICAgICAgICAgIDxncm91cElkPm9yZy5hcGFjaGUubWF2ZW4ucGx1Z2luczwvZ3JvdXBJZD4KKyAgICAgICAgICAgIDxhcnRpZmFjdElkPm1hdmVuLWFudHJ1bi1wbHVnaW48L2FydGlmYWN0SWQ+CisgICAgICAgICAgICA8ZXhlY3V0aW9ucz4KKyAgICAgICAgICAgICAgPGV4ZWN1dGlvbj4KKyAgICAgICAgICAgICAgICA8cGhhc2U+cHJvY2Vzcy10ZXN0LXJlc291cmNlczwvcGhhc2U+CisgICAgICAgICAgICAgICAgPGNvbmZpZ3VyYXRpb24+CisgICAgICAgICAgICAgICAgICA8dGFyZ2V0PgorICAgICAgICAgICAgICAgICAgICA8dW50YXIgc3JjPSIke2Jhc2VkaXJ9L3NyYy90ZXN0L3Jlc291cmNlcy96aXA2NHN1cHBvcnQudGFyLmJ6MiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc3Q9IiR7cHJvamVjdC5idWlsZC50ZXN0T3V0cHV0RGlyZWN0b3J5fSIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXByZXNzaW9uPSJiemlwMiIvPgorICAgICAgICAgICAgICAgICAgPC90YXJnZXQ+CisgICAgICAgICAgICAgICAgPC9jb25maWd1cmF0aW9uPgorICAgICAgICAgICAgICAgIDxnb2Fscz4KKyAgICAgICAgICAgICAgICAgIDxnb2FsPnJ1bjwvZ29hbD4KKyAgICAgICAgICAgICAgICA8L2dvYWxzPgorICAgICAgICAgICAgICA8L2V4ZWN1dGlvbj4KKyAgICAgICAgICAgIDwvZXhlY3V0aW9ucz4KKyAgICAgICAgICA8L3BsdWdpbj4KKyAgICAgICAgICA8cGx1Z2luPgorICAgICAgICAgICAgPGFydGlmYWN0SWQ+bWF2ZW4tc3VyZWZpcmUtcGx1Z2luPC9hcnRpZmFjdElkPgorICAgICAgICAgICAgPGNvbmZpZ3VyYXRpb24+CisgICAgICAgICAgICAgIDxpbmNsdWRlcz4KKyAgICAgICAgICAgICAgICA8aW5jbHVkZT4qKi96aXAvKklULmphdmE8L2luY2x1ZGU+CisgICAgICAgICAgICAgIDwvaW5jbHVkZXM+CisgICAgICAgICAgICA8L2NvbmZpZ3VyYXRpb24+CisgICAgICAgICAgPC9wbHVnaW4+CisgICAgICAgIDwvcGx1Z2lucz4KKyAgICAgIDwvYnVpbGQ+CisgICAgPC9wcm9maWxlPgorICAgIDxwcm9maWxlPgorICAgICAgPGlkPnJ1bi10YXJpdDwvaWQ+CisgICAgICA8YnVpbGQ+CisgICAgICAgIDxwbHVnaW5zPgorICAgICAgICAgIDxwbHVnaW4+CisgICAgICAgICAgICA8YXJ0aWZhY3RJZD5tYXZlbi1zdXJlZmlyZS1wbHVnaW48L2FydGlmYWN0SWQ+CisgICAgICAgICAgICA8Y29uZmlndXJhdGlvbj4KKyAgICAgICAgICAgICAgPGluY2x1ZGVzPgorICAgICAgICAgICAgICAgIDxpbmNsdWRlPioqL3Rhci8qSVQuamF2YTwvaW5jbHVkZT4KKyAgICAgICAgICAgICAgPC9pbmNsdWRlcz4KKyAgICAgICAgICAgIDwvY29uZmlndXJhdGlvbj4KKyAgICAgICAgICA8L3BsdWdpbj4KKyAgICAgICAgPC9wbHVnaW5zPgorICAgICAgPC9idWlsZD4KKyAgICA8L3Byb2ZpbGU+CisgICAgPHByb2ZpbGU+CisgICAgICA8aWQ+amF2YTkrPC9pZD4KKyAgICAgIDxhY3RpdmF0aW9uPgorICAgICAgICA8amRrPls5LCk8L2pkaz4KKyAgICAgIDwvYWN0aXZhdGlvbj4KKyAgICAgIDxwcm9wZXJ0aWVzPgorICAgICAgICA8bWF2ZW4uY29tcGlsZXIucmVsZWFzZT45PC9tYXZlbi5jb21waWxlci5yZWxlYXNlPgorICAgICAgICA8Y29tbW9ucy5qYWNvY28udmVyc2lvbj4wLjcuOTwvY29tbW9ucy5qYWNvY28udmVyc2lvbj4KKyAgICAgICAgPGFuaW1hbC5zbmlmZmVyLnNraXA+dHJ1ZTwvYW5pbWFsLnNuaWZmZXIuc2tpcD4KKyAgICAgICAgPCEtLSBjb3ZlcmFsbCB2ZXJzaW9uIDQuMy4wIGRvZXMgbm90IHdvcmsgd2l0aCBqYXZhIDksIHNlZSBodHRwczovL2dpdGh1Yi5jb20vdHJhdXRvbmVuL2NvdmVyYWxscy1tYXZlbi1wbHVnaW4vaXNzdWVzLzExMiAtLT4KKyAgICAgICAgPGNvdmVyYWxscy5za2lwPnRydWU8L2NvdmVyYWxscy5za2lwPgorICAgICAgPC9wcm9wZXJ0aWVzPgorICAgIDwvcHJvZmlsZT4KKworICA8L3Byb2ZpbGVzPgorCis8L3Byb2plY3Q+CmRpZmYgLS1naXQgYS9zcmMvYXNzZW1ibHkvYmluLnhtbCBiL3NyYy9hc3NlbWJseS9iaW4ueG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE1OGMyZTUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvYXNzZW1ibHkvYmluLnhtbApAQCAtMCwwICsxLDQ1IEBACis8IS0tCisgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorCisgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKworIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKy0tPgorPGFzc2VtYmx5PgorICAgIDxpZD5iaW48L2lkPgorICAgIDxmb3JtYXRzPgorICAgICAgICA8Zm9ybWF0PnRhci5nejwvZm9ybWF0PgorICAgICAgICA8Zm9ybWF0PnppcDwvZm9ybWF0PgorICAgIDwvZm9ybWF0cz4KKyAgICA8aW5jbHVkZVNpdGVEaXJlY3Rvcnk+ZmFsc2U8L2luY2x1ZGVTaXRlRGlyZWN0b3J5PgorICAgIDxmaWxlU2V0cz4KKyAgICAgICAgPGZpbGVTZXQ+CisgICAgICAgICAgICA8aW5jbHVkZXM+CisgICAgICAgICAgICAgICAgPGluY2x1ZGU+TElDRU5TRS50eHQ8L2luY2x1ZGU+CisgICAgICAgICAgICAgICAgPGluY2x1ZGU+Tk9USUNFLnR4dDwvaW5jbHVkZT4KKyAgICAgICAgICAgICAgICA8aW5jbHVkZT5SRUFETUUudHh0PC9pbmNsdWRlPgorICAgICAgICAgICAgICAgIDxpbmNsdWRlPlJFTEVBU0UtTk9URVMudHh0PC9pbmNsdWRlPgorICAgICAgICAgICAgPC9pbmNsdWRlcz4KKyAgICAgICAgPC9maWxlU2V0PgorICAgICAgICA8ZmlsZVNldD4KKyAgICAgICAgICAgIDxkaXJlY3Rvcnk+dGFyZ2V0PC9kaXJlY3Rvcnk+CisgICAgICAgICAgICA8b3V0cHV0RGlyZWN0b3J5Pjwvb3V0cHV0RGlyZWN0b3J5PgorICAgICAgICAgICAgPGluY2x1ZGVzPgorICAgICAgICAgICAgICAgIDxpbmNsdWRlPiouamFyPC9pbmNsdWRlPgorICAgICAgICAgICAgPC9pbmNsdWRlcz4KKyAgICAgICAgPC9maWxlU2V0PgorICAgICAgICA8ZmlsZVNldD4KKyAgICAgICAgICAgIDxkaXJlY3Rvcnk+dGFyZ2V0L3NpdGUvYXBpZG9jczwvZGlyZWN0b3J5PgorICAgICAgICAgICAgPG91dHB1dERpcmVjdG9yeT5hcGlkb2NzPC9vdXRwdXREaXJlY3Rvcnk+CisgICAgICAgIDwvZmlsZVNldD4KKyAgICA8L2ZpbGVTZXRzPgorPC9hc3NlbWJseT4KZGlmZiAtLWdpdCBhL3NyYy9hc3NlbWJseS9zcmMueG1sIGIvc3JjL2Fzc2VtYmx5L3NyYy54bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzBmZTE0YQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9hc3NlbWJseS9zcmMueG1sCkBAIC0wLDAgKzEsNDAgQEAKKzwhLS0KKyBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisKKyAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorCisgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorLS0+Cis8YXNzZW1ibHk+CisgICAgPGlkPnNyYzwvaWQ+CisgICAgPGZvcm1hdHM+CisgICAgICAgIDxmb3JtYXQ+dGFyLmd6PC9mb3JtYXQ+CisgICAgICAgIDxmb3JtYXQ+emlwPC9mb3JtYXQ+CisgICAgPC9mb3JtYXRzPgorICAgIDxiYXNlRGlyZWN0b3J5PiR7YXJ0aWZhY3RJZH0tJHtjb21tb25zLnJlbGVhc2UudmVyc2lvbn0tc3JjPC9iYXNlRGlyZWN0b3J5PgorICAgIDxmaWxlU2V0cz4KKyAgICAgICAgPGZpbGVTZXQ+CisgICAgICAgICAgICA8aW5jbHVkZXM+CisgICAgICAgICAgICAgICAgPGluY2x1ZGU+TElDRU5TRS50eHQ8L2luY2x1ZGU+CisgICAgICAgICAgICAgICAgPGluY2x1ZGU+Tk9USUNFLnR4dDwvaW5jbHVkZT4KKyAgICAgICAgICAgICAgICA8aW5jbHVkZT5SRUFETUUudHh0PC9pbmNsdWRlPgorICAgICAgICAgICAgICAgIDxpbmNsdWRlPlJFTEVBU0UtTk9URVMudHh0PC9pbmNsdWRlPgorICAgICAgICAgICAgICAgIDxpbmNsdWRlPnBvbS54bWw8L2luY2x1ZGU+CisgICAgICAgICAgICAgICAgPGluY2x1ZGU+ZmluZGJ1Z3MtZXhjbHVkZS1maWx0ZXIueG1sPC9pbmNsdWRlPgorICAgICAgICAgICAgICAgIDxpbmNsdWRlPnBtZC1ydWxlc2V0LnhtbDwvaW5jbHVkZT4KKyAgICAgICAgICAgIDwvaW5jbHVkZXM+CisgICAgICAgIDwvZmlsZVNldD4KKyAgICAgICAgPGZpbGVTZXQ+CisgICAgICAgICAgICA8ZGlyZWN0b3J5PnNyYzwvZGlyZWN0b3J5PgorICAgICAgICA8L2ZpbGVTZXQ+CisgICAgPC9maWxlU2V0cz4KKzwvYXNzZW1ibHk+CmRpZmYgLS1naXQgYS9zcmMvY2hhbmdlcy9jaGFuZ2VzLnhtbCBiL3NyYy9jaGFuZ2VzL2NoYW5nZXMueG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc3YmU1MGEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvY2hhbmdlcy9jaGFuZ2VzLnhtbApAQCAtMCwwICsxLDE0NjggQEAKKzw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04Ij8+Cis8IS0tCisgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorCisgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKworIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyB1bmRlciB0aGUgTGljZW5zZS4KKy0tPgorCis8IS0tCitUaGlzIGZpbGUgaXMgYWxzbyB1c2VkIGJ5IHRoZSBtYXZlbi1jaGFuZ2VzLXBsdWdpbiB0byBnZW5lcmF0ZSB0aGUgcmVsZWFzZSBub3Rlcy4KK1VzZWZ1bCB3YXlzIG9mIGZpbmRpbmcgaXRlbXMgdG8gYWRkIHRvIHRoaXMgZmlsZSBhcmU6CisKKzEuICBBZGQgaXRlbXMgd2hlbiB5b3UgZml4IGEgYnVnIG9yIGFkZCBhIGZlYXR1cmUgKHRoaXMgbWFrZXMgdGhlCityZWxlYXNlIHByb2Nlc3MgZWFzeSA6LSkuCisKKzIuICBEbyBhIEpJUkEgc2VhcmNoIGZvciB0aWNrZXRzIGNsb3NlZCBzaW5jZSB0aGUgcHJldmlvdXMgcmVsZWFzZS4KKworMy4gIFVzZSB0aGUgcmVwb3J0IGdlbmVyYXRlZCBieSB0aGUgbWF2ZW4tY2hhbmdlbG9nLXBsdWdpbiB0byBzZWUgYWxsCitTVk4gY29tbWl0cy4gVEJBIGhvdyB0byB1c2UgdGhpcyB3aXRoIFNWTi4KKworVG8gZ2VuZXJhdGUgdGhlIHJlbGVhc2Ugbm90ZXMgZnJvbSB0aGlzIGZpbGU6CisKK212biBjaGFuZ2VzOmFubm91bmNlbWVudC1nZW5lcmF0ZSAtUHJlbGVhc2Utbm90ZXMgWy1EY2hhbmdlcy52ZXJzaW9uPW0ubl0KKworVGhlIDxhY3Rpb24+IHR5cGUgYXR0cmlidXRlIGNhbiBiZSBhZGQsdXBkYXRlLGZpeCxyZW1vdmUuCistLT4KKworPGRvY3VtZW50PgorICA8cHJvcGVydGllcz4KKyAgICA8dGl0bGU+Y29tbW9ucy1jb21wcmVzczwvdGl0bGU+CisgIDwvcHJvcGVydGllcz4KKyAgPGJvZHk+CisgICAgPHJlbGVhc2UgdmVyc2lvbj0iMS4xOSIgZGF0ZT0ibm90IHJlbGVhc2VkLCB5ZXQiCisgICAgICAgICAgICAgZGVzY3JpcHRpb249IlJlbGVhc2UgMS4xOSI+CisgICAgICA8YWN0aW9uIHR5cGU9ImZpeCIgZGF0ZT0iMjAxOC0wOS0wNyI+CisgICAgICAgIFppcEFyY2hpdmVJbnB1dFN0cmVhbSBjb3VsZCBmb3JnZXQgdGhlIGNvbXByZXNzaW9uIGxldmVsIGhhcworICAgICAgICBjaGFuZ2VkIHVuZGVyIGNlcnRhaW4gY2lyY3Vtc3RhbmNlcy4KKyAgICAgIDwvYWN0aW9uPgorICAgIDwvcmVsZWFzZT4KKyAgICA8cmVsZWFzZSB2ZXJzaW9uPSIxLjE4IiBkYXRlPSIyMDE4LTA4LTE2IgorICAgICAgICAgICAgIGRlc2NyaXB0aW9uPSJSZWxlYXNlIDEuMTgiPgorICAgICAgPGFjdGlvbiB0eXBlPSJmaXgiIGRhdGU9IjIwMTgtMDYtMTUiIGR1ZS10bz0iRGlkaWVyTG9pc2VhdSI+CisgICAgICAgIFRoZSBleGFtcGxlIEV4cGFuZGVyIGNsYXNzIGhhcyBiZWVuIHZ1bG5lcmFibGUgdG8gYSBwYXRoCisgICAgICAgIHRyYXZlcnNhbCBpbiB0aGUgZWRnZSBjYXNlIHRoYXQgaGFwcGVucyB3aGVuIHRoZSB0YXJnZXQKKyAgICAgICAgZGlyZWN0b3J5IGhhcyBhIHNpYmxpbmcgZGlyZWN0b3J5IGFuZCB0aGUgbmFtZSBvZiB0aGUgdGFyZ2V0CisgICAgICAgIGRpcmVjdG9yeSBpcyBhIHByZWZpeCBvZiB0aGUgc2libGluZyBkaXJlY3RvcnkncyBuYW1lLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy00NTYiIHR5cGU9ImZpeCIgZGF0ZT0iMjAxOC0wNi0xOSI+CisgICAgICAgIENoYW5nZWQgdGhlIE9TR2kgSW1wb3J0LVBhY2thZ2UgdG8gYWxzbyBvcHRpb25hbGx5IGltcG9ydAorICAgICAgICBqYXZheC5jcnlwdG8gc28gZW5jcnlwdGVkIGFyY2hpdmVzIGNhbiBiZSByZWFkLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy00NTciIHR5cGU9ImZpeCIgZGF0ZT0iMjAxOC0wNy0wMSI+CisgICAgICAgIENoYW5nZWQgdmFyaW91cyBpbXBsZW1lbnRhdGlvbnMgb2YgdGhlIGNsb3NlIG1ldGhvZCB0byBiZXR0ZXIKKyAgICAgICAgZW5zdXJlIGFsbCBoZWxkIHJlc291cmNlcyBnZXQgY2xvc2VkIGV2ZW4gaWYgZXhjZXB0aW9ucyBhcmUKKyAgICAgICAgdGhyb3duIGR1cmluZyB0aGUgY2xvc2luZyB0aGUgc3RyZWFtLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy00NTUiIHR5cGU9ImZpeCIgZGF0ZT0iMjAxOC0wNy0wMSI+CisgICAgICAgIFppcEFyY2hpdmVJbnB1dFN0cmVhbSBjYW4gbm93IGRldGVjdCB0aGUgQVBLIFNpZ25pbmcgQmxvY2sKKyAgICAgICAgdXNlZCBpbiBzaWduZWQgQW5kcm9pZCBBUEsgZmlsZXMgYW5kIHRyZWF0cyBpdCBhcyBhbiAiZW5kIG9mCisgICAgICAgIGFyY2hpdmUiIG1hcmtlci4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtNDU5IiB0eXBlPSJmaXgiIGRhdGU9IjIwMTgtMDctMTEiCisgICAgICAgICAgICAgIGR1ZS10bz0iSmVucyBSZWltYW5uIj4KKyAgICAgICAgVGhlIGNwaW8gc3RyZWFtcyBkaWRuJ3QgaGFuZGxlIGFyY2hpdmVzIHVzaW5nIGEgbXVsdGktYnl0ZQorICAgICAgICBlbmNvZGluZyBwcm9wZXJseS4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtNDYwIiB0eXBlPSJhZGQiIGRhdGU9IjIwMTgtMDctMjgiCisgICAgICAgICAgICAgIGR1ZS10bz0iQ2FybWkgR3J1c2hrbyI+CisgICAgICAgIEl0IGlzIG5vdyBwb3NzaWJsZSB0byBzcGVjaWZ5IHRoZSBhcmd1bWVudHMgb2YgenN0ZC1qbmkncworICAgICAgICBac3RkT3V0cHV0U3RyZWFtIGNvbnN0cnVjdG9ycyB2aWEgQ29tbW9ucyBDb21wcmVzcyBhcyB3ZWxsLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy00NjMiIHR5cGU9ImZpeCIgZGF0ZT0iMjAxOC0wOC0wOSI+CisgICAgICAgIFppcEFyY2hpdmVJbnB1dFN0cmVhbSNyZWFkIHdvdWxkIHNpbGVudGx5IHJldHVybiAtMSBvbiBhCisgICAgICAgIGNvcnJ1cHRlZCBzdG9yZWQgZW50cnkgYW5kIGV2ZW4gcmV0dXJuID4gMCBhZnRlciBoaXR0aW5nIHRoZQorICAgICAgICBlbmQgb2YgdGhlIGFyY2hpdmUuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTQ2MiIgdHlwZT0iZml4IiBkYXRlPSIyMDE4LTA4LTEwIj4KKyAgICAgICAgQXJBcmNoaXZlSW5wdXRTdHJlYW0jcmVhZCB3b3VsZCBhbGxvdyB0byByZWFkIGZyb20gdGhlIHN0cmVhbQorICAgICAgICB3aXRob3V0IG9wZW5pbmcgYW4gZW50cnkgYXQgYWxsLgorICAgICAgPC9hY3Rpb24+CisgICAgPC9yZWxlYXNlPgorICAgIDxyZWxlYXNlIHZlcnNpb249IjEuMTciIGRhdGU9IjIwMTgtMDYtMDMiCisgICAgICAgICAgICAgZGVzY3JpcHRpb249IlJlbGVhc2UgMS4xNyI+CisgICAgICA8YWN0aW9uIHR5cGU9ImZpeCIgZGF0ZT0iMjAxOC0wMi0wNiI+CisgICAgICAgIFJlbW92ZWQgdGhlIG9iamVuZXNpcyBkZXBlbmRlbmN5IGZyb20gdGhlIHBvbSBhcyBpdCBpcyBub3QKKyAgICAgICAgbmVlZGVkIGF0IGFsbC4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtNDQ2IiB0eXBlPSJmaXgiIGRhdGU9IjIwMTgtMDMtMjkiPgorICAgICAgICBGaXhlZCByZXNvdXJjZSBsZWFrIGluIFBhcmFsbGVsU2NhdHRlclppcENyZWF0b3Ijd3JpdGVUby4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiB0eXBlPSJ1cGRhdGUiIGRhdGU9IjIwMTgtMDQtMDEiIGR1ZS10bz0iTWFyY2hlbmtvIFNlcmdleSI+CisgICAgICAgIEZpeGVkIHNvbWUgY29kZSBleGFtcGxlcy4KKyAgICAgICAgR2l0aHViIFB1bGwgUmVxdWVzdCAjNjMuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTQ0NyIgdHlwZT0iZml4IiBkYXRlPSIyMDE4LTA0LTIyIj4KKyAgICAgICAgQ2VydGFpbiBlcnJvcnMgd2hlbiBwYXJzaW5nIFpJUCBleHRyYSBmaWVsZHMgaW4gY29ycnVwdAorICAgICAgICBhcmNoaXZlcyBhcmUgbm93IHR1cm5lZCBpbnRvIFppcEV4Y2VwdGlvbiwgdGhleSB1c2VkIHRvCisgICAgICAgIG1hbmlmZXN0IGFzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBiZWZvcmUuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTQ0NSIgdHlwZT0idXBkYXRlIiBkYXRlPSIyMDE4LTA0LTIyIgorICAgICAgICAgICAgICBkdWUtdG89IkFuZHJlYXMgQmVla2VyIj4KKyAgICAgICAgVGhlIHN0cmVhbXMgcmV0dXJuZWQgYnkgWmlwRmlsZSBhbmQgbW9zdCBvdGhlciBkZWNvbXByZXNzaW5nCisgICAgICAgIHN0cmVhbXMgbm93IHByb3ZpZGUgaW5mb3JtYXRpb24gYWJvdXQgdGhlIG51bWJlciBvZiBjb21wcmVzc2VkCisgICAgICAgIGFuZCB1bmNvbXByZXNzZWQgYnl0ZXMgcmVhZCBzbyBmYXIuIFRoaXMgbWF5IGJlIHVzZWQgdG8gZGV0ZWN0CisgICAgICAgIGEgWmlwQm9tYiBpZiB0aGUgY29tcHJlc3Npb24gcmF0aW8gZXhjZWVkcyBhIGNlcnRhaW4KKyAgICAgICAgdGhyZXNob2xkLCBmb3IgZXhhbXBsZS4KKyAgICAgICAgRm9yIFNldmVuWkZpbGUgYSBuZXcgbWV0aG9kIHJldHVybnMgdGhlIHN0YXRpc3RpY3MgZm9yIHRoZQorICAgICAgICBjdXJyZW50IGVudHJ5LgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy00NDMiIHR5cGU9ImFkZCIgZGF0ZT0iMjAxOC0wNC0yNSI+CisgICAgICAgIEFkZGVkIGEgdW5pdCB0ZXN0IHRoYXQgaXMgc3VwcG9zZWQgdG8gZmFpbCBpZiB3ZSBicmVhayB0aGUKKyAgICAgICAgT1NHaSBtYW5pZmVzdCBlbnRyaWVzIGFnYWluLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy00NDkiIHR5cGU9ImFkZCIgZGF0ZT0iMjAxOC0wNS0wMiI+CisgICAgICAgIEFkZCBhIG5ldyBTa2lwU2hpZWxkaW5nSW5wdXRTdHJlYW0gY2xhc3MgdGhhdCBjYW4gYmUgdXNlZCB3aXRoCisgICAgICAgIHN0cmVhbXMgdGhhdCB0aHJvdyBhbiBJT0V4Y2VwdGlvbiB3aGVuIHNraXAgaXMgaW52b2tlZC4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtNDUxIiB0eXBlPSJmaXgiIGRhdGU9IjIwMTgtMDUtMDQiPgorICAgICAgICBJT1V0aWxzLmNvcHkgbm93IHZlcmlmaWVzIHRoZSBidWZmZXIgc2l6ZSBpcyBiaWdnZXIgdGhhbiAwLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy00NTIiIHR5cGU9ImFkZCIgZGF0ZT0iMjAxOC0wNS0wOSI+CisgICAgICAgIE5ldyBjb25zdHJ1Y3RvcnMgaGF2ZSBiZWVuIGFkZGVkIHRvIFNldmVuWkZpbGUgdGhhdCBhY2NlcHQKKyAgICAgICAgY2hhcltdcyByYXRoZXIgdGhhbiBieXRlW11zIGluIG9yZGVyIHRvIGF2b2lkIGEgY29tbW9uIGVycm9yCisgICAgICAgIG9mIHVzaW5nIHRoZSB3cm9uZyBlbmNvZGluZyB3aGVuIGNyZWF0aW5nIHRoZSBieXRlW10uICBUaGlzCisgICAgICAgIGNoYW5nZSBtYXkgYnJlYWsgc291cmNlIGNvbXBhdGliaWxpdHkgZm9yIGNsaWVudCBjb2RlIHRoYXQKKyAgICAgICAgdXNlcyBvbmUgb2YgdGhlIGNvbnN0cnVjdG9ycyBleHBlY3RpbmcgYSBwYXNzd29yZCBhbmQgcGFzc2VzCisgICAgICAgIGluIG51bGwgYXMgcGFzc3dvcmQuIFdlIHJlY29tbWVuZCB0byBjaGFuZ2UgdGhlIGNvZGUgdG8gdXNlIGEKKyAgICAgICAgY29uc3RydWN0b3Igd2l0aG91dCBwYXNzd29yZCBhcmd1bWVudC4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtNDUzIiB0eXBlPSJ1cGRhdGUiIGRhdGU9IjIwMTgtMDUtMjQiPgorICAgICAgICBBZGRlZCBhIHdvcmthcm91bmQgZm9yIGEgYnVnIGluIEFkb3B0T3BlbkpESyBmb3IgUy8zOTAgdG8KKyAgICAgICAgQlppcDJDb21wcmVzc29ySW5wdXRTdHJlYW0uCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTQ1NCIgdHlwZT0iZml4IiBkYXRlPSIyMDE4LTA1LTMwIj4KKyAgICAgICAgWmlwQXJjaGl2ZUlucHV0U3RyZWFtIGZhaWxlZCB0byByZWFkIHNvbWUgZmlsZXMgd2l0aCBzdG9yZWQKKyAgICAgICAgZW50cmllcyB1c2luZyBhIGRhdGEgZGVzY3JpcHRvci4KKyAgICAgIDwvYWN0aW9uPgorICAgIDwvcmVsZWFzZT4KKyAgICA8cmVsZWFzZSB2ZXJzaW9uPSIxLjE2LjEiIGRhdGU9IjIwMTgtMDItMTAiCisgICAgICAgICAgICAgZGVzY3JpcHRpb249IlJlbGVhc2UgMS4xNi4xIj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTQ0MiIgdHlwZT0iZml4IiBkYXRlPSIyMDE4LTAyLTA2Ij4KKyAgICAgICAgRml4ZWQgdGhlIE9TR2kgbWFuaWZlc3QgZW50cnkgZm9yIGltcG9ydHMgdGhhdCBoYXMgYmVlbiBicm9rZW4KKyAgICAgICAgaW4gMS4xNi4KKyAgICAgIDwvYWN0aW9uPgorICAgIDwvcmVsZWFzZT4KKyAgICA8cmVsZWFzZSB2ZXJzaW9uPSIxLjE2IiBkYXRlPSIyMDE4LTAyLTA1IgorICAgICAgICAgICAgIGRlc2NyaXB0aW9uPSJSZWxlYXNlIDEuMTYiPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtNDIzIiB0eXBlPSJhZGQiIGRhdGU9IjIwMTctMTAtMTciCisgICAgICAgICAgICAgIGR1ZS10bz0iQW5kcmUgRiBkZSBNaXJhbmRhIj4KKyAgICAgICAgQWRkIHJlYWQtb25seSBzdXBwb3J0IGZvciBac3RhbmRhcmQgY29tcHJlc3Npb24gYmFzZWQgb24gdGhlCisgICAgICAgIFpzdGQtam5pIHByb2plY3QuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTQyNSIgdHlwZT0iYWRkIiBkYXRlPSIyMDE3LTEwLTIyIj4KKyAgICAgICAgQWRkZWQgYXV0by1kZXRlY3Rpb24gZm9yIFpzdGFuZGFyZCBjb21wcmVzc2VkIHN0cmVhbXMuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTQzMCIgdHlwZT0iZml4IiBkYXRlPSIyMDE3LTExLTI1IgorICAgICAgICAgICAgICBkdWUtdG89IkJydW5vIFAuIEtpbm9zaGl0YSI+CisgICAgICAgIFN5bmNocm9uaXplZCBpdGVyYXRpb24gb3ZlciBhIHN5bmNocm9uaXplZExpc3QgaW4gUGFyYWxsZWxTY2F0dGVyWmlwQ3JlYXRvci4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtNDMyIiB0eXBlPSJmaXgiIGRhdGU9IjIwMTctMTItMjIiPgorICAgICAgICBaaXBGaWxlIGNvdWxkIGdldCBzdHVjayBpbiBhbiBpbmZpbml0ZSBsb29wIHdoZW4gcGFyc2luZyBaSVAKKyAgICAgICAgYXJjaGl2ZXMgd2l0aCBjZXJ0YWluIHN0cm9uZyBlbmNyeXB0aW9uIGhlYWRlcnMuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTQzNSIgdHlwZT0idXBkYXRlIiBkYXRlPSIyMDE3LTEyLTI3IgorICAgICAgICAgICAgICBkdWUtdG89IkJFTFVHQSBCRUhSIj4KKyAgICAgICAgUmVwbGFjZXMgaW5zdGFuY2VvZiBjaGVja3Mgd2l0aCBhIHR5cGUgbWFya2VyIGluIExaNzcgc3VwcG9ydCBjb2RlLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy00MjYiIHR5cGU9ImFkZCIgZGF0ZT0iMjAxNy0xMi0yOCI+CisgICAgICAgIEFkZGVkIHdyaXRlLXN1cHBvcnQgZm9yIFpzdGFuZGFyZCBjb21wcmVzc2lvbi4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtNDI0IiB0eXBlPSJmaXgiIGRhdGU9IjIwMTctMTItMzAiPgorICAgICAgICBBZGRlZCBpbXByb3ZlZCBjaGVja3MgdG8gZGV0ZWN0IGNvcnJ1cHRlZCBiemlwMiBzdHJlYW1zIGFuZAorICAgICAgICB0aHJvdyB0aGUgZXhwZWN0ZWQgSU9FeGNlcHRpb24gcmF0aGVyIHRoYW4gb2JzY3VyZQorICAgICAgICBSdW50aW1lRXhjZXB0aW9ucy4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiB0eXBlPSJ1cGRhdGUiIGRhdGU9IjIwMTgtMDEtMDQiPgorICAgICAgICBVcGRhdGVkIFhaIGZvciBKYXZhIGRlcGVuZGVuY3kgdG8gMS44IGluIG9yZGVyIHRvIHBpY2sgdXAgYnVnCisgICAgICAgIGZpeCB0byBMWk1BMklucHV0U3RyZWFtJ3MgYXZhaWxhYmxlIG1ldGhvZC4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiB0eXBlPSJ1cGRhdGUiIGRhdGU9IjIwMTgtMDEtMDUiIGlzc3VlPSJDT01QUkVTUy00MjkiCisgICAgICAgICAgICAgIGR1ZS10bz0iRGFtaWFubyBBbGJhbmkiPgorICAgICAgICBaaXBBcmNoaXZlRW50cnkgbm93IGV4cG9zZXMgaG93IHRoZSBuYW1lIG9yIGNvbW1lbnQgaGF2ZSBiZWVuCisgICAgICAgIGRldGVybWluZWQgd2hlbiB0aGUgZW50cnkgd2FzIHJlYWQuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTM4MCIgdHlwZT0iYWRkIiBkYXRlPSIyMDE4LTAxLTA5IgorICAgICAgICAgICAgICBkdWUtdG89IkNocmlzdGlhbiBNYXJxdWV6IEdyYWJpYSI+CisgICAgICAgIEFkZGVkIHJlYWQtb25seSBERUZMQVRFNjQgc3VwcG9ydCB0byBaSVAgYXJjaGl2ZXMgYW5kIGFzCisgICAgICAgIHN0YW5kLWFsb25lIENvbXByZXNzb3JJbnB1dFN0cmVhbS4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtNDM4IiB0eXBlPSJ1cGRhdGUiIGRhdGU9IjIwMTgtMDEtMTAiPgorICAgICAgICBaaXBGaWxlLmdldElucHV0U3RyZWFtIHdpbGwgbm93IGFsd2F5cyBidWZmZXIgdGhlIHN0cmVhbQorICAgICAgICBpbnRlcm5hbGx5IGluIG9yZGVyIHRvIGltcHJvdmUgcmVhZCBwZXJmb3JtYW5jZS4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtNDQwIiB0eXBlPSJ1cGRhdGUiIGRhdGU9IjIwMTgtMDEtMTIiCisgICAgICAgICAgICAgIGR1ZS10bz0iRGF3aWQgV2Vpc3MiPgorICAgICAgICBTcGVlZCBpbXByb3ZlbWVudCBmb3IgREVGTEFURTY0IGRlY29tcHJlc3Npb24uCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTQzNyIgdHlwZT0iYWRkIiBkYXRlPSIyMDE4LTAxLTEzIj4KKyAgICAgICAgQWRkZWQgcmVhZC1vbmx5IERFRkxBVEU2NCBzdXBwb3J0IHRvIDd6IGFyY2hpdmVzLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy00MzYiIHR5cGU9InVwZGF0ZSIgZGF0ZT0iMjAxOC0wMS0xNCI+CisgICAgICAgIEFkZGVkIGEgZmV3IGV4dHJhIHNhbml0eSBjaGVja3MgZm9yIHRoZSByYXJlciBjb21wcmVzc2lvbgorICAgICAgICBtZXRob2RzIHVzZWQgaW4gWklQIGFyY2hpdmVzLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy00NDEiIHR5cGU9InVwZGF0ZSIgZGF0ZT0iMjAxOC0wMS0xNCI+CisgICAgICAgIFNpbXBsaWZpZWQgdGhlIHNwZWNpYWwgaGFuZGxpbmcgZm9yIHRoZSBkdW1teSBieXRlIHJlcXVpcmVkIGJ5CisgICAgICAgIHpsaWIgd2hlbiB1c2luZyBqYXZhLnV0aWwuemlwLkluZmxhdGVyLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIHR5cGU9InVwZGF0ZSIgZGF0ZT0iMjAxOC0wMS0xOCIgZHVlLXRvPSJTaGFoYWIgS29uZHJpIj4KKyAgICAgICAgVmFyaW91cyBjb2RlIGNsZWFudXBzLgorICAgICAgICBHaXRodWIgUHVsbCBSZXF1ZXN0ICM2MS4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiB0eXBlPSJ1cGRhdGUiIGRhdGU9IjIwMTgtMDEtMjkiPgorICAgICAgICBUYXJBcmNoaXZlRW50cnkncyBwcmVzZXJ2ZUxlYWRpbmdTbGFzaGVzIGNvbnN0cnVjdG9yIGFyZ3VtZW50CisgICAgICAgIGhhcyBiZWVuIHJlbmFtZWQgYW5kIGNhbiBub3cgYWxzbyBiZSB1c2VkIHRvIHByZXNlcnZlIHRoZQorICAgICAgICBkcml2ZSBsZXR0ZXIgb24gV2luZG93cy4KKyAgICAgIDwvYWN0aW9uPgorICAgIDwvcmVsZWFzZT4KKyAgICA8cmVsZWFzZSB2ZXJzaW9uPSIxLjE1IiBkYXRlPSIyMDE3LTEwLTE3IgorICAgICAgICAgICAgIGRlc2NyaXB0aW9uPSJSZWxlYXNlIDEuMTUKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworVGFyQXJjaGl2ZU91dHB1dFN0cmVhbSBub3cgZW5zdXJlcyByZWNvcmQgc2l6ZSBpcyA1MTIgYW5kIGJsb2NrIHNpemUgaXMKK2EgbXVsdGlwbGUgb2YgNTEyIGFzIGFueSBvdGhlciB2YWx1ZSB3b3VsZCBjcmVhdGUgaW52YWxpZCB0YXIKK2FyY2hpdmVzLiBUaGlzIG1heSBicmVhayBjb21wYXRpYmlsaXR5IGZvciBjb2RlIHRoYXQgZGVsaWJlcmF0ZWx5Cit3YW50ZWQgdG8gY3JlYXRlIHN1Y2ggZmlsZXMuIj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTM5NCIgdHlwZT0iZml4IiBkYXRlPSIyMDE3LTA1LTIyIj4KKyAgICAgICAgTWFrZSBzdXJlICJ2ZXJzaW9uIG5lZWRlZCB0byBleHRyYWN0IiBpbiBsb2NhbCBmaWxlIGhlYWRlciBhbmQKKyAgICAgICAgY2VudHJhbCBkaXJlY3Rvcnkgb2YgYSBaSVAgYXJjaGl2ZSBhZ3JlZSB3aXRoIGVhY2ggb3RoZXIuCisgICAgICAgIEFsc28gZW5zdXJlIHRoZSB2ZXJzaW9uIGlzIHNldCB0byAyLjAgaWYgREVGTEFURSBpcyB1c2VkLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0zOTUiIHR5cGU9ImZpeCIgZGF0ZT0iMjAxNy0wNS0yMiI+CisgICAgICAgIERvbid0IHVzZSBhIGRhdGEgZGVzY3JpcHRvciBpbiBaSVAgYXJjaGl2ZXMgd2hlbiBjb3B5aW5nIGEgcmF3CisgICAgICAgIGVudHJ5IHRoYXQgYWxyZWFkeSBrbm93cyBpdHMgc2l6ZSBhbmQgQ1JDIGluZm9ybWF0aW9uLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy00MTMiIHR5cGU9ImZpeCIgZGF0ZT0iMjAxNy0wNS0yMiIgZHVlLXRvPSJTaW1vbiBTcGVybyI+CisgICAgICAgIFRyYXZpcyBidWlsZCByZWR1bmRhbnRseSByZXBlYXRzIGNvbXBpbGF0aW9uIGFuZCB0ZXN0cyByZWR1bmRhbnRseSAjNDMuICAgICAgCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTM5NyIgdHlwZT0iYWRkIiBkYXRlPSIyMDE3LTA1LTIyIj4KKyAgICAgICAgQWRkZWQgbWFnaWMgTUFOSUZFU1QgZW50cnkgQXV0b21hdGljLU1vZHVsZS1OYW1lIHNvIHRoZSBtb2R1bGUKKyAgICAgICAgbmFtZSB3aWxsIGJlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcyB3aGVuIHRoZSBqYXIgaXMgdXNlZAorICAgICAgICBhcyBhbiBhdXRvbWF0aWMgbW9kdWxlIGluIEphdmE5LgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0zOTYiIHR5cGU9ImZpeCIgZGF0ZT0iMjAxNy0wNS0yMyI+CisgICAgICAgIFRoZSBNQU5JRkVTVCBvZiAxLjE0IGxhY2tzIGFuIE9TR2kgSW1wb3J0LVBhY2thZ2UgZm9yIFhaIGZvcgorICAgICAgICBKYXZhLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy00MDYiIHR5cGU9ImZpeCIgZGF0ZT0iMjAxNy0wNi0xMiIKKyAgICAgICAgICAgICAgZHVlLXRvPSJTaW1vbiBTcGVybyI+CisgICAgICAgIEJVSUxESU5HLm1kIG5vdyBwYXNzZXMgdGhlIFJBVCBjaGVjay4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtNDA1IiB0eXBlPSJhZGQiIGRhdGU9IjIwMTctMDYtMTUiCisgICAgICAgICAgICAgIGR1ZS10bz0iU2ltb24gU3Blcm8gIj4KKyAgICAgICAgQWRkZWQgYSBuZXcgdXRpbGl0eSBjbGFzcyBGaXhlZExlbmd0aEJsb2NrT3V0cHV0U3RyZWFtIHRoYXQKKyAgICAgICAgY2FuIGJlIHVzZWQgdG8gZW5zdXJlIHdyaXRpbmcgYWx3YXlzIGhhcHBlbnMgaW4gYmxvY2tzIG9mIGEKKyAgICAgICAgZ2l2ZW4gc2l6ZS4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtNDEyIiB0eXBlPSJmaXgiIGRhdGU9IjIwMTctMDYtMTciCisgICAgICAgICAgICAgIGR1ZS10bz0iTWljaGFlbCBIYXVzZWdnZXIiPgorICAgICAgICBNYWRlIHN1cmUgQ2hlY2tzdW1DYWxjdWxhdGluZ0lucHV0U3RyZWFtIHJlY2VpdmVzIHZhbGlkCisgICAgICAgIGNoZWNrc3VtIGFuZCBpbnB1dCBzdHJlYW0gaW5zdGFuY2VzIHZpYSB0aGUgY29uc3RydWN0b3IuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTQwNyIgdHlwZT0iZml4IiBkYXRlPSIyMDE3LTA2LTI0IgorICAgICAgICAgICAgICBkdWUtdG89IlNpbW9uIFNwZXJvICI+CisgICAgICAgIFRhckFyY2hpdmVPdXRwdXRTdHJlYW0gbm93IHZlcmlmaWVzIHRoZSBibG9jayBhbmQgcmVjb3JkIHNpemVzCisgICAgICAgIHNwZWNpZmllZCBhdCBjb25zdHJ1Y3Rpb24gdGltZSBhcmUgY29tcGF0aWJsZSB3aXRoIHRoZSB0YXIKKyAgICAgICAgc3BlY2lmaWNhdGlvbi4gSW4gcGFydGljdWxhciA1MTIgaXMgdGhlIG9ubHkgcmVjb3JkIHNpemUKKyAgICAgICAgYWNjZXB0ZWQgYW5kIHRoZSBibG9jayBzaXplIG11c3QgYmUgYSBtdWx0aXBsZSBvZiA1MTIuCisgICAgICAgIEF0IHRoZSBzYW1lIHRpbWUgdGhlIGRlZmF1bHQgYmxvY2sgc2l6ZSBpbgorICAgICAgICBUYXJBcmNoaXZlT3V0cHV0U3RyZWFtIGhhcyBiZWVuIGNoYW5nZWQgZnJvbSAxMDI0MCB0byA1MTIKKyAgICAgICAgYnl0ZXMuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTQwMCIgdHlwZT0iYWRkIiBkYXRlPSIyMDE3LTA2LTI2IgorICAgICAgICAgICAgICBkdWUtdG89IlNpbW9uIFNwZXJvICI+CisgICAgICAgIEl0IGlzIG5vdyBwb3NzaWJsZSB0byBzcGVjaWZ5L3JlYWQgY3VzdG9tIFBBWCBoZWFkZXJzIHdoZW4KKyAgICAgICAgd3JpdGluZy9yZWFkaW5nIHRhciBhcmNoaXZlcy4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtNDE1IiB0eXBlPSJmaXgiIGRhdGU9IjIwMTctMDYtMjciPgorICAgICAgICBGaXhlZCBjbGFzcyBuYW1lcyBvZiBDcGlvQXJjaGl2ZUVudHJ5IGFuZAorICAgICAgICBDcGlvQXJjaGl2ZUlucHV0U3RyZWFtIGluIHZhcmlvdXMgSmF2YWRvY3MuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTQxNiIgdHlwZT0iZml4IiBkYXRlPSIyMDE3LTA3LTA0IgorICAgICAgICAgICAgICBkdWUtdG89IlNpbW9uIFNwZXJvICI+CisgICAgICAgIFRoZSBjb2RlIG9mIHRoZSBleHRlbmRlZCB0aW1lc3RhbXAgemlwIGV4dHJhIGZpZWxkIGluY29ycmVjdGx5CisgICAgICAgIGFzc3VtZWQgdGhlIHRpbWUgd2FzIHN0b3JlZCBhcyB1bnNpZ25lZCAzMi1iaXQgaW50IGFuZCB0aHVzCisgICAgICAgIGNyZWF0ZWQgaW5jb3JyZWN0IHJlc3VsdHMgZm9yIHllYXJzIGFmdGVyIDIwMzcuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTQxMCIgdHlwZT0iZml4IiBkYXRlPSIyMDE3LTA3LTA1IgorICAgICAgICAgICAgICBkdWUtdG89IlNpbW9uIFNwZXJvICI+CisgICAgICAgIFJlbW92ZWQgWmlwRW5jb2RpbmcgY29kZSB0aGF0IGJlY2FtZSBvYnNvbGV0ZSB3aGVuIHdlIHN0YXJ0ZWQKKyAgICAgICAgdG8gcmVxdWlyZSBKYXZhIDUgYXMgYmFzZWxpbmUgbG9uZyBhZ28uCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTQxNyIgdHlwZT0iZml4IiBkYXRlPSIyMDE3LTA3LTE5Ij4KKyAgICAgICAgVGhlIHRhciBwYWNrYWdlIHdpbGwgbm8gbG9uZ2VyIHRyeSB0byBwYXJzZSB0aGUgbWFqb3IgYW5kCisgICAgICAgIG1pbm9yIGRldmljZSBudW1iZXJzIHVubGVzcyB0aGUgZW50cnkgcmVwcmVzZW50cyBhIGNoYXJhY3RlcgorICAgICAgICBvciBibG9jayBzcGVjaWFsIGZpbGUuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTQyMSIgdHlwZT0iZml4IiBkYXRlPSIyMDE3LTEwLTA2IgorICAgICAgICAgICAgICBkdWUtdG89IlJvZWwgU3BpbGtlciI+CisgICAgICAgIFdoZW4gcmVhZGluZyB0YXIgaGVhZGVycyB3aXRoIG5hbWUgZmllbGRzIGNvbnRhaW5pbmcgZW1iZWRkZWQKKyAgICAgICAgTlVMcywgdGhlIG5hbWUgd2lsbCBub3cgYmUgdGVybWluYXRlZCBhdCB0aGUgZmlyc3QgTlVMIGJ5dGUuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTQwOSIgdHlwZT0iZml4IiBkYXRlPSIyMDE3LTEwLTA4Ij4KKyAgICAgICAgU2ltcGxpZmllZCBUYXJBcmNoaXZlT3V0cHV0U3RyZWFtIGJ5IHJlcGxhY2luZyB0aGUgaW50ZXJuYWwKKyAgICAgICAgYnVmZmVyaW5nIHdpdGggbmV3IGNsYXNzIEZpeGVkTGVuZ3RoQmxvY2tPdXRwdXRTdHJlYW0uCisgICAgICA8L2FjdGlvbj4KKyAgICA8L3JlbGVhc2U+CisgICAgPHJlbGVhc2UgdmVyc2lvbj0iMS4xNCIgZGF0ZT0iMjAxNy0wNS0xNCIKKyAgICAgICAgICAgICBkZXNjcmlwdGlvbj0iUmVsZWFzZSAxLjE0Ij4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTM3OCIgdHlwZT0iZml4IiBkYXRlPSIyMDE3LTAxLTA5Ij4KKyAgICAgICAgU25hcHB5Q29tcHJlc3NvcklucHV0U3RyZWFtIHNsaWRlcyB0aGUgd2luZG93IHRvbyBlYXJseQorICAgICAgICBsZWFkaW5nIHRvIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbnMgZm9yIHNvbWUgc3RyZWFtcy4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtMjQ2IiB0eXBlPSJhZGQiIGRhdGU9IjIwMTctMDEtMTAiPgorICAgICAgICBBZGRlZCB3cml0ZSBzdXBwb3J0IGZvciBTbmFwcHkuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTM1OCIgdHlwZT0idXBkYXRlIiBkYXRlPSIyMDE3LTAxLTEwIj4KKyAgICAgICAgVGhlIGJsb2Nrc2l6ZSBmb3IgRnJhbWVkU25hcHB5Q29tcHJlc3NvcklucHV0U3RyZWFtIGNhbiBub3cgYmUKKyAgICAgICAgY29uZmlndXJlZCBhcyBzb21lIElXQSBmaWxlcyBzZWVtIHRvIGJlIHVzaW5nIGJsb2NrcyBsYXJnZXIKKyAgICAgICAgdGhhbiB0aGUgZGVmYXVsdCAzMmsuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTM3OSIgdHlwZT0iZml4IiBkYXRlPSIyMDE3LTAxLTE1IgorICAgICAgICAgICAgICBkdWUtdG89Ikd1aWxsYXVtZSBCb3XDqSI+CisgICAgICAgIFppcEFyY2hpdmVFbnRyeSNpc1VuaXhTeW1saW5rIG5vdyBvbmx5IHJldHVybnMgdHJ1ZSBpZiB0aGUKKyAgICAgICAgY29ycmVzcG9uZGluZyBsaW5rIGZsYWcgaXMgdGhlIG9ubHkgZmlsZS10eXBlIGZsYWcgc2V0LgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0yNzEiIHR5cGU9ImFkZCIgZGF0ZT0iMjAxNy0wMi0wNyI+CisgICAgICAgIEFkZGVkIHN1cHBvcnQgZm9yIExaNCAoYmxvY2sgYW5kIGZyYW1lIGZvcm1hdCkuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gdHlwZT0idXBkYXRlIiBkYXRlPSIyMDE3LTAyLTE1IiBkdWUtdG89IlRob21hcyBNZXllciI+CisgICAgICAgIEJaaXAyQ29tcHJlc3NvcklucHV0c3RyZWFtIG5vdyB1c2VzIEJpdElucHV0U3RyZWFtIGludGVybmFsbHkuCisgICAgICAgIFB1bGwgUmVxdWVzdCAjMTMuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gdHlwZT0iZml4IiBkYXRlPSIyMDE3LTAzLTI5IiBkdWUtdG89IkRhbmllbCBDb2xsaW4iPgorICAgICAgICBGaXhlZCBhbiBpbnRlZ2VyIG92ZXJmbG93IGluIENQSU8ncyBDUkMgY2FsY3VsYXRpb24uCisgICAgICAgIFB1bGwgUmVxdWVzdCAjMTcuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTM4NSIgdHlwZT0iYWRkIiBkYXRlPSIyMDE3LTA0LTE4Ij4KKyAgICAgICAgQWRkIHN0YXRpYyBkZXRlY3QoSW5wdXRTdHJlYW0gaW4pIHRvIENvbXByZXNzb3JTdHJlYW1GYWN0b3J5CisgICAgICAgIGFuZCBBcmNoaXZlU3RyZWFtRmFjdG9yeQorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0zODciIHR5cGU9ImZpeCIgZGF0ZT0iMjAxNy0wNC0xOCI+CisgICAgICAgIE1ha2UgdW5pdCB0ZXN0cyB3b3JrIG9uIFdpbmRvd3MgcGF0aHMgd2l0aCBzcGFjZXMgaW4gdGhlaXIgbmFtZXMuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTM4OCIgdHlwZT0idXBkYXRlIiBkYXRlPSIyMDE3LTA0LTI1IgorICAgICAgICAgICAgICBkdWUtdG89IlpieW5layBWeXNrb3Zza3kiPgorICAgICAgICBJbXByb3ZlZCBwZXJmb3JtYW5jZSBmb3IgY29uY3VycmVudCByZWFkcyBmcm9tIFppcEZpbGUgd2hlbgorICAgICAgICByZWFkaW5nIGZyb20gYSBmaWxlLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0zODIiIHR5cGU9ImFkZCIgZGF0ZT0iMjAxNy0wNC0yNSIKKyAgICAgICAgICAgICAgZHVlLXRvPSJUaW0gQWxsaXNvbiI+CisgICAgICAgIEFkZGVkIGEgd2F5IHRvIGxpbWl0IGFtb3VudCBvZiBtZW1vcnkgWkNvbXByZXNzb3JTdHJlYW0gbWF5CisgICAgICAgIHVzZS4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtMzg2IiB0eXBlPSJhZGQiIGRhdGU9IjIwMTctMDQtMjUiCisgICAgICAgICAgICAgIGR1ZS10bz0iVGltIEFsbGlzb24iPgorICAgICAgICBBZGRlZCBhIHdheSB0byBsaW1pdCBhbW91bnQgb2YgbWVtb3J5IFpDb21wcmVzc29yU3RyZWFtIG1heQorICAgICAgICB1c2UuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTM4MiIgdHlwZT0iYWRkIiBkYXRlPSIyMDE3LTA0LTI1IgorICAgICAgICAgICAgICBkdWUtdG89IlRpbSBBbGxpc29uIj4KKyAgICAgICAgQWRkZWQgYSB3YXkgdG8gbGltaXQgYW1vdW50IG9mIG1lbW9yeSBMWk1BQ29tcHJlc3NvclN0cmVhbSBhbmQKKyAgICAgICAgWFpDb21wcmVzc29ySW5wdXRTdHJlYW0gbWF5IHVzZS4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtMzg5IiB0eXBlPSJmaXgiIGRhdGU9IjIwMTctMDQtMjYiPgorICAgICAgICBJbnRlcm5hbCBsb2NhdGlvbiBwb2ludGVyIGluIFppcEZpbGUgY291bGQgZ2V0IGluY3JlbWVudGVkCisgICAgICAgIGV2ZW4gaWYgbm90aGluZyBoYWQgYmVlbiByZWFkLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0zOTIiIHR5cGU9ImFkZCIgZGF0ZT0iMjAxNy0wNS0wMiIgZHVlLXRvPSJQaGlsaXBwZSBNb3Vhd2FkIj4KKyAgICAgICAgQWRkIEJyb3RsaSBkZWNvZGVyIGJhc2VkIG9uIHRoZSBHb29nbGUgQnJvdGxpIGxpYnJhcnkuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTM5MCIgdHlwZT0iYWRkIiBkYXRlPSIyMDE3LTA1LTA0IgorICAgICAgICAgICAgICBkdWUtdG89IlpieW5layBWeXNrb3Zza3kiPgorICAgICAgICBaaXBFbnRyeSBub3cgZXhwb3NlcyBpdHMgZGF0YSBvZmZzZXQuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTM5MyIgdHlwZT0iZml4IiBkYXRlPSIyMDE3LTA1LTA3Ij4KKyAgICAgICAgTFpNQUNvbXByZXNzb3JPdXRwdXRTdHJlYW0jZmx1c2ggd291bGQgdGhyb3cgYW4gZXhjZXB0aW9uCisgICAgICAgIHJhdGhlciB0aGFuIGJlIHRoZSBOT1AgaXQgcHJvbWlzZWQgdG8gYmUuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTM5MSIgdHlwZT0iYWRkIiBkYXRlPSIyMDE3LTA1LTExIgorICAgICAgICAgICAgICBkdWUtdG89IlpieW5layBWeXNrb3Zza3kiPgorICAgICAgICBVc2luZyBaaXBBcmNoaXZlRW50cnkncyBzZXRBbGlnbm1lbnQgaXQgaXMgbm93IHBvc3NpYmxlIHRvCisgICAgICAgIGVuc3VyZSB0aGUgZGF0YSBvZmZzZXQgb2YgYW4gZW50cnkgc3RhcnRzIGF0IGEgZmlsZSBwb3NpdGlvbgorICAgICAgICB0aGF0IGF0IHdvcmQgb3IgcGFnZSBib3VuZGFyaWVzLgorICAgICAgICBBIG5ldyBleHRyYSBmaWVsZCBoYXMgYmVlbiBhZGRlZCBmb3IgdGhpcyBwdXJwb3NlLgorICAgICAgPC9hY3Rpb24+CisgICAgPC9yZWxlYXNlPgorICAgIDxyZWxlYXNlIHZlcnNpb249IjEuMTMiIGRhdGU9IjIwMTYtMTItMjkiCisgICAgICAgICAgICAgZGVzY3JpcHRpb249IlJlbGVhc2UgMS4xMyAtIEFQSSBjb21wYXRpYmxlIHRvIDEuMTIgYnV0IHJlcXVpcmVzIEphdmEgNyBhdCBydW50aW1lLiI+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0zNjAiIHR5cGU9InVwZGF0ZSIgZGF0ZT0iMjAxNi0wNi0yNSIgZGV2PSJnZ3JlZ29yeSI+CisgICAgICAgIFVwZGF0ZSBKYXZhIHJlcXVpcmVtZW50IGZyb20gNiB0byA3LgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0zNjMiIHR5cGU9ImZpeCIgZGF0ZT0iMjAxNi0wNy0wMSI+CisgICAgICAgIEJpdElucHV0U3RyZWFtIGNvdWxkIHJldHVybiBiYWQgcmVzdWx0cyB3aGVuIG92ZXJmbG93aW5nCisgICAgICAgIGludGVybmFsbHkgLSBpZiB0d28gY29uc2VjdXRpdmUgcmVhZHMgdHJpZWQgdG8gcmVhZCBtb3JlIHRoYW4KKyAgICAgICAgNjQgYml0cy4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtMzY2IiB0eXBlPSJ1cGRhdGUiIGRhdGU9IjIwMTYtMTAtMDciPgorICAgICAgICBDbGFyaWZpZWQgd2hpY2ggVGFyQXJjaGl2ZUVudHJ5IG1ldGhvZHMgYXJlIHVzZWxlc3MgZm9yCisgICAgICAgIGVudHJpZXMgcmVhZCBmcm9tIGFuIGFyY2hpdmUuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTM2NCIgdHlwZT0iZml4IiBkYXRlPSIyMDE2LTEwLTA3IgorICAgICAgICAgICAgICBkdWUtdG89Ik1pa2UgTW9sZSI+CisgICAgICAgIFppcEFyY2hpdmVJbnB1dFN0cmVhbS5jbG9zZUVudHJ5IGRvZXMgbm90IHByb3Blcmx5IGFkdmFuY2UgdG8KKyAgICAgICAgbmV4dCBlbnRyeSBpZiB0aGVyZSBhcmUganVuayBieXRlcyBhdCBlbmQgb2YgZGF0YSBzZWN0aW9uCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTMyNyIgdHlwZT0iYWRkIiBkYXRlPSIyMDE2LTEwLTEyIj4KKyAgICAgICAgU2V2ZW5aRmlsZSwgU2V2ZW5aT3V0cHV0RmlsZSwgWmlwRmlsZSBhbmQKKyAgICAgICAgWmlwQXJjaGl2ZU91dHB1dFN0cmVhbSBjYW4gbm93IHdvcmsgb24gbm9uLWZpbGUgcmVzb3VyY2VzIGlmCisgICAgICAgIHRoZXkgY2FuIGJlIGFjY2Vzc2VkIHZpYSBTZWVrYWJsZUJ5dGVDaGFubmVsLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0zNjgiIHR5cGU9ImFkZCIgZGF0ZT0iMjAxNi0xMS0xNSI+CisgICAgICAgIEFsbG93IGNvbXByZXNzb3IgZXh0ZW5zaW9ucyB0aHJvdWdoIGEgc3RhbmRhcmQgSlJFIFNlcnZpY2VMb2FkZXIuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTM2OSIgdHlwZT0iYWRkIiBkYXRlPSIyMDE2LTExLTE1Ij4KKyAgICAgICAgQWxsb3cgYXJjaGl2ZSBleHRlbnNpb25zIHRocm91Z2ggYSBzdGFuZGFyZCBKUkUgU2VydmljZUxvYWRlci4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtMzczIiB0eXBlPSJhZGQiIGRhdGU9IjIwMTYtMTEtMjkiPgorICAgICAgICBBZGQgd3JpdGUgc3VwcG9ydCBmb3IgdGhlIGxlZ2FjeSBMWk1BIGZvcm1hdCwgdGhpcyByZXF1aXJlcyBYWgorICAgICAgICBmb3IgSmF2YSAxLjYuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTM3NCIgdHlwZT0iYWRkIiBkYXRlPSIyMDE2LTExLTI5Ij4KKyAgICAgICAgQWRkIHdyaXRlIHN1cHBvcnQgZm9yIHRoZSBsZWdhY3kgTFpNQSBzdHJlYW0gdG8gN3osIHRoaXMKKyAgICAgICAgcmVxdWlyZXMgWFogZm9yIEphdmEgMS42LgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0zNzUiIHR5cGU9ImFkZCIgZGF0ZT0iMjAxNi0xMi0wNCIKKyAgICAgICAgICAgICAgZHVlLXRvPSJQbGFtZW4gVG90ZXYiPgorICAgICAgICBBbGxvdyB0aGUgY2xpZW50cyBvZiBQYXJhbGxlbFNjYXR0ZXJaaXBDcmVhdG9yIHRvIHByb3ZpZGUKKyAgICAgICAgWmlwQXJjaGl2ZUVudHJ5UmVxdWVzdFN1cHBsaWVyLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0zNjciIHR5cGU9ImZpeCIgZGF0ZT0iMjAxNi0xMi0wOSIKKyAgICAgICAgICAgICAgZHVlLXRvPSJNaWtlIE1vbGUiPgorICAgICAgICBaaXBBcmNoaXZlSW5wdXRTdHJlYW0gbm93IHRocm93cyBhbiBFeGNlcHRpb24gaWYgaXQgZW5jb3VudGVycworICAgICAgICBhIGJyb2tlbiBaSVAgYXJjaGl2ZSByYXRoZXIgdGhhbiBzaWduYWxpbmcgZW5kLW9mLWFyY2hpdmUuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTM3NyIgdHlwZT0iZml4IiBkYXRlPSIyMDE2LTEyLTIwIj4KKyAgICAgICAgU2NhdHRlclppcE91dHB1dFN0cmVhbSBkaWRuJ3QgY2xvc2UgdGhlIFN0cmVhbUNvbXByZXNzb3IKKyAgICAgICAgY2F1c2luZyBhIHBvdGVudGlhbCByZXNvdXJjZSBsZWFrLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0zNzIiIHR5cGU9ImFkZCIgZGF0ZT0iMjAxNi0xMi0yMCI+CisgICAgICAgIEFkZCBhIHZlcnNpb24taW5kZXBlbmRlbnQgbGluayB0byB0aGUgQVBJIGRvY3Mgb2YgdGhlIGxhdGVzdAorICAgICAgICByZWxlYXNlLgorICAgICAgPC9hY3Rpb24+CisgICAgPC9yZWxlYXNlPgorICAgIDxyZWxlYXNlIHZlcnNpb249IjEuMTIiIGRhdGU9IjIwMTYtMDYtMjEiCisgICAgICAgICAgICAgZGVzY3JpcHRpb249IlJlbGVhc2UgMS4xMiAtIEFQSSBjb21wYXRpYmxlIHRvIDEuMTEgYnV0IHJlcXVpcmVzIEphdmEgNiBhdCBydW50aW1lLgorLS0tLS0tLS0tLS0tCisKKworCitSZWxlYXNlIDEuMTIgY2hhbmdlcyB0aGUgYmVoYXZpb3Igb2YgQlppcDJDb21wcmVzc29yT3V0cHV0U3RyZWFtJ3MKK2ZpbmFsaXplIG1ldGhvZCBzbyB0aGF0IGl0IG5vIGxvbmdlciBpbnZva2VzIGZpbmlzaC4gVGhpcyBpcyBnb2luZyB0bworYnJlYWsgY29kZSB0aGF0IHJlbGllZCBvbiB0aGUgZmluYWxpemVyIHRvIGNsZWFuIHVwIGFuIHVuZmluaXNoZWQKK3N0cmVhbS4gVGhlIGNvZGUgd2lsbCBuZWVkIHRvIGJlIGNoYW5nZWQgdG8gY2FsbCBmaW5pc2ggb3IKK2Nsb3NlIGl0c2VsZi4gTm90ZSB0aGF0IGEgZmluYWxpemVyIGlzIG5vdCBndWFyYW50ZWVkIHRvIHJ1biwgc28KK3RoZSBmZWF0dXJlIHdhcyBub3QgMTAwJSBlZmZlY3RpdmUgaW4gYW55IGNhc2UuCisiPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtMzQ5IiB0eXBlPSJ1cGRhdGUiIGRhdGU9IjIwMTYtMDQtMDkiIGRldj0iZ2dyZWdvcnkiPgorICAgICAgICBVcGRhdGUgcmVxdWlyZW1lbnQgZnJvbSBKYXZhIDUgdG8gNi4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtMzUwIiB0eXBlPSJ1cGRhdGUiIGRhdGU9IjIwMTYtMDQtMDkiIGRldj0iZ2dyZWdvcnkiPgorICAgICAgICBUYXJBcmNoaXZlRW50cnkgd2FzdGVmdWxseSBhbGxvY2F0ZXMgZW1wdHkgYXJyYXlzLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0zNDgiIHR5cGU9ImZpeCIgZGF0ZT0iMjAxNi0wNC0yNCI+CisgICAgICAgIFNldmVuWkZpbGUucmVhZCgpIHRocm93cyBhbiBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZm9yIGVtcHR5IGVudHJpZXMuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTM1MyIgdHlwZT0idXBkYXRlIiBkYXRlPSIyMDE2LTA1LTA2IiBkZXY9ImdncmVnb3J5Ij4KKyAgICAgICAgSmF2YWRvYyBmb3IgQlppcDJDb21wcmVzc29ySW5wdXRTdHJlYW0oSW5wdXRTdHJlYW0sIGJvb2xlYW4pIHNob3VsZCByZWZlciB0byBJT0V4LCBub3QgTlBFLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0zNTQiIHR5cGU9InVwZGF0ZSIgZGF0ZT0iMjAxNi0wNS0xNiI+CisgICAgICAgIFB1cmVKYXZhQ3JjMzJDIGluIHRoZSBzbmFwcHkgcGFja2FnZSBpcyBub3cgZmluYWwgc28gaXQgaXMgbm93CisgICAgICAgIHNhZmUgdG8gY2FsbCBhIHZpcnR1YWwgbWV0aG9kIGluc2lkZSB0aGUgY29uc3RydWN0b3IuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTM1NSIgdHlwZT0iZml4IiBkYXRlPSIyMDE2LTA1LTIwIgorICAgICAgICAgICAgICBkdWUtdG89IkplcmVteSBHdXN0aWUiPgorICAgICAgICBUYXJBcmNoaXZlSW5wdXRTdHJlYW0gZmFpbGVkIHRvIHBhcnNlIFBBWCBoZWFkZXJzIHRoYXQKKyAgICAgICAgaW5jbHVkZWQgYmxhbmsgbGluZXMuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTM1NiIgdHlwZT0iZml4IiBkYXRlPSIyMDE2LTA1LTIwIgorICAgICAgICAgICAgICBkdWUtdG89IkplcmVteSBHdXN0aWUiPgorICAgICAgICBUYXJBcmNoaXZlSW5wdXRTdHJlYW0gZmFpbGVkIHRvIHBhcnNlIFBBWCBoZWFkZXJzIHdob3NlIHRhcgorICAgICAgICBlbnRyeSBuYW1lIGVuZGVkIHdpdGggYSBzbGFzaC4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtMzUyIiB0eXBlPSJhZGQiIGRhdGU9IjIwMTYtMDUtMjIiPgorICAgICAgICBGcmFtZWRTbmFwcHlDb21wcmVzc29ySW5wdXRTdHJlYW0gbm93IHN1cHBvcnRzIHRoZSBkaWFsZWN0IG9mCisgICAgICAgIFNuYXBweSB1c2VkIGJ5IHRoZSBJV0EgZmlsZXMgY29udGFpbmVkIHdpdGhpbiB0aGUgemlwIGFyY2hpdmVzCisgICAgICAgIHVzZWQgaW4gQXBwbGUncyBpV29yayAxMyBmaWxlcy4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtMzUxIiB0eXBlPSJ1cGRhdGUiIGRhdGU9IjIwMTYtMDYtMDciPgorICAgICAgICBaaXBBcmNoaXZlSW5wdXRTdHJlYW0gYW5kIENwaW9BcmNoaXZlSW5wdXRTdHJlYW0gY291bGQgdGhyb3cKKyAgICAgICAgZXhjZXB0aW9ucyB3aG8ncyBtZXNzYWdlcyBjb250YWluZWQgcG90ZW50aWFsbHkgY29ycnVwdCBlbnRyeQorICAgICAgICBuYW1lcyByZWFkIGZyb20gYSBicm9rZW4gYXJjaGl2ZS4gVGhleSB3aWxsIG5vdyBzYW5pdGl6ZSB0aGUKKyAgICAgICAgbmFtZXMgYnkgcmVwbGFjaW5nIHVucHJpbnRhYmxlIGNoYXJhY3RlcnMgYW5kIHJlc3RyaWN0aW5nIHRoZQorICAgICAgICBsZW5ndGggdG8gMjU1IGNoYXJhY3RlcnMuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTM1NyIgdHlwZT0idXBkYXRlIiBkYXRlPSIyMDE2LTA2LTE1Ij4KKyAgICAgICAgQlppcDJDb21wcmVzc29yT3V0cHV0U3RyZWFtIG5vIGxvbmdlciB0cmllcyB0byBmaW5pc2ggdGhlCisgICAgICAgIG91dHB1dCBzdHJlYW0gaW4gZmluYWxpemUuIFRoaXMgaXMgYSBicmVha2luZyBjaGFuZ2UgZm9yIGNvZGUKKyAgICAgICAgdGhhdCByZWxpZWQgb24gdGhlIGZpbmFsaXplci4KKyAgICAgIDwvYWN0aW9uPgorICAgIDwvcmVsZWFzZT4KKyAgICA8cmVsZWFzZSB2ZXJzaW9uPSIxLjExIiBkYXRlPSIyMDE2LTA0LTA2IgorICAgICAgICAgICAgIGRlc2NyaXB0aW9uPSJSZWxlYXNlIDEuMTEiPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtMzQ3IiB0eXBlPSJhZGQiIGRhdGU9IjIwMTYtMDMtMjMiPgorICAgICAgICBUYXJBcmNoaXZlSW5wdXRTdHJlYW0gbm93IHN1cHBvcnRzIHJlYWRpbmcgZ2xvYmFsIFBBWCBoZWFkZXJzLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0zNDYiIHR5cGU9ImFkZCIgZGF0ZT0iMjAxNi0wMy0yMyI+CisgICAgICAgIFRoZSBQQVggaGVhZGVycyBmb3Igc3BhcnNlIGVudHJpZXMgd3JpdHRlbiBieSBzdGFyIGFyZSBub3cKKyAgICAgICAgYXBwbGllZC4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtMzQ1IiB0eXBlPSJhZGQiIGRhdGU9IjIwMTYtMDMtMjMiPgorICAgICAgICBHTlUgc3BhcnNlIGZpbGVzIHVzaW5nIG9uZSBvZiB0aGUgUEFYIGZvcm1hdHMgYXJlIG5vdworICAgICAgICBkZXRlY3RlZCwgYnV0IGNhbm5vdCBiZSBleHRyYWN0ZWQuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTM0NCIgdHlwZT0iZml4IiBkYXRlPSIyMDE2LTAzLTIyIj4KKyAgICAgICAgQXJBcmNoaXZlSW5wdXRTdHJlYW0gY2FuIG5vdyByZWFkIEdOVSBleHRlbmRlZCBuYW1lcyB0aGF0IGFyZQorICAgICAgICB0ZXJtaW5hdGVkIHdpdGggYSBOVUwgYnl0ZSByYXRoZXIgdGhhbiBhIGxpbmVmZWVkLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0zNDEiIHR5cGU9ImFkZCIgZGF0ZT0iMjAxNi0wMy0yMCI+CisgICAgICAgIE5ldyBtZXRob2QgU2V2ZW5aRmlsZS5nZXRFbnRyaWVzIGNhbiBiZSB1c2VkIHRvIGxpc3QgdGhlCisgICAgICAgIGNvbnRlbnRzIG9mIGEgN3ogYXJjaGl2ZS4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtMzQzIiB0eXBlPSJmaXgiIGRhdGU9IjIwMTYtMDMtMTciCisgICAgICAgICAgICAgIGR1ZS10bz0iUmVuZSBQcmVpc3NlbCI+CisgICAgICAgIE5hdGl2ZSBNZW1vcnkgTGVhayBpbiBTZXZlbnotRGVmbGF0ZURlY29kZXIuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gdHlwZT0iYWRkIiBkYXRlPSIyMDE2LTAzLTA1IgorICAgICAgICAgICAgICBkdWUtdG89Ik1hdHQgSG92ZXkiPgorICAgICAgICBXaGVuIHVzaW5nIFppcDY0TW9kZS5BbHdheXMgYWxzbyB1c2UgWklQNjQgZXh0ZW5zaW9ucyBpbnNpZGUKKyAgICAgICAgdGhlIGNlbnRyYWwgZGlyZWN0b3J5LgorICAgICAgICBHaXRIdWIgUHVsbCBSZXF1ZXN0ICMxMAorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0zNDAiIHR5cGU9ImZpeCIgZGF0ZT0iMjAxNi0wMi0yNCIKKyAgICAgICAgICAgICAgZHVlLXRvPSJEYXdpZCBXZWlzcyI+CisgICAgICAgIFNldmVuWkZpbGUgd2lsbCBub3cgb25seSB0cnkgdG8gZHJhaW4gYW4gZW50cnkncyBjb250ZW50IHdoZW4KKyAgICAgICAgbW92aW5nIG9uIHRvIHRoZSBuZXh0IGVudHJ5IGlmIGRhdGEgaXMgcmVhZCBmcm9tIHRoZSBuZXh0CisgICAgICAgIGVudHJ5LiBUaGlzIHNob3VsZCBpbXByb3ZlIHBlcmZvcm1hbmNlIGZvciBhcHBsaWNhdGlvbnMgdGhhdAorICAgICAgICB0cnkgdG8gc2tpcCBvdmVyIGVudHJpZXMuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTMzNiIgdHlwZT0iZml4IiBkYXRlPSIyMDE2LTAyLTE0Ij4KKyAgICAgICAgZmlsZSBuYW1lcyBvZiB0YXIgYXJjaGl2ZXMgdXNpbmcgdGhlIHhzdGFyIGZvcm1hdCBhcmUgbm93CisgICAgICAgIHBhcnNlZCBwcm9wZXJseS4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtMzM1IiB0eXBlPSJmaXgiIGRhdGU9IjIwMTYtMDItMDUiPgorICAgICAgICBjaGVja3N1bXMgb2YgdGFycyB0aGF0IHBhZCB0aGUgY2hlY2tzdW0gZmllbGQgdG8gdGhlIGxlZnQgYXJlCisgICAgICAgIG5vdyBjYWxjdWxhdGVkIHByb3Blcmx5LgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0zMzQiIHR5cGU9ImZpeCIgZGF0ZT0iMjAxNi0wMi0wNSIKKyAgICAgICAgICAgICAgZHVlLXRvPSJKZXJlbXkgR3VzdGllIj4KKyAgICAgICAgQXJBcmNoaXZlSW5wdXRTdHJlYW0gZmFpbGVkIHRvIHJlYWQgcGFzdCB0aGUgZmlyc3QgZW50cnkgd2hlbgorICAgICAgICBCU0QgbG9uZyBuYW1lcyBoYXZlIGJlZW4gdXNlZC4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtMzMzIiB0eXBlPSJmaXgiIGRhdGU9IjIwMTYtMDItMDMiIGR1ZS10bz0iRGF3aWQgV2Vpc3MiPgorICAgICAgICBBZGRlZCBidWZmZXJpbmcgZm9yIHJhbmRvbSBhY2Nlc3Mgd2hpY2ggc3BlZWRzIHVwIDdaIHN1cHBvcnQuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTMzMSIgdHlwZT0iZml4IiBkYXRlPSIyMDE2LTAxLTMxIj4KKyAgICAgICAgVGhlIGNoZWNrc3VtIHZhbGlkYXRpb24gb2YgVGFyYXJjaGl2ZUVudHJ5IGlzIG5vdyBhcyBzdHJpY3QgYXMKKyAgICAgICAgdGhlIHZhbGlkYXRpb24gb2YgR05VIHRhciwgd2hpY2ggZWxpbWluYXRlcyBhIGZldyBjYXNlcyBvZgorICAgICAgICBmYWxzZSBwb3NpdGl2ZXMgb2YgQXJjaGl2ZVN0cmVhbUZhY3RvcnkuCisgICAgICAgIFRoaXMgYmVoYXZpb3IgaXMgYSBicmVha2luZyBjaGFuZ2Ugc2luY2UgdGhlIGNoZWNrIGhhcyBiZWNvbWUKKyAgICAgICAgbW9yZSBzdHJpY3QgYnV0IGFueSBhcmNoaXZlIHRoYXQgZmFpbHMgdGhlIGNoZWNrc3VtIHRlc3Qgbm93CisgICAgICAgIHdvdWxkIGFsc28gZmFpbCBpdCB3aGVuIGV4dHJhY3RlZCB3aXRoIG90aGVyIHRvb2xzIGFuZCBtdXN0IGJlCisgICAgICAgIGNvbnNpZGVyZWQgYW4gaW52YWxpZCBhcmNoaXZlLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0zMjMiIHR5cGU9ImFkZCIgZGF0ZT0iMjAxNi0wMS0yOSI+CisgICAgICAgIFppcEZpbGUuZ2V0UmF3SW5wdXRTdHJlYW0oKSBpcyBub3cgcGFydCBvZiB0aGUgcHVibGljIEFQSQorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0zMzIiIHR5cGU9ImZpeCIgZGF0ZT0iMjAxNi0wMS0yOSI+CisgICAgICAgIFNuYXBweUNvbXByZXNzb3JJbnB1dFN0cmVhbSBhbmQKKyAgICAgICAgRnJhbWVkU25hcHB5Q29tcHJlc3NvcklucHV0U3RyZWFtIHJldHVybmVkIDAgYXQgdGhlIGVuZCBvZiB0aGUKKyAgICAgICAgc3RyZWFtIHVuZGVyIGNlcnRhaW4gY2lyY3Vtc3RhbmNlcy4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiB0eXBlPSJhZGQiIGRhdGU9IjIwMTYtMDEtMjciIGR1ZS10bz0iSmFzb24gdmFuIFp5bCI+CisgICAgICAgIEFsbG93IGJ5dGUtZm9yLWJ5dGUgcmVwbGljYXRpb24gb2YgWmlwIGVudHJpZXMuCisgICAgICAgIEdpdEh1YiBQdWxsIFJlcXVlc3QgIzYuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTMyOCIgdHlwZT0iYWRkIiBkYXRlPSIyMDE2LTAxLTE1Ij4KKyAgICAgICAgVGFyQXJjaGl2ZUVudHJ5J3MgcHJlc2VydmVMZWFkaW5nU2xhc2hlcyBpcyBub3cgYSBwcm9wZXJ0eSBhbmQgdXNlZAorICAgICAgICBvbiBsYXRlciBjYWxscyB0byBzZXROYW1lLCB0b28uCisgICAgICAgIFRoaXMgYmVoYXZpb3IgaXMgYSBicmVha2luZyBjaGFuZ2UuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTMyNiIgdHlwZT0iZml4IiBkYXRlPSIyMDE1LTEwLTI0Ij4KKyAgICAgICAgQWRqdXN0ZWQgdW5pdCB0ZXN0IHRvIHVwZGF0ZXMgaW4gSmF2YTggYW5kIGxhdGVyIHRoYXQgY2hhbmdlCisgICAgICAgIHRoZSBsb2dpYyBvZiBaaXBFbnRyeSNnZXRUaW1lLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0zMjQiIHR5cGU9ImZpeCIgZGF0ZT0iMjAxNS0xMC0wNiI+CisgICAgICAgIFRhckFyY2hpdmVPdXRwdXRTdHJlYW0gd2lsbCBub3cgcmVjb2duaXplIEdOVSBsb25nIG5hbWUgYW5kCisgICAgICAgIGxpbmsgZW50cmllcyBldmVuIGlmIHRoZSBzcGVjaWFsIGVudHJ5IGhhcyBhIGRpZmZlcmVudCBuYW1lCisgICAgICAgIHRoYW4gR05VIHRhciB1c2VzIGl0c2VsZi4gIFRoaXMgc2VlbXMgdG8gYmUgdGhlIGNhc2UgZm9yCisgICAgICAgIGFyY2hpdmVzIGNyZWF0ZWQgYnkgc3Rhci4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtMzIxIiB0eXBlPSJmaXgiIGRhdGU9IjIwMTUtMDgtMjIiPgorICAgICAgICBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gd2hlbiBJbmZvWklQIHR5cGUgNzg3NSBleHRyYQorICAgICAgICBmaWVsZHMgYXJlIHJlYWQgZnJvbSB0aGUgY2VudHJhbCBkaXJlY3RvcnkuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gdHlwZT0iYWRkIiBkYXRlPSIyMDE1LTExLTExIiBkdWUtdG89IlPDtnJlbiBHbGltbSI+CisgICAgICAgIEFkZGVkIHJlYWQtb25seSBzdXBwb3J0IGZvciBiemlwMiBjb21wcmVzc2lvbiB1c2VkIGluc2lkZSBvZgorICAgICAgICBaSVAgYXJjaGl2ZXMuCisgICAgICAgIEdpdEh1YiBQdWxsIFJlcXVlc3QgIzQuCisgICAgICA8L2FjdGlvbj4KKyAgICA8L3JlbGVhc2U+CisKKyAgICA8cmVsZWFzZSB2ZXJzaW9uPSIxLjEwIiBkYXRlPSIyMDE1LTA4LTE4IgorICAgICAgICAgICAgIGRlc2NyaXB0aW9uPSJSZWxlYXNlIDEuMTAKKy0tLS0tLS0tLS0tLQorCisKKworUmVsZWFzZSAxLjEwIG1vdmVzIHRoZSBmb3JtZXIKK29yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy56Ll9pbnRlcm5hbF8gcGFja2FnZSB3aGljaAorYnJlYWtzIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5IGZvciBjb2RlIHdoaWNoIHVzZWQgdGhlIG9sZCBwYWNrYWdlLgorVGhpcyBhbHNvIGNoYW5nZXMgdGhlIHN1cGVyY2xhc3Mgb2YgWkNvbXByZXNzb3JJbnB1dFN0cmVhbS4KKyI+CisKKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTMxNyIgdHlwZT0iZml4IiBkYXRlPSIyMDE1LTA2LTA5IgorICAgICAgICAgICAgICBkdWUtdG89Ikx1Y2FzIFdlcmttZWlzdGVyIj4KKyAgICAgICAgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIHdoZW4gWklQIGV4dHJhIGZpZWxkcyBhcmUgcmVhZAorICAgICAgICBhbmQgdGhlIGVudHJ5IGNvbnRhaW5zIGFuIFVucGFyc2VhYmxlRXh0cmFGaWVsZC4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtMzE2IiB0eXBlPSJhZGQiIGRhdGU9IjIwMTUtMDUtMjMiCisgICAgICAgICAgICAgIGR1ZS10bz0iTmljayBCdXJjaCI+CisgICAgICAgIENvbXByZXNzb3JTdHJlYW1GYWN0b3J5IGNhbiBub3cgYXV0by1kZXRlY3QgREVGTEFURSBzdHJlYW1zCisgICAgICAgIHdpdGggWkxJQiBoZWFkZXIuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTMxNCIgdHlwZT0iZml4IiBkYXRlPSIyMDE1LTA1LTA4Ij4KKyAgICAgICAgVGFyQXJjaGl2ZUlucHV0U3RyZWFtIGNhbiBub3cgcmVhZCBlbnRyaWVzIHdpdGggZ3JvdXAgb3IKKyAgICAgICAgdXNlciBpZHMgJmd0OyAweDgwMDAwMDAwLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0zMTUiIHR5cGU9ImZpeCIgZGF0ZT0iMjAxNS0wNS0wNiI+CisgICAgICAgIFRhckFyY2hpdmVPdXRwdXRTdHJlYW0gY2FuIG5vdyB3cml0ZSBlbnRyaWVzIHdpdGggZ3JvdXAgb3IKKyAgICAgICAgdXNlciBpZHMgJmd0OyAweDgwMDAwMDAwLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0zMTMiIHR5cGU9ImFkZCIgZGF0ZT0iMjAxNS0wMy0zMCI+CisgICAgICAgIENvbXByZXNzb3JTdHJlYW1GYWN0b3J5IGNhbiBub3cgYXV0by1kZXRlY3QgTFpNQSBzdHJlYW1zLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0zMTIiIHR5cGU9ImZpeCIgZGF0ZT0iMjAxNS0wMy0yOCI+CisgICAgICAgIFRhckFyY2hpdmVFbnRyeSdzIGNvbnN0cnVjdG9yIHdpdGggYSBGaWxlIGFuZCBhIFN0cmluZyBhcmcKKyAgICAgICAgZGlkbid0IG5vcm1hbGl6ZSB0aGUgbmFtZS4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtMzA4IiB0eXBlPSJmaXgiIGRhdGU9IjIwMTUtMDItMjAiPgorICAgICAgICBaaXBFbmNvZGluZ0hlbHBlciBubyBsb25nZXIgcmVhZHMgc3lzdGVtIHByb3BlcnRpZXMgZGlyZWN0bHkKKyAgICAgICAgdG8gZGV0ZXJtaW5lIHRoZSBkZWZhdWx0IGNoYXJzZXQuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTMwOSIgdHlwZT0iZml4IiBkYXRlPSIyMDE1LTAyLTIwIj4KKyAgICAgICAgQlppcDJDb21wcmVzc29ySW5wdXRTdHJlYW0jcmVhZCB3b3VsZCByZXR1cm4gLTEgd2hlbiBhc2tlZCB0bworICAgICAgICByZWFkIDAgYnl0ZXMuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTMwNiIgdHlwZT0iZml4IiBkYXRlPSIyMDE1LTAyLTE3Ij4KKyAgICAgICAgQXJjaGl2ZVN0cmVhbUZhY3RvcnkgZmFpbHMgdG8gcGFzcyBvbiB0aGUgZW5jb2Rpbmcgd2hlbiBjcmVhdGluZyBzb21lIHN0cmVhbXMuCisgICAgICAgICogQXJqQXJjaGl2ZUlucHV0U3RyZWFtCisgICAgICAgICogQ3Bpb0FyY2hpdmVJbnB1dFN0cmVhbQorICAgICAgICAqIER1bXBBcmNoaXZlSW5wdXRTdHJlYW0KKyAgICAgICAgKiBKYXJBcmNoaXZlSW5wdXRTdHJlYW0KKyAgICAgICAgKiBUYXJBcmNoaXZlSW5wdXRTdHJlYW0KKyAgICAgICAgKiBKYXJBcmNoaXZlT3V0cHV0U3RyZWFtCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTMwMiIgdHlwZT0iZml4IiBkYXRlPSIyMDE1LTAyLTE2Ij4KKyAgICAgICAgUmVzdG9yZSBpbW11dGFiaWxpdHkvdGhyZWFkLXNhZmV0eSB0byBBcmNoaXZlU3RyZWFtRmFjdG9yeS4KKyAgICAgICAgVGhlIGNsYXNzIGlzIG5vdyBpbW11dGFibGUgcHJvdmlkZWQgdGhhdCB0aGUgbWV0aG9kIHNldEVudHJ5RW5jb2RpbmcgaXMgbm90IHVzZWQuCisgICAgICAgIFRoZSBjbGFzcyBpcyB0aHJlYWQtc2FmZS4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtMzAzIiB0eXBlPSJmaXgiIGRhdGU9IjIwMTUtMDItMTYiPgorICAgICAgICBSZXN0b3JlIGltbXV0YWJpbGl0eS90aHJlYWQtc2FmZXR5IHRvIENvbXByZXNzb3JTdHJlYW1GYWN0b3J5LgorICAgICAgICBUaGUgY2xhc3MgaXMgbm93IGltbXV0YWJsZSBwcm92aWRlZCB0aGF0IHRoZSBtZXRob2Qgc2V0RGVjb21wcmVzc0NvbmNhdGVuYXRlZCBpcyBub3QgdXNlZC4KKyAgICAgICAgVGhlIGNsYXNzIGlzIHRocmVhZC1zYWZlLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0yOTgiIHR5cGU9ImZpeCIgZGF0ZT0iMjAxNS0wMS0yMCI+CisgICAgICAgIFNldmVuWkZpbGUgbm93IHRocm93cyB0aGUgc3BlY2lmaWMgUGFzc3dvcmRSZXF1aXJlZEV4Y2VwdGlvbgorICAgICAgICB3aGVuIGl0IGVuY291bnRlcnMgYW4gZW5jcnlwdGVkIHN0cmVhbSBidXQgbm8gcGFzc3dvcmQgaGFzCisgICAgICAgIGJlZW4gc3BlY2lmaWVkLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0yOTAiIHR5cGU9ImZpeCIgZGF0ZT0iMjAxNS0wMS0xMyIKKyAgICAgICAgICAgICAgZHVlLXRvPSJLcmlzdGlhbiBSb3NlbnZvbGQiPgorICAgICAgICBJbXByb3ZlZCBlcnJvciBtZXNzYWdlIHdoZW4gdGFyIGVuY291bnRlcnMgYSBncm91cElkIHRoYXQgaXMKKyAgICAgICAgdG9vIGJpZyB0byB3cml0ZSB3aXRob3V0IHVzaW5nIHRoZSBTVEFSIG9yIFBPU0lYIGZvcm1hdC4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtMjk2IiB0eXBlPSJhZGQiIGRhdGU9IjIwMTUtMDEtMTAiCisgICAgICAgICAgICAgIGR1ZS10bz0iS3Jpc3RpYW4gUm9zZW52b2xkIj4KKyAgICAgICAgQWRkZWQgc3VwcG9ydCBmb3IgcGFyYWxsZWwgY29tcHJlc3Npb24uIFRoaXMgbG93LWxldmVsIEFQSSBhbGxvd3MKKyAgICAgICAgYSBjbGllbnQgdG8gYnVpbGQgYSB6aXAvamFyIGZpbGUgYnkgdXNpbmcgdGhlIGNsYXNzCisgICAgICAgIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwLlBhcmFsbGVsU2NhdHRlclppcENyZWF0b3IuCisKKyAgICAgICAgWmlwIGRvY3VtZW50YXRpb24gdXBkYXRlZCB3aXRoIGZ1cnRoZXIgbm90ZXMgYWJvdXQgcGFyYWxsZWwgZmVhdHVyZXMuCisKKyAgICAgICAgUGxlYXNlIG5vdGUgdGhhdCBzb21lIGFzcGVjdHMgb2YgamFyIGNyZWF0aW9uIG5lZWQgdG8gYmUKKyAgICAgICAgaGFuZGxlZCBieSBjbGllbnQgY29kZSBhbmQgaXMgbm90IHBhcnQgb2YgY29tbW9ucy1jb21wcmVzcyBmb3IgdGhpcworICAgICAgICByZWxlYXNlLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIHR5cGU9ImFkZCIgZGF0ZT0iMjAxNC0xMi0yNCIKKyAgICAgICAgICAgICAgZHVlLXRvPSJLcmlzdGlhbiBSb3NlbnZvbGQiPgorICAgICAgICBDdXQgb3ZlcmFsbCBvYmplY3QgaW5zdGFudGlhdGlvbiBpbiBoYWxmIGJ5IGNoYW5naW5nIGZpbGUKKyAgICAgICAgaGVhZGVyIGdlbmVyYXRpb24gYWxnb3JpdGhtLCBmb3IgYSAxMC0xNSBwZXJjZW50IHBlcmZvcm1hbmNlCisgICAgICAgIGltcHJvdmVtZW50LgorCisgICAgICAgIEFsc28gZXh0cmFjdGVkIHR3byBwcml2YXRlIG1ldGhvZHMgY3JlYXRlTG9jYWxGaWxlSGVhZGVyCisgICAgICAgIGFuZCBjcmVhdGVDZW50cmFsRmlsZUhlYWRlciBpbiBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtLgorICAgICAgICBUaGVzZSBtYXkgaGF2ZSBzb21lIGludGVyZXN0aW5nIGFkZGl0aW9uYWwgdXNhZ2VzIGluIHRoZQorICAgICAgICBuZWFyIGZ1dHVyZS4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtMjk3IiB0eXBlPSJmaXgiIGRhdGU9IjIwMTQtMTItMjIiPgorICAgICAgICBaaXBGaWxlIGxvZ3MgYSB3YXJuaW5nIGluIGl0cyBmaW5hbGl6ZXIgd2hlbiBpdHMgY29uc3RydWN0b3IKKyAgICAgICAgaGFzIHRocm93biBhbiBleGNlcHRpb24gcmVhZGluZyB0aGUgZmlsZSAtIGZvciBleGFtcGxlIGlmIHRoZQorICAgICAgICBmaWxlIGRvZXNuJ3QgZXhpc3QuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTI5NSIgdHlwZT0iYWRkIiBkYXRlPSIyMDE0LTEyLTE4IgorICAgICAgICAgICAgICBkdWUtdG89IktyaXN0aWFuIFJvc2Vudm9sZCI+CisgICAgICAgIE5ldyBtZXRob2RzIGluIFppcEFyY2hpdmVPdXRwdXRTdHJlYW0gYW5kIFppcEZpbGUgYWxsb3dzCisgICAgICAgIGVudHJpZXMgdG8gYmUgY29waWVkIGZyb20gb25lIGFyY2hpdmUgdG8gYW5vdGhlciB3aXRob3V0CisgICAgICAgIGhhdmluZyB0byByZS1jb21wcmVzcyB0aGVtLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIHR5cGU9InVwZGF0ZSIgZGF0ZT0iMjAxNC0xMC0yOCIKKyAgICAgICAgICAgICAgZHVlLXRvPSJEYW1qYW4gSm92YW5vdmljIj4KKyAgICAgICAgTW92ZWQgdGhlIHBhY2thZ2UKKyAgICAgICAgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLnouX2ludGVybmFsXyB0bworICAgICAgICBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMubHp3IGFuZCBtYWRlIGl0IHBhcnQKKyAgICAgICAgb2YgdGhlIEFQSSB0aGF0IGlzIG9mZmljaWFsbHkgc3VwcG9ydGVkLiAgVGhpcyB3aWxsIGJyZWFrCisgICAgICAgIGV4aXN0aW5nIGNvZGUgdGhhdCB1c2VzIHRoZSBvbGQgcGFja2FnZS4KKyAgICAgIDwvYWN0aW9uPgorICAgIDwvcmVsZWFzZT4KKworICAgIDxyZWxlYXNlIHZlcnNpb249IjEuOSIgZGF0ZT0iMjAxNC0xMC0wOSIKKyAgICAgICAgICAgICBkZXNjcmlwdGlvbj0iUmVsZWFzZSAxLjkiPgorICAgICAgPGFjdGlvbiB0eXBlPSJhZGQiIGRhdGU9IjIwMTQtMDYtMTQiIGlzc3VlPSJDT01QUkVTUy0yNjMiCisgICAgICAgICAgICAgIGR1ZS10bz0iTWF0dGhpYXMgU3RldmVucyI+CisgICAgICAgIEFkZGVkIHN1cHBvcnQgZm9yIERFRkxBVEUgc3RyZWFtcyB3aXRob3V0IGFueSBnemlwIGZyYW1pbmcuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gdHlwZT0iZml4IiBkYXRlPSIyMDE0LTA4LTE0IiBpc3N1ZT0iQ09NUFJFU1MtMjg3Ij4KKyAgICAgICAgV2hlbiByZWFkaW5nIDd6IGZpbGVzIHVua25vd24gZmlsZSBwcm9wZXJ0aWVzIGFuZCBwcm9wZXJ0aWVzCisgICAgICAgIG9mIHR5cGUga0R1bW15IGFyZSBub3cgaWdub3JlZC4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiB0eXBlPSJmaXgiIGRhdGU9IjIwMTQtMDgtMjEiIGlzc3VlPSJDT01QUkVTUy0yODYiPgorICAgICAgICBFeHBhbmRpbmcgN3ogYXJjaGl2ZXMgdXNpbmcgTFpNQSBjb21wcmVzc2lvbiBjb3VsZCBjYXVzZSBhbgorICAgICAgICBFT0ZFeGNlcHRpb24uCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gdHlwZT0idXBkYXRlIiBkYXRlPSIyMDE0LTA4LTMxIiBpc3N1ZT0iQ09NUFJFU1MtMjg1Ij4KKyAgICAgICAgQ2hlY2tpbmcgZm9yIFhaIGZvciBKYXZhIG1heSBiZSBleHBlbnNpdmUuICBUaGUgcmVzdWx0IHdpbGwKKyAgICAgICAgbm93IGJlIGNhY2hlZCBvdXRzaWRlIG9mIGFuIE9TR2kgZW52aXJvbm1lbnQuICBZb3UgY2FuIHVzZSB0aGUKKyAgICAgICAgbmV3IFhaVXRpbHMjc2V0Q2FjaGVYWkF2YWlsYWJpbGl0eSB0byBvdmVycnJpZGUgdGhpcyBkZWZhdWx0CisgICAgICAgIGJlaGF2aW9yLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIHR5cGU9ImZpeCIgZGF0ZT0iMjAxNC0wOS0xOSIgaXNzdWU9IkNPTVBSRVNTLTI4OSIKKyAgICAgICAgICAgICAgZHVlLXRvPSJCb2IgUm9iZXJ0c29uIj4KKyAgICAgICAgTG9uZy1OYW1lIGFuZCAtbGluayBvciBQQVgtaGVhZGVyIGVudHJpZXMgaW4gVEFSIGFyY2hpdmVzCisgICAgICAgIGFsd2F5cyBoYWQgdGhlIGN1cnJlbnQgdGltZSBhcyBsYXN0IG1vZGZpY2F0aW9uIHRpbWUsIGNyZWF0aW5nCisgICAgICAgIGFyY2hpdmVzIHRoYXQgYXJlIGRpZmZlcmVudCBhdCB0aGUgYnl0ZSBsZXZlbCBlYWNoIHRpbWUgYW4KKyAgICAgICAgYXJjaGl2ZSB3YXMgYnVpbHQuCisgICAgICA8L2FjdGlvbj4KKyAgICA8L3JlbGVhc2U+CisKKyAgICA8cmVsZWFzZSB2ZXJzaW9uPSIxLjguMSIgZGF0ZT0iMjAxNC0wNS0xNCIKKyAgICAgICAgICAgICBkZXNjcmlwdGlvbj0iUmVsZWFzZSAxLjguMSI+CisgICAgICA8YWN0aW9uIHR5cGU9InVwZGF0ZSIgZGF0ZT0iMjAxNC0wMy0xOSI+CisgICAgICAgIFRoZSBkZXBlbmRlbmN5IG9uIG9yZy50dWthYW5pOnh6IGlzIG5vdyBtYXJrZWQgYXMgb3B0aW9uYWwuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gdHlwZT0iZml4IiBkYXRlPSIyMDE0LTAzLTI4IiBpc3N1ZT0iQ09NUFJFU1MtMjcwIj4KKyAgICAgICAgVGhlIHNuYXBweSwgYXIgYW5kIHRhciBpbnB1dHN0cmVhbXMgbWlnaHQgZmFpbCB0byByZWFkIGZyb20gYQorICAgICAgICBub24tYnVmZmVyZWQgc3RyZWFtIGluIGNlcnRhaW4gY2FzZXMuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gdHlwZT0iYWRkIiBkYXRlPSIyMDE0LTA0LTEyIiBpc3N1ZT0iQ09NUFJFU1MtMjcyIj4KKyAgICAgICAgQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkgY2FuIG5vdyBhdXRvLWRldGVjdCBVbml4IGNvbXByZXNzCisgICAgICAgICgiLloiKSBzdHJlYW1zLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIHR5cGU9ImZpeCIgZGF0ZT0iMjAxNC0wNC0xMiIgaXNzdWU9IkNPTVBSRVNTLTI3NyI+CisgICAgICAgIElPVXRpbHMjc2tpcCBtaWdodCBza2lwIGZld2VyIGJ5dGVzIHRoYW4gcmVxdWVzdGVkIGV2ZW4gdGhvdWdoCisgICAgICAgIG1vcmUgY291bGQgYmUgcmVhZCBmcm9tIHRoZSBzdHJlYW0uCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gdHlwZT0iZml4IiBkYXRlPSIyMDE0LTA0LTEzIiBpc3N1ZT0iQ09NUFJFU1MtMjc2Ij4KKyAgICAgICAgQXJjaGl2ZVN0cmVhbXMgbm93IHZhbGlkYXRlIHRoZXJlIGlzIGEgY3VycmVudCBlbnRyeSBiZWZvcmUKKyAgICAgICAgcmVhZGluZyBvciB3cml0aW5nIGVudHJ5IGRhdGEuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gdHlwZT0iZml4IiBkYXRlPSIyMDE0LTA0LTEzIj4KKyAgICAgICAgQXJqQXJjaGl2ZUlucHV0U3RyZWFtI2NhblJlYWRFbnRyeURhdGEgdGVzdGVkIHRoZSBjdXJyZW50CisgICAgICAgIGVudHJ5IG9mIHRoZSBzdHJlYW0gcmF0aGVyIHRoYW4gaXRzIGFyZ3VtZW50LgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIHR5cGU9ImZpeCIgZGF0ZT0iMjAxNC0wNC0xMyIgaXNzdWU9IkNPTVBSRVNTLTI3NCI+CisgICAgICAgIENoYW5nZVNldCNkZWxldGUgYW5kIGRlbGV0ZURpciBub3cgcHJvcGVybHkgZGVhbCB3aXRoIHVubmFtZWQKKyAgICAgICAgZW50cmllcy4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiB0eXBlPSJmaXgiIGRhdGU9IjIwMTQtMDQtMTgiIGlzc3VlPSJDT01QUkVTUy0yNzMiPgorICAgICAgICBBZGRlZCBhIGZldyBudWxsIGNoZWNrcyB0byBpbXByb3ZlIHJvYnVzdG5lc3MuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gdHlwZT0iZml4IiBkYXRlPSIyMDE0LTA0LTE5IiBpc3N1ZT0iQ09NUFJFU1MtMjc4Ij4KKyAgICAgICAgVGFyQXJjaGl2ZUlucHV0U3RyZWFtIGZhaWxlZCB0byByZWFkIGFyY2hpdmVzIHdpdGggZW1wdHkKKyAgICAgICAgZ2lkL3VpZCBmaWVsZHMuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gdHlwZT0iZml4IiBkYXRlPSIyMDE0LTA0LTI3IiBpc3N1ZT0iQ09NUFJFU1MtMjc5Ij4KKyAgICAgICAgVGFyQXJjaGl2ZUlucHV0U3RyZWFtIG5vdyBhZ2FpbiB0aHJvd3MgYW4gZXhjZXB0aW9uIHdoZW4gaXQKKyAgICAgICAgZW5jb3VudGVycyBhIHRydW5jYXRlZCBhcmNoaXZlIHdoaWxlIHJlYWRpbmcgZnJvbSB0aGUgbGFzdAorICAgICAgICBlbnRyeS4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiB0eXBlPSJmaXgiIGRhdGU9IjIwMTQtMDUtMDIiIGlzc3VlPSJDT01QUkVTUy0yODAiCisgICAgICAgICAgICAgIGR1ZS10bz0iQkVMVUdBIEJFSFIiPgorICAgICAgICBBZGFwdGVkIFRhckFyY2hpdmVJbnB1dFN0cmVhbSNza2lwIHRvIHRoZSBtb2RpZmllZAorICAgICAgICBJT1V0aWxzI3NraXAgbWV0aG9kLgorICAgICAgPC9hY3Rpb24+CisgICAgPC9yZWxlYXNlPgorICAgIDxyZWxlYXNlIHZlcnNpb249IjEuOCIgZGF0ZT0iMjAxNC0wMy0xMiIKKyAgICAgICAgICAgICBkZXNjcmlwdGlvbj0iUmVsZWFzZSAxLjgiPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtMjUzIiB0eXBlPSJmaXgiIGRhdGU9IjIwMTQtMDEtMjAiPgorICAgICAgICBCWmlwMkNvbXByZXNzb3JJbnB1dFN0cmVhbSByZWFkIGZld2VyIGJ5dGVzIHRoYW4gcG9zc2libGUgZnJvbQorICAgICAgICBhIHRydW5jYXRlZCBzdHJlYW0uCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTI1MyIgdHlwZT0iZml4IiBkYXRlPSIyMDE0LTAxLTIyIj4KKyAgICAgICAgU2V2ZW5aRmlsZSBmYWlsZWQgY2xhaW1pbmcgdGhlIGRpY3Rpb25hcnkgd2FzIHRvbyBsYXJnZSB3aGVuCisgICAgICAgIGFyY2hpdmVzIHVzZWQgTFpNQSBjb21wcmVzc2lvbiBmb3IgaGVhZGVycyBhbmQgY29udGVudCBhbmQKKyAgICAgICAgY2VydGFpbiBub24tZGVmYXVsdCBkaWN0aW9uYXJ5IHNpemVzLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0yNTkiIHR5cGU9ImZpeCIgZGF0ZT0iMjAxNC0wMS0yNCI+CisgICAgICAgIENvbXByZXNzb3JTdHJlYW1GYWN0b3J5LmNyZWF0ZUNvbXByZXNzb3JJbnB1dFN0cmVhbSB3aXRoCisgICAgICAgIGV4cGxpY2l0IGNvbXByZXNzaW9uIGRpZCBub3QgaG9ub3IgZGVjb21wcmVzc0NvbmNhdGVuYXRlZAorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0yNjAiIHR5cGU9ImFkZCIgZGF0ZT0iMjAxNC0wMi0yMCI+CisgICAgICAgIEd6aXBDb21wcmVzc29ySW5wdXRTdHJlYW0gbm93IHByb3ZpZGVzIGFjY2VzcyB0byB0aGUgc2FtZQorICAgICAgICBtZXRhZGF0YSB0aGF0IGNhbiBiZSBwcm92aWRlZCB2aWEgR3ppcFBhcmFtZXRlcnMgd2hlbiB3cml0aW5nCisgICAgICAgIGEgZ3ppcCBzdHJlYW0uCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTI2MiIgdHlwZT0iZml4IiBkYXRlPSIyMDE0LTAyLTIxIj4KKyAgICAgICAgVGFyQXJjaGl2ZUlucHV0U3RyZWFtIHdpbGwgbm93IHJlYWQgYXJjaGl2ZXMgY3JlYXRlZCBieSB0YXIKKyAgICAgICAgaW1wbGVtZW50YXRpb25zIHRoYXQgZW5jb2RlIGJpZyBudW1iZXJzIGJ5IG5vdCBhZGRpbmcgYQorICAgICAgICB0cmFpbGluZyBOVUwuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTI2NCIgdHlwZT0iZml4IiBkYXRlPSIyMDE0LTAyLTIxIj4KKyAgICAgICAgWmlwQXJjaGl2ZUlucHV0U3RyZWFtIHdvdWxkIHJldHVybiBOVUwgYnl0ZXMgZm9yIHRoZSBmaXJzdCA1MTIKKyAgICAgICAgYnl0ZXMgb2YgYSBTVE9SRUQgZW50cnkgaWYgaXQgd2FzIHRoZSB2ZXJ5IGZpcnN0IGVudHJ5IG9mIHRoZQorICAgICAgICBhcmNoaXZlLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0yNjUiIHR5cGU9ImZpeCIgZGF0ZT0iMjAxNC0wMi0yMiI+CisgICAgICAgIFdoZW4gd3JpdGluZyBQQVgvUE9TSVggaGVhZGVycyBmb3IgVEFSIGVudHJpZXMgd2l0aAorICAgICAgICBiYWNrc2xhc2hlcyBvciBjZXJ0YWluIG5vbi1BU0NJSSBjaGFyYWN0ZXJzIGluIHRoZWlyIG5hbWUKKyAgICAgICAgVGFyQXJjaGl2ZU91dHB1dFN0cmVhbSBjb3VsZCBmYWlsLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0yNjciIHR5cGU9ImZpeCIgZGF0ZT0iMjAxNC0wMi0yMiI+CisgICAgICAgIEFyY2hpdmVTdHJlYW1GYWN0b3J5IG5vdyB0aHJvd3MgYSBTdHJlYW1pbmdOb3RTdXBwb3J0ZWQgLSBhCisgICAgICAgIG5ldyBzdWJjbGFzcyBvZiBBcmNoaXZlRXhjZXB0aW9uIC0gaWYgaXQgaXMgYXNrZWQgdG8gcmVhZCBmcm9tCisgICAgICAgIG9yIHdyaXRlIHRvIGEgc3RyZWFtIGFuZCBDb21tb25zIENvbXByZXNzIGRvZXNuJ3Qgc3VwcG9ydAorICAgICAgICBzdHJlYW1pbmcgZm9yIHRoZSBmb3JtYXQuICBUaGlzIGN1cnJlbnRseSBvbmx5IGFwcGxpZXMgdG8gdGhlCisgICAgICAgIDd6IGZvcm1hdC4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtMjY2IiB0eXBlPSJhZGQiIGRhdGU9IjIwMTQtMDItMjUiPgorICAgICAgICBTZXZlblpPdXRwdXRGaWxlIG5vdyBzdXBwb3J0cyBjaGFpbmluZyBtdWx0aXBsZQorICAgICAgICBjb21wcmVzc2lvbi9lbmNyeXB0aW9uL2ZpbHRlciBtZXRob2RzIGFuZCBwYXNzaW5nIG9wdGlvbnMgdG8KKyAgICAgICAgdGhlIG1ldGhvZHMuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTI2MSIgdHlwZT0iYWRkIiBkYXRlPSIyMDE0LTAyLTI2Ij4KKyAgICAgICAgVGhlIChjb21wcmVzc2lvbikgbWV0aG9kKHMpIGNhbiBub3cgYmUgc3BlY2lmaWVkIHBlciBlbnRyeSBpbgorICAgICAgICBTZXZlblpPdXRwdXRGaWxlLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0yNTgiIHR5cGU9ImFkZCIgZGF0ZT0iMjAxNC0wMi0yNiI+CisgICAgICAgIFNldmVuWkFyY2hpdmVFbnRyeSAia25vd3MiIHdoaWNoIG1ldGhvZChzKSBoYXZlIGJlZW4gdXNlZCB0bworICAgICAgICB3cml0ZSBpdCB0byB0aGUgYXJjaGl2ZS4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiB0eXBlPSJhZGQiIGRhdGU9IjIwMTQtMDItMjgiPgorICAgICAgICBUaGUgN3ogcGFja2FnZSBub3cgc3VwcG9ydHMgdGhlIGRlbHRhIGZpbHRlciBhcyBtZXRob2QuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTI1NyIgdHlwZT0iYWRkIiBkYXRlPSIyMDE0LTAzLTAzIj4KKyAgICAgICAgVGhlIDd6IHBhY2thZ2Ugbm93IHN1cHBvcnRzIEJDSiBmaWx0ZXJzIGZvciBzZXZlcmFsIHBsYXRmb3Jtcy4KKyAgICAgICAgWW91IHdpbGwgbmVlZCBhIHZlcnNpb24gJmd0Oz0gMS41IG9mIFhaIGZvciBKYXZhIHRvIHJlYWQgYXJjaGl2ZXMKKyAgICAgICAgdXNpbmcgQkNKLCB0aG91Z2guCisgICAgICA8L2FjdGlvbj4KKyAgICA8L3JlbGVhc2U+CisgICAgPHJlbGVhc2UgdmVyc2lvbj0iMS43IiBkYXRlPSIyMDE0LTAxLTIwIgorICAgICAgICAgICAgIGRlc2NyaXB0aW9uPSJSZWxlYXNlIDEuNyI+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0yNDEiIHR5cGU9ImZpeCIgZGF0ZT0iMjAxMy0xMC0yNyI+CisgICAgICAgIFNldmVuWk91dHB1dEZpbGUjY2xvc2VBcmNoaXZlRW50cnkgdGhyb3dzIGFuIGV4Y2VwdGlvbiB3aGVuCisgICAgICAgIHVzaW5nIExaTUEyIGNvbXByZXNzaW9uIG9uIEphdmE4LgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0xNDciIHR5cGU9ImFkZCIgZGF0ZT0iMjAxMy0xMS0wNyIKKyAgICAgICAgICAgICAgZHVlLXRvPSJCRUxVR0EgQkVIUiI+CisgICAgICAgIFJlYWQtT25seSBzdXBwb3J0IGZvciBTbmFwcHkgY29tcHJlc3Npb24uCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTI0NCIgdHlwZT0iZml4IiBkYXRlPSIyMDEzLTExLTI3IgorICAgICAgICAgICAgICBkdWUtdG89Ik5pY28gS3J1YmVyIj4KKyAgICAgICAgN3ogcmVhZGluZyBvZiBiaWcgNjRiaXQgdmFsdWVzIGNvdWxkIGJlIHdyb25nLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0yNDMiIHR5cGU9ImFkZCIgZGF0ZT0iMjAxMy0xMS0zMCIKKyAgICAgICAgICAgICAgZHVlLXRvPSJEYW1qYW4gSm92YW5vdmljIj4KKyAgICAgICAgUmVhZC1Pbmx5IHN1cHBvcnQgZm9yIC5aIGNvbXByZXNzZWQgZmlsZXMuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gdHlwZT0iYWRkIiBkYXRlPSIyMDEzLTEyLTA2IiBkdWUtdG89IkRhbWphbiBKb3Zhbm92aWMiPgorICAgICAgICBaaXBGaWxlIGFuZCBaaXBBcmNoaXZlSW5wdXRTdHJlYW0gbm93IHN1cHBvcnQgcmVhZGluZyBlbnRyaWVzIGNvbXByZXNzZWQgdXNpbmcgdGhlCisgICAgICAgIFNIUklOS0lORyBtZXRob2QuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTI0NSIgdHlwZT0iZml4IiBkYXRlPSIyMDEzLTEyLTA2Ij4KKyAgICAgICAgVGFyQXJjaGl2ZUlucHV0U3RyZWFtIGNvdWxkIGZhaWwgdG8gcmVhZCBhbiBhcmNoaXZlIGNvbXBsZXRlbHkuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTI0MiIgdHlwZT0iZml4IiBkYXRlPSIyMDEzLTEyLTA4Ij4KKyAgICAgICAgVGhlIHRpbWUtc2V0dGVycyBpbiBYNTQ1NV9FeHRlbmRlZFRpbWVzdGFtcCBub3cgc2V0IHRoZQorICAgICAgICBjb3JyZXNwb25kaW5nIGZsYWdzIGV4cGxpY2l0bHkgLSBpLmUuIHRoZXkgc2V0IHRoZSBiaXQgaWYgdGhlCisgICAgICAgIHZhbHVzIGlzIG5vdC1udWxsIGFuZCByZXNldCBpdCBvdGhlcndpc2UuICBUaGlzIG1heSBjYXVzZQorICAgICAgICBpbmNvbXBhdGliaWxpdGllcyBpZiB5b3UgdXNlIHNldEZsYWdzIHRvIHVuc2V0IGEgYml0IGFuZCBsYXRlcgorICAgICAgICBzZXQgdGhlIHRpbWUgdG8gYSBub24tbnVsbCB2YWx1ZSAtIHRoZSBmbGFnIHdpbGwgbm93IGJlIHNldC4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtMjUwIiB0eXBlPSJhZGQiIGRhdGU9IjIwMTMtMTItMTYiIGR1ZS10bz0iRW1tYW51ZWwgQm91cmciPgorICAgICAgICBHemlwQ29tcHJlc3Nvck91dHB1dFN0cmVhbSBub3cgc3VwcG9ydHMgc2V0dGluZyB0aGUgY29tcHJlc3Npb24gbGV2ZWwgYW5kIHRoZSBoZWFkZXIgbWV0YWRhdGEKKyAgICAgICAgKGZpbGVuYW1lLCBjb21tZW50LCBtb2RpZmljYXRpb24gdGltZSwgb3BlcmF0aW5nIHN5c3RlbSBhbmQgZXh0cmEgZmxhZ3MpCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTExNSIgdHlwZT0iYWRkIiBkYXRlPSIyMDEzLTEyLTE5IiBkdWUtdG89IkVtbWFudWVsIEJvdXJnIj4KKyAgICAgICAgWmlwRmlsZSBhbmQgWmlwQXJjaGl2ZUlucHV0U3RyZWFtIG5vdyBzdXBwb3J0IHJlYWRpbmcgZW50cmllcyBjb21wcmVzc2VkIHVzaW5nIHRoZSBJTVBMT0RFIG1ldGhvZC4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtMjUyIiB0eXBlPSJmaXgiIGRhdGU9IjIwMTMtMTItMjAiPgorICAgICAgICBTZXZlblpPdXRwdXRGaWxlIHdvdWxkIGNyZWF0ZSBpbnZhbGlkIGFyY2hpdmVzIGlmIG1vcmUgdGhhbgorICAgICAgICBzaXggZW1wdHkgZmlsZXMgb3IgZGlyZWN0b3JpZXMgd2VyZSBpbmNsdWRlZC4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiB0eXBlPSJhZGQiIGRhdGU9IjIwMTMtMTItMjAiPgorICAgICAgICBaaXBGaWxlIGFuZCB0aGUgN3ogZmlsZSBjbGFzc2VzIG5vdyBpbXBsZW1lbnQgQ2xvc2VhYmxlIGFuZAorICAgICAgICBjYW4gYmUgdXNlZCBpbiB0cnktd2l0aC1yZXNvdXJjZXMgY29uc3RydWN0cy4KKyAgICAgIDwvYWN0aW9uPgorICAgIDwvcmVsZWFzZT4KKyAgICA8cmVsZWFzZSB2ZXJzaW9uPSIxLjYiIGRhdGU9IjIwMTMtMTAtMjYiCisgICAgICAgICAgICAgZGVzY3JpcHRpb249IlJlbGVhc2UgMS42Ij4KKyAgICAgIDxhY3Rpb24gdHlwZT0iZml4IiBkYXRlPSIyMDEzLTA0LTI1IiBpc3N1ZT0iQ09NUFJFU1MtMjIzIgorICAgICAgICAgICAgICBkdWUtdG89IkplcmVteSBHdXN0aWUiPgorICAgICAgICBUYXJCdWZmZXIudHJ5VG9Db25zdW1lU2Vjb25kRU9GUmVjb3JkIGNvdWxkIHRocm93IGEKKyAgICAgICAgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiB0eXBlPSJhZGQiIGRhdGU9IjIwMTMtMDUtMDciIGlzc3VlPSJDT01QUkVTUy01NCIKKyAgICAgICAgICAgICAgZHVlLXRvPSJEYW1qYW4gSm92YW5vdmljIj4KKyAgICAgICAgQWRkZWQgc3VwcG9ydCBmb3IgN3ogYXJjaGl2ZXMuICBNb3N0IGNvbXByZXNzaW9uIGFsZ29yaXRobXMKKyAgICAgICAgY2FuIGJlIHJlYWQgYW5kIHdyaXR0ZW4sIExaTUEgYW5kIGVuY3J5cHRpb24gYXJlIG9ubHkKKyAgICAgICAgc3VwcG9ydGVkIHdoZW4gcmVhZGluZy4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiB0eXBlPSJhZGQiIGRhdGU9IjIwMTMtMDUtMTkiIGlzc3VlPSJDT01QUkVTUy0yMjYiCisgICAgICAgICAgICAgIGR1ZS10bz0iRGFtamFuIEpvdmFub3ZpYyI+CisgICAgICAgIEFkZGVkIHJlYWQtb25seSBzdXBwb3J0IGZvciBBUkogYXJjaGl2ZXMgdGhhdCBkb24ndCB1c2UKKyAgICAgICAgY29tcHJlc3Npb24uCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gdHlwZT0iZml4IiBkYXRlPSIyMDEzLTA1LTI2IiBpc3N1ZT0iQ09NUFJFU1MtMjI4Ij4KKyAgICAgICAgUGFyc2luZyBvZiB6aXA2NCBleHRyYSBmaWVsZHMgaGFzIGJlY29tZSBtb3JlIGxlbmllbnQgaW4gb3JkZXIKKyAgICAgICAgdG8gYmUgYWJsZSB0byByZWFkIGFyY2hpdmVzIGNyZWF0ZWQgYnkgRG90TmV0WmlwIGFuZCBtYXliZQorICAgICAgICBvdGhlciBhcmNoaXZlcnMgYXMgd2VsbC4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiB0eXBlPSJmaXgiIGRhdGU9IjIwMTMtMDYtMDMiIGlzc3VlPSJDT01QUkVTUy0yMjkiCisgICAgICAgICAgICAgIGR1ZS10bz0iQ2hyaXN0b3BoIEd5c2luIj4KKyAgICAgICAgVEFSIHdpbGwgbm93IHByb3Blcmx5IHJlYWQgdGhlIG5hbWVzIG9mIHN5bWJvbGljIGxpbmtzIHdpdGgKKyAgICAgICAgbG9uZyBuYW1lcyB0aGF0IHVzZSB0aGUgR05VIHZhcmlhbnQgdG8gc3BlY2lmeSB0aGUgbG9uZyBmaWxlCisgICAgICAgIG5hbWUuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gdHlwZT0iZml4IiBkYXRlPSIyMDEzLTA2LTA0IiBpc3N1ZT0iQ09NUFJFU1MtMjI3Ij4KKyAgICAgICAgWmlwRmlsZSNnZXRJbnB1dFN0cmVhbSBjb3VsZCByZXR1cm4gbnVsbCBpZiB0aGUgYXJjaGl2ZQorICAgICAgICBjb250YWluZWQgZHVwbGljYXRlIGVudHJpZXMuCisgICAgICAgIFRoZSBjbGFzcyBub3cgYWxzbyBwcm92aWRlcyB0d28gbmV3IG1ldGhvZHMgdG8gb2J0YWluIGFsbAorICAgICAgICBlbnRyaWVzIG9mIGEgZ2l2ZW4gbmFtZSByYXRoZXIgdGhhbiBqdXN0IHRoZSBmaXJzdCBvbmUuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gdHlwZT0idXBkYXRlIiBkYXRlPSIyMDEzLTA3LTA4IiBpc3N1ZT0iQ09NUFJFU1MtMjMyIgorICAgICAgICAgICAgICBkdWUtdG89IkJFTFVHQSBCRUhSIj4KKyAgICAgICAgUmVhZGFiaWx0eSBwYXRjaCB0byBUYXJBcmNoaXZlSW5wdXRTdHJlYW0uCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gdHlwZT0idXBkYXRlIiBkYXRlPSIyMDEzLTA4LTA4IiBpc3N1ZT0iQ09NUFJFU1MtMjM0IgorICAgICAgICAgICAgICBkdWUtdG89IkJFTFVHQSBCRUhSIj4KKyAgICAgICAgUGVyZm9ybWFuY2UgaW1wcm92ZW1lbnRzIHRvIFRhckFyY2hpdmVJbnB1dFN0cmVhbSwgaW4KKyAgICAgICAgcGFydGljdWxhciB0byB0aGUgc2tpcCBtZXRob2QuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gdHlwZT0iZml4IiBkYXRlPSIyMDEzLTA4LTA4IiBpc3N1ZT0iQ09NUFJFU1MtMjM2IgorICAgICAgICAgICAgICBkdWUtdG89IkFuZHJldyBEdWZmeSI+CisgICAgICAgIENwaW9BcmNoaXZlSW5wdXRTdHJlYW0gZmFpbGVkIHRvIHJlYWQgYXJjaGl2ZXMgY3JlYXRlZCBieQorICAgICAgICBSZWRsaW5lIFJQTS4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiB0eXBlPSJmaXgiIGRhdGU9IjIwMTMtMDgtMDkiIGlzc3VlPSJDT01QUkVTUy0yMzciCisgICAgICAgICAgICAgIGR1ZS10bz0iRW1tYW51ZWwgQm91cmciPgorICAgICAgICBUYXJBcmNoaXZlT3V0cHV0U3RyZWFtIG5vdyBwcm9wZXJseSBoYW5kbGVzIGxpbmsgbmFtZXMgdGhhdAorICAgICAgICBhcmUgdG9vIGxvbmcgdG8gZml0IGludG8gYSB0cmFkaXRpb25hbCBUQVIgaGVhZGVyLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIHR5cGU9ImFkZCIgZGF0ZT0iMjAxMy0wOC0xMCI+CisgICAgICAgIER1bXBBcmNoaXZlSW5wdXRTdHJlYW0gbm93IHN1cHBvcnRzIGFuIGVuY29kaW5nIHBhcmFtZXRlciB0aGF0CisgICAgICAgIGNhbiBiZSB1c2VkIHRvIHNwZWNpZnkgdGhlIGVuY29kaW5nIG9mIGZpbGUgbmFtZXMuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gdHlwZT0iYWRkIiBkYXRlPSIyMDEzLTA4LTEwIj4KKyAgICAgICAgVGhlIENQSU8gc3RyZWFtcyBub3cgc3VwcG9ydCBhbiBlbmNvZGluZyBwYXJhbWV0ZXIgdGhhdCBjYW4gYmUKKyAgICAgICAgdXNlZCB0byBzcGVjaWZ5IHRoZSBlbmNvZGluZyBvZiBmaWxlIG5hbWVzLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIHR5cGU9ImFkZCIgZGF0ZT0iMjAxMy0wOS0yMiIgaXNzdWU9IkNPTVBSRVNTLTExMSI+CisgICAgICAgIFJlYWQtb25seSBzdXBwb3J0IGZvciBMWk1BIHN0YW5kYWxvbmUgY29tcHJlc3Npb24gaGFzIGJlZW4gYWRkZWQuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gdHlwZT0iZml4IiBkYXRlPSIyMDEzLTEwLTA0IiBpc3N1ZT0iQ09NUFJFU1MtMjM5Ij4KKyAgICAgICAgVGhlIGF1dG8tZGV0ZWN0aW5nIGNyZWF0ZSpJbnB1dFN0cmVhbSBtZXRob2RzIG9mIEFyY2hpdmUgYW5kCisgICAgICAgIENvbXByZXNzb3JTdHJlYW1GYWN0b3J5IGNvdWxkIGZhaWwgdG8gZGV0ZWN0IHRoZSBmb3JtYXQgb2YKKyAgICAgICAgYmxvY2tpbmcgaW5wdXQgc3RyZWFtcy4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiB0eXBlPSJmaXgiIGRhdGU9IjIwMTMtMTAtMjEiIGlzc3VlPSJDT01QUkVTUy0yNDAiCisgICAgICAgICAgICAgIGR1ZS10bz0iR2FyeSBHcmVnb3J5Ij4KKyAgICAgICAgWmlwRW5jb2RpbmdIZWxwZXIuaXNVVEY4KFN0cmluZykgZG9lcyBub3QgY2hlY2sgYWxsIFVURi04IGFsaWFzZXMuCisgICAgICA8L2FjdGlvbj4KKyAgICA8L3JlbGVhc2U+CisgICAgPHJlbGVhc2UgdmVyc2lvbj0iMS41IiBkYXRlPSIyMDEzLTAzLTE0IgorICAgICAgICAgICAgIGRlc2NyaXB0aW9uPSJSZWxlYXNlIDEuNSI+CisgICAgICA8YWN0aW9uIHR5cGU9ImZpeCIgZGF0ZT0iMjAxMi0wMi0xOSIgaXNzdWU9IkNPTVBSRVNTLTIxOCIKKyAgICAgICAgICAgICAgZHVlLXRvPSJHaWxpIj4KKyAgICAgICAgVHlwbyBpbiBDb21wcmVzc29yU3RyZWFtRmFjdG9yeSBKYXZhZG9jCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gdHlwZT0idXBkYXRlIiBkYXRlPSIyMDEyLTA3LTA4IiBpc3N1ZT0iQ09NUFJFU1MtMTg4IgorICAgICAgICAgICAgICBkdWUtdG89IkhhcmFsZCBLdWhuIj4KKyAgICAgICAgSW1wcm92ZWQgZXhjZXB0aW9uIG1lc3NhZ2UgaWYgYSB6aXAgYXJjaGl2ZSBjYW5ub3QgYmUgcmVhZAorICAgICAgICBiZWNhdXNlIG9mIGFuIHVuc3VwcG9ydGVkIGNvbXByZXNzaW9uIG1ldGhvZC4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiB0eXBlPSJ1cGRhdGUiIGRhdGU9IjIwMTItMDctMDciIGlzc3VlPSJDT01QUkVTUy0xOTIiCisgICAgICAgICAgICAgIGR1ZS10bz0iSnVra2EgWml0dGluZyI+CisgICAgICAgIEFyY2hpdmVTdHJlYW1GYWN0b3J5IGhhcyBhIHNldHRpbmcgZm9yIGZpbGUgbmFtZSBlbmNvZGluZyB0aGF0CisgICAgICAgIHNldHMgdXAgZW5jb2RpbmcgZm9yIFpJUCBhbmQgVEFSIHN0cmVhbXMuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gdHlwZT0iZml4IiBkYXRlPSIyMDEyLTA3LTA3IiBpc3N1ZT0iQ09NUFJFU1MtMTkxIgorICAgICAgICAgICAgICBkdWUtdG89Ikp1a2thIFppdHRpbmciPgorICAgICAgICBBcmNoaXZlU3RyZWFtRmFjdG9yeSdzIHRhciBzdHJlYW0gZGV0ZWN0aW9uIGNyZWF0ZWQgZmFsc2UKKyAgICAgICAgcG9zaXRpdmVzIGZvciBBSUZGIGZpbGVzLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIHR5cGU9InVwZGF0ZSIgZGF0ZT0iMjAxMi0wNy0wNyIgaXNzdWU9IkNPTVBSRVNTLTE5MSIKKyAgICAgICAgICAgICAgZHVlLXRvPSJKdWtrYSBaaXR0aW5nIj4KKyAgICAgICAgVGFyQXJjaGl2ZUVudHJ5IG5vdyBoYXMgYSBtZXRob2QgdG8gdmVyaWZ5IGl0cyBjaGVja3N1bS4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiB0eXBlPSJmaXgiIGRhdGU9IjIwMTItMTItMjciIGlzc3VlPSJDT01QUkVTUy0xOTkiCisgICAgICAgICAgICAgIGR1ZS10bz0iSnVra2EgWml0dGluZyI+CisgICAgICAgIFhaIGZvciBKYXZhIGRpZG4ndCBwcm92aWRlIGFuIE9TR2kgYnVuZGxlLiAgQ29tcHJlc3MnCisgICAgICAgIGRlcGVuZGVuY3kgb24gaXQgaGFzIG5vdyBiZWVuIG1hcmtlZCBvcHRpb25hbCBzbyBDb21wcmVzcworICAgICAgICBpdHNlbGYgY2FuIHN0aWxsIGJlIHVzZWQgaW4gYW4gT1NHaSBjb250ZXh0LgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIHR5cGU9ImZpeCIgZGF0ZT0iMjAxMi0xMi0yNyIgaXNzdWU9IkNPTVBSRVNTLTIwMCIKKyAgICAgICAgICAgICAgZHVlLXRvPSJDaHJpc3RpYW4gU2NobGljaHRoZXJsZSI+CisgICAgICAgIFdoZW4gc3BlY2lmeWluZyB0aGUgZW5jb2RpbmcgZXhwbGljaXRseSBUYXJBcmNoaXZlT3V0cHV0U3RyZWFtCisgICAgICAgIHdvdWxkIHdyaXRlIHVucmVhZGFibGUgbmFtZXMgaW4gR05VIG1vZGUgb3IgZXZlbiBjYXVzZSBlcnJvcnMKKyAgICAgICAgaW4gUE9TSVggbW9kZSBmb3IgZmlsZSBuYW1lcyBsb25nZXIgdGhhbiA2NiBjaGFyYWN0ZXJzLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIHR5cGU9ImZpeCIgZGF0ZT0iMjAxMi0xMi0yNyIgaXNzdWU9IkNPTVBSRVNTLTIwMyI+CisgICAgICAgIFdyaXRpbmcgVEFSIFBBWCBoZWFkZXJzIGZhaWxlZCBpZiB0aGUgZ2VuZXJhdGVkIGVudHJ5IG5hbWUKKyAgICAgICAgZW5kZWQgd2l0aCBhICIvIi4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiB0eXBlPSJmaXgiIGRhdGU9IjIwMTItMTItMjgiIGlzc3VlPSJDT01QUkVTUy0xODkiCisgICAgICAgICAgICAgIGR1ZS10bz0iRGFuaWVsIExvd2UiPgorICAgICAgICBaaXBBcmNoaXZlSW5wdXRTdHJlYW0gc29tZXRpbWVzIGZhaWxlZCB0byBwcm92aWRlIGlucHV0IHRvIHRoZQorICAgICAgICBJbmZsYXRlciB3aGVuIGl0IG5lZWRlZCBpdCwgbGVhZGluZyB0byByZWFkcyByZXR1cm5pbmcgMC4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiB0eXBlPSJ1cGRhdGUiIGRhdGU9IjIwMTMtMDEtMDEiPgorICAgICAgICBTcGxpdC9zcGFubmVkIFpJUCBhcmNoaXZlcyBhcmUgbm93IHByb3Blcmx5IGRldGVjdGVkIGJ5CisgICAgICAgIEFyY2hpdmVTdHJlYW1GYWN0b3J5IGJ1dCB3aWxsIGNhdXNlIGFuCisgICAgICAgIFVuc3VwcG9ydGVkWmlwRmVhdHVyZUV4Y2VwdGlvbiB3aGVuIHJlYWQuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gdHlwZT0idXBkYXRlIiBkYXRlPSIyMDEzLTAxLTAxIiBpc3N1ZT0iQ09NUFJFU1MtMjA4Ij4KKyAgICAgICAgWmlwQXJjaGl2ZUlucHV0U3RyZWFtIG5vdyByZWFkcyBhcmNoaXZlcyB0aGF0IHN0YXJ0IHdpdGggYQorICAgICAgICAiUEswMCIgc2lnbmF0dXJlLiAgQXJjaGl2ZXMgd2l0aCB0aGlzIHNpZ25hdHVyZXMgYXJlIGNyZWF0ZWQKKyAgICAgICAgd2hlbiB0aGUgYXJjaGl2ZXIgd2FzIHdpbGxpbmcgdG8gc3BsaXQgdGhlIGFyY2hpdmUgYnV0IGluIHRoZQorICAgICAgICBlbmQgb25seSBuZWVkZWQgYSBzaW5nbGUgc2VnbWVudCAtIHNvIGRpZG4ndCBzcGxpdCBhbnl0aGluZy4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiB0eXBlPSJ1cGRhdGUiIGRhdGU9IjIwMTMtMDEtMDEiIGlzc3VlPSJDT01QUkVTUy0yMDEiPgorICAgICAgICBUYXJBcmNoaXZlRW50cnkgaGFzIGEgbmV3IGNvbnN0cnVjdG9yIHRoYXQgYWxsb3dzIHNldHRpbmcKKyAgICAgICAgbGlua0ZsYWcgYW5kIHByZXNlcnZlTGVhZGluZ1NsYXNoZXMgYXQgdGhlIHNhbWUgdGltZS4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiB0eXBlPSJ1cGRhdGUiIGRhdGU9IjIwMTMtMDEtMDEiIGlzc3VlPSJDT01QUkVTUy0xNTkiPgorICAgICAgICBDaGFuZ2VTZXRQZXJmb3JtZXIgaGFzIGEgbmV3IHBlcmZvcm0gb3ZlcmxvYWQgdGhhdCB1c2VzIGEKKyAgICAgICAgWmlwRmlsZSBpbnN0YW5jZSBhcyBpbnB1dC4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiB0eXBlPSJmaXgiIGRhdGU9IjIwMTMtMDEtMDQiIGlzc3VlPSJDT01QUkVTUy0yMTIiPgorICAgICAgICBUYXJBcmNoaXZlSW5wdXRTdHJlYW0gaWdub3JlZCB0aGUgZW5jb2RpbmcgZm9yIEdOVSBsb25nIG5hbWUKKyAgICAgICAgZW50cmllcy4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiB0eXBlPSJ1cGRhdGUiIGRhdGU9IjIwMTMtMDEtMDUiIGlzc3VlPSJDT01QUkVTUy0xNzIiCisgICAgICAgICAgICAgIGR1ZS10bz0iVGhvbWFzIE1haXIiPgorICAgICAgICBHYXJiYWdlIGNvbGxlY3Rpb24gcHJlc3N1cmUgaGFzIGJlZW4gcmVkdWNlZCBieSByZXVzaW5nCisgICAgICAgIHRlbXBvcmFyeSBieXRlIGFycmF5cyBpbiBjbGFzc2VzLgorICAgICAgPC9hY3Rpb24+CisgICAgICAgIDxhY3Rpb24gdHlwZT0idXBkYXRlIiBkYXRlPSIyMDEzLTAxLTA4IiBpc3N1ZT0iQ09NUFJFU1MtMjEwIgorICAgICAgICAgICAgICAgIGR1ZS10bz0iSnVsaXVzIERhdmllcyI+CisgICAgICAgICAgQ2FuIG5vdyBoYW5kbGUgemlwIGV4dHJhIGZpZWxkIDB4NTQ1NSAtIEV4dGVuZGVkIFRpbWVzdGFtcC4KKyAgICAgICAgPC9hY3Rpb24+CisgICAgICAgIDxhY3Rpb24gdHlwZT0idXBkYXRlIiBkYXRlPSIyMDEzLTAxLTA3IiBpc3N1ZT0iQ09NUFJFU1MtMjExIgorICAgICAgICAgICAgICAgIGR1ZS10bz0iSnVsaXVzIERhdmllcyI+CisgICAgICAgICAgaGFuZGxlIHppcCBleHRyYSBmaWVsZCAweDc4NzUgLSBJbmZvIFppcCBOZXcgVW5peCBFeHRyYSBGaWVsZC4KKyAgICAgICAgPC9hY3Rpb24+CisgICAgICAgIDxhY3Rpb24gdHlwZT0idXBkYXRlIiBkYXRlPSIyMDEzLTAxLTA3IiBpc3N1ZT0iQ09NUFJFU1MtMjEzIgorICAgICAgICAgICAgICAgIGR1ZS10bz0iSnVsaXVzIERhdmllcyI+CisgICAgICAgICAgICBaaXBTaG9ydCwgWmlwTG9uZywgWmlwRWlnaHRCeXRlSW50ZWdlciBzaG91bGQgaW1wbGVtZW50IFNlcmlhbGl6YWJsZQorICAgICAgICA8L2FjdGlvbj4KKyAgICAgICAgPGFjdGlvbiB0eXBlPSJ1cGRhdGUiIGRhdGU9IjIwMTMtMDEtMTQiIGlzc3VlPSJDT01QUkVTUy0yMTQiCisgICAgICAgICAgICAgICAgZHVlLXRvPSJKdWxpdXMgRGF2aWVzIj4KKyAgICAgICAgICAgIGJldHRlciBzdXBwb3J0IGZvciB1bml4IHN5bWxpbmtzIGluIFppcEZpbGUgZW50cmllcworICAgICAgICA8L2FjdGlvbj4KKyAgICAgICAgPGFjdGlvbiB0eXBlPSJ1cGRhdGUiIGRhdGU9IjIwMTMtMDEtMTkiIGlzc3VlPSJDT01QUkVTUy0yMTUiCisgICAgICAgICAgICAgICAgZHVlLXRvPSJSb2JpbiBQb3dlciI+CisgICAgICAgICAgWmlwRmlsZSdzIGluaXRpYWxpemF0aW9uIGhhcyBiZWVuIGltcHJvdmVkIGZvciBub24tWmlwNjQKKyAgICAgICAgICBhcmNoaXZlcy4KKyAgICAgICAgPC9hY3Rpb24+CisgICAgICAgIDxhY3Rpb24gdHlwZT0iZml4IiBkYXRlPSIyMDEzLTAxLTIwIiBpc3N1ZT0iQ09NUFJFU1MtMjA2IgorICAgICAgICAgICAgICAgIGR1ZS10bz0iUGV0ZXIgRGUgTWFleWVyIj4KKyAgICAgICAgICBUYXJBcmNoaXZlSW5wdXRTdHJlYW0gY291bGQgbGVhdmUgdGhlIHNlY29uZCBFT0YgcmVjb3JkCisgICAgICAgICAgaW5zaWRlIHRoZSBzdHJlYW0gaXQgaGFkIGp1c3QgZmluaXNoZWQgcmVhZGluZy4KKyAgICAgICAgPC9hY3Rpb24+CisgICAgICAgIDxhY3Rpb24gdHlwZT0iZml4IiBkYXRlPSIyMDEzLTAxLTIwIj4KKyAgICAgICAgICBEdW1wQXJjaGl2ZUlucHV0U3RyZWFtIG5vIGxvbmdlciBpbXBsaWNpdGx5IGNsb3NlcyB0aGUKKyAgICAgICAgICBvcmlnaW5hbCBpbnB1dCBzdHJlYW0gd2hlbiBpdCByZWFjaGVzIHRoZSBlbmQgb2YgdGhlCisgICAgICAgICAgYXJjaGl2ZS4KKyAgICAgICAgPC9hY3Rpb24+CisgICAgICAgIDxhY3Rpb24gdHlwZT0iZml4IiBkYXRlPSIyMDEzLTAxLTIyIj4KKyAgICAgICAgICBaaXBBcmNoaXZlSW5wdXRTdHJlYW0gbm93IGNvbnN1bWVzIHRoZSByZW1haW5kZXIgb2YgdGhlCisgICAgICAgICAgYXJjaGl2ZSB3aGVuIGdldE5leHRaaXBFbnRyeSByZXR1cm5zIG51bGwuCisgICAgICAgIDwvYWN0aW9uPgorICAgICAgICA8YWN0aW9uIHR5cGU9ImZpeCIgZGF0ZT0iMjAxMy0wMS0yNyIgaXNzdWU9IkNPTVBSRVNTLTIwNSIKKyAgICAgICAgICAgICAgICBkdWUtdG89IkRhbmllbCBMb3dlIj4KKyAgICAgICAgICBVbml0IHRlc3RzIGNvdWxkIGZhaWwgaWYgdGhlIHNvdXJjZSB0cmVlIHdhcyBjaGVja2VkIG91dCB0bworICAgICAgICAgIGEgZGlyZWN0b3J5IHRyZWUgY29udGFpbmlnbiBzcGFjZXMuCisgICAgICAgIDwvYWN0aW9uPgorICAgICAgICA8YWN0aW9uIHR5cGU9InVwZGF0ZSIgZGF0ZT0iMjAxMy0wMS0zMSI+CisgICAgICAgICAgVXBkYXRlZCBYWiBmb3IgSmF2YSBkZXBlbmRlbmN5IHRvIDEuMiBhcyB0aGlzIHZlcnNpb24KKyAgICAgICAgICBwcm92aWRlcyBwcm9wZXIgT1NHaSBtYW5pZmVzdCBhdHRyaWJ1dGVzLgorICAgICAgICA8L2FjdGlvbj4KKyAgICAgICAgPGFjdGlvbiB0eXBlPSJmaXgiIGRhdGU9IjIwMTMtMDItMjAiIGlzc3VlPSJDT01QUkVTUy0yMTkiPgorICAgICAgICAgIEZpeGVkIGEgcG90ZW50aWFsIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB3aGVuCisgICAgICAgICAgcmVhZGluZyBTVE9SRUQgZW50cmllcyBmcm9tIFppcEFyY2hpdmVJbnB1dFN0cmVhbS4KKyAgICAgICAgPC9hY3Rpb24+CisgICAgICAgIDxhY3Rpb24gdHlwZT0iZml4IiBkYXRlPSIyMDEzLTAzLTA3IiBpc3N1ZT0iQ09NUFJFU1MtMjIxIj4KKyAgICAgICAgICBDb21wcmVzc29yU3RyZWFtRmFjdG9yeSBjYW4gbm93IGJlIHVzZWQgd2l0aG91dCBYWiBmb3IgSmF2YQorICAgICAgICAgIGJlaW5nIGF2YWlsYWJsZS4KKyAgICAgICAgPC9hY3Rpb24+CisgICAgICAgIDxhY3Rpb24gdHlwZT0iYWRkIiBkYXRlPSIyMDEzLTAzLTA3IiBpc3N1ZT0iQ09NUFJFU1MtMjIwIj4KKyAgICAgICAgICBDb21wcmVzc29yU3RyZWFtRmFjdG9yeSBoYXMgYW4gb3B0aW9uIHRvIGNyZWF0ZQorICAgICAgICAgIGRlY29tcHJlc3Npbmcgc3RyZWFtcyB0aGF0IGRlY29tcHJlc3MgdGhlIGZ1bGwgaW5wdXQgZm9yCisgICAgICAgICAgZm9ybWF0cyB0aGF0IHN1cHBvcnQgbXVsdGlwbGUgY29uY2F0ZW5hdGVkIHN0cmVhbXMuCisgICAgICAgIDwvYWN0aW9uPgorICAgIDwvcmVsZWFzZT4KKyAgICA8cmVsZWFzZSB2ZXJzaW9uPSIxLjQuMSIgZGF0ZT0iMjAxMi0wNS0yMyIKKyAgICAgICAgICAgICBkZXNjcmlwdGlvbj0iUmVsZWFzZSAxLjQuMSI+CisgICAgICA8YWN0aW9uIHR5cGU9ImZpeCIgZGF0ZT0iMjAxMi0wNS0yMCI+CisgICAgICAgIFBvcnRlZCBsaWJiemlwMidzIGZhbGxiYWNrIHNvcnQgYWxnb3JpdGhtIHRvCisgICAgICAgIEJaaXAyQ29tcHJlc3Nvck91dHB1dFN0cmVhbSB0byBzcGVlZCB1cCBjb21wcmVzc2lvbiBpbiBjZXJ0YWluCisgICAgICAgIGVkZ2UgY2FzZXMuCisgICAgICAgIFVzaW5nIHNwZWNpYWxseSBjcmFmdGVkIGlucHV0cyB0aGlzIGNhbiBiZSB1c2VkIGFzIGEgZGVuaWFsCisgICAgICAgIG9mIHNlcnZpY2UgYXR0YWNrLiAgU2VlIHRoZSBzZWN1cml0eSByZXBvcnRzIHBhZ2UgZm9yIGRldGFpbHMuCisgICAgICA8L2FjdGlvbj4KKyAgICA8L3JlbGVhc2U+CisgICAgPHJlbGVhc2UgdmVyc2lvbj0iMS40IiBkYXRlPSIyMDEyLTA0LTExIgorICAgICAgICAgICAgIGRlc2NyaXB0aW9uPSJSZWxlYXNlIDEuNCI+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0xODMiIHR5cGU9ImZpeCIgZGF0ZT0iMjAxMi0wMy0yNCI+CisgICAgICAgIFRoZSB0YXIgcGFja2FnZSBub3cgYWxsb3dzIHRoZSBlbmNvZGluZyBvZiBmaWxlIG5hbWVzIHRvIGJlCisgICAgICAgIHNwZWNpZmllZCBhbmQgY2FuIG9wdGlvbmFsbHkgdXNlIFBBWCBleHRlbnNpb24gaGVhZGVycyB0bworICAgICAgICB3cml0ZSBub24tQVNDSUkgZmlsZSBuYW1lcy4KKyAgICAgICAgVGhlIHN0cmVhbSBjbGFzc2VzIG5vdyB3cml0ZSAob3IgZXhwZWN0IHRvIHJlYWQpIGFyY2hpdmVzIHRoYXQKKyAgICAgICAgdXNlIHRoZSBwbGF0Zm9ybSdzIG5hdGl2ZSBlbmNvZGluZyBmb3IgZmlsZSBuYW1lcy4gIEFwYWNoZQorICAgICAgICBDb21tb25zIENvbXByZXNzIDEuMyB1c2VkIHRvIHN0cmlwIGV2ZXJ5dGhpbmcgYnV0IHRoZSBsb3dlcgorICAgICAgICBlaWdodCBiaXRzIG9mIGVhY2ggY2hhcmFjdGVyIHdoaWNoIGVmZmVjdGl2ZWx5IG9ubHkgd29ya2VkIGZvcgorICAgICAgICBBU0NJSSBhbmQgSVNPLTg4NTktMSBmaWxlIG5hbWVzLgorICAgICAgICBUaGlzIG5ldyBkZWZhdWx0IGJlaGF2aW9yIGlzIGEgYnJlYWtpbmcgY2hhbmdlLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0xODQiIHR5cGU9ImZpeCIgZGF0ZT0iMjAxMi0wMy0yMyI+CisgICAgICAgIFRhckFyY2hpdmVJbnB1dFN0cmVhbSBmYWlsZWQgdG8gcGFyc2UgUEFYIGhlYWRlcnMgdGhhdAorICAgICAgICBjb250YWluZWQgbm9uLUFTQ0lJIGNoYXJhY3RlcnMuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTE4MiIgdHlwZT0idXBkYXRlIiBkYXRlPSIyMDEyLTAzLTAyIj4KKyAgICAgICAgVGhlIHRhciBwYWNrYWdlIGNhbiBub3cgd3JpdGUgYXJjaGl2ZXMgdGhhdCB1c2Ugc3Rhci9HTlUvQlNECisgICAgICAgIGV4dGVuc2lvbnMgb3IgdXNlIHRoZSBQT1NJWC9QQVggdmFyaWFudCB0byBzdG9yZSBudW1lcmljCisgICAgICAgIHZhbHVlcyB0aGF0IGRvbid0IGZpdCBpbnRvIHRoZSB0cmFkaXRpb25hbCBoZWFkZXIgZmllbGRzLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0xODEiIHR5cGU9InVwZGF0ZSIgZGF0ZT0iMjAxMi0wMy0wMiI+CisgICAgICAgIEFkZGVkIGEgd29ya2Fyb3VuZCBmb3IgYSBCdWcgc29tZSB0YXIgaW1wbGVtZW50YXRpb25zIHRoYXQgYWRkCisgICAgICAgIGEgTlVMIGJ5dGUgYXMgZmlyc3QgYnl0ZSBpbiBudW1lcmljIGhlYWRlciBmaWVsZHMuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTE3NiIgdHlwZT0idXBkYXRlIiBkYXRlPSIyMDEyLTAyLTI4Ij4KKyAgICAgICAgQWRkZWQgYSB3b3JrYXJvdW5kIGZvciBhIEJ1ZyBpbiBXaW5aSVAgd2hpY2ggdXNlcyBiYWNrc2xhc2hlcworICAgICAgICBhcyBwYXRoIHNlcGFyYXRvcnMgaW4gVW5pY29kZSBFeHRyYSBGaWVsZHMuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTEzMSIgdHlwZT0idXBkYXRlIiBkYXRlPSIyMDEyLTAyLTIzIj4KKyAgICAgICAgQXJyYXlPdXRPZkJvdW5kcyB3aGlsZSBkZWNvbXByZXNzaW5nIGJ6Mi4gQWRkZWQgdGVzdCBjYXNlIC0gY29kZSBhbHJlYWR5IHNlZW1zIHRvIGhhdmUgYmVlbiBmaXhlZC4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtMTc4IiB0eXBlPSJmaXgiIGRhdGU9IjIwMTItMDItMjMiPgorICAgICAgICBUYXJBcmNoaXZlSW5wdXRTdHJlYW0gdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpbnN0ZWFkIG9mIElPRXhjZXB0aW9uCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTE3OSIgdHlwZT0iZml4IiBkYXRlPSIyMDEyLTAyLTIzIj4KKyAgICAgICAgVGFyVXRpbHMuZm9ybWF0TG9uZ09jdGFsT3JCaW5hcnlCeXRlcygpIGFzc3VtZXMgdGhlIGZpZWxkIHdpbGwgYmUgMTIgYnl0ZXMgbG9uZworICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0xNzUiIHR5cGU9ImZpeCIgZGF0ZT0iMjAxMi0wMi0yMiI+CisgICAgICAgIEdOVSBUYXIgc29tZXRpbWVzIHVzZXMgYmluYXJ5IGVuY29kaW5nIGZvciBVSUQgYW5kIEdJRAorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0xNzEiIHR5cGU9ImZpeCIgZGF0ZT0iMjAxMi0wMS0yOSI+CisgICAgICAgIEFyY2hpdmVTdHJlYW1GYWN0b3J5LmNyZWF0ZUFyY2hpdmVJbnB1dFN0cmVhbSB3b3VsZCBjbGFpbQorICAgICAgICBzaG9ydCB0ZXh0IGZpbGVzIHdlcmUgVEFSIGFyY2hpdmVzLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0xNTYiIHR5cGU9ImFkZCIgZGF0ZT0iMjAxMS0xMS0wMiI+CisgICAgICAgIFN1cHBvcnQgZm9yIHRoZSBYWiBmb3JtYXQgaGFzIGJlZW4gYWRkZWQuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTE0NiIgdHlwZT0idXBkYXRlIiBkYXRlPSIyMDExLTExLTA3Ij4KKyAgICAgICAgQlppcDJDb21wcmVzc29ySW5wdXRTdHJlYW0gbm93IG9wdGlvbmFsbHkgc3VwcG9ydHMgcmVhZGluZyBvZgorICAgICAgICBjb25jYXRlbmF0ZWQgLmJ6MiBmaWxlcy4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtMTU0IiB0eXBlPSJ1cGRhdGUiIGRhdGU9IjIwMTEtMTEtMDkiPgorICAgICAgICBHWmlwQ29tcHJlc3NvcklucHV0U3RyZWFtIG5vdyBvcHRpb25hbGx5IHN1cHBvcnRzIHJlYWRpbmcgb2YKKyAgICAgICAgY29uY2F0ZW5hdGVkIC5neiBmaWxlcy4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtMTY0IiB0eXBlPSJmaXgiIGRhdGU9IjIwMTEtMTItMDUiPgorICAgICAgICBaaXBGaWxlIGRpZG4ndCB3b3JrIHByb3Blcmx5IGZvciBhcmNoaXZlcyB1c2luZyB1bmljb2RlIGV4dHJhCisgICAgICAgIGZpZWxkcyByYXRoZXIgdGhhbiBVVEYtOCBmaWxlbmFtZXMgYW5kIHRoZSBFRlMtRmxhZy4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtMTYiIHR5cGU9InVwZGF0ZSIgZGF0ZT0iMjAxMS0xMi0wNyI+CisgICAgICAgIFRoZSB0YXIgcGFja2FnZSBjYW4gbm93IHJlYWQgYXJjaGl2ZXMgdGhhdCB1c2Ugc3Rhci9HTlUvQlNECisgICAgICAgIGV4dGVuc2lvbnMgZm9yIGZpbGVzIHRoYXQgYXJlIGxvbmdlciB0aGFuIDggR0J5dGUgYXMgd2VsbCBhcworICAgICAgICBhcmNoaXZlcyB0aGF0IHVzZSB0aGUgUE9TSVgvUEFYIHZhcmlhbnQuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTE2NSIgdHlwZT0idXBkYXRlIiBkYXRlPSIyMDExLTEyLTA4Ij4KKyAgICAgICAgVGhlIHRhciBwYWNrYWdlIGNhbiBub3cgd3JpdGUgYXJjaGl2ZXMgdGhhdCB1c2Ugc3Rhci9HTlUvQlNECisgICAgICAgIGV4dGVuc2lvbnMgZm9yIGZpbGVzIHRoYXQgYXJlIGxvbmdlciB0aGFuIDggR0J5dGUgYXMgd2VsbCBhcworICAgICAgICBhcmNoaXZlcyB0aGF0IHVzZSB0aGUgUE9TSVgvUEFYIHZhcmlhbnQuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTE2NiIgdHlwZT0idXBkYXRlIiBkYXRlPSIyMDExLTEyLTA4Ij4KKyAgICAgICAgVGhlIHRhciBwYWNrYWdlIGNhbiBub3cgdXNlIHRoZSBQT1NJWC9QQVggdmFyaWFudCBmb3Igd3JpdGluZworICAgICAgICBlbnRyaWVzIHdpdGggbmFtZXMgbG9uZ2VyIHRoYW4gMTAwIGNoYXJhY3RlcnMuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTE2OSIgdHlwZT0iZml4IiBkYXRlPSIyMDExLTEyLTIyIj4KKyAgICAgICAgRm9yIGNvcnJ1cHQgYXJjaGl2ZXMgWmlwRmlsZSB3b3VsZCB0aHJvdyBhIFJ1bnRpbWVFeGNlcHRpb24gaW4KKyAgICAgICAgc29tZSBjYXNlcyBhbmQgYW4gSU9FeGNlcHRpb24gaW4gb3RoZXJzLiAgSXQgd2lsbCBub3cKKyAgICAgICAgY29uc2lzdGVudGx5IHRocm93IGFuIElPRXhjZXB0aW9uLgorICAgICAgPC9hY3Rpb24+CisgICAgPC9yZWxlYXNlPgorICAgIDxyZWxlYXNlIHZlcnNpb249IjEuMyIgZGF0ZT0iMjAxMS0xMS0wMSIKKyAgICAgICAgICAgICBkZXNjcmlwdGlvbj0iUmVsZWFzZSAxLjMgLSBBUEkgY29tcGF0aWJsZSB0byAxLjIgYnV0IHJlcXVpcmVzIEphdmE1IGF0IHJ1bnRpbWUiPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtMTQyIiB0eXBlPSJhZGQiIGRhdGU9IjIwMTEtMDktMTQiPgorICAgICAgICBTdXBwb3J0IGZvciB0aGUgUGFjazIwMCBmb3JtYXQgaGFzIGJlZW4gYWRkZWQuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTEzMiIgdHlwZT0iYWRkIiBkYXRlPSIyMDExLTA4LTE3Ij4KKyAgICAgICAgUmVhZC1vbmx5IHN1cHBvcnQgZm9yIHRoZSBmb3JtYXQgdXNlZCBieSB0aGUgVW5peCBkdW1wKDgpIHRvb2wKKyAgICAgICAgaGFzIGJlZW4gYWRkZWQuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTM2IiB0eXBlPSJ1cGRhdGUiIGRhdGU9IjIwMTEtMDgtMTUiPgorICAgICAgICBUaGUgWklQIHBhY2thZ2Ugbm93IHN1cHBvcnRzIFppcDY0IGV4dGVuc2lvbnMuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTE0NCIgdHlwZT0idXBkYXRlIiBkYXRlPSIyMDExLTA4LTA4Ij4KKyAgICAgICAgVGhlIEFSIHBhY2thZ2Ugbm93IHN1cHBvcnRzIHRoZSBCU0QgZGlhbGVjdCBvZiBzdG9yaW5nIGZpbGUKKyAgICAgICAgbmFtZXMgbG9uZ2VyIHRoYW4gMTYgY2hhcnMgKGJvdGggcmVhZGluZyBhbmQgd3JpdGluZykuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gdHlwZT0iZml4IiBkYXRlPSIyMDExLTA4LTA4Ij4KKyAgICAgICAgQlppcDJDb21wcmVzc29ySW5wdXRTdHJlYW0ncyBnZXRCeXRlc1JlYWQgbWV0aG9kIGFsd2F5cworICAgICAgICByZXR1cm5lZCAwLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0xNTIiIHR5cGU9ImZpeCIgZGF0ZT0iMjAxMS0wOC0wMyI+CisgICAgICAgIFppcEFyY2hpdmVJbnB1dFN0cmVhbSBhbmQgWmlwQXJjaGl2ZU91dHB1dFN0cmVhbSBjb3VsZCBsZWFrCisgICAgICAgIHJlc291cmNlcyBvbiBzb21lIEpES3MuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTE2MCIgdHlwZT0iZml4IiBkYXRlPSIyMDExLTEwLTIzIj4KKyAgICAgICAgVGFyQXJjaGl2ZU91dHB1dFN0cmVhbSdzIGdldEJ5dGVzV3JpdHRlbiBtZXRob2QgZGlkbid0IGNvdW50CisgICAgICAgIGNvcnJlY3RseS4KKyAgICAgIDwvYWN0aW9uPgorICAgIDwvcmVsZWFzZT4KKyAgICA8cmVsZWFzZSB2ZXJzaW9uPSIxLjIiIGRhdGU9IjIwMTEtMDctMzEiCisgICAgICAgICAgICAgZGVzY3JpcHRpb249IlJlbGVhc2UgMS4yIC0gYSBidWdmaXggcmVsZWFzZSwgdGhlIGxhc3QgcmVsZWFzZSBleHBlY3RlZCB0byBiZSBjb21wYXRpYmxlIHdpdGggSmF2YSAxLjQiPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtMTI5IiB0eXBlPSJmaXgiIGRhdGU9IjIwMTEtMDctMjYiPgorICAgICAgICBaaXBBcmNoaXZlSW5wdXRTdHJlYW0gY291bGQgZmFpbCB3aXRoIGEgIlRydW5jYXRlZCBaSVAiIGVycm9yCisgICAgICAgIG1lc3NhZ2UgZm9yIGVudHJpZXMgYmV0d2VlbiAyIEdCeXRlIGFuZCA0IEdCeXRlIGluIHNpemUuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTE0NSIgdHlwZT0iZml4IiBkYXRlPSIyMDExLTA3LTIzIgorICAgICAgICAgICAgICBkdWUtdHVlPSJQYXRyaWNrIERyZXllciI+CisgICAgICAgIFRhckFyY2hpdmVJbnB1dFN0cmVhbSBub3cgZGV0ZWN0cyBzcGFyc2UgZW50cmllcyB1c2luZyB0aGUKKyAgICAgICAgb2xkZ251IGZvcm1hdCBhbmQgcHJvcGVybHkgcmVwb3J0cyBpdCBjYW5ub3QgZXh0cmFjdCB0aGVpcgorICAgICAgICBjb250ZW50cy4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtMTIzIiB0eXBlPSJhZGQiIGRhdGU9IjIwMTEtMDctMjMiPgorICAgICAgICBaaXBBcmNoaXZlRW50cnkgaGFzIGEgbmV3IG1ldGhvZCBnZXRSYXdOYW1lIHRoYXQgcHJvdmlkZXMgdGhlCisgICAgICAgIG9yaWdpbmFsIGJ5dGVzIHRoYXQgbWFkZSB1cCB0aGUgbmFtZS4gIFRoaXMgbWF5IGFsbG93IHVzZXIKKyAgICAgICAgY29kZSB0byBkZXRlY3QgdGhlIGVuY29kaW5nLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0xMzAiIHR5cGU9ImZpeCIgZGF0ZT0iMjAxMS0wNy0yMCI+CisgICAgICAgIFRoZSBKYXZhZG9jIGZvciBaaXBBcmNoaXZlSW5wdXRTdHJlYW0jc2tpcCBub3cgbWF0Y2hlcyB0aGUKKyAgICAgICAgaW1wbGVtZW50YXRpb24sIHRoZSBjb2RlIGhhcyBiZWVuIG1hZGUgbW9yZSBkZWZlbnNpdmUuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTE0MCIgdHlwZT0iZml4IiBkYXRlPSIyMDExLTA3LTIwIgorICAgICAgICAgICAgICBkdWUtdG89IlRyZWprYXoiPgorICAgICAgICBBckFyY2hpdmVJbnB1dFN0cmVhbSBmYWlscyBpZiBlbnRyaWVzIGNvbnRhaW4gb25seSBibGFua3MgZm9yCisgICAgICAgIHVzZXJJZCBvciBncm91cElkLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0xMzkiIHR5cGU9ImZpeCIgZGF0ZT0iMjAxMS0wNy0xMyI+CisgICAgICAgIFppcEZpbGUgbWF5IGxlYWsgcmVzb3VyY2VzIG9uIHNvbWUgSkRLcy4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiB0eXBlPSJ1cGRhdGUiIGRhdGU9IjIwMTEtMDQtMTgiPgorICAgICAgICBaaXBGaWxlIG5vdyBpbXBsZW1lbnRzIGZpbmFsaXplIHdoaWNoIGNsb3NlcyB0aGUgdW5kZXJseWluZworICAgICAgICBmaWxlLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0xMTciIHR5cGU9InVwZGF0ZSIgZGF0ZT0iMjAxMS0wMy0yMyI+CisgICAgICAgIENlcnRhaW4gdGFyIGZpbGVzIG5vdCByZWNvZ25pc2VkIGJ5IEFyY2hpdmVTdHJlYW1GYWN0b3J5LgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0xMjUiIHR5cGU9ImZpeCIgZGF0ZT0iMjAxMS0wMy0yMyI+CisgICAgICAgIEJaaXAyQ29tcHJlc3NvcklucHV0U3RyZWFtIHRocm93cyBJT0V4Y2VwdGlvbiBpZiB1bmRlcmx5aW5nIHN0cmVhbSByZXR1cm5zIGF2YWlsYWJsZSgpID09IDAuCisgICAgICAgIFJlbW92ZWQgdGhlIGNoZWNrLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0xMjciIHR5cGU9ImZpeCIgZGF0ZT0iMjAxMS0wMy0yMyI+CisgICAgICAgIENhbGxpbmcgY2xvc2UoKSBvbiBpbnB1dFN0cmVhbSByZXR1cm5lZCBieSBDb21wcmVzc29yU3RyZWFtRmFjdG9yeS5jcmVhdGVDb21wcmVzc29ySW5wdXRTdHJlYW0oKQorICAgICAgICBkb2VzIG5vdCBjbG9zZSB0aGUgdW5kZXJseWluZyBpbnB1dCBzdHJlYW0uCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTEyMiIgdHlwZT0iYWRkIiBkYXRlPSIyMDEwLTEwLTI5Ij4KKyAgICAgICAgVGFyQXJjaGl2ZUVudHJ5IHByb3ZpZGVzIGFjY2VzcyB0byB0aGUgZmxhZ3MgdGhhdCBkZXRlcm1pbmUKKyAgICAgICAgd2hldGhlciBpdCBpcyBhbiBhcmNoaXZlZCBzeW1ib2xpYyBsaW5rLCBwaXBlIG9yIG90aGVyCisgICAgICAgICJ1bmNvbW1vbiIgZmlsZSBzeXN0ZW0gb2JqZWN0LgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0xMTkiIHR5cGU9ImZpeCIgZGF0ZT0iMjAxMC0xMC0yNiI+CisgICAgICAgIFRhckFyY2hpdmVPdXRwdXRTdHJlYW0jZmluaXNoIG5vdyB3cml0ZXMgYWxsIGJ1ZmZlcmVkIGRhdGEgdG8gdGhlIHN0cmVhbQorICAgICAgPC9hY3Rpb24+CisgICAgPC9yZWxlYXNlPgorICAgIDxyZWxlYXNlIHZlcnNpb249IjEuMSIgZGF0ZT0iMjAxMC0wOC0xMyIgZGVzY3JpcHRpb249IlJlbGVhc2UgMS4xIj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTcyIiB0eXBlPSJmaXgiIGRhdGU9IjIwMTAtMDYtMDIiPgorICAgICAgIE1vdmUgYWNrbm93bGVkZ2VtZW50cyBmcm9tIE5PVElDRSB0byBSRUFETUUKKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtMTEzIiB0eXBlPSJmaXgiIGRhdGU9IjIwMTAtMDYtMDIiPgorICAgICAgIFRhckFyY2hpdmVFbnRyeS5wYXJzZVRhckhlYWRlcigpIGluY2x1ZGVzIHRoZSB0cmFpbGluZyBzcGFjZS9OVUwgd2hlbiBwYXJzaW5nIHRoZSBvY3RhbCBzaXplCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTEwOCIgdHlwZT0iYWRkIiBkYXRlPSIyMDEwLTA1LTIzIj4KKyAgICAgICBDb21tYW5kLWxpbmUgaW50ZXJmYWNlIHRvIGxpc3QgYXJjaGl2ZSBjb250ZW50cy4KKyAgICAgICBVc2FnZTogamF2YSAtamFyIGNvbW1vbnMtY29tcHJlc3Mtbi5tLmphciBhcmNoaXZlLW5hbWUgW3ppcHx0YXJ8ZXRjXQorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0xMTgiIHR5cGU9ImZpeCIgZGF0ZT0iMjAxMC0wNS0xNyI+CisgICAgICAgVGFyVXRpbHMucGFyc2VOYW1lIGRvZXMgbm90IHByb3Blcmx5IGhhbmRsZSBjaGFyYWN0ZXJzIG91dHNpZGUgdGhlIHJhbmdlIDAtMTI3CisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTExMiIgdHlwZT0idXBkYXRlIiBkYXRlPSIyMDEwLTA1LTEzIj4KKyAgICAgICBBckFyY2hpdmVJbnB1dFN0cmVhbSBkb2VzIG5vdCBoYW5kbGUgR05VIGV4dGVuZGVkIGZpbGVuYW1lIHJlY29yZHMgKC8vKQorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy0xMDkiIHR5cGU9ImFkZCIgZGF0ZT0iMjAxMC0wNS0xMCI+CisgICAgICAgVGFyIGltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgUGF4IGhlYWRlcnMKKyAgICAgICBBZGRlZCBzdXBwb3J0IGZvciByZWFkaW5nIHBheCBoZWFkZXJzLgorICAgICAgIE5vdGU6IGRvZXMgbm90IHN1cHBvcnQgZ2xvYmFsIHBheCBoZWFkZXJzCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTEwNyIgdHlwZT0iZml4IiBkYXRlPSIyMDEwLTA1LTEwIj4KKyAgICAgICBBcmNoaXZlU3RyZWFtRmFjdG9yeSBkb2VzIG5vdCByZWNvZ25pc2UgdGFyIGZpbGVzIGNyZWF0ZWQgYnkgQW50CisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTExMCIgdHlwZT0iZml4IiBkYXRlPSIyMDEwLTA1LTA5Ij4KKyAgICAgICBTdXBwb3J0ICJ1c3RhciIgcHJlZml4IGZpZWxkLCB3aGljaCBpcyB1c2VkIHdoZW4gZmlsZSBwYXRocyBhcmUgbG9uZ2VyCisgICAgICAgdGhhbiAxMDAgY2hhcmFjdGVycy4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiB0eXBlPSJ1cGRhdGUiIGRhdGU9IjIwMTAtMDQtMTkiIGlzc3VlPSJDT01QUkVTUy0xMDUiPgorICAgICAgIERvY3VtZW50IHRoYXQgdGhlIG5hbWUgb2YgYW4gWmlwQXJjaGl2ZUVudHJ5IGRldGVybWluZXMgd2hldGhlcgorICAgICAgIGFuIGVudHJ5IGlzIGNvbnNpZGVyZWQgYSBkaXJlY3Rvcnkgb3Igbm90LgorICAgICAgIElmIHlvdSBkb24ndCB1c2UgdGhlIGNvbnN0cnVjdG9yIHdpdGggdGhlIEZpbGUgYXJndW1lbnQgdGhlIGVudHJ5J3MKKyAgICAgICAgbmFtZSBtdXN0IGVuZCBpbiBhICIvIiBpbiBvcmRlciBmb3IgdGhlIGVudHJ5IHRvIGJlIGtub3duIGFzIGEgZGlyZWN0b3J5LgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIHR5cGU9ImFkZCIgZGF0ZT0iMjAxMC0wMy0xOSIgaXNzdWU9IkNPTVBSRVNTLTEwMyI+CisgICAgICAgIFppcEFyY2hpdmVJbnB1dFN0cmVhbSBjYW4gb3B0aW9uYWxseSBleHRyYWN0IGRhdGEgdGhhdCB1c2VkCisgICAgICAgIHRoZSBTVE9SRUQgY29tcHJlc3Npb24gbWV0aG9kIGFuZCBhIGRhdGEgZGVzY3JpcHRvci4KKyAgICAgICAgRG9pbmcgc28gaW4gYSBzdHJlYW0gaXMgbm90IHNhZmUgaW4gZ2VuZXJhbCwgc28geW91IGhhdmUgdG8KKyAgICAgICAgZXhwbGljaXRseSBlbmFibGUgdGhlIGZlYXR1cmUuICBCeSBkZWZhdWx0IHRoZSBzdHJlYW0gd2lsbAorICAgICAgICB0aHJvdyBhbiBleGNlcHRpb24gaWYgaXQgZW5jb3VudGVycyBzdWNoIGFuIGVudHJ5LgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIHR5cGU9ImZpeCIgZGF0ZT0iMjAxMC0wMy0xMiIgaXNzdWU9IkNPTVBSRVNTLTEwMCI+CisgICAgICAgIFppcEFyY2hpdmVJbnB1dFN0cmVhbSB3aWxsIHRocm93IGFuIGV4Y2VwdGlvbiBpZiBpdCBkZXRlY3RzIGFuCisgICAgICAgIGVudHJ5IHRoYXQgdXNlcyBhIGRhdGEgZGVzY3JpcHRvciBmb3IgYSBTVE9SRUQgZW50cnkgc2luY2UgaXQKKyAgICAgICAgY2Fubm90IHJlbGlhYmx5IGZpbmQgdGhlIGVuZCBvZiBkYXRhIGZvciB0aGlzICJjb21wcmVzc2lvbiIKKyAgICAgICAgbWV0aG9kLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIHR5cGU9ImZpeCIgZGF0ZT0iMjAxMC0wMy0xMiIgaXNzdWU9IkNPTVBSRVNTLTEwMSI+CisgICAgICAgIFppcEFyY2hpdmVJbnB1dFN0cmVhbSBzaG91bGQgbm93IHByb3Blcmx5IHJlYWQgYXJjaGl2ZXMgdGhhdAorICAgICAgICB1c2UgZGF0YSBkZXNjcmlwdG9ycyBidXQgd2l0aG91dCB0aGUgInVub2ZmaWNpYWwiIHNpZ25hdHVyZS4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiB0eXBlPSJhZGQiIGRhdGU9IjIwMTAtMDMtMDkiIGlzc3VlPSJDT01QUkVTUy05OCI+CisgICAgICAgIFRoZSBaSVAgY2xhc3NlcyB3aWxsIHRocm93IHNwZWNpYWxpemVkIGV4Y2VwdGlvbnMgaWYgYW55CisgICAgICAgIGF0dGVtcHQgaXMgbWFkZSB0byByZWFkIG9yIHdyaXRlIGRhdGEgdGhhdCB1c2VzIHppcCBmZWF0dXJlcworICAgICAgICBub3Qgc3VwcG9ydGVkICh5ZXQpLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIHR5cGU9ImFkZCIgZGF0ZT0iMjAxMC0wMy0wOCIgaXNzdWU9IkNPTVBSRVNTLTk5Ij4KKyAgICAgICAgWmlwRmlsZSNnZXRFbnRyaWVzIHJldHVybnMgZW50cmllcyBpbiBhIHByZWRpY3RhYmxlIG9yZGVyIC0KKyAgICAgICAgdGhlIG9yZGVyIHRoZXkgYXBwZWFyIGluc2lkZSB0aGUgY2VudHJhbCBkaXJlY3RvcnkuCisgICAgICAgIEEgbmV3IG1ldGhvZCBnZXRFbnRyaWVzSW5QaHlzaWNhbE9yZGVyIHJldHVybnMgZW50cmllcyBpbgorICAgICAgICBvcmRlciBvZiB0aGUgZW50cnkgZGF0YSwgaS5lLiB0aGUgb3JkZXIgWmlwQXJjaGl2ZUlucHV0U3RyZWFtCisgICAgICAgIHdvdWxkIHNlZS4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiB0eXBlPSJhZGQiIGRhdGU9IjIwMTAtMDItMTkiPgorICAgICAgICBUaGUgQXJjaGl2ZSpTdHJlYW0gYW5kIFppcEZpbGUgY2xhc3NlcyBub3cgaGF2ZQorICAgICAgICBjYW4oUmVhZHxXcml0ZSlFbnRyeURhdGEgbWV0aG9kcyB0aGF0IGNhbiBiZSB1c2VkIHRvIGNoZWNrCisgICAgICAgIHdoZXRoZXIgYSBnaXZlbiBlbnRyeSdzIGRhdGEgY2FuIGJlIHJlYWQvd3JpdHRlbi4KKyAgICAgICAgVGhlIG1ldGhvZCBjdXJyZW50bHkgcmV0dXJucyBmYWxzZSBmb3IgWklQIGFyY2hpdmVzIGlmIGFuCisgICAgICAgIGVudHJ5IHVzZXMgYW4gdW5zdXBwb3J0ZWQgY29tcHJlc3Npb24gbWV0aG9kIG9yIGVuY3J5cHRpb24uCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gdHlwZT0iYWRkIiBkYXRlPSIyMDEwLTAyLTE5IiBpc3N1ZT0iQ09NUFJFU1MtODkiPgorICAgICAgICBUaGUgWklQIGNsYXNzZXMgbm93IGRldGVjdCBlbmNyeXB0ZWQgZW50cmllcy4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiB0eXBlPSJ1cGRhdGUiIGRhdGU9IjIwMTAtMDItMTgiIGlzc3VlPSJDT01QUkVTUy03OSI+CisgICAgICAgIE1vdmUgRE9TL0phdmEgdGltZSBjb252ZXJzaW9ucyBpbnRvIFppcCB1dGlsaXR5IGNsYXNzLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIHR5cGU9ImZpeCIgZGF0ZT0iMjAxMC0wMi0xOCIgaXNzdWU9IkNPTVBSRVNTLTc0Ij4KKyAgICAgICAgWmlwQXJjaGl2ZUlucHV0U3RyZWFtIGZhaWxlZCB0byB1cGRhdGUgdGhlIG51bWJlciBvZiBieXRlcworICAgICAgICByZWFkIHByb3Blcmx5LgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIHR5cGU9ImZpeCIgZGF0ZT0iMjAxMC0wMi0xOCI+CisgICAgICAgIEFyY2hpdmVJbnB1dFN0cmVhbSBoYXMgYSBuZXcgbWV0aG9kIGdldEJ5dGVzUmVhZCB0aGF0IHNob3VsZAorICAgICAgICBiZSBwcmVmZXJyZWQgb3ZlciBnZXRDb3VudCBzaW5jZSB0aGUgbGF0ZXIgbWF5IHRydW5jYXRlIHRoZQorICAgICAgICBudW1iZXIgb2YgYnl0ZXMgcmVhZCBmb3IgYmlnIGFyY2hpdmVzLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIHR5cGU9ImZpeCIgZGF0ZT0iMjAxMC0wMi0xOCIgaXNzdWU9IkNPTVBSRVNTLTg1Ij4KKyAgICAgICAgVGhlIGNwaW8gYXJjaGl2ZXMgY3JlYXRlZCBieSBDcGlvQXJjaGl2ZU91dHB1dFN0cmVhbSBjb3VsZG4ndAorICAgICAgICBiZSByZWFkIGJ5IG1hbnkgZXhpc3RpbmcgbmF0aXZlIGltcGxlbWVudGF0aW9ucyBiZWNhdXNlIHRoZQorICAgICAgICBhcmNoaXZlcyBjb250YWluZWQgbXVsdGlwbGUgZW50cmllcyB3aXRoIHRoZSBzYW1lIGlub2RlL2RldmljZQorICAgICAgICBjb21iaW5hdGlvbnMgYW5kIHdlcmVuJ3QgcGFkZGVkIHRvIGEgYmxvY2tzaXplIG9mIDUxMiBieXRlcy4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiB0eXBlPSJmaXgiIGRhdGU9IjIwMTAtMDItMTYiIGlzc3VlPSJDT01QUkVTUy03MyI+CisgICAgICAgIFppcEFyY2hpdmVFbnRyeSwgWmlwRmlsZSBhbmQgWmlwQXJjaGl2ZUlucHV0U3RyZWFtIGFyZSBub3cKKyAgICAgICAgbW9yZSBsZW5pZW50IHdoZW4gcGFyc2luZyBleHRyYSBmaWVsZHMuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gaXNzdWU9IkNPTVBSRVNTLTc1IiB0eXBlPSJ1cGRhdGUiIGRhdGU9IjIwMTAtMDItMTIiPgorICAgICAgIFppcEFyY2hpdmVJbnB1dFN0cmVhbSBkb2VzIG5vdCBzaG93IGxvY2F0aW9uIGluIGZpbGUgd2hlcmUgYSBwcm9ibGVtIG9jY3VycmVkLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIHR5cGU9ImZpeCIgZGF0ZT0iMjAxMC0wMi0xMiIgaXNzdWU9IkNPTVBSRVNTLTgyIj4KKyAgICAgICAgY3BpbyBpcyB0ZXJyaWJseSBzbG93LgorICAgICAgICBEb2N1bWVudGVkIHRoYXQgYnVmZmVyZWQgc3RyZWFtcyBhcmUgbmVlZGVkIGZvciBwZXJmb3JtYW5jZQorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIHR5cGU9ImFkZCIgZGF0ZT0iMjAxMC0wMi0xMiIgaXNzdWU9IkNPTVBSRVNTLTk3Ij4KKyAgICAgICAgQWRkZWQgYXV0b2RldGVjdGlvbiBvZiBjb21wcmVzc2lvbiBmb3JtYXQgdG8KKyAgICAgICAgQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gdHlwZT0iZml4IiBkYXRlPSIyMDEwLTAyLTEyIj4KKyAgICAgICAgSW1wcm92ZWQgZXhjZXB0aW9uIG1lc3NhZ2UgaWYgdGhlIGV4dHJhIGZpZWxkIGRhdGEgaW4gWklQCisgICAgICAgIGFyY2hpdmVzIGNhbm5vdCBiZSBwYXJzZWQuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gdHlwZT0iZml4IiBkYXRlPSIyMDEwLTAyLTExIiBpc3N1ZT0iQ09NUFJFU1MtMTciPgorICAgICAgICBUYXIgZm9ybWF0IHVuc3BlY2lmaWVkIC0gY3VycmVudCBzdXBwb3J0IGRvY3VtZW50ZWQuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gdHlwZT0iYWRkIiBpc3N1ZT0iQ09NUFJFU1MtOTUiIGRhdGU9IjIwMTAtMDEtMjkiCisgICAgICAgICAgICAgIGR1ZS10bz0iSm9lcmcgQmVsbG1hbm4iPgorICAgICAgICBJbXByb3ZlIEV4Y2VwdGlvbk1lc3NhZ2VzIGluIEFyY2hpdmVTdHJlYW1GYWN0b3J5CisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gdHlwZT0iZml4IiBpc3N1ZT0iQ09NUFJFU1MtOTQiIGRhdGU9IjIwMTAtMDEtMDciCisgICAgICAgICAgICAgIGR1ZS10bz0iQW5vbiBEZXZzIj4KKyAgICAgICAgWmlwQXJjaGl2ZUVudHJ5J3MgZXF1YWxzIG1ldGhvZCB3YXMgYnJva2VuIGZvciBlbnRyaWVzIGNyZWF0ZWQKKyAgICAgICAgd2l0aCB0aGUgU3RyaW5nLWFyZyBjb25zdHJ1Y3Rvci4gIFRoaXMgbGVhZCB0byBicm9rZW4gWklQCisgICAgICAgIGFyY2hpdmVzIGlmIHR3byBkaWZmZXJlbnQgZW50cmllcyBoYWQgdGhlIHNhbWUgaGFzaCBjb2RlLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIHR5cGU9ImZpeCIgaXNzdWU9IkNPTVBSRVNTLTg3IiBkYXRlPSIyMDA5LTEwLTMwIgorICAgICAgICAgICAgICBkdWUtdG89IkFudG9uaSBNeWxrYSI+CisgICAgICAgIFppcEFyY2hpdmVJbnB1dFN0cmVhbSBjb3VsZCByZXBlYXRlZGx5IHJldHVybiAwIG9uIHJlYWQoKSB3aGVuCisgICAgICAgIHRoZSBhcmNoaXZlIHdhcyB0cnVuY2F0ZWQuCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gdHlwZT0iZml4IiBpc3N1ZT0iQ09NUFJFU1MtODYiIGRhdGU9IjIwMDktMTAtMDgiPgorICAgICAgICBUYXIgYXJjaGl2ZSBlbnRyaWVzIGhvbGRpbmcgdGhlIGZpbGUgbmFtZSBmb3IgbmFtZXMgbG9uZ2VyCisgICAgICAgIHRoYW4gMTAwIGNoYXJhY3RlcnMgaW4gR05VIGxvbmdmaWxlIG1vZGUgZGlkbid0IHByb3Blcmx5CisgICAgICAgIHNwZWNpZnkgdGhleSdkIGJlIHVzaW5nIHRoZSAib2xkZ251IiBleHRlbnNpb24uCisgICAgICA8L2FjdGlvbj4KKyAgICAgIDxhY3Rpb24gdHlwZT0iYWRkIiBkYXRlPSIyMDA5LTA4LTI1Ij4KKyAgICAgICAgQSBuZXcgY29uc3RydWN0b3Igb2YgVGFyQXJjaGl2ZUVudHJ5IGNhbiBjcmVhdGUgZW50cmllcyB3aXRoCisgICAgICAgIG5hbWVzIHRoYXQgc3RhcnQgd2l0aCBzbGFzaGVzIC0gdGhlIGRlZmF1bHQgaXMgdG8gc3RyaXAKKyAgICAgICAgbGVhZGluZyBzbGFzaGVzIGluIG9yZGVyIHRvIGNyZWF0ZSByZWxhdGl2ZSBwYXRoIG5hbWVzLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy04MyIgdHlwZT0iZml4IiBkYXRlPSIyMDA5LTA4LTAxIj4KKyAgICAgICAgRGVsZWdhdGUgYWxsIHJlYWQgYW5kIHdyaXRlIG1ldGhvZHMgaW4gR1ppcCBzdHJlYW0gaW4gb3JkZXIgdG8KKyAgICAgICAgc3BlZWQgdXAgb3BlcmF0aW9ucy4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiB0eXBlPSJhZGQiIGRhdGU9IjIwMDktMDgtMDEiPgorICAgICAgICBBcmNoaXZlRW50cnkgbm93IGhhcyBhIGdldExhc3RNb2RpZmllZERhdGUgbWV0aG9kLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIHR5cGU9ImZpeCIgZGF0ZT0iMjAwOS0wOC0wMSI+CisgICAgICAgIFRoZSBhciBhbmQgY3BpbyBzdHJlYW1zIG5vdyBwcm9wZXJseSByZWFkIGFuZCB3cml0ZSBsYXN0CisgICAgICAgIG1vZGlmaWVkIHRpbWVzLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGlzc3VlPSJDT01QUkVTUy04MSIgdHlwZT0iZml4IiBkYXRlPSIyMDA5LTA2LTMwIj4KKyAgICAgICAgVGFyT3V0cHV0U3RyZWFtIGNhbiBsZWF2ZSBnYXJiYWdlIGF0IHRoZSBlbmQgb2YgdGhlIGFyY2hpdmUKKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiBpc3N1ZT0iQ09NUFJFU1MtNzgiIHR5cGU9ImFkZCIgZGF0ZT0iMjAwOS0wNi0zMCIKKyAgICAgICAgICAgICAgZHVlLXRvPSJKdWtrYSBaaXR0aW5nIj4KKyAgICAgICAgQWRkIGEgQlppcDJVdGlscyBjbGFzcyBtb2RlbGxlZCBhZnRlciBHWmlwVXRpbHMKKyAgICAgIDwvYWN0aW9uPgorICAgIDwvcmVsZWFzZT4KKyAgICA8cmVsZWFzZSB2ZXJzaW9uPSIxLjAiIGRhdGU9IjIwMDktMDUtMjEiIGRlc2NyaXB0aW9uPSJGaXJzdCBQdWJsaWMgUmVsZWFzZSI+CisgICAgICA8YWN0aW9uIGRldj0iYWxsIiB0eXBlPSJhZGQiIGRhdGU9IjIwMDktMDUtMjEiPgorICAgICAgICBJbml0aWFsIHJlbGVhc2UKKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiBkZXY9InNnb2VzY2hsIiB0eXBlPSJmaXgiPgorICAgICAgICBVcGRhdGluZyB0aGUgcG9tLnhtbCBmb3IgcHJlcGFyaW5nIGEgbW92ZSB0byBjb21tb25zLXByb3BlcgorICAgICAgPC9hY3Rpb24+CisgICAgPC9yZWxlYXNlPgorICA8L2JvZHk+Cis8L2RvY3VtZW50PgpkaWZmIC0tZ2l0IGEvc3JjL2NoYW5nZXMvcmVsZWFzZS1ub3Rlcy52bSBiL3NyYy9jaGFuZ2VzL3JlbGVhc2Utbm90ZXMudm0KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzc5NmFlMwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9jaGFuZ2VzL3JlbGVhc2Utbm90ZXMudm0KQEAgLTAsMCArMSw2ODggQEAKKyMjIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyMjIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorIyMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyMjIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyMjIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyMjICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyMjIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyMjCisjIyAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisjIworIyMgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorIyMgc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyMjICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorIyMgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisjIyBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisjIyB1bmRlciB0aGUgTGljZW5zZS4KKyAgICAgICAgICAgICAgJHtwcm9qZWN0Lm5hbWV9IFJFTEVBU0UgTk9URVMKKworJGludHJvZHVjdGlvbi5yZXBsYWNlQWxsKCIoPzwhXDAxNSlcMDEyIiwgIgorIikKKworIyMgTi5CLiB0aGUgYXZhaWxhYmxlIHZhcmlhYmxlcyBhcmUgZGVzY3JpYmVkIGhlcmU6CisjIyBodHRwOi8vbWF2ZW4uYXBhY2hlLm9yZy9wbHVnaW5zL21hdmVuLWNoYW5nZXMtcGx1Z2luL2V4YW1wbGVzL3VzaW5nLWEtY3VzdG9tLWFubm91bmNlbWVudC10ZW1wbGF0ZS5odG1sCisjIyBIYWNrIHRvIGltcHJvdmUgbGF5b3V0OiByZXBsYWNlIGFsbCBwYWlycyBvZiBzcGFjZXMgd2l0aCBhIHNpbmdsZSBuZXctbGluZQorJHJlbGVhc2UuZGVzY3JpcHRpb24ucmVwbGFjZUFsbCgiICAiLCAiCisiKQorCisjIyBGaXggdXAgaW5kZW50YXRpb24gZm9yIG11bHRpLWxpbmUgYWN0aW9uIGRlc2NyaXB0aW9ucworI21hY3JvICggaW5kZW50ICkKKyNzZXQoJGFjdGlvbj0kYWN0aW9uLnJlcGxhY2VBbGwoIig/bSleICArIiwiICAiKSkKKyNlbmQKKyNpZiAoJHJlbGVhc2UuZ2V0QWN0aW9ucygpLnNpemUoKSA9PSAwKQorTm8gY2hhbmdlcyBkZWZpbmVkIGluIHRoaXMgdmVyc2lvbi4KKyNlbHNlCisjaWYgKCRyZWxlYXNlLmdldEFjdGlvbnMoJ2FkZCcpLnNpemUoKSAhPTApCitOZXcgZmVhdHVyZXM6CisjZm9yZWFjaCgkYWN0aW9uSXRlbSBpbiAkcmVsZWFzZS5nZXRBY3Rpb25zKCdhZGQnKSkKKyMjIFVzZSByZXBsYWNlQWxsIHRvIGZpeCB1cCBMRi1vbmx5IGxpbmUgZW5kcyBvbiBXaW5kb3dzLgorI3NldCgkYWN0aW9uPSRhY3Rpb25JdGVtLmdldEFjdGlvbigpLnJlcGxhY2VBbGwoIlxuIiwiCisiKSkKKyNpbmRlbnQoKQorI2lmICgkYWN0aW9uSXRlbS5nZXRJc3N1ZSgpKQorI3NldCgkaXNzdWU9JGFjdGlvbkl0ZW0uZ2V0SXNzdWUoKSkKKyNlbHNlCisjc2V0KCRpc3N1ZT0iIikKKyNlbmQKKyNpZiAoJGFjdGlvbkl0ZW0uZ2V0RHVlVG8oKSkKKyNzZXQoJGR1ZXRvPSRhY3Rpb25JdGVtLmdldER1ZVRvKCkpCisjZWxzZQorI3NldCgkZHVldG89IiIpCisjZW5kCitvICR7YWN0aW9ufSMjCisjaWYoJCFpc3N1ZSAhPSAiIikKKworICBJc3N1ZTogJGlzc3VlLiAjaWYoJCFkdWV0byAhPSAiIilUaGFua3MgdG8gJGR1ZXRvLiAjZW5kCisjZWxzZSNpZigkIWR1ZXRvICE9ICIiKSBUaGFua3MgdG8gJGR1ZXRvLiAjZW5kCisjZW5kCisKKyNzZXQoJGlzc3VlPSIiKQorI3NldCgkZHVldG89IiIpCisjZW5kIAorI2VuZAorCisjaWYgKCRyZWxlYXNlLmdldEFjdGlvbnMoJ2ZpeCcpLnNpemUoKSAhPTApCitGaXhlZCBCdWdzOgorI2ZvcmVhY2goJGFjdGlvbkl0ZW0gaW4gJHJlbGVhc2UuZ2V0QWN0aW9ucygnZml4JykpCisjIyBVc2UgcmVwbGFjZUFsbCB0byBmaXggdXAgTEYtb25seSBsaW5lIGVuZHMgb24gV2luZG93cy4KKyNzZXQoJGFjdGlvbj0kYWN0aW9uSXRlbS5nZXRBY3Rpb24oKS5yZXBsYWNlQWxsKCJcbiIsIgorIikpCisjaW5kZW50KCkKKyNpZiAoJGFjdGlvbkl0ZW0uZ2V0SXNzdWUoKSkKKyNzZXQoJGlzc3VlPSRhY3Rpb25JdGVtLmdldElzc3VlKCkpCisjZWxzZQorI3NldCgkaXNzdWU9IiIpCisjZW5kCisjaWYgKCRhY3Rpb25JdGVtLmdldER1ZVRvKCkpCisjc2V0KCRkdWV0bz0kYWN0aW9uSXRlbS5nZXREdWVUbygpKQorI2Vsc2UKKyNzZXQoJGR1ZXRvPSIiKQorI2VuZAorbyAke2FjdGlvbn0jIworI2lmKCQhaXNzdWUgIT0gIiIpCisKKyAgSXNzdWU6ICRpc3N1ZS4gI2lmKCQhZHVldG8gIT0gIiIpVGhhbmtzIHRvICRkdWV0by4gI2VuZAorI2Vsc2UjaWYoJCFkdWV0byAhPSAiIikgVGhhbmtzIHRvICRkdWV0by4gI2VuZAorI2VuZAorCisjc2V0KCRpc3N1ZT0iIikKKyNzZXQoJGR1ZXRvPSIiKQorI2VuZAorI2VuZAorCisjaWYgKCRyZWxlYXNlLmdldEFjdGlvbnMoJ3VwZGF0ZScpLnNpemUoKSAhPTApCitDaGFuZ2VzOgorI2ZvcmVhY2goJGFjdGlvbkl0ZW0gaW4gJHJlbGVhc2UuZ2V0QWN0aW9ucygndXBkYXRlJykpCisjIyBVc2UgcmVwbGFjZUFsbCB0byBmaXggdXAgTEYtb25seSBsaW5lIGVuZHMgb24gV2luZG93cy4KKyNzZXQoJGFjdGlvbj0kYWN0aW9uSXRlbS5nZXRBY3Rpb24oKS5yZXBsYWNlQWxsKCJcbiIsIgorIikpCisjaW5kZW50KCkKKyNpZiAoJGFjdGlvbkl0ZW0uZ2V0SXNzdWUoKSkKKyNzZXQoJGlzc3VlPSRhY3Rpb25JdGVtLmdldElzc3VlKCkpCisjZWxzZQorI3NldCgkaXNzdWU9IiIpCisjZW5kCisjaWYgKCRhY3Rpb25JdGVtLmdldER1ZVRvKCkpCisjc2V0KCRkdWV0bz0kYWN0aW9uSXRlbS5nZXREdWVUbygpKQorI2Vsc2UKKyNzZXQoJGR1ZXRvPSIiKQorI2VuZAorbyAke2FjdGlvbn0jIworI2lmKCQhaXNzdWUgIT0gIiIpCisKKyAgSXNzdWU6ICRpc3N1ZS4gI2lmKCQhZHVldG8gIT0gIiIpVGhhbmtzIHRvICRkdWV0by4gI2VuZAorI2Vsc2UjaWYoJCFkdWV0byAhPSAiIikgVGhhbmtzIHRvICRkdWV0by4gI2VuZAorI2VuZAorCisjc2V0KCRpc3N1ZT0iIikKKyNzZXQoJGR1ZXRvPSIiKQorI2VuZAorI2VuZAorCisjaWYgKCRyZWxlYXNlLmdldEFjdGlvbnMoJ3JlbW92ZScpLnNpemUoKSAhPTApCitSZW1vdmVkOgorI2ZvcmVhY2goJGFjdGlvbkl0ZW0gaW4gJHJlbGVhc2UuZ2V0QWN0aW9ucygncmVtb3ZlJykpCisjIyBVc2UgcmVwbGFjZUFsbCB0byBmaXggdXAgTEYtb25seSBsaW5lIGVuZHMgb24gV2luZG93cy4KKyNzZXQoJGFjdGlvbj0kYWN0aW9uSXRlbS5nZXRBY3Rpb24oKS5yZXBsYWNlQWxsKCJcbiIsIgorIikpCisjaW5kZW50KCkKKyNpZiAoJGFjdGlvbkl0ZW0uZ2V0SXNzdWUoKSkKKyNzZXQoJGlzc3VlPSRhY3Rpb25JdGVtLmdldElzc3VlKCkpCisjZWxzZQorI3NldCgkaXNzdWU9IiIpCisjZW5kCisjaWYgKCRhY3Rpb25JdGVtLmdldER1ZVRvKCkpCisjc2V0KCRkdWV0bz0kYWN0aW9uSXRlbS5nZXREdWVUbygpKQorI2Vsc2UKKyNzZXQoJGR1ZXRvPSIiKQorI2VuZAorbyAke2FjdGlvbn0jIworI2lmKCQhaXNzdWUgIT0gIiIpCisKKyAgSXNzdWU6ICRpc3N1ZS4gI2lmKCQhZHVldG8gIT0gIiIpVGhhbmtzIHRvICRkdWV0by4gI2VuZAorI2Vsc2UjaWYoJCFkdWV0byAhPSAiIikgVGhhbmtzIHRvICRkdWV0by4gI2VuZAorI2VuZAorCisjc2V0KCRpc3N1ZT0iIikKKyNzZXQoJGR1ZXRvPSIiKQorI2VuZAorI2VuZAorIyMgRW5kIG9mIG1haW4gbG9vcAorI2VuZAorI21hY3JvICggZml4dXJsICR1cmwgKQorJHVybC5yZXBsYWNlQWxsKCJwcm9wZXIvY29tbW9ucy0iLCIiKQorI2VuZAorRm9yIGNvbXBsZXRlIGluZm9ybWF0aW9uIG9uICR7cHJvamVjdC5uYW1lfSwgaW5jbHVkaW5nIGluc3RydWN0aW9ucworb24gaG93IHRvIHN1Ym1pdCBidWcgcmVwb3J0cywgcGF0Y2hlcywgb3Igc3VnZ2VzdGlvbnMgZm9yIGltcHJvdmVtZW50LAorc2VlIHRoZSAke3Byb2plY3QubmFtZX0gd2Vic2l0ZToKKworI2ZpeHVybCAoICR7cHJvamVjdC51cmx9ICkKKworT2xkIFJlbGVhc2UgTm90ZXMKKz09PT09PT09PT09PT09PT09CisKK1JlbGVhc2UgMS45CistLS0tLS0tLS0tLQorCitOZXcgZmVhdHVyZXM6CitvIEFkZGVkIHN1cHBvcnQgZm9yIERFRkxBVEUgc3RyZWFtcyB3aXRob3V0IGFueSBnemlwIGZyYW1pbmcuCisgIElzc3VlOiBDT01QUkVTUy0yNjMuCisgIFRoYW5rcyB0byBNYXR0aGlhcyBTdGV2ZW5zLgorCitGaXhlZCBCdWdzOgorbyBXaGVuIHJlYWRpbmcgN3ogZmlsZXMgdW5rbm93biBmaWxlIHByb3BlcnRpZXMgYW5kIHByb3BlcnRpZXMgb2YgdHlwZQorICBrRHVtbXkgYXJlIG5vdyBpZ25vcmVkLgorICBJc3N1ZTogQ09NUFJFU1MtMjg3LgorbyBFeHBhbmRpbmcgN3ogYXJjaGl2ZXMgdXNpbmcgTFpNQSBjb21wcmVzc2lvbiBjb3VsZCBjYXVzZSBhbgorICBFT0ZFeGNlcHRpb24uCisgIElzc3VlOiBDT01QUkVTUy0yODYuIAorbyBMb25nLU5hbWUgYW5kIC1saW5rIG9yIFBBWC1oZWFkZXIgZW50cmllcyBpbiBUQVIgYXJjaGl2ZXMgYWx3YXlzIGhhZAorICB0aGUgY3VycmVudCB0aW1lIGFzIGxhc3QgbW9kZmljYXRpb24gdGltZSwgY3JlYXRpbmcgYXJjaGl2ZXMgdGhhdAorICBhcmUgZGlmZmVyZW50IGF0IHRoZSBieXRlIGxldmVsIGVhY2ggdGltZSBhbiBhcmNoaXZlIHdhcyBidWlsdC4KKyAgSXNzdWU6IENPTVBSRVNTLTI4OS4KKyAgVGhhbmtzIHRvIEJvYiBSb2JlcnRzb24uCisKK0NoYW5nZXM6CitvIENoZWNraW5nIGZvciBYWiBmb3IgSmF2YSBtYXkgYmUgZXhwZW5zaXZlLiAgVGhlIHJlc3VsdCB3aWxsIG5vdyBiZQorICBjYWNoZWQgb3V0c2lkZSBvZiBhbiBPU0dpIGVudmlyb25tZW50LiAgWW91IGNhbiB1c2UgdGhlIG5ldworICBYWlV0aWxzI3NldENhY2hlWFpBdmFpbGFiaWxpdHkgdG8gb3ZlcnJyaWRlIHRoaXMgZGVmYXVsdCBiZWhhdmlvci4KKyAgSXNzdWU6IENPTVBSRVNTLTI4NS4KKworUmVsZWFzZSAxLjguMQorLS0tLS0tLS0tLS0tLQorCitOZXcgZmVhdHVyZXM6CitvIENPTVBSRVNTLTI3MjogIENvbXByZXNzb3JTdHJlYW1GYWN0b3J5IGNhbiBub3cgYXV0by1kZXRlY3QgVW5peCBjb21wcmVzcworICAgICAgICAgICAgICAgICAoIi5aIikgc3RyZWFtcy4gCisKK0ZpeGVkIEJ1Z3M6CitvIENPTVBSRVNTLTI3MDogIFRoZSBzbmFwcHksIGFyIGFuZCB0YXIgaW5wdXRzdHJlYW1zIG1pZ2h0IGZhaWwgdG8gcmVhZCBmcm9tIGEKKyAgICAgICAgICAgICAgICAgbm9uLWJ1ZmZlcmVkIHN0cmVhbSBpbiBjZXJ0YWluIGNhc2VzLiAKK28gQ09NUFJFU1MtMjc3OiAgSU9VdGlscyNza2lwIG1pZ2h0IHNraXAgZmV3ZXIgYnl0ZXMgdGhhbiByZXF1ZXN0ZWQgZXZlbiB0aG91Z2gKKyAgICAgICAgICAgICAgICAgbW9yZSBjb3VsZCBiZSByZWFkIGZyb20gdGhlIHN0cmVhbS4gCitvIENPTVBSRVNTLTI3NjogIEFyY2hpdmVTdHJlYW1zIG5vdyB2YWxpZGF0ZSB0aGVyZSBpcyBhIGN1cnJlbnQgZW50cnkgYmVmb3JlCisgICAgICAgICAgICAgICAgIHJlYWRpbmcgb3Igd3JpdGluZyBlbnRyeSBkYXRhLiAKK28gQXJqQXJjaGl2ZUlucHV0U3RyZWFtI2NhblJlYWRFbnRyeURhdGEgdGVzdGVkIHRoZSBjdXJyZW50CisgICAgICAgICAgICAgICAgIGVudHJ5IG9mIHRoZSBzdHJlYW0gcmF0aGVyIHRoYW4gaXRzIGFyZ3VtZW50LiAKK28gQ09NUFJFU1MtMjc0OiAgQ2hhbmdlU2V0I2RlbGV0ZSBhbmQgZGVsZXRlRGlyIG5vdyBwcm9wZXJseSBkZWFsIHdpdGggdW5uYW1lZAorICAgICAgICAgICAgICAgICBlbnRyaWVzLiAKK28gQ09NUFJFU1MtMjczOiAgQWRkZWQgYSBmZXcgbnVsbCBjaGVja3MgdG8gaW1wcm92ZSByb2J1c3RuZXNzLiAKK28gQ09NUFJFU1MtMjc4OiAgVGFyQXJjaGl2ZUlucHV0U3RyZWFtIGZhaWxlZCB0byByZWFkIGFyY2hpdmVzIHdpdGggZW1wdHkKKyAgICAgICAgICAgICAgICAgZ2lkL3VpZCBmaWVsZHMuIAorbyBDT01QUkVTUy0yNzk6ICBUYXJBcmNoaXZlSW5wdXRTdHJlYW0gbm93IGFnYWluIHRocm93cyBhbiBleGNlcHRpb24gd2hlbiBpdAorICAgICAgICAgICAgICAgICBlbmNvdW50ZXJzIGEgdHJ1bmNhdGVkIGFyY2hpdmUgd2hpbGUgcmVhZGluZyBmcm9tIHRoZSBsYXN0CisgICAgICAgICAgICAgICAgIGVudHJ5LiAKK28gQ09NUFJFU1MtMjgwOiAgQWRhcHRlZCBUYXJBcmNoaXZlSW5wdXRTdHJlYW0jc2tpcCB0byB0aGUgbW9kaWZpZWQKKyAgICAgICAgICAgICAgICAgSU9VdGlscyNza2lwIG1ldGhvZC4gVGhhbmtzIHRvIEJFTFVHQSBCRUhSLiAKKworQ2hhbmdlczoKK28gVGhlIGRlcGVuZGVuY3kgb24gb3JnLnR1a2Fhbmk6eHogaXMgbm93IG1hcmtlZCBhcyBvcHRpb25hbC4gCisKK1JlbGVhc2UgMS44CistLS0tLS0tLS0tLQorCitOZXcgZmVhdHVyZXM6CitvIEd6aXBDb21wcmVzc29ySW5wdXRTdHJlYW0gbm93IHByb3ZpZGVzIGFjY2VzcyB0byB0aGUgc2FtZQorICBtZXRhZGF0YSB0aGF0IGNhbiBiZSBwcm92aWRlZCB2aWEgR3ppcFBhcmFtZXRlcnMgd2hlbiB3cml0aW5nCisgIGEgZ3ppcCBzdHJlYW0uCisgIElzc3VlOiBDT01QUkVTUy0yNjAuIAorbyBTZXZlblpPdXRwdXRGaWxlIG5vdyBzdXBwb3J0cyBjaGFpbmluZyBtdWx0aXBsZQorICBjb21wcmVzc2lvbi9lbmNyeXB0aW9uL2ZpbHRlciBtZXRob2RzIGFuZCBwYXNzaW5nIG9wdGlvbnMgdG8KKyAgdGhlIG1ldGhvZHMuCisgIElzc3VlOiBDT01QUkVTUy0yNjYuIAorbyBUaGUgKGNvbXByZXNzaW9uKSBtZXRob2QocykgY2FuIG5vdyBiZSBzcGVjaWZpZWQgcGVyIGVudHJ5IGluCisgIFNldmVuWk91dHB1dEZpbGUuCisgIElzc3VlOiBDT01QUkVTUy0yNjEuIAorbyBTZXZlblpBcmNoaXZlRW50cnkgImtub3dzIiB3aGljaCBtZXRob2QocykgaGF2ZSBiZWVuIHVzZWQgdG8KKyAgd3JpdGUgaXQgdG8gdGhlIGFyY2hpdmUuCisgIElzc3VlOiBDT01QUkVTUy0yNTguIAorbyBUaGUgN3ogcGFja2FnZSBub3cgc3VwcG9ydHMgdGhlIGRlbHRhIGZpbHRlciBhcyBtZXRob2QuIAorbyBUaGUgN3ogcGFja2FnZSBub3cgc3VwcG9ydHMgQkNKIGZpbHRlcnMgZm9yIHNldmVyYWwgcGxhdGZvcm1zLgorICBZb3Ugd2lsbCBuZWVkIGEgdmVyc2lvbiA+PSAxLjUgb2YgWFogZm9yIEphdmEgdG8gcmVhZCBhcmNoaXZlcworICB1c2luZyBCQ0osIHRob3VnaC4KKyAgSXNzdWU6IENPTVBSRVNTLTI1Ny4gCisKK0ZpeGVkIEJ1Z3M6CitvIEJaaXAyQ29tcHJlc3NvcklucHV0U3RyZWFtIHJlYWQgZmV3ZXIgYnl0ZXMgdGhhbiBwb3NzaWJsZSBmcm9tCisgIGEgdHJ1bmNhdGVkIHN0cmVhbS4KKyAgSXNzdWU6IENPTVBSRVNTLTI1My4gCitvIFNldmVuWkZpbGUgZmFpbGVkIGNsYWltaW5nIHRoZSBkaWN0aW9uYXJ5IHdhcyB0b28gbGFyZ2Ugd2hlbgorICBhcmNoaXZlcyB1c2VkIExaTUEgY29tcHJlc3Npb24gZm9yIGhlYWRlcnMgYW5kIGNvbnRlbnQgYW5kCisgIGNlcnRhaW4gbm9uLWRlZmF1bHQgZGljdGlvbmFyeSBzaXplcy4KKyAgSXNzdWU6IENPTVBSRVNTLTI1My4gCitvIENvbXByZXNzb3JTdHJlYW1GYWN0b3J5LmNyZWF0ZUNvbXByZXNzb3JJbnB1dFN0cmVhbSB3aXRoCisgIGV4cGxpY2l0IGNvbXByZXNzaW9uIGRpZCBub3QgaG9ub3IgZGVjb21wcmVzc0NvbmNhdGVuYXRlZAorICBJc3N1ZTogQ09NUFJFU1MtMjU5LiAKK28gVGFyQXJjaGl2ZUlucHV0U3RyZWFtIHdpbGwgbm93IHJlYWQgYXJjaGl2ZXMgY3JlYXRlZCBieSB0YXIKKyAgaW1wbGVtZW50YXRpb25zIHRoYXQgZW5jb2RlIGJpZyBudW1iZXJzIGJ5IG5vdCBhZGRpbmcgYQorICB0cmFpbGluZyBOVUwuCisgIElzc3VlOiBDT01QUkVTUy0yNjIuIAorbyBaaXBBcmNoaXZlSW5wdXRTdHJlYW0gd291bGQgcmV0dXJuIE5VTCBieXRlcyBmb3IgdGhlIGZpcnN0IDUxMgorICBieXRlcyBvZiBhIFNUT1JFRCBlbnRyeSBpZiBpdCB3YXMgdGhlIHZlcnkgZmlyc3QgZW50cnkgb2YgdGhlCisgIGFyY2hpdmUuCisgIElzc3VlOiBDT01QUkVTUy0yNjQuIAorbyBXaGVuIHdyaXRpbmcgUEFYL1BPU0lYIGhlYWRlcnMgZm9yIFRBUiBlbnRyaWVzIHdpdGgKKyAgYmFja3NsYXNoZXMgb3IgY2VydGFpbiBub24tQVNDSUkgY2hhcmFjdGVycyBpbiB0aGVpciBuYW1lCisgIFRhckFyY2hpdmVPdXRwdXRTdHJlYW0gY291bGQgZmFpbC4KKyAgSXNzdWU6IENPTVBSRVNTLTI2NS4gCitvIEFyY2hpdmVTdHJlYW1GYWN0b3J5IG5vdyB0aHJvd3MgYSBTdHJlYW1pbmdOb3RTdXBwb3J0ZWQgLSBhCisgIG5ldyBzdWJjbGFzcyBvZiBBcmNoaXZlRXhjZXB0aW9uIC0gaWYgaXQgaXMgYXNrZWQgdG8gcmVhZCBmcm9tCisgIG9yIHdyaXRlIHRvIGEgc3RyZWFtIGFuZCBDb21tb25zIENvbXByZXNzIGRvZXNuJ3Qgc3VwcG9ydAorICBzdHJlYW1pbmcgZm9yIHRoZSBmb3JtYXQuICBUaGlzIGN1cnJlbnRseSBvbmx5IGFwcGxpZXMgdG8gdGhlCisgIDd6IGZvcm1hdC4KKyAgSXNzdWU6IENPTVBSRVNTLTI2Ny4gCisKK1JlbGVhc2UgMS43CistLS0tLS0tLS0tLQorCitOZXcgZmVhdHVyZXM6CitvIFJlYWQtT25seSBzdXBwb3J0IGZvciBTbmFwcHkgY29tcHJlc3Npb24uCisgIElzc3VlOiBDT01QUkVTUy0xNDcuIFRoYW5rcyB0byBCRUxVR0EgQkVIUi4KK28gUmVhZC1Pbmx5IHN1cHBvcnQgZm9yIC5aIGNvbXByZXNzZWQgZmlsZXMuCisgIElzc3VlOiBDT01QUkVTUy0yNDMuIFRoYW5rcyB0byBEYW1qYW4gSm92YW5vdmljLgorbyBaaXBGaWxlIGFuZCBaaXBBcmNoaXZlSW5wdXRTdHJlYW0gbm93IHN1cHBvcnQgcmVhZGluZyBlbnRyaWVzCisgIGNvbXByZXNzZWQgdXNpbmcgdGhlIFNIUklOS0lORyBtZXRob2QuIFRoYW5rcyB0byBEYW1qYW4gSm92YW5vdmljLgorbyBHemlwQ29tcHJlc3Nvck91dHB1dFN0cmVhbSBub3cgc3VwcG9ydHMgc2V0dGluZyB0aGUgY29tcHJlc3Npb24KKyAgbGV2ZWwgYW5kIHRoZSBoZWFkZXIgbWV0YWRhdGEgKGZpbGVuYW1lLCBjb21tZW50LCBtb2RpZmljYXRpb24gdGltZSwKKyAgb3BlcmF0aW5nIHN5c3RlbSBhbmQgZXh0cmEgZmxhZ3MpCisgIElzc3VlOiBDT01QUkVTUy0yNTAuIFRoYW5rcyB0byBFbW1hbnVlbCBCb3VyZy4KK28gWmlwRmlsZSBhbmQgWmlwQXJjaGl2ZUlucHV0U3RyZWFtIG5vdyBzdXBwb3J0IHJlYWRpbmcgZW50cmllcworICBjb21wcmVzc2VkIHVzaW5nIHRoZSBJTVBMT0RFIG1ldGhvZC4KKyAgSXNzdWU6IENPTVBSRVNTLTExNS4gVGhhbmtzIHRvIEVtbWFudWVsIEJvdXJnLgorbyBaaXBGaWxlIGFuZCB0aGUgN3ogZmlsZSBjbGFzc2VzIG5vdyBpbXBsZW1lbnQgQ2xvc2VhYmxlIGFuZCBjYW4gYmUKKyAgdXNlZCBpbiB0cnktd2l0aC1yZXNvdXJjZXMgY29uc3RydWN0cy4KKworRml4ZWQgQnVnczoKK28gU2V2ZW5aT3V0cHV0RmlsZSNjbG9zZUFyY2hpdmVFbnRyeSB0aHJvd3MgYW4gZXhjZXB0aW9uIHdoZW4gdXNpbmcKKyAgTFpNQTIgY29tcHJlc3Npb24gb24gSmF2YTguICBJc3N1ZTogQ09NUFJFU1MtMjQxLgorbyA3eiByZWFkaW5nIG9mIGJpZyA2NGJpdCB2YWx1ZXMgY291bGQgYmUgd3JvbmcuCisgIElzc3VlOiBDT01QUkVTUy0yNDQuIFRoYW5rcyB0byBOaWNvIEtydWJlci4KK28gVGFyQXJjaGl2ZUlucHV0U3RyZWFtIGNvdWxkIGZhaWwgdG8gcmVhZCBhbiBhcmNoaXZlIGNvbXBsZXRlbHkuCisgIElzc3VlOiBDT01QUkVTUy0yNDUuCitvIFRoZSB0aW1lLXNldHRlcnMgaW4gWDU0NTVfRXh0ZW5kZWRUaW1lc3RhbXAgbm93IHNldCB0aGUKKyAgY29ycmVzcG9uZGluZyBmbGFncyBleHBsaWNpdGx5IC0gaS5lLiB0aGV5IHNldCB0aGUgYml0IGlmIHRoZSB2YWx1cworICBpcyBub3QtbnVsbCBhbmQgcmVzZXQgaXQgb3RoZXJ3aXNlLiAgVGhpcyBtYXkgY2F1c2UKKyAgaW5jb21wYXRpYmlsaXRpZXMgaWYgeW91IHVzZSBzZXRGbGFncyB0byB1bnNldCBhIGJpdCBhbmQgbGF0ZXIgc2V0CisgIHRoZSB0aW1lIHRvIGEgbm9uLW51bGwgdmFsdWUgLSB0aGUgZmxhZyB3aWxsIG5vdyBiZSBzZXQuCisgIElzc3VlOiBDT01QUkVTUy0yNDIuCitvIFNldmVuWk91dHB1dEZpbGUgd291bGQgY3JlYXRlIGludmFsaWQgYXJjaGl2ZXMgaWYgbW9yZSB0aGFuIHNpeAorICBlbXB0eSBmaWxlcyBvciBkaXJlY3RvcmllcyB3ZXJlIGluY2x1ZGVkLiAgSXNzdWU6IENPTVBSRVNTLTI1Mi4KKworUmVsZWFzZSAxLjYKKy0tLS0tLS0tLS0tCisKK1ZlcnNpb24gMS42IGludHJvZHVjZXMgY2hhbmdlcyB0byB0aGUgaW50ZXJuYWwgQVBJIG9mIHRoZSB0YXIgcGFja2FnZSB0aGF0IAorYnJlYWsgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkgaW4gdGhlIGZvbGxvd2luZyByYXJlIGNhc2VzLiAgVGhpcyB2ZXJzaW9uIAorcmVtb3ZlcyB0aGUgcGFja2FnZSBwcml2YXRlIFRhckJ1ZmZlciBjbGFzcyBhbG9uZyB3aXRoIHRoZSBwcm90ZWN0ZWQgImJ1ZmZlciIgCittZW1iZXJzIGluIFRhckFyY2hpdmVJbnB1dFN0cmVhbSBhbmQgVGFyQXJjaGl2ZU91dHB1dFN0cmVhbS4gIFRoaXMgY2hhbmdlIHdpbGwgCitvbmx5IGFmZmVjdCB5b3UgaWYgeW91IGhhdmUgY3JlYXRlZCBhIHN1YmNsYXNzIG9mIG9uZSBvZiB0aGUgc3RyZWFtIGNsYXNzZXMgCithbmQgYWNjZXNzZWQgdGhlIGJ1ZmZlciBtZW1iZXIgb3IgZGlyZWN0bHkgdXNlZCB0aGUgVGFyQnVmZmVyIGNsYXNzLgorCitDaGFuZ2VzIGluIHRoaXMgdmVyc2lvbiBpbmNsdWRlOgorCitOZXcgZmVhdHVyZXM6CitvIEFkZGVkIHN1cHBvcnQgZm9yIDd6IGFyY2hpdmVzLiAgTW9zdCBjb21wcmVzc2lvbiBhbGdvcml0aG1zCisgIGNhbiBiZSByZWFkIGFuZCB3cml0dGVuLCBMWk1BIGFuZCBlbmNyeXB0aW9uIGFyZSBvbmx5CisgIHN1cHBvcnRlZCB3aGVuIHJlYWRpbmcuICBJc3N1ZTogQ09NUFJFU1MtNTQuIFRoYW5rcyB0byBEYW1qYW4gSm92YW5vdmljLiAKK28gQWRkZWQgcmVhZC1vbmx5IHN1cHBvcnQgZm9yIEFSSiBhcmNoaXZlcyB0aGF0IGRvbid0IHVzZQorICBjb21wcmVzc2lvbi4gIElzc3VlOiBDT01QUkVTUy0yMjYuIFRoYW5rcyB0byBEYW1qYW4gSm92YW5vdmljLiAKK28gRHVtcEFyY2hpdmVJbnB1dFN0cmVhbSBub3cgc3VwcG9ydHMgYW4gZW5jb2RpbmcgcGFyYW1ldGVyIHRoYXQKKyAgY2FuIGJlIHVzZWQgdG8gc3BlY2lmeSB0aGUgZW5jb2Rpbmcgb2YgZmlsZSBuYW1lcy4gCitvIFRoZSBDUElPIHN0cmVhbXMgbm93IHN1cHBvcnQgYW4gZW5jb2RpbmcgcGFyYW1ldGVyIHRoYXQgY2FuIGJlCisgIHVzZWQgdG8gc3BlY2lmeSB0aGUgZW5jb2Rpbmcgb2YgZmlsZSBuYW1lcy4gCitvIFJlYWQtb25seSBzdXBwb3J0IGZvciBMWk1BIHN0YW5kYWxvbmUgY29tcHJlc3Npb24gaGFzIGJlZW4gYWRkZWQuCisgIElzc3VlOiBDT01QUkVTUy0xMTEuCisKK0ZpeGVkIEJ1Z3M6CitvIFRhckJ1ZmZlci50cnlUb0NvbnN1bWVTZWNvbmRFT0ZSZWNvcmQgY291bGQgdGhyb3cgYQorICBOdWxsUG9pbnRlckV4Y2VwdGlvbiAgSXNzdWU6IENPTVBSRVNTLTIyMy4gVGhhbmtzIHRvIEplcmVteSBHdXN0aWUuIAorbyBQYXJzaW5nIG9mIHppcDY0IGV4dHJhIGZpZWxkcyBoYXMgYmVjb21lIG1vcmUgbGVuaWVudCBpbiBvcmRlcgorICB0byBiZSBhYmxlIHRvIHJlYWQgYXJjaGl2ZXMgY3JlYXRlZCBieSBEb3ROZXRaaXAgYW5kIG1heWJlCisgIG90aGVyIGFyY2hpdmVycyBhcyB3ZWxsLiAgSXNzdWU6IENPTVBSRVNTLTIyOC4gCitvIFRBUiB3aWxsIG5vdyBwcm9wZXJseSByZWFkIHRoZSBuYW1lcyBvZiBzeW1ib2xpYyBsaW5rcyB3aXRoCisgIGxvbmcgbmFtZXMgdGhhdCB1c2UgdGhlIEdOVSB2YXJpYW50IHRvIHNwZWNpZnkgdGhlIGxvbmcgZmlsZQorICBuYW1lLiAgSXNzdWU6IENPTVBSRVNTLTIyOS4gVGhhbmtzIHRvIENocmlzdG9waCBHeXNpbi4gCitvIFppcEZpbGUjZ2V0SW5wdXRTdHJlYW0gY291bGQgcmV0dXJuIG51bGwgaWYgdGhlIGFyY2hpdmUKKyAgY29udGFpbmVkIGR1cGxpY2F0ZSBlbnRyaWVzLgorICBUaGUgY2xhc3Mgbm93IGFsc28gcHJvdmlkZXMgdHdvIG5ldyBtZXRob2RzIHRvIG9idGFpbiBhbGwKKyAgZW50cmllcyBvZiBhIGdpdmVuIG5hbWUgcmF0aGVyIHRoYW4ganVzdCB0aGUgZmlyc3Qgb25lLgorICBJc3N1ZTogQ09NUFJFU1MtMjI3LiAKK28gQ3Bpb0FyY2hpdmVJbnB1dFN0cmVhbSBmYWlsZWQgdG8gcmVhZCBhcmNoaXZlcyBjcmVhdGVkIGJ5CisgIFJlZGxpbmUgUlBNLiAgSXNzdWU6IENPTVBSRVNTLTIzNi4gVGhhbmtzIHRvIEFuZHJldyBEdWZmeS4gCitvIFRhckFyY2hpdmVPdXRwdXRTdHJlYW0gbm93IHByb3Blcmx5IGhhbmRsZXMgbGluayBuYW1lcyB0aGF0CisgIGFyZSB0b28gbG9uZyB0byBmaXQgaW50byBhIHRyYWRpdGlvbmFsIFRBUiBoZWFkZXIuICBJc3N1ZToKKyAgQ09NUFJFU1MtMjM3LiBUaGFua3MgdG8gRW1tYW51ZWwgQm91cmcuCitvIFRoZSBhdXRvLWRldGVjdGluZyBjcmVhdGUqSW5wdXRTdHJlYW0gbWV0aG9kcyBvZiBBcmNoaXZlIGFuZAorICBDb21wcmVzc29yU3RyZWFtRmFjdG9yeSBjb3VsZCBmYWlsIHRvIGRldGVjdCB0aGUgZm9ybWF0IG9mCisgIGJsb2NraW5nIGlucHV0IHN0cmVhbXMuICBJc3N1ZTogQ09NUFJFU1MtMjM5LiAKKworQ2hhbmdlczoKK28gUmVhZGFiaWx0eSBwYXRjaCB0byBUYXJBcmNoaXZlSW5wdXRTdHJlYW0uICBJc3N1ZToKKyAgQ09NUFJFU1MtMjMyLiBUaGFua3MgdG8gQkVMVUdBIEJFSFIuCitvIFBlcmZvcm1hbmNlIGltcHJvdmVtZW50cyB0byBUYXJBcmNoaXZlSW5wdXRTdHJlYW0sIGluCisgIHBhcnRpY3VsYXIgdG8gdGhlIHNraXAgbWV0aG9kLiAgSXNzdWU6IENPTVBSRVNTLTIzNC4gVGhhbmtzIHRvCisgIEJFTFVHQSBCRUhSLiAKKworUmVsZWFzZSAxLjUKKy0tLS0tLS0tLS0tCisKK05ldyBmZWF0dXJlczoKKworbyBDb21wcmVzc29yU3RyZWFtRmFjdG9yeSBoYXMgYW4gb3B0aW9uIHRvIGNyZWF0ZSBkZWNvbXByZXNzaW5nCisgIHN0cmVhbXMgdGhhdCBkZWNvbXByZXNzIHRoZSBmdWxsIGlucHV0IGZvciBmb3JtYXRzIHRoYXQgc3VwcG9ydAorICBtdWx0aXBsZSBjb25jYXRlbmF0ZWQgc3RyZWFtcy4KKyAgSXNzdWU6IENPTVBSRVNTLTIyMC4KKworRml4ZWQgQnVnczoKKworbyBUeXBvIGluIENvbXByZXNzb3JTdHJlYW1GYWN0b3J5IEphdmFkb2MKKyAgSXNzdWU6IENPTVBSRVNTLTIxOC4KKyAgVGhhbmtzIHRvIEdpbGkuCitvIEFyY2hpdmVTdHJlYW1GYWN0b3J5J3MgdGFyIHN0cmVhbSBkZXRlY3Rpb24gY3JlYXRlZCBmYWxzZSBwb3NpdGl2ZXMKKyAgZm9yIEFJRkYgZmlsZXMuCisgIElzc3VlOiBDT01QUkVTUy0xOTEuCisgIFRoYW5rcyB0byBKdWtrYSBaaXR0aW5nLgorbyBYWiBmb3IgSmF2YSBkaWRuJ3QgcHJvdmlkZSBhbiBPU0dpIGJ1bmRsZS4gIENvbXByZXNzJyBkZXBlbmRlbmN5IG9uCisgIGl0IGhhcyBub3cgYmVlbiBtYXJrZWQgb3B0aW9uYWwgc28gQ29tcHJlc3MgaXRzZWxmIGNhbiBzdGlsbCBiZSB1c2VkCisgIGluIGFuIE9TR2kgY29udGV4dC4KKyAgSXNzdWU6IENPTVBSRVNTLTE5OS4KKyAgVGhhbmtzIHRvIEp1a2thIFppdHRpbmcuCitvIFdoZW4gc3BlY2lmeWluZyB0aGUgZW5jb2RpbmcgZXhwbGljaXRseSBUYXJBcmNoaXZlT3V0cHV0U3RyZWFtIHdvdWxkCisgIHdyaXRlIHVucmVhZGFibGUgbmFtZXMgaW4gR05VIG1vZGUgb3IgZXZlbiBjYXVzZSBlcnJvcnMgaW4gUE9TSVgKKyAgbW9kZSBmb3IgZmlsZSBuYW1lcyBsb25nZXIgdGhhbiA2NiBjaGFyYWN0ZXJzLgorICBJc3N1ZTogQ09NUFJFU1MtMjAwLgorICBUaGFua3MgdG8gQ2hyaXN0aWFuIFNjaGxpY2h0aGVybGUuCitvIFdyaXRpbmcgVEFSIFBBWCBoZWFkZXJzIGZhaWxlZCBpZiB0aGUgZ2VuZXJhdGVkIGVudHJ5IG5hbWUgZW5kZWQKKyAgd2l0aCBhICIvIi4KKyAgSXNzdWU6IENPTVBSRVNTLTIwMy4KK28gWmlwQXJjaGl2ZUlucHV0U3RyZWFtIHNvbWV0aW1lcyBmYWlsZWQgdG8gcHJvdmlkZSBpbnB1dCB0byB0aGUKKyAgSW5mbGF0ZXIgd2hlbiBpdCBuZWVkZWQgaXQsIGxlYWRpbmcgdG8gcmVhZHMgcmV0dXJuaW5nIDAuCisgIElzc3VlOiBDT01QUkVTUy0xODkuCisgIFRoYW5rcyB0byBEYW5pZWwgTG93ZS4KK28gVGFyQXJjaGl2ZUlucHV0U3RyZWFtIGlnbm9yZWQgdGhlIGVuY29kaW5nIGZvciBHTlUgbG9uZyBuYW1lCisgIGVudHJpZXMuCisgIElzc3VlOiBDT01QUkVTUy0yMTIuCitvIFRhckFyY2hpdmVJbnB1dFN0cmVhbSBjb3VsZCBsZWF2ZSB0aGUgc2Vjb25kIEVPRiByZWNvcmQgaW5zaWRlIHRoZQorICBzdHJlYW0gaXQgaGFkIGp1c3QgZmluaXNoZWQgcmVhZGluZy4KKyAgSXNzdWU6IENPTVBSRVNTLTIwNi4KKyAgVGhhbmtzIHRvIFBldGVyIERlIE1hZXllci4KK28gRHVtcEFyY2hpdmVJbnB1dFN0cmVhbSBubyBsb25nZXIgaW1wbGljaXRseSBjbG9zZXMgdGhlIG9yaWdpbmFsCisgIGlucHV0IHN0cmVhbSB3aGVuIGl0IHJlYWNoZXMgdGhlIGVuZCBvZiB0aGUgYXJjaGl2ZS4KK28gWmlwQXJjaGl2ZUlucHV0U3RyZWFtIG5vdyBjb25zdW1lcyB0aGUgcmVtYWluZGVyIG9mIHRoZSBhcmNoaXZlIHdoZW4KKyAgZ2V0TmV4dFppcEVudHJ5IHJldHVybnMgbnVsbC4KK28gVW5pdCB0ZXN0cyBjb3VsZCBmYWlsIGlmIHRoZSBzb3VyY2UgdHJlZSB3YXMgY2hlY2tlZCBvdXQgdG8gYQorICBkaXJlY3RvcnkgdHJlZSBjb250YWluaWduIHNwYWNlcy4KKyAgSXNzdWU6IENPTVBSRVNTLTIwNS4KKyAgVGhhbmtzIHRvIERhbmllbCBMb3dlLgorbyBGaXhlZCBhIHBvdGVudGlhbCBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gd2hlbiByZWFkaW5nIFNUT1JFRAorICBlbnRyaWVzIGZyb20gWmlwQXJjaGl2ZUlucHV0U3RyZWFtLgorICBJc3N1ZTogQ09NUFJFU1MtMjE5LgorbyBDb21wcmVzc29yU3RyZWFtRmFjdG9yeSBjYW4gbm93IGJlIHVzZWQgd2l0aG91dCBYWiBmb3IgSmF2YSBiZWluZworICBhdmFpbGFibGUuCisgIElzc3VlOiBDT01QUkVTUy0yMjEuCisKK0NoYW5nZXM6CisKK28gSW1wcm92ZWQgZXhjZXB0aW9uIG1lc3NhZ2UgaWYgYSB6aXAgYXJjaGl2ZSBjYW5ub3QgYmUgcmVhZCBiZWNhdXNlCisgIG9mIGFuIHVuc3VwcG9ydGVkIGNvbXByZXNzaW9uIG1ldGhvZC4KKyAgSXNzdWU6IENPTVBSRVNTLTE4OC4KKyAgVGhhbmtzIHRvIEhhcmFsZCBLdWhuLgorbyBBcmNoaXZlU3RyZWFtRmFjdG9yeSBoYXMgYSBzZXR0aW5nIGZvciBmaWxlIG5hbWUgZW5jb2RpbmcgdGhhdCBzZXRzCisgIHVwIGVuY29kaW5nIGZvciBaSVAgYW5kIFRBUiBzdHJlYW1zLgorICBJc3N1ZTogQ09NUFJFU1MtMTkyLgorICBUaGFua3MgdG8gSnVra2EgWml0dGluZy4KK28gVGFyQXJjaGl2ZUVudHJ5IG5vdyBoYXMgYSBtZXRob2QgdG8gdmVyaWZ5IGl0cyBjaGVja3N1bS4KKyAgSXNzdWU6IENPTVBSRVNTLTE5MS4KKyAgVGhhbmtzIHRvIEp1a2thIFppdHRpbmcuCitvIFNwbGl0L3NwYW5uZWQgWklQIGFyY2hpdmVzIGFyZSBub3cgcHJvcGVybHkgZGV0ZWN0ZWQgYnkKKyAgQXJjaGl2ZVN0cmVhbUZhY3RvcnkgYnV0IHdpbGwgY2F1c2UgYW4KKyAgVW5zdXBwb3J0ZWRaaXBGZWF0dXJlRXhjZXB0aW9uIHdoZW4gcmVhZC4KK28gWmlwQXJjaGl2ZUlucHV0U3RyZWFtIG5vdyByZWFkcyBhcmNoaXZlcyB0aGF0IHN0YXJ0IHdpdGggYSAiUEswMCIKKyAgc2lnbmF0dXJlLiAgQXJjaGl2ZXMgd2l0aCB0aGlzIHNpZ25hdHVyZXMgYXJlIGNyZWF0ZWQgd2hlbiB0aGUKKyAgYXJjaGl2ZXIgd2FzIHdpbGxpbmcgdG8gc3BsaXQgdGhlIGFyY2hpdmUgYnV0IGluIHRoZSBlbmQgb25seSBuZWVkZWQKKyAgYSBzaW5nbGUgc2VnbWVudCAtIHNvIGRpZG4ndCBzcGxpdCBhbnl0aGluZy4KKyAgSXNzdWU6IENPTVBSRVNTLTIwOC4KK28gVGFyQXJjaGl2ZUVudHJ5IGhhcyBhIG5ldyBjb25zdHJ1Y3RvciB0aGF0IGFsbG93cyBzZXR0aW5nIGxpbmtGbGFnCisgIGFuZCBwcmVzZXJ2ZUxlYWRpbmdTbGFzaGVzIGF0IHRoZSBzYW1lIHRpbWUuCisgIElzc3VlOiBDT01QUkVTUy0yMDEuCitvIENoYW5nZVNldFBlcmZvcm1lciBoYXMgYSBuZXcgcGVyZm9ybSBvdmVybG9hZCB0aGF0IHVzZXMgYSBaaXBGaWxlCisgIGluc3RhbmNlIGFzIGlucHV0LgorICBJc3N1ZTogQ09NUFJFU1MtMTU5LgorbyBHYXJiYWdlIGNvbGxlY3Rpb24gcHJlc3N1cmUgaGFzIGJlZW4gcmVkdWNlZCBieSByZXVzaW5nIHRlbXBvcmFyeQorICBieXRlIGFycmF5cyBpbiBjbGFzc2VzLgorICBJc3N1ZTogQ09NUFJFU1MtMTcyLgorICBUaGFua3MgdG8gVGhvbWFzIE1haXIuCitvIENhbiBub3cgaGFuZGxlIHppcCBleHRyYSBmaWVsZCAweDU0NTUgLSBFeHRlbmRlZCBUaW1lc3RhbXAuCisgIElzc3VlOiBDT01QUkVTUy0yMTAuCisgIFRoYW5rcyB0byBKdWxpdXMgRGF2aWVzLgorbyBoYW5kbGUgemlwIGV4dHJhIGZpZWxkIDB4Nzg3NSAtIEluZm8gWmlwIE5ldyBVbml4IEV4dHJhIEZpZWxkLgorICBJc3N1ZTogQ09NUFJFU1MtMjExLgorICBUaGFua3MgdG8gSnVsaXVzIERhdmllcy4KK28gWmlwU2hvcnQsIFppcExvbmcsIFppcEVpZ2h0Qnl0ZUludGVnZXIgc2hvdWxkIGltcGxlbWVudCBTZXJpYWxpemFibGUKKyAgSXNzdWU6IENPTVBSRVNTLTIxMy4KKyAgVGhhbmtzIHRvIEp1bGl1cyBEYXZpZXMuCitvIGJldHRlciBzdXBwb3J0IGZvciB1bml4IHN5bWxpbmtzIGluIFppcEZpbGUgZW50cmllcy4KKyAgSXNzdWU6IENPTVBSRVNTLTIxNC4KKyAgVGhhbmtzIHRvIEp1bGl1cyBEYXZpZXMuCitvIFppcEZpbGUncyBpbml0aWFsaXphdGlvbiBoYXMgYmVlbiBpbXByb3ZlZCBmb3Igbm9uLVppcDY0IGFyY2hpdmVzLgorICBJc3N1ZTogQ09NUFJFU1MtMjE1LgorICBUaGFua3MgdG8gUm9iaW4gUG93ZXIuCitvIFVwZGF0ZWQgWFogZm9yIEphdmEgZGVwZW5kZW5jeSB0byAxLjIgYXMgdGhpcyB2ZXJzaW9uIHByb3ZpZGVzCisgIHByb3BlciBPU0dpIG1hbmlmZXN0IGF0dHJpYnV0ZXMuCisKK1JlbGVhc2UgMS40LjEKKy0tLS0tLS0tLS0tLS0KKworVGhpcyBpcyBhIHNlY3VyaXR5IGJ1Z2ZpeCByZWxlYXNlLCBzZWUKK2h0dHBzOi8vY29tbW9ucy5hcGFjaGUub3JnL3Byb3Blci9jb21tb25zLWNvbXByZXNzL3NlY3VyaXR5Lmh0bWwjRml4ZWRfaW5fQXBhY2hlX0NvbW1vbnNfQ29tcHJlc3NfMS40LjEKKworRml4ZWQgQnVnczoKKworbyBQb3J0ZWQgbGliYnppcDIncyBmYWxsYmFjayBzb3J0IGFsZ29yaXRobSB0bworICBCWmlwMkNvbXByZXNzb3JPdXRwdXRTdHJlYW0gdG8gc3BlZWQgdXAgY29tcHJlc3Npb24gaW4gY2VydGFpbgorICBlZGdlIGNhc2VzLgorCitSZWxlYXNlIDEuNAorLS0tLS0tLS0tLS0KKworTmV3IGZlYXR1cmVzOgorbyBDT01QUkVTUy0xNTY6ICBTdXBwb3J0IGZvciB0aGUgWFogZm9ybWF0IGhhcyBiZWVuIGFkZGVkLiAKKworRml4ZWQgQnVnczoKK28gQ09NUFJFU1MtMTgzOiAgVGhlIHRhciBwYWNrYWdlIG5vdyBhbGxvd3MgdGhlIGVuY29kaW5nIG9mIGZpbGUgbmFtZXMgdG8gYmUKKyAgICAgICAgICAgICAgICAgc3BlY2lmaWVkIGFuZCBjYW4gb3B0aW9uYWxseSB1c2UgUEFYIGV4dGVuc2lvbiBoZWFkZXJzIHRvCisgICAgICAgICAgICAgICAgIHdyaXRlIG5vbi1BU0NJSSBmaWxlIG5hbWVzLgorICAgICAgICAgICAgICAgICBUaGUgc3RyZWFtIGNsYXNzZXMgbm93IHdyaXRlIChvciBleHBlY3QgdG8gcmVhZCkgYXJjaGl2ZXMgdGhhdAorICAgICAgICAgICAgICAgICB1c2UgdGhlIHBsYXRmb3JtJ3MgbmF0aXZlIGVuY29kaW5nIGZvciBmaWxlIG5hbWVzLiAgQXBhY2hlCisgICAgICAgICAgICAgICAgIENvbW1vbnMgQ29tcHJlc3MgMS4zIHVzZWQgdG8gc3RyaXAgZXZlcnl0aGluZyBidXQgdGhlIGxvd2VyCisgICAgICAgICAgICAgICAgIGVpZ2h0IGJpdHMgb2YgZWFjaCBjaGFyYWN0ZXIgd2hpY2ggZWZmZWN0aXZlbHkgb25seSB3b3JrZWQgZm9yCisgICAgICAgICAgICAgICAgIEFTQ0lJIGFuZCBJU08tODg1OS0xIGZpbGUgbmFtZXMuCisgICAgICAgICAgICAgICAgIFRoaXMgbmV3IGRlZmF1bHQgYmVoYXZpb3IgaXMgYSBicmVha2luZyBjaGFuZ2UuIAorbyBDT01QUkVTUy0xODQ6ICBUYXJBcmNoaXZlSW5wdXRTdHJlYW0gZmFpbGVkIHRvIHBhcnNlIFBBWCBoZWFkZXJzIHRoYXQKKyAgICAgICAgICAgICAgICAgY29udGFpbmVkIG5vbi1BU0NJSSBjaGFyYWN0ZXJzLiAKK28gQ09NUFJFU1MtMTc4OiAgVGFyQXJjaGl2ZUlucHV0U3RyZWFtIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaW5zdGVhZCBvZiBJT0V4Y2VwdGlvbiAKK28gQ09NUFJFU1MtMTc5OiAgVGFyVXRpbHMuZm9ybWF0TG9uZ09jdGFsT3JCaW5hcnlCeXRlcygpIGFzc3VtZXMgdGhlIGZpZWxkIHdpbGwgYmUgMTIgYnl0ZXMgbG9uZyAKK28gQ09NUFJFU1MtMTc1OiAgR05VIFRhciBzb21ldGltZXMgdXNlcyBiaW5hcnkgZW5jb2RpbmcgZm9yIFVJRCBhbmQgR0lEIAorbyBDT01QUkVTUy0xNzE6ICBBcmNoaXZlU3RyZWFtRmFjdG9yeS5jcmVhdGVBcmNoaXZlSW5wdXRTdHJlYW0gd291bGQgY2xhaW0KKyAgICAgICAgICAgICAgICAgc2hvcnQgdGV4dCBmaWxlcyB3ZXJlIFRBUiBhcmNoaXZlcy4gCitvIENPTVBSRVNTLTE2NDogIFppcEZpbGUgZGlkbid0IHdvcmsgcHJvcGVybHkgZm9yIGFyY2hpdmVzIHVzaW5nIHVuaWNvZGUgZXh0cmEKKyAgICAgICAgICAgICAgICAgZmllbGRzIHJhdGhlciB0aGFuIFVURi04IGZpbGVuYW1lcyBhbmQgdGhlIEVGUy1GbGFnLiAKK28gQ09NUFJFU1MtMTY5OiAgRm9yIGNvcnJ1cHQgYXJjaGl2ZXMgWmlwRmlsZSB3b3VsZCB0aHJvdyBhIFJ1bnRpbWVFeGNlcHRpb24gaW4KKyAgICAgICAgICAgICAgICAgc29tZSBjYXNlcyBhbmQgYW4gSU9FeGNlcHRpb24gaW4gb3RoZXJzLiAgSXQgd2lsbCBub3cKKyAgICAgICAgICAgICAgICAgY29uc2lzdGVudGx5IHRocm93IGFuIElPRXhjZXB0aW9uLiAKKworQ2hhbmdlczoKK28gQ09NUFJFU1MtMTgyOiAgVGhlIHRhciBwYWNrYWdlIGNhbiBub3cgd3JpdGUgYXJjaGl2ZXMgdGhhdCB1c2Ugc3Rhci9HTlUvQlNECisgICAgICAgICAgICAgICAgIGV4dGVuc2lvbnMgb3IgdXNlIHRoZSBQT1NJWC9QQVggdmFyaWFudCB0byBzdG9yZSBudW1lcmljCisgICAgICAgICAgICAgICAgIHZhbHVlcyB0aGF0IGRvbid0IGZpdCBpbnRvIHRoZSB0cmFkaXRpb25hbCBoZWFkZXIgZmllbGRzLiAKK28gQ09NUFJFU1MtMTgxOiAgQWRkZWQgYSB3b3JrYXJvdW5kIGZvciBhIEJ1ZyBzb21lIHRhciBpbXBsZW1lbnRhdGlvbnMgdGhhdCBhZGQKKyAgICAgICAgICAgICAgICAgYSBOVUwgYnl0ZSBhcyBmaXJzdCBieXRlIGluIG51bWVyaWMgaGVhZGVyIGZpZWxkcy4gCitvIENPTVBSRVNTLTE3NjogIEFkZGVkIGEgd29ya2Fyb3VuZCBmb3IgYSBCdWcgaW4gV2luWklQIHdoaWNoIHVzZXMgYmFja3NsYXNoZXMKKyAgICAgICAgICAgICAgICAgYXMgcGF0aCBzZXBhcmF0b3JzIGluIFVuaWNvZGUgRXh0cmEgRmllbGRzLiAKK28gQ09NUFJFU1MtMTMxOiAgQXJyYXlPdXRPZkJvdW5kcyB3aGlsZSBkZWNvbXByZXNzaW5nIGJ6Mi4gQWRkZWQgdGVzdCBjYXNlIC0gY29kZSBhbHJlYWR5IHNlZW1zIHRvIGhhdmUgYmVlbiBmaXhlZC4gCitvIENPTVBSRVNTLTE0NjogIEJaaXAyQ29tcHJlc3NvcklucHV0U3RyZWFtIG5vdyBvcHRpb25hbGx5IHN1cHBvcnRzIHJlYWRpbmcgb2YKKyAgICAgICAgICAgICAgICAgY29uY2F0ZW5hdGVkIC5iejIgZmlsZXMuIAorbyBDT01QUkVTUy0xNTQ6ICBHWmlwQ29tcHJlc3NvcklucHV0U3RyZWFtIG5vdyBvcHRpb25hbGx5IHN1cHBvcnRzIHJlYWRpbmcgb2YKKyAgICAgICAgICAgICAgICAgY29uY2F0ZW5hdGVkIC5neiBmaWxlcy4gCitvIENPTVBSRVNTLTE2OiAgVGhlIHRhciBwYWNrYWdlIGNhbiBub3cgcmVhZCBhcmNoaXZlcyB0aGF0IHVzZSBzdGFyL0dOVS9CU0QKKyAgICAgICAgICAgICAgICAgZXh0ZW5zaW9ucyBmb3IgZmlsZXMgdGhhdCBhcmUgbG9uZ2VyIHRoYW4gOCBHQnl0ZSBhcyB3ZWxsIGFzCisgICAgICAgICAgICAgICAgIGFyY2hpdmVzIHRoYXQgdXNlIHRoZSBQT1NJWC9QQVggdmFyaWFudC4gCitvIENPTVBSRVNTLTE2NTogIFRoZSB0YXIgcGFja2FnZSBjYW4gbm93IHdyaXRlIGFyY2hpdmVzIHRoYXQgdXNlIHN0YXIvR05VL0JTRAorICAgICAgICAgICAgICAgICBleHRlbnNpb25zIGZvciBmaWxlcyB0aGF0IGFyZSBsb25nZXIgdGhhbiA4IEdCeXRlIGFzIHdlbGwgYXMKKyAgICAgICAgICAgICAgICAgYXJjaGl2ZXMgdGhhdCB1c2UgdGhlIFBPU0lYL1BBWCB2YXJpYW50LiAKK28gQ09NUFJFU1MtMTY2OiAgVGhlIHRhciBwYWNrYWdlIGNhbiBub3cgdXNlIHRoZSBQT1NJWC9QQVggdmFyaWFudCBmb3Igd3JpdGluZworICAgICAgICAgICAgICAgICBlbnRyaWVzIHdpdGggbmFtZXMgbG9uZ2VyIHRoYW4gMTAwIGNoYXJhY3RlcnMuIAorCitSZWxlYXNlIDEuMworLS0tLS0tLS0tLS0KKworQ29tbW9ucyBDb21wcmVzcyAxLjMgaXMgdGhlIGZpcnN0IHZlcnNpb24gdG8gcmVxdWlyZSBKYXZhNSBhdCBydW50aW1lLgorCitDaGFuZ2VzIGluIHRoaXMgdmVyc2lvbiBpbmNsdWRlOgorCitOZXcgZmVhdHVyZXM6CitvIFN1cHBvcnQgZm9yIHRoZSBQYWNrMjAwIGZvcm1hdCBoYXMgYmVlbiBhZGRlZC4gIElzc3VlOiBDT01QUkVTUy0xNDIuIAorbyBSZWFkLW9ubHkgc3VwcG9ydCBmb3IgdGhlIGZvcm1hdCB1c2VkIGJ5IHRoZSBVbml4IGR1bXAoOCkgdG9vbAorICBoYXMgYmVlbiBhZGRlZC4gIElzc3VlOiBDT01QUkVTUy0xMzIuIAorCitGaXhlZCBCdWdzOgorbyBCWmlwMkNvbXByZXNzb3JJbnB1dFN0cmVhbSdzIGdldEJ5dGVzUmVhZCBtZXRob2QgYWx3YXlzCisgIHJldHVybmVkIDAuIAorbyBaaXBBcmNoaXZlSW5wdXRTdHJlYW0gYW5kIFppcEFyY2hpdmVPdXRwdXRTdHJlYW0gY291bGQgbGVhaworICByZXNvdXJjZXMgb24gc29tZSBKREtzLiAgSXNzdWU6IENPTVBSRVNTLTE1Mi4gCitvIFRhckFyY2hpdmVPdXRwdXRTdHJlYW0ncyBnZXRCeXRlc1dyaXR0ZW4gbWV0aG9kIGRpZG4ndCBjb3VudAorICBjb3JyZWN0bHkuICBJc3N1ZTogQ09NUFJFU1MtMTYwLiAKKworQ2hhbmdlczoKK28gVGhlIFpJUCBwYWNrYWdlIG5vdyBzdXBwb3J0cyBaaXA2NCBleHRlbnNpb25zLiAgSXNzdWU6IENPTVBSRVNTLTM2LiAKK28gVGhlIEFSIHBhY2thZ2Ugbm93IHN1cHBvcnRzIHRoZSBCU0QgZGlhbGVjdCBvZiBzdG9yaW5nIGZpbGUKKyAgbmFtZXMgbG9uZ2VyIHRoYW4gMTYgY2hhcnMgKGJvdGggcmVhZGluZyBhbmQgd3JpdGluZykuCisgIElzc3VlOiBDT01QUkVTUy0xNDQuIAorCitSZWxlYXNlIDEuMgorLS0tLS0tLS0tLS0KKworTmV3IGZlYXR1cmVzOgorbyBDT01QUkVTUy0xMjM6ICBaaXBBcmNoaXZlRW50cnkgaGFzIGEgbmV3IG1ldGhvZCBnZXRSYXdOYW1lIHRoYXQgcHJvdmlkZXMgdGhlCisgICAgICAgIG9yaWdpbmFsIGJ5dGVzIHRoYXQgbWFkZSB1cCB0aGUgbmFtZS4gIFRoaXMgbWF5IGFsbG93IHVzZXIKKyAgICAgICAgY29kZSB0byBkZXRlY3QgdGhlIGVuY29kaW5nLiAKK28gQ09NUFJFU1MtMTIyOiAgVGFyQXJjaGl2ZUVudHJ5IHByb3ZpZGVzIGFjY2VzcyB0byB0aGUgZmxhZ3MgdGhhdCBkZXRlcm1pbmUKKyAgICAgICAgd2hldGhlciBpdCBpcyBhbiBhcmNoaXZlZCBzeW1ib2xpYyBsaW5rLCBwaXBlIG9yIG90aGVyCisgICAgICAgICJ1bmNvbW1vbiIgZmlsZSBzeXN0ZW0gb2JqZWN0LiAKKworRml4ZWQgQnVnczoKK28gQ09NUFJFU1MtMTI5OiAgWmlwQXJjaGl2ZUlucHV0U3RyZWFtIGNvdWxkIGZhaWwgd2l0aCBhICJUcnVuY2F0ZWQgWklQIiBlcnJvcgorICAgICAgICBtZXNzYWdlIGZvciBlbnRyaWVzIGJldHdlZW4gMiBHQnl0ZSBhbmQgNCBHQnl0ZSBpbiBzaXplLiAKK28gQ09NUFJFU1MtMTQ1OiAgVGFyQXJjaGl2ZUlucHV0U3RyZWFtIG5vdyBkZXRlY3RzIHNwYXJzZSBlbnRyaWVzIHVzaW5nIHRoZQorICAgICAgICBvbGRnbnUgZm9ybWF0IGFuZCBwcm9wZXJseSByZXBvcnRzIGl0IGNhbm5vdCBleHRyYWN0IHRoZWlyCisgICAgICAgIGNvbnRlbnRzLiAKK28gQ09NUFJFU1MtMTMwOiAgVGhlIEphdmFkb2MgZm9yIFppcEFyY2hpdmVJbnB1dFN0cmVhbSNza2lwIG5vdyBtYXRjaGVzIHRoZQorICAgICAgICBpbXBsZW1lbnRhdGlvbiwgdGhlIGNvZGUgaGFzIGJlZW4gbWFkZSBtb3JlIGRlZmVuc2l2ZS4gCitvIENPTVBSRVNTLTE0MDogIEFyQXJjaGl2ZUlucHV0U3RyZWFtIGZhaWxzIGlmIGVudHJpZXMgY29udGFpbiBvbmx5IGJsYW5rcyBmb3IKKyAgICAgICAgdXNlcklkIG9yIGdyb3VwSWQuIFRoYW5rcyB0byBUcmVqa2F6LiAKK28gQ09NUFJFU1MtMTM5OiAgWmlwRmlsZSBtYXkgbGVhayByZXNvdXJjZXMgb24gc29tZSBKREtzLiAKK28gQ09NUFJFU1MtMTI1OiAgQlppcDJDb21wcmVzc29ySW5wdXRTdHJlYW0gdGhyb3dzIElPRXhjZXB0aW9uIGlmCisgICAgICAgIHVuZGVybHlpbmcgc3RyZWFtIHJldHVybnMgYXZhaWxhYmxlKCkgPT0gMC4KKyAgICAgICAgUmVtb3ZlZCB0aGUgY2hlY2suIAorbyBDT01QUkVTUy0xMjc6ICBDYWxsaW5nIGNsb3NlKCkgb24gaW5wdXRTdHJlYW0gcmV0dXJuZWQgYnkKKyAgICAgICAgQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkuY3JlYXRlQ29tcHJlc3NvcklucHV0U3RyZWFtKCkKKyAgICAgICAgZG9lcyBub3QgY2xvc2UgdGhlIHVuZGVybHlpbmcgaW5wdXQgc3RyZWFtLiAKK28gQ09NUFJFU1MtMTE5OiAgVGFyQXJjaGl2ZU91dHB1dFN0cmVhbSNmaW5pc2ggbm93IHdyaXRlcyBhbGwgYnVmZmVyZWQKKyAgICAgICAgZGF0YSB0byB0aGUgc3RyZWFtIAorCitDaGFuZ2VzOgorbyBaaXBGaWxlIG5vdyBpbXBsZW1lbnRzIGZpbmFsaXplIHdoaWNoIGNsb3NlcyB0aGUgdW5kZXJseWluZworICAgICAgICBmaWxlLiAKK28gQ09NUFJFU1MtMTE3OiAgQ2VydGFpbiB0YXIgZmlsZXMgbm90IHJlY29nbmlzZWQgYnkKKyAgICAgICAgQXJjaGl2ZVN0cmVhbUZhY3RvcnkuIAorCitSZWxlYXNlIDEuMQorLS0tLS0tLS0tLS0KKworTmV3IGZlYXR1cmVzOgorbyBDT01QUkVTUy0xMDg6ICBDb21tYW5kLWxpbmUgaW50ZXJmYWNlIHRvIGxpc3QgYXJjaGl2ZSBjb250ZW50cy4KKyAgICAgICBVc2FnZTogamF2YSAtamFyIGNvbW1vbnMtY29tcHJlc3Mtbi5tLmphciBhcmNoaXZlLW5hbWUgW3ppcHx0YXJ8ZXRjXSAKK28gQ09NUFJFU1MtMTA5OiAgVGFyIGltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgUGF4IGhlYWRlcnMKKyAgICAgICBBZGRlZCBzdXBwb3J0IGZvciByZWFkaW5nIHBheCBoZWFkZXJzLgorICAgICAgIE5vdGU6IGRvZXMgbm90IHN1cHBvcnQgZ2xvYmFsIHBheCBoZWFkZXJzIAorbyBDT01QUkVTUy0xMDM6ICBaaXBBcmNoaXZlSW5wdXRTdHJlYW0gY2FuIG9wdGlvbmFsbHkgZXh0cmFjdCBkYXRhIHRoYXQgdXNlZAorICAgICAgICB0aGUgU1RPUkVEIGNvbXByZXNzaW9uIG1ldGhvZCBhbmQgYSBkYXRhIGRlc2NyaXB0b3IuCisgICAgICAgIERvaW5nIHNvIGluIGEgc3RyZWFtIGlzIG5vdCBzYWZlIGluIGdlbmVyYWwsIHNvIHlvdSBoYXZlIHRvCisgICAgICAgIGV4cGxpY2l0bHkgZW5hYmxlIHRoZSBmZWF0dXJlLiAgQnkgZGVmYXVsdCB0aGUgc3RyZWFtIHdpbGwKKyAgICAgICAgdGhyb3cgYW4gZXhjZXB0aW9uIGlmIGl0IGVuY291bnRlcnMgc3VjaCBhbiBlbnRyeS4gCitvIENPTVBSRVNTLTk4OiAgVGhlIFpJUCBjbGFzc2VzIHdpbGwgdGhyb3cgc3BlY2lhbGl6ZWQgZXhjZXB0aW9ucyBpZiBhbnkKKyAgICAgICAgYXR0ZW1wdCBpcyBtYWRlIHRvIHJlYWQgb3Igd3JpdGUgZGF0YSB0aGF0IHVzZXMgemlwIGZlYXR1cmVzCisgICAgICAgIG5vdCBzdXBwb3J0ZWQgKHlldCkuIAorbyBDT01QUkVTUy05OTogIFppcEZpbGUjZ2V0RW50cmllcyByZXR1cm5zIGVudHJpZXMgaW4gYSBwcmVkaWN0YWJsZSBvcmRlciAtCisgICAgICAgIHRoZSBvcmRlciB0aGV5IGFwcGVhciBpbnNpZGUgdGhlIGNlbnRyYWwgZGlyZWN0b3J5LgorICAgICAgICBBIG5ldyBtZXRob2QgZ2V0RW50cmllc0luUGh5c2ljYWxPcmRlciByZXR1cm5zIGVudHJpZXMgaW4KKyAgICAgICAgb3JkZXIgb2YgdGhlIGVudHJ5IGRhdGEsIGkuZS4gdGhlIG9yZGVyIFppcEFyY2hpdmVJbnB1dFN0cmVhbQorICAgICAgICB3b3VsZCBzZWUuIAorbyBUaGUgQXJjaGl2ZSpTdHJlYW0gYW5kIFppcEZpbGUgY2xhc3NlcyBub3cgaGF2ZQorICAgICAgICBjYW4oUmVhZHxXcml0ZSlFbnRyeURhdGEgbWV0aG9kcyB0aGF0IGNhbiBiZSB1c2VkIHRvIGNoZWNrCisgICAgICAgIHdoZXRoZXIgYSBnaXZlbiBlbnRyeSdzIGRhdGEgY2FuIGJlIHJlYWQvd3JpdHRlbi4KKyAgICAgICAgVGhlIG1ldGhvZCBjdXJyZW50bHkgcmV0dXJucyBmYWxzZSBmb3IgWklQIGFyY2hpdmVzIGlmIGFuCisgICAgICAgIGVudHJ5IHVzZXMgYW4gdW5zdXBwb3J0ZWQgY29tcHJlc3Npb24gbWV0aG9kIG9yIGVuY3J5cHRpb24uIAorbyBDT01QUkVTUy04OTogIFRoZSBaSVAgY2xhc3NlcyBub3cgZGV0ZWN0IGVuY3J5cHRlZCBlbnRyaWVzLiAKK28gQ09NUFJFU1MtOTc6ICBBZGRlZCBhdXRvZGV0ZWN0aW9uIG9mIGNvbXByZXNzaW9uIGZvcm1hdCB0bworICAgICAgICBDb21wcmVzc29yU3RyZWFtRmFjdG9yeS4gCitvIENPTVBSRVNTLTk1OiAgSW1wcm92ZSBFeGNlcHRpb25NZXNzYWdlcyBpbiBBcmNoaXZlU3RyZWFtRmFjdG9yeSBUaGFua3MgdG8gSm9lcmcgQmVsbG1hbm4uIAorbyBBIG5ldyBjb25zdHJ1Y3RvciBvZiBUYXJBcmNoaXZlRW50cnkgY2FuIGNyZWF0ZSBlbnRyaWVzIHdpdGgKKyAgICAgICAgbmFtZXMgdGhhdCBzdGFydCB3aXRoIHNsYXNoZXMgLSB0aGUgZGVmYXVsdCBpcyB0byBzdHJpcAorICAgICAgICBsZWFkaW5nIHNsYXNoZXMgaW4gb3JkZXIgdG8gY3JlYXRlIHJlbGF0aXZlIHBhdGggbmFtZXMuIAorbyBBcmNoaXZlRW50cnkgbm93IGhhcyBhIGdldExhc3RNb2RpZmllZERhdGUgbWV0aG9kLiAKK28gQ09NUFJFU1MtNzg6ICBBZGQgYSBCWmlwMlV0aWxzIGNsYXNzIG1vZGVsbGVkIGFmdGVyIEdaaXBVdGlscyBUaGFua3MgdG8gSnVra2EgWml0dGluZy4gCisKK0ZpeGVkIEJ1Z3M6CitvIENPTVBSRVNTLTcyOiAgTW92ZSBhY2tub3dsZWRnZW1lbnRzIGZyb20gTk9USUNFIHRvIFJFQURNRSAKK28gQ09NUFJFU1MtMTEzOiAgVGFyQXJjaGl2ZUVudHJ5LnBhcnNlVGFySGVhZGVyKCkgaW5jbHVkZXMgdGhlIHRyYWlsaW5nIHNwYWNlL05VTCB3aGVuIHBhcnNpbmcgdGhlIG9jdGFsIHNpemUgCitvIENPTVBSRVNTLTExODogIFRhclV0aWxzLnBhcnNlTmFtZSBkb2VzIG5vdCBwcm9wZXJseSBoYW5kbGUgY2hhcmFjdGVycyBvdXRzaWRlIHRoZSByYW5nZSAwLTEyNyAKK28gQ09NUFJFU1MtMTA3OiAgQXJjaGl2ZVN0cmVhbUZhY3RvcnkgZG9lcyBub3QgcmVjb2duaXNlIHRhciBmaWxlcyBjcmVhdGVkIGJ5IEFudCAKK28gQ09NUFJFU1MtMTEwOiAgU3VwcG9ydCAidXN0YXIiIHByZWZpeCBmaWVsZCwgd2hpY2ggaXMgdXNlZCB3aGVuIGZpbGUgcGF0aHMgYXJlIGxvbmdlcgorICAgICAgIHRoYW4gMTAwIGNoYXJhY3RlcnMuIAorbyBDT01QUkVTUy0xMDA6ICBaaXBBcmNoaXZlSW5wdXRTdHJlYW0gd2lsbCB0aHJvdyBhbiBleGNlcHRpb24gaWYgaXQgZGV0ZWN0cyBhbgorICAgICAgICBlbnRyeSB0aGF0IHVzZXMgYSBkYXRhIGRlc2NyaXB0b3IgZm9yIGEgU1RPUkVEIGVudHJ5IHNpbmNlIGl0CisgICAgICAgIGNhbm5vdCByZWxpYWJseSBmaW5kIHRoZSBlbmQgb2YgZGF0YSBmb3IgdGhpcyAiY29tcHJlc3Npb24iCisgICAgICAgIG1ldGhvZC4gCitvIENPTVBSRVNTLTEwMTogIFppcEFyY2hpdmVJbnB1dFN0cmVhbSBzaG91bGQgbm93IHByb3Blcmx5IHJlYWQgYXJjaGl2ZXMgdGhhdAorICAgICAgICB1c2UgZGF0YSBkZXNjcmlwdG9ycyBidXQgd2l0aG91dCB0aGUgInVub2ZmaWNpYWwiIHNpZ25hdHVyZS4gCitvIENPTVBSRVNTLTc0OiAgWmlwQXJjaGl2ZUlucHV0U3RyZWFtIGZhaWxlZCB0byB1cGRhdGUgdGhlIG51bWJlciBvZiBieXRlcworICAgICAgICByZWFkIHByb3Blcmx5LiAKK28gQXJjaGl2ZUlucHV0U3RyZWFtIGhhcyBhIG5ldyBtZXRob2QgZ2V0Qnl0ZXNSZWFkIHRoYXQgc2hvdWxkCisgICAgICAgIGJlIHByZWZlcnJlZCBvdmVyIGdldENvdW50IHNpbmNlIHRoZSBsYXRlciBtYXkgdHJ1bmNhdGUgdGhlCisgICAgICAgIG51bWJlciBvZiBieXRlcyByZWFkIGZvciBiaWcgYXJjaGl2ZXMuIAorbyBDT01QUkVTUy04NTogIFRoZSBjcGlvIGFyY2hpdmVzIGNyZWF0ZWQgYnkgQ3Bpb0FyY2hpdmVPdXRwdXRTdHJlYW0gY291bGRuJ3QKKyAgICAgICAgYmUgcmVhZCBieSBtYW55IGV4aXN0aW5nIG5hdGl2ZSBpbXBsZW1lbnRhdGlvbnMgYmVjYXVzZSB0aGUKKyAgICAgICAgYXJjaGl2ZXMgY29udGFpbmVkIG11bHRpcGxlIGVudHJpZXMgd2l0aCB0aGUgc2FtZSBpbm9kZS9kZXZpY2UKKyAgICAgICAgY29tYmluYXRpb25zIGFuZCB3ZXJlbid0IHBhZGRlZCB0byBhIGJsb2Nrc2l6ZSBvZiA1MTIgYnl0ZXMuIAorbyBDT01QUkVTUy03MzogIFppcEFyY2hpdmVFbnRyeSwgWmlwRmlsZSBhbmQgWmlwQXJjaGl2ZUlucHV0U3RyZWFtIGFyZSBub3cKKyAgICAgICAgbW9yZSBsZW5pZW50IHdoZW4gcGFyc2luZyBleHRyYSBmaWVsZHMuIAorbyBDT01QUkVTUy04MjogIGNwaW8gaXMgdGVycmlibHkgc2xvdy4KKyAgICAgICAgRG9jdW1lbnRlZCB0aGF0IGJ1ZmZlcmVkIHN0cmVhbXMgYXJlIG5lZWRlZCBmb3IgcGVyZm9ybWFuY2UgCitvIEltcHJvdmVkIGV4Y2VwdGlvbiBtZXNzYWdlIGlmIHRoZSBleHRyYSBmaWVsZCBkYXRhIGluIFpJUAorICAgICAgICBhcmNoaXZlcyBjYW5ub3QgYmUgcGFyc2VkLiAKK28gQ09NUFJFU1MtMTc6ICBUYXIgZm9ybWF0IHVuc3BlY2lmaWVkIC0gY3VycmVudCBzdXBwb3J0IGRvY3VtZW50ZWQuIAorbyBDT01QUkVTUy05NDogIFppcEFyY2hpdmVFbnRyeSdzIGVxdWFscyBtZXRob2Qgd2FzIGJyb2tlbiBmb3IgZW50cmllcyBjcmVhdGVkCisgICAgICAgIHdpdGggdGhlIFN0cmluZy1hcmcgY29uc3RydWN0b3IuICBUaGlzIGxlYWQgdG8gYnJva2VuIFpJUAorICAgICAgICBhcmNoaXZlcyBpZiB0d28gZGlmZmVyZW50IGVudHJpZXMgaGFkIHRoZSBzYW1lIGhhc2ggY29kZS4gVGhhbmtzIHRvIEFub24gRGV2cy4gCitvIENPTVBSRVNTLTg3OiAgWmlwQXJjaGl2ZUlucHV0U3RyZWFtIGNvdWxkIHJlcGVhdGVkbHkgcmV0dXJuIDAgb24gcmVhZCgpIHdoZW4KKyAgICAgICAgdGhlIGFyY2hpdmUgd2FzIHRydW5jYXRlZC4gVGhhbmtzIHRvIEFudG9uaSBNeWxrYS4gCitvIENPTVBSRVNTLTg2OiAgVGFyIGFyY2hpdmUgZW50cmllcyBob2xkaW5nIHRoZSBmaWxlIG5hbWUgZm9yIG5hbWVzIGxvbmdlcgorICAgICAgICB0aGFuIDEwMCBjaGFyYWN0ZXJzIGluIEdOVSBsb25nZmlsZSBtb2RlIGRpZG4ndCBwcm9wZXJseQorICAgICAgICBzcGVjaWZ5IHRoZXknZCBiZSB1c2luZyB0aGUgIm9sZGdudSIgZXh0ZW5zaW9uLiAKK28gQ09NUFJFU1MtODM6ICBEZWxlZ2F0ZSBhbGwgcmVhZCBhbmQgd3JpdGUgbWV0aG9kcyBpbiBHWmlwIHN0cmVhbSBpbiBvcmRlciB0bworICAgICAgICBzcGVlZCB1cCBvcGVyYXRpb25zLiAKK28gVGhlIGFyIGFuZCBjcGlvIHN0cmVhbXMgbm93IHByb3Blcmx5IHJlYWQgYW5kIHdyaXRlIGxhc3QKKyAgICAgICAgbW9kaWZpZWQgdGltZXMuIAorbyBDT01QUkVTUy04MTogIFRhck91dHB1dFN0cmVhbSBjYW4gbGVhdmUgZ2FyYmFnZSBhdCB0aGUgZW5kIG9mIHRoZSBhcmNoaXZlIAorCitDaGFuZ2VzOgorbyBDT01QUkVTUy0xMTI6ICBBckFyY2hpdmVJbnB1dFN0cmVhbSBkb2VzIG5vdCBoYW5kbGUgR05VIGV4dGVuZGVkIGZpbGVuYW1lIHJlY29yZHMgKC8vKSAKK28gQ09NUFJFU1MtMTA1OiAgRG9jdW1lbnQgdGhhdCB0aGUgbmFtZSBvZiBhbiBaaXBBcmNoaXZlRW50cnkgZGV0ZXJtaW5lcyB3aGV0aGVyCisgICAgICAgYW4gZW50cnkgaXMgY29uc2lkZXJlZCBhIGRpcmVjdG9yeSBvciBub3QuCisgICAgICAgSWYgeW91IGRvbid0IHVzZSB0aGUgY29uc3RydWN0b3Igd2l0aCB0aGUgRmlsZSBhcmd1bWVudCB0aGUgZW50cnkncworICAgICAgICBuYW1lIG11c3QgZW5kIGluIGEgIi8iIGluIG9yZGVyIGZvciB0aGUgZW50cnkgdG8gYmUga25vd24gYXMgYSBkaXJlY3RvcnkuIAorbyBDT01QUkVTUy03OTogIE1vdmUgRE9TL0phdmEgdGltZSBjb252ZXJzaW9ucyBpbnRvIFppcCB1dGlsaXR5IGNsYXNzLiAKK28gQ09NUFJFU1MtNzU6ICBaaXBBcmNoaXZlSW5wdXRTdHJlYW0gZG9lcyBub3Qgc2hvdyBsb2NhdGlvbiBpbiBmaWxlCisgICAgICAgd2hlcmUgYSBwcm9ibGVtIG9jY3VycmVkLiAKKwpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvTWVtb3J5TGltaXRFeGNlcHRpb24uamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL01lbW9yeUxpbWl0RXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDI1MWZiMwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL01lbW9yeUxpbWl0RXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw2NCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzczsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKKy8qKgorICogSWYgYSBzdHJlYW0gY2hlY2tzIGZvciBlc3RpbWF0ZWQgbWVtb3J5IGFsbG9jYXRpb24sIGFuZCB0aGUgZXN0aW1hdGUKKyAqIGdvZXMgYWJvdmUgdGhlIG1lbW9yeSBsaW1pdCwgdGhpcyBpcyB0aHJvd24uICBUaGlzIGNhbiBhbHNvIGJlIHRocm93bgorICogaWYgYSBzdHJlYW0gdHJpZXMgdG8gYWxsb2NhdGUgYSBieXRlIGFycmF5IHRoYXQgaXMgbGFyZ2VyIHRoYW4KKyAqIHRoZSBhbGxvd2FibGUgbGltaXQuCisgKgorICogQHNpbmNlIDEuMTQKKyAqLworcHVibGljIGNsYXNzIE1lbW9yeUxpbWl0RXhjZXB0aW9uIGV4dGVuZHMgSU9FeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7CisKKyAgICAvL2xvbmcgaW5zdGVhZCBvZiBpbnQgdG8gYWNjb3VudCBmb3Igb3ZlcmZsb3cgZm9yIGNvcnJ1cHQgZmlsZXMKKyAgICBwcml2YXRlIGZpbmFsIGxvbmcgbWVtb3J5TmVlZGVkSW5LYjsKKyAgICBwcml2YXRlIGZpbmFsIGludCBtZW1vcnlMaW1pdEluS2I7CisKKyAgICBwdWJsaWMgTWVtb3J5TGltaXRFeGNlcHRpb24obG9uZyBtZW1vcnlOZWVkZWRJbktiLCBpbnQgbWVtb3J5TGltaXRJbktiKSB7CisgICAgICAgIHN1cGVyKGJ1aWxkTWVzc2FnZShtZW1vcnlOZWVkZWRJbktiLCBtZW1vcnlMaW1pdEluS2IpKTsKKyAgICAgICAgdGhpcy5tZW1vcnlOZWVkZWRJbktiID0gbWVtb3J5TmVlZGVkSW5LYjsKKyAgICAgICAgdGhpcy5tZW1vcnlMaW1pdEluS2IgPSBtZW1vcnlMaW1pdEluS2I7CisgICAgfQorCisgICAgcHVibGljIE1lbW9yeUxpbWl0RXhjZXB0aW9uKGxvbmcgbWVtb3J5TmVlZGVkSW5LYiwgaW50IG1lbW9yeUxpbWl0SW5LYiwgRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgc3VwZXIoYnVpbGRNZXNzYWdlKG1lbW9yeU5lZWRlZEluS2IsIG1lbW9yeUxpbWl0SW5LYiksIGUpOworICAgICAgICB0aGlzLm1lbW9yeU5lZWRlZEluS2IgPSBtZW1vcnlOZWVkZWRJbktiOworICAgICAgICB0aGlzLm1lbW9yeUxpbWl0SW5LYiA9IG1lbW9yeUxpbWl0SW5LYjsKKyAgICB9CisKKyAgICBwdWJsaWMgbG9uZyBnZXRNZW1vcnlOZWVkZWRJbktiKCkgeworICAgICAgICByZXR1cm4gbWVtb3J5TmVlZGVkSW5LYjsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldE1lbW9yeUxpbWl0SW5LYigpIHsKKyAgICAgICAgcmV0dXJuIG1lbW9yeUxpbWl0SW5LYjsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgYnVpbGRNZXNzYWdlKGxvbmcgbWVtb3J5TmVlZGVkSW5LYiwgaW50IG1lbW9yeUxpbWl0SW5LYikgeworICAgICAgICByZXR1cm4gbWVtb3J5TmVlZGVkSW5LYiArICIga2Igb2YgbWVtb3J5IHdvdWxkIGJlIG5lZWRlZDsgbGltaXQgd2FzICIKKyAgICAgICAgICAgICAgICArIG1lbW9yeUxpbWl0SW5LYiArICIga2IuICIgKworICAgICAgICAgICAgICAgICJJZiB0aGUgZmlsZSBpcyBub3QgY29ycnVwdCwgY29uc2lkZXIgaW5jcmVhc2luZyB0aGUgbWVtb3J5IGxpbWl0LiI7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvUGFzc3dvcmRSZXF1aXJlZEV4Y2VwdGlvbi5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvUGFzc3dvcmRSZXF1aXJlZEV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ4NzZiOTYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9QYXNzd29yZFJlcXVpcmVkRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw0MCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICoKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3M7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCisvKioKKyAqIEV4Y2VwdGlvbiB0aHJvd24gd2hlbiB0cnlpbmcgdG8gcmVhZCBhbiBlbmNyeXB0ZWQgZW50cnkgb3IgZmlsZSB3aXRob3V0CisgKiBjb25maWd1cmluZyBhIHBhc3N3b3JkLgorICogQHNpbmNlIDEuMTAKKyAqLworcHVibGljIGNsYXNzIFBhc3N3b3JkUmVxdWlyZWRFeGNlcHRpb24gZXh0ZW5kcyBJT0V4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxMzkxMDcwMDA1NDkxNjg0NDgzTDsKKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIG5ldyBleGNlcHRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSBuYW1lIG9mIHRoZSBhcmNoaXZlIGNvbnRhaW5pbmcgZW5jcnlwdGVkIHN0cmVhbXMgb3IKKyAgICAgKiB0aGUgZW5jcnlwdGVkIGZpbGUuCisgICAgICovCisgICAgcHVibGljIFBhc3N3b3JkUmVxdWlyZWRFeGNlcHRpb24oZmluYWwgU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgc3VwZXIoIkNhbm5vdCByZWFkIGVuY3J5cHRlZCBjb250ZW50IGZyb20gIiArIG5hbWUgKyAiIHdpdGhvdXQgYSBwYXNzd29yZC4iKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvQXJjaGl2ZUVudHJ5LmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvQXJjaGl2ZUVudHJ5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDVmYTc0NgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9BcmNoaXZlRW50cnkuamF2YQpAQCAtMCwwICsxLDYxIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVyczsKKworaW1wb3J0IGphdmEudXRpbC5EYXRlOworCisvKioKKyAqIFJlcHJlc2VudHMgYW4gZW50cnkgb2YgYW4gYXJjaGl2ZS4KKyAqLworcHVibGljIGludGVyZmFjZSBBcmNoaXZlRW50cnkgeworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbmFtZSBvZiB0aGUgZW50cnkgaW4gdGhpcyBhcmNoaXZlLiBNYXkgcmVmZXIgdG8gYSBmaWxlIG9yIGRpcmVjdG9yeSBvciBvdGhlciBpdGVtLgorICAgICAqCisgICAgICogPHA+VGhpcyBtZXRob2QgcmV0dXJucyB0aGUgcmF3IG5hbWUgYXMgaXQgaXMgc3RvcmVkIGluc2lkZSBvZiB0aGUgYXJjaGl2ZS48L3A+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoZSBuYW1lIG9mIHRoaXMgZW50cnkgaW4gdGhlIGFyY2hpdmUuCisgICAgICovCisgICAgU3RyaW5nIGdldE5hbWUoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHVuY29tcHJlc3NlZCBzaXplIG9mIHRoaXMgZW50cnkuIE1heSBiZSAtMSAoU0laRV9VTktOT1dOKSBpZiB0aGUgc2l6ZSBpcyB1bmtub3duCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB1bmNvbXByZXNzZWQgc2l6ZSBvZiB0aGlzIGVudHJ5LgorICAgICAqLworICAgIGxvbmcgZ2V0U2l6ZSgpOworCisgICAgLyoqIFNwZWNpYWwgdmFsdWUgaW5kaWNhdGluZyB0aGF0IHRoZSBzaXplIGlzIHVua25vd24gKi8KKyAgICBsb25nIFNJWkVfVU5LTk9XTiA9IC0xOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgZW50cnkgcmVmZXJzIHRvIGEgZGlyZWN0b3J5LgorICAgICAqCisgICAgICogQHJldHVybiB0cnVlIGlmIHRoaXMgZW50cnkgcmVmZXJzIHRvIGEgZGlyZWN0b3J5LgorICAgICAqLworICAgIGJvb2xlYW4gaXNEaXJlY3RvcnkoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGxhc3QgbW9kaWZpZWQgZGF0ZSBvZiB0aGlzIGVudHJ5LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbGFzdCBtb2RpZmllZCBkYXRlIG9mIHRoaXMgZW50cnkuCisgICAgICogQHNpbmNlIDEuMQorICAgICAqLworICAgIERhdGUgZ2V0TGFzdE1vZGlmaWVkRGF0ZSgpOworfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL0FyY2hpdmVFeGNlcHRpb24uamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9BcmNoaXZlRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmI1Nzc4NQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9BcmNoaXZlRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw1MiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnM7CisKKy8qKgorICogQXJjaGl2ZXIgcmVsYXRlZCBFeGNlcHRpb24KKyAqLworcHVibGljIGNsYXNzIEFyY2hpdmVFeGNlcHRpb24gZXh0ZW5kcyBFeGNlcHRpb24geworCisgICAgLyoqIFNlcmlhbCAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDI3NzI2OTA3MDgxMjMyNjcxMDBMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBleGNlcHRpb24gd2l0aCB0aGUgc3BlY2lmaWVkIGRldGFpbCBtZXNzYWdlLiBUaGUgY2F1c2UKKyAgICAgKiBpcyBub3QgaW5pdGlhbGl6ZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWVzc2FnZQorICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlCisgICAgICovCisgICAgcHVibGljIEFyY2hpdmVFeGNlcHRpb24oZmluYWwgU3RyaW5nIG1lc3NhZ2UpIHsKKyAgICAgICAgc3VwZXIobWVzc2FnZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBleGNlcHRpb24gd2l0aCB0aGUgc3BlY2lmaWVkIGRldGFpbCBtZXNzYWdlIGFuZCBjYXVzZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtZXNzYWdlCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UKKyAgICAgKiBAcGFyYW0gY2F1c2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBjYXVzZQorICAgICAqLworICAgIHB1YmxpYyBBcmNoaXZlRXhjZXB0aW9uKGZpbmFsIFN0cmluZyBtZXNzYWdlLCBmaW5hbCBFeGNlcHRpb24gY2F1c2UpIHsKKyAgICAgICAgc3VwZXIobWVzc2FnZSk7CisgICAgICAgIHRoaXMuaW5pdENhdXNlKGNhdXNlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvQXJjaGl2ZUlucHV0U3RyZWFtLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvQXJjaGl2ZUlucHV0U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWM0ZTk3OAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9BcmNoaXZlSW5wdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDE1NSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnM7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CisKKy8qKgorICogQXJjaGl2ZSBpbnB1dCBzdHJlYW1zIDxiPk1VU1Q8L2I+IG92ZXJyaWRlIHRoZQorICoge0BsaW5rICNyZWFkKGJ5dGVbXSwgaW50LCBpbnQpfSAtIG9yIHtAbGluayAjcmVhZCgpfSAtCisgKiBtZXRob2Qgc28gdGhhdCByZWFkaW5nIGZyb20gdGhlIHN0cmVhbSBnZW5lcmF0ZXMgRU9GIGZvciB0aGUgZW5kIG9mCisgKiBkYXRhIGluIGVhY2ggZW50cnkgYXMgd2VsbCBhcyBhdCB0aGUgZW5kIG9mIHRoZSBmaWxlIHByb3Blci4KKyAqIDxwPgorICogVGhlIHtAbGluayAjZ2V0TmV4dEVudHJ5KCl9IG1ldGhvZCBpcyB1c2VkIHRvIHJlc2V0IHRoZSBpbnB1dCBzdHJlYW0KKyAqIHJlYWR5IGZvciByZWFkaW5nIHRoZSBkYXRhIGZyb20gdGhlIG5leHQgZW50cnkuCisgKiA8cD4KKyAqIFRoZSBpbnB1dCBzdHJlYW0gY2xhc3NlcyBtdXN0IGFsc28gaW1wbGVtZW50IGEgbWV0aG9kIHdpdGggdGhlIHNpZ25hdHVyZToKKyAqIDxwcmU+CisgKiBwdWJsaWMgc3RhdGljIGJvb2xlYW4gbWF0Y2hlcyhieXRlW10gc2lnbmF0dXJlLCBpbnQgbGVuZ3RoKQorICogPC9wcmU+CisgKiB3aGljaCBpcyB1c2VkIGJ5IHRoZSB7QGxpbmsgQXJjaGl2ZVN0cmVhbUZhY3Rvcnl9IHRvIGF1dG9kZXRlY3QKKyAqIHRoZSBhcmNoaXZlIHR5cGUgZnJvbSB0aGUgZmlyc3QgZmV3IGJ5dGVzIG9mIGEgc3RyZWFtLgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQXJjaGl2ZUlucHV0U3RyZWFtIGV4dGVuZHMgSW5wdXRTdHJlYW0geworCisgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10gc2luZ2xlID0gbmV3IGJ5dGVbMV07CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEJZVEVfTUFTSyA9IDB4RkY7CisKKyAgICAvKiogaG9sZHMgdGhlIG51bWJlciBvZiBieXRlcyByZWFkIGluIHRoaXMgc3RyZWFtICovCisgICAgcHJpdmF0ZSBsb25nIGJ5dGVzUmVhZCA9IDA7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuZXh0IEFyY2hpdmUgRW50cnkgaW4gdGhpcyBTdHJlYW0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IGVudHJ5LAorICAgICAqICAgICAgICAgb3Ige0Bjb2RlIG51bGx9IGlmIHRoZXJlIGFyZSBubyBtb3JlIGVudHJpZXMKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHRoZSBuZXh0IGVudHJ5IGNvdWxkIG5vdCBiZSByZWFkCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEFyY2hpdmVFbnRyeSBnZXROZXh0RW50cnkoKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKgorICAgICAqIE5vdGUgdGhhdCBzdWJjbGFzc2VzIGFsc28gaW1wbGVtZW50IHNwZWNpZmljIGdldCgpIG1ldGhvZHMgd2hpY2gKKyAgICAgKiByZXR1cm4gdGhlIGFwcHJvcHJpYXRlIGNsYXNzIHdpdGhvdXQgbmVlZCBmb3IgYSBjYXN0LgorICAgICAqIFNlZSBTVk4gcmV2aXNpb24gcjc0MzI1OQorICAgICAqIEByZXR1cm4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICovCisgICAgLy8gcHVibGljIGFic3RyYWN0IFhYWEFyY2hpdmVFbnRyeSBnZXROZXh0WFhYRW50cnkoKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhIGJ5dGUgb2YgZGF0YS4gVGhpcyBtZXRob2Qgd2lsbCBibG9jayB1bnRpbCBlbm91Z2ggaW5wdXQgaXMKKyAgICAgKiBhdmFpbGFibGUuCisgICAgICoKKyAgICAgKiBTaW1wbHkgY2FsbHMgdGhlIHtAbGluayAjcmVhZChieXRlW10sIGludCwgaW50KX0gbWV0aG9kLgorICAgICAqCisgICAgICogTVVTVCBiZSBvdmVycmlkZGVuIGlmIHRoZSB7QGxpbmsgI3JlYWQoYnl0ZVtdLCBpbnQsIGludCl9IG1ldGhvZAorICAgICAqIGlzIG5vdCBvdmVycmlkZGVuOyBtYXkgYmUgb3ZlcnJpZGRlbiBvdGhlcndpc2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBieXRlIHJlYWQsIG9yIC0xIGlmIGVuZCBvZiBpbnB1dCBpcyByZWFjaGVkCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBlcnJvciBoYXMgb2NjdXJyZWQKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHJlYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBpbnQgbnVtID0gcmVhZChzaW5nbGUsIDAsIDEpOworICAgICAgICByZXR1cm4gbnVtID09IC0xID8gLTEgOiBzaW5nbGVbMF0gJiBCWVRFX01BU0s7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5jcmVtZW50cyB0aGUgY291bnRlciBvZiBhbHJlYWR5IHJlYWQgYnl0ZXMuCisgICAgICogRG9lc24ndCBpbmNyZW1lbnQgaWYgdGhlIEVPRiBoYXMgYmVlbiBoaXQgKHJlYWQgPT0gLTEpCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVhZCB0aGUgbnVtYmVyIG9mIGJ5dGVzIHJlYWQKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBjb3VudChmaW5hbCBpbnQgcmVhZCkgeworICAgICAgICBjb3VudCgobG9uZykgcmVhZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5jcmVtZW50cyB0aGUgY291bnRlciBvZiBhbHJlYWR5IHJlYWQgYnl0ZXMuCisgICAgICogRG9lc24ndCBpbmNyZW1lbnQgaWYgdGhlIEVPRiBoYXMgYmVlbiBoaXQgKHJlYWQgPT0gLTEpCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVhZCB0aGUgbnVtYmVyIG9mIGJ5dGVzIHJlYWQKKyAgICAgKiBAc2luY2UgMS4xCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgY291bnQoZmluYWwgbG9uZyByZWFkKSB7CisgICAgICAgIGlmIChyZWFkICE9IC0xKSB7CisgICAgICAgICAgICBieXRlc1JlYWQgPSBieXRlc1JlYWQgKyByZWFkOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRGVjcmVtZW50cyB0aGUgY291bnRlciBvZiBhbHJlYWR5IHJlYWQgYnl0ZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcHVzaGVkQmFjayB0aGUgbnVtYmVyIG9mIGJ5dGVzIHB1c2hlZCBiYWNrLgorICAgICAqIEBzaW5jZSAxLjEKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBwdXNoZWRCYWNrQnl0ZXMoZmluYWwgbG9uZyBwdXNoZWRCYWNrKSB7CisgICAgICAgIGJ5dGVzUmVhZCAtPSBwdXNoZWRCYWNrOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGN1cnJlbnQgbnVtYmVyIG9mIGJ5dGVzIHJlYWQgZnJvbSB0aGlzIHN0cmVhbS4KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgcmVhZCBieXRlcworICAgICAqIEBkZXByZWNhdGVkIHRoaXMgbWV0aG9kIG1heSB5aWVsZCB3cm9uZyByZXN1bHRzIGZvciBsYXJnZQorICAgICAqIGFyY2hpdmVzLCB1c2UgI2dldEJ5dGVzUmVhZCBpbnN0ZWFkCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgaW50IGdldENvdW50KCkgeworICAgICAgICByZXR1cm4gKGludCkgYnl0ZXNSZWFkOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGN1cnJlbnQgbnVtYmVyIG9mIGJ5dGVzIHJlYWQgZnJvbSB0aGlzIHN0cmVhbS4KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgcmVhZCBieXRlcworICAgICAqIEBzaW5jZSAxLjEKKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBnZXRCeXRlc1JlYWQoKSB7CisgICAgICAgIHJldHVybiBieXRlc1JlYWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogV2hldGhlciB0aGlzIHN0cmVhbSBpcyBhYmxlIHRvIHJlYWQgdGhlIGdpdmVuIGVudHJ5LgorICAgICAqCisgICAgICogPHA+CisgICAgICogU29tZSBhcmNoaXZlIGZvcm1hdHMgc3VwcG9ydCB2YXJpYW50cyBvciBkZXRhaWxzIHRoYXQgYXJlIG5vdCBzdXBwb3J0ZWQgKHlldCkuCisgICAgICogPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGFyY2hpdmVFbnRyeQorICAgICAqICAgICAgICAgICAgdGhlIGVudHJ5IHRvIHRlc3QKKyAgICAgKiBAcmV0dXJuIFRoaXMgaW1wbGVtZW50YXRpb24gYWx3YXlzIHJldHVybnMgdHJ1ZS4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjEKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBjYW5SZWFkRW50cnlEYXRhKGZpbmFsIEFyY2hpdmVFbnRyeSBhcmNoaXZlRW50cnkpIHsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvQXJjaGl2ZU91dHB1dFN0cmVhbS5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL0FyY2hpdmVPdXRwdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40Mzc3YjZkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL0FyY2hpdmVPdXRwdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDE2OSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnM7CisKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKKworLyoqCisgKiBBcmNoaXZlIG91dHB1dCBzdHJlYW0gaW1wbGVtZW50YXRpb25zIGFyZSBleHBlY3RlZCB0byBvdmVycmlkZSB0aGUKKyAqIHtAbGluayAjd3JpdGUoYnl0ZVtdLCBpbnQsIGludCl9IG1ldGhvZCB0byBpbXByb3ZlIHBlcmZvcm1hbmNlLgorICogVGhleSBzaG91bGQgYWxzbyBvdmVycmlkZSB7QGxpbmsgI2Nsb3NlKCl9IHRvIGVuc3VyZSB0aGF0IGFueSBuZWNlc3NhcnkKKyAqIHRyYWlsZXJzIGFyZSBhZGRlZC4KKyAqCisgKiA8cD5UaGUgbm9ybWFsIHNlcXVlbmNlIG9mIGNhbGxzIHdoZW4gd29ya2luZyB3aXRoIEFyY2hpdmVPdXRwdXRTdHJlYW1zIGlzOjwvcD4KKyAqIDx1bD4KKyAqICAgPGxpPkNyZWF0ZSBBcmNoaXZlT3V0cHV0U3RyZWFtIG9iamVjdCw8L2xpPgorICogICA8bGk+b3B0aW9uYWxseSB3cml0ZSBTRlggaGVhZGVyIChaaXAgb25seSksPC9saT4KKyAqICAgPGxpPnJlcGVhdCBhcyBuZWVkZWQ6CisgKiAgICAgPHVsPgorICogICAgICAgPGxpPntAbGluayAjcHV0QXJjaGl2ZUVudHJ5KEFyY2hpdmVFbnRyeSl9ICh3cml0ZXMgZW50cnkgaGVhZGVyKSwKKyAqICAgICAgIDxsaT57QGxpbmsgI3dyaXRlKGJ5dGVbXSl9ICh3cml0ZXMgZW50cnkgZGF0YSwgYXMgb2Z0ZW4gYXMgbmVlZGVkKSwKKyAqICAgICAgIDxsaT57QGxpbmsgI2Nsb3NlQXJjaGl2ZUVudHJ5KCl9IChjbG9zZXMgZW50cnkpLAorICogICAgIDwvdWw+CisgKiAgIDwvbGk+CisgKiAgIDxsaT4ge0BsaW5rICNmaW5pc2goKX0gKGVuZHMgdGhlIGFkZGl0aW9uIG9mIGVudHJpZXMpLDwvbGk+CisgKiAgIDxsaT4gb3B0aW9uYWxseSB3cml0ZSBhZGRpdGlvbmFsIGRhdGEsIHByb3ZpZGVkIGZvcm1hdCBzdXBwb3J0cyBpdCw8L2xpPgorICogICA8bGk+e0BsaW5rICNjbG9zZSgpfS48L2xpPgorICogPC91bD4KKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEFyY2hpdmVPdXRwdXRTdHJlYW0gZXh0ZW5kcyBPdXRwdXRTdHJlYW0geworCisgICAgLyoqIFRlbXBvcmFyeSBidWZmZXIgdXNlZCBmb3IgdGhlIHtAbGluayAjd3JpdGUoaW50KX0gbWV0aG9kICovCisgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10gb25lQnl0ZSA9IG5ldyBieXRlWzFdOworICAgIHN0YXRpYyBmaW5hbCBpbnQgQllURV9NQVNLID0gMHhGRjsKKworICAgIC8qKiBob2xkcyB0aGUgbnVtYmVyIG9mIGJ5dGVzIHdyaXR0ZW4gdG8gdGhpcyBzdHJlYW0gKi8KKyAgICBwcml2YXRlIGxvbmcgYnl0ZXNXcml0dGVuID0gMDsKKyAgICAvLyBNZXRob2RzIHNwZWNpZmljIHRvIEFyY2hpdmVPdXRwdXRTdHJlYW0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyB0aGUgaGVhZGVycyBmb3IgYW4gYXJjaGl2ZSBlbnRyeSB0byB0aGUgb3V0cHV0IHN0cmVhbS4KKyAgICAgKiBUaGUgY2FsbGVyIG11c3QgdGhlbiB3cml0ZSB0aGUgY29udGVudCB0byB0aGUgc3RyZWFtIGFuZCBjYWxsCisgICAgICoge0BsaW5rICNjbG9zZUFyY2hpdmVFbnRyeSgpfSB0byBjb21wbGV0ZSB0aGUgcHJvY2Vzcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlbnRyeSBkZXNjcmliZXMgdGhlIGVudHJ5CisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiBhbiBJL08gZXJyb3Igb2NjdXJzCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgcHV0QXJjaGl2ZUVudHJ5KEFyY2hpdmVFbnRyeSBlbnRyeSkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQ2xvc2VzIHRoZSBhcmNoaXZlIGVudHJ5LCB3cml0aW5nIGFueSB0cmFpbGVyIGluZm9ybWF0aW9uIHRoYXQgbWF5CisgICAgICogYmUgcmVxdWlyZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiBhbiBJL08gZXJyb3Igb2NjdXJzCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgY2xvc2VBcmNoaXZlRW50cnkoKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBGaW5pc2hlcyB0aGUgYWRkaXRpb24gb2YgZW50cmllcyB0byB0aGlzIHN0cmVhbSwgd2l0aG91dCBjbG9zaW5nIGl0LgorICAgICAqIEFkZGl0aW9uYWwgZGF0YSBjYW4gYmUgd3JpdHRlbiwgaWYgdGhlIGZvcm1hdCBzdXBwb3J0cyBpdC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgdGhlIHVzZXIgZm9yZ2V0cyB0byBjbG9zZSB0aGUgZW50cnkuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgZmluaXNoKCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQ3JlYXRlIGFuIGFyY2hpdmUgZW50cnkgdXNpbmcgdGhlIGlucHV0RmlsZSBhbmQgZW50cnlOYW1lIHByb3ZpZGVkLgorICAgICAqCisgICAgICogQHBhcmFtIGlucHV0RmlsZSB0aGUgZmlsZSB0byBjcmVhdGUgdGhlIGVudHJ5IGZyb20KKyAgICAgKiBAcGFyYW0gZW50cnlOYW1lIG5hbWUgdG8gdXNlIGZvciB0aGUgZW50cnkKKyAgICAgKiBAcmV0dXJuIHRoZSBBcmNoaXZlRW50cnkgc2V0IHVwIHdpdGggZGV0YWlscyBmcm9tIHRoZSBmaWxlCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQXJjaGl2ZUVudHJ5IGNyZWF0ZUFyY2hpdmVFbnRyeShGaWxlIGlucHV0RmlsZSwgU3RyaW5nIGVudHJ5TmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLy8gR2VuZXJpYyBpbXBsZW1lbnRhdGlvbnMgb2YgT3V0cHV0U3RyZWFtIG1ldGhvZHMgdGhhdCBtYXkgYmUgdXNlZnVsIHRvIHN1Yi1jbGFzc2VzCisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgYSBieXRlIHRvIHRoZSBjdXJyZW50IGFyY2hpdmUgZW50cnkuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBzaW1wbHkgY2FsbHMge0Bjb2RlIHdyaXRlKCBieXRlW10sIDAsIDEgKX0uCisgICAgICoKKyAgICAgKiA8cD5NVVNUIGJlIG92ZXJyaWRkZW4gaWYgdGhlIHtAbGluayAjd3JpdGUoYnl0ZVtdLCBpbnQsIGludCl9IG1ldGhvZAorICAgICAqIGlzIG5vdCBvdmVycmlkZGVuOyBtYXkgYmUgb3ZlcnJpZGRlbiBvdGhlcndpc2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYiBUaGUgYnl0ZSB0byBiZSB3cml0dGVuLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gb24gZXJyb3IKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShmaW5hbCBpbnQgYikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgb25lQnl0ZVswXSA9IChieXRlKSAoYiAmIEJZVEVfTUFTSyk7CisgICAgICAgIHdyaXRlKG9uZUJ5dGUsIDAsIDEpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluY3JlbWVudHMgdGhlIGNvdW50ZXIgb2YgYWxyZWFkeSB3cml0dGVuIGJ5dGVzLgorICAgICAqIERvZXNuJ3QgaW5jcmVtZW50IGlmIEVPRiBoYXMgYmVlbiBoaXQgKHtAY29kZSB3cml0dGVuID09IC0xfSkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gd3JpdHRlbiB0aGUgbnVtYmVyIG9mIGJ5dGVzIHdyaXR0ZW4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBjb3VudChmaW5hbCBpbnQgd3JpdHRlbikgeworICAgICAgICBjb3VudCgobG9uZykgd3JpdHRlbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5jcmVtZW50cyB0aGUgY291bnRlciBvZiBhbHJlYWR5IHdyaXR0ZW4gYnl0ZXMuCisgICAgICogRG9lc24ndCBpbmNyZW1lbnQgaWYgRU9GIGhhcyBiZWVuIGhpdCAoe0Bjb2RlIHdyaXR0ZW4gPT0gLTF9KS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB3cml0dGVuIHRoZSBudW1iZXIgb2YgYnl0ZXMgd3JpdHRlbgorICAgICAqIEBzaW5jZSAxLjEKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBjb3VudChmaW5hbCBsb25nIHdyaXR0ZW4pIHsKKyAgICAgICAgaWYgKHdyaXR0ZW4gIT0gLTEpIHsKKyAgICAgICAgICAgIGJ5dGVzV3JpdHRlbiA9IGJ5dGVzV3JpdHRlbiArIHdyaXR0ZW47CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IG51bWJlciBvZiBieXRlcyB3cml0dGVuIHRvIHRoaXMgc3RyZWFtLgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiB3cml0dGVuIGJ5dGVzCisgICAgICogQGRlcHJlY2F0ZWQgdGhpcyBtZXRob2QgbWF5IHlpZWxkIHdyb25nIHJlc3VsdHMgZm9yIGxhcmdlCisgICAgICogYXJjaGl2ZXMsIHVzZSAjZ2V0Qnl0ZXNXcml0dGVuIGluc3RlYWQKKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBpbnQgZ2V0Q291bnQoKSB7CisgICAgICAgIHJldHVybiAoaW50KSBieXRlc1dyaXR0ZW47CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY3VycmVudCBudW1iZXIgb2YgYnl0ZXMgd3JpdHRlbiB0byB0aGlzIHN0cmVhbS4KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2Ygd3JpdHRlbiBieXRlcworICAgICAqIEBzaW5jZSAxLjEKKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBnZXRCeXRlc1dyaXR0ZW4oKSB7CisgICAgICAgIHJldHVybiBieXRlc1dyaXR0ZW47CisgICAgfQorCisgICAgLyoqCisgICAgICogV2hldGhlciB0aGlzIHN0cmVhbSBpcyBhYmxlIHRvIHdyaXRlIHRoZSBnaXZlbiBlbnRyeS4KKyAgICAgKgorICAgICAqIDxwPlNvbWUgYXJjaGl2ZSBmb3JtYXRzIHN1cHBvcnQgdmFyaWFudHMgb3IgZGV0YWlscyB0aGF0IGFyZQorICAgICAqIG5vdCBzdXBwb3J0ZWQgKHlldCkuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGFyY2hpdmVFbnRyeQorICAgICAqICAgICAgICAgICAgdGhlIGVudHJ5IHRvIHRlc3QKKyAgICAgKiBAcmV0dXJuIFRoaXMgaW1wbGVtZW50YXRpb24gYWx3YXlzIHJldHVybnMgdHJ1ZS4KKyAgICAgKiBAc2luY2UgMS4xCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gY2FuV3JpdGVFbnRyeURhdGEoZmluYWwgQXJjaGl2ZUVudHJ5IGFyY2hpdmVFbnRyeSkgeworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvQXJjaGl2ZVN0cmVhbUZhY3RvcnkuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9BcmNoaXZlU3RyZWFtRmFjdG9yeS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNjZDhiYTcKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvQXJjaGl2ZVN0cmVhbUZhY3RvcnkuamF2YQpAQCAtMCwwICsxLDU5MiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnM7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkFjY2Vzc0NvbnRyb2xsZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcml2aWxlZ2VkQWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YS51dGlsLlNvcnRlZE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuVHJlZU1hcDsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuYXIuQXJBcmNoaXZlSW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5hci5BckFyY2hpdmVPdXRwdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5hcmouQXJqQXJjaGl2ZUlucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuY3Bpby5DcGlvQXJjaGl2ZUlucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuY3Bpby5DcGlvQXJjaGl2ZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLmR1bXAuRHVtcEFyY2hpdmVJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLmphci5KYXJBcmNoaXZlSW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5qYXIuSmFyQXJjaGl2ZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnNldmVuei5TZXZlblpGaWxlOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMudGFyLlRhckFyY2hpdmVJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnRhci5UYXJBcmNoaXZlT3V0cHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwLlppcEFyY2hpdmVJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcC5aaXBBcmNoaXZlT3V0cHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5JT1V0aWxzOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5MaXN0czsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuU2VydmljZUxvYWRlckl0ZXJhdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5TZXRzOworCisvKioKKyAqIEZhY3RvcnkgdG8gY3JlYXRlIEFyY2hpdmVbSW58T3V0XXB1dFN0cmVhbXMgZnJvbSBuYW1lcyBvciB0aGUgZmlyc3QgYnl0ZXMgb2YKKyAqIHRoZSBJbnB1dFN0cmVhbS4gSW4gb3JkZXIgdG8gYWRkIG90aGVyIGltcGxlbWVudGF0aW9ucywgeW91IHNob3VsZCBleHRlbmQKKyAqIEFyY2hpdmVTdHJlYW1GYWN0b3J5IGFuZCBvdmVycmlkZSB0aGUgYXBwcm9wcmlhdGUgbWV0aG9kcyAoYW5kIGNhbGwgdGhlaXIKKyAqIGltcGxlbWVudGF0aW9uIGZyb20gc3VwZXIgb2YgY291cnNlKS4KKyAqCisgKiBDb21wcmVzc2luZyBhIFpJUC1GaWxlOgorICoKKyAqIDxwcmU+CisgKiBmaW5hbCBPdXRwdXRTdHJlYW0gb3V0ID0gRmlsZXMubmV3T3V0cHV0U3RyZWFtKG91dHB1dC50b1BhdGgoKSk7CisgKiBBcmNoaXZlT3V0cHV0U3RyZWFtIG9zID0gbmV3IEFyY2hpdmVTdHJlYW1GYWN0b3J5KCkuY3JlYXRlQXJjaGl2ZU91dHB1dFN0cmVhbShBcmNoaXZlU3RyZWFtRmFjdG9yeS5aSVAsIG91dCk7CisgKgorICogb3MucHV0QXJjaGl2ZUVudHJ5KG5ldyBaaXBBcmNoaXZlRW50cnkoInRlc3RkYXRhL3Rlc3QxLnhtbCIpKTsKKyAqIElPVXRpbHMuY29weShGaWxlcy5uZXdJbnB1dFN0cmVhbShmaWxlMS50b1BhdGgoKSksIG9zKTsKKyAqIG9zLmNsb3NlQXJjaGl2ZUVudHJ5KCk7CisgKgorICogb3MucHV0QXJjaGl2ZUVudHJ5KG5ldyBaaXBBcmNoaXZlRW50cnkoInRlc3RkYXRhL3Rlc3QyLnhtbCIpKTsKKyAqIElPVXRpbHMuY29weShGaWxlcy5uZXdJbnB1dFN0cmVhbShmaWxlMi50b1BhdGgoKSksIG9zKTsKKyAqIG9zLmNsb3NlQXJjaGl2ZUVudHJ5KCk7CisgKiBvcy5jbG9zZSgpOworICogPC9wcmU+CisgKgorICogRGVjb21wcmVzc2luZyBhIFpJUC1GaWxlOgorICoKKyAqIDxwcmU+CisgKiBmaW5hbCBJbnB1dFN0cmVhbSBpcyA9IEZpbGVzLm5ld0lucHV0U3RyZWFtKGlucHV0LnRvUGF0aCgpKTsKKyAqIEFyY2hpdmVJbnB1dFN0cmVhbSBpbiA9IG5ldyBBcmNoaXZlU3RyZWFtRmFjdG9yeSgpLmNyZWF0ZUFyY2hpdmVJbnB1dFN0cmVhbShBcmNoaXZlU3RyZWFtRmFjdG9yeS5aSVAsIGlzKTsKKyAqIFppcEFyY2hpdmVFbnRyeSBlbnRyeSA9IChaaXBBcmNoaXZlRW50cnkpaW4uZ2V0TmV4dEVudHJ5KCk7CisgKiBPdXRwdXRTdHJlYW0gb3V0ID0gRmlsZXMubmV3T3V0cHV0U3RyZWFtKGRpci50b1BhdGgoKS5yZXNvbHZlKGVudHJ5LmdldE5hbWUoKSkpOworICogSU9VdGlscy5jb3B5KGluLCBvdXQpOworICogb3V0LmNsb3NlKCk7CisgKiBpbi5jbG9zZSgpOworICogPC9wcmU+CisgKiBASW1tdXRhYmxlIHByb3ZpZGVkIHRoYXQgdGhlIGRlcHJlY2F0ZWQgbWV0aG9kIHNldEVudHJ5RW5jb2RpbmcgaXMgbm90IHVzZWQuCisgKiBAVGhyZWFkU2FmZSBldmVuIGlmIHRoZSBkZXByZWNhdGVkIG1ldGhvZCBzZXRFbnRyeUVuY29kaW5nIGlzIHVzZWQKKyAqLworcHVibGljIGNsYXNzIEFyY2hpdmVTdHJlYW1GYWN0b3J5IGltcGxlbWVudHMgQXJjaGl2ZVN0cmVhbVByb3ZpZGVyIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBUQVJfSEVBREVSX1NJWkUgPSA1MTI7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgRFVNUF9TSUdOQVRVUkVfU0laRSA9IDMyOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFNJR05BVFVSRV9TSVpFID0gMTI7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBBcmNoaXZlU3RyZWFtRmFjdG9yeSBTSU5HTEVUT04gPSBuZXcgQXJjaGl2ZVN0cmVhbUZhY3RvcnkoKTsKKworICAgIC8qKgorICAgICAqIENvbnN0YW50ICh2YWx1ZSB7QHZhbHVlfSkgdXNlZCB0byBpZGVudGlmeSB0aGUgQVIgYXJjaGl2ZSBmb3JtYXQuCisgICAgICogQHNpbmNlIDEuMQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFSID0gImFyIjsKKworICAgIC8qKgorICAgICAqIENvbnN0YW50ICh2YWx1ZSB7QHZhbHVlfSkgdXNlZCB0byBpZGVudGlmeSB0aGUgQVJKIGFyY2hpdmUgZm9ybWF0LgorICAgICAqIE5vdCBzdXBwb3J0ZWQgYXMgYW4gb3V0cHV0IHN0cmVhbSB0eXBlLgorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBUkogPSAiYXJqIjsKKworICAgIC8qKgorICAgICAqIENvbnN0YW50ICh2YWx1ZSB7QHZhbHVlfSkgdXNlZCB0byBpZGVudGlmeSB0aGUgQ1BJTyBhcmNoaXZlIGZvcm1hdC4KKyAgICAgKiBAc2luY2UgMS4xCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ1BJTyA9ICJjcGlvIjsKKworICAgIC8qKgorICAgICAqIENvbnN0YW50ICh2YWx1ZSB7QHZhbHVlfSkgdXNlZCB0byBpZGVudGlmeSB0aGUgVW5peCBEVU1QIGFyY2hpdmUgZm9ybWF0LgorICAgICAqIE5vdCBzdXBwb3J0ZWQgYXMgYW4gb3V0cHV0IHN0cmVhbSB0eXBlLgorICAgICAqIEBzaW5jZSAxLjMKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBEVU1QID0gImR1bXAiOworCisgICAgLyoqCisgICAgICogQ29uc3RhbnQgKHZhbHVlIHtAdmFsdWV9KSB1c2VkIHRvIGlkZW50aWZ5IHRoZSBKQVIgYXJjaGl2ZSBmb3JtYXQuCisgICAgICogQHNpbmNlIDEuMQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEpBUiA9ICJqYXIiOworCisgICAgLyoqCisgICAgICogQ29uc3RhbnQgdXNlZCB0byBpZGVudGlmeSB0aGUgVEFSIGFyY2hpdmUgZm9ybWF0LgorICAgICAqIEBzaW5jZSAxLjEKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBUQVIgPSAidGFyIjsKKworICAgIC8qKgorICAgICAqIENvbnN0YW50ICh2YWx1ZSB7QHZhbHVlfSkgdXNlZCB0byBpZGVudGlmeSB0aGUgWklQIGFyY2hpdmUgZm9ybWF0LgorICAgICAqIEBzaW5jZSAxLjEKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBaSVAgPSAiemlwIjsKKworICAgIC8qKgorICAgICAqIENvbnN0YW50ICh2YWx1ZSB7QHZhbHVlfSkgdXNlZCB0byBpZGVudGlmeSB0aGUgN3ogYXJjaGl2ZSBmb3JtYXQuCisgICAgICogQHNpbmNlIDEuOAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNFVkVOX1ogPSAiN3oiOworCisgICAgLyoqCisgICAgICogRW50cnkgZW5jb2RpbmcsIG51bGwgZm9yIHRoZSBwbGF0Zm9ybSBkZWZhdWx0LgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGVuY29kaW5nOworCisgICAgLyoqCisgICAgICogRW50cnkgZW5jb2RpbmcsIG51bGwgZm9yIHRoZSBkZWZhdWx0LgorICAgICAqLworICAgIHByaXZhdGUgdm9sYXRpbGUgU3RyaW5nIGVudHJ5RW5jb2Rpbmc7CisKKyAgICBwcml2YXRlIFNvcnRlZE1hcDxTdHJpbmcsIEFyY2hpdmVTdHJlYW1Qcm92aWRlcj4gYXJjaGl2ZUlucHV0U3RyZWFtUHJvdmlkZXJzOworCisgICAgcHJpdmF0ZSBTb3J0ZWRNYXA8U3RyaW5nLCBBcmNoaXZlU3RyZWFtUHJvdmlkZXI+IGFyY2hpdmVPdXRwdXRTdHJlYW1Qcm92aWRlcnM7CisKKyAgICBwcml2YXRlIHN0YXRpYyBBcnJheUxpc3Q8QXJjaGl2ZVN0cmVhbVByb3ZpZGVyPiBmaW5kQXJjaGl2ZVN0cmVhbVByb3ZpZGVycygpIHsKKyAgICAgICAgcmV0dXJuIExpc3RzLm5ld0FycmF5TGlzdChzZXJ2aWNlTG9hZGVySXRlcmF0b3IoKSk7CisgICAgfQorCisgICAgc3RhdGljIHZvaWQgcHV0QWxsKFNldDxTdHJpbmc+IG5hbWVzLCBBcmNoaXZlU3RyZWFtUHJvdmlkZXIgcHJvdmlkZXIsCisgICAgICAgICAgICBUcmVlTWFwPFN0cmluZywgQXJjaGl2ZVN0cmVhbVByb3ZpZGVyPiBtYXApIHsKKyAgICAgICAgZm9yIChTdHJpbmcgbmFtZSA6IG5hbWVzKSB7CisgICAgICAgICAgICBtYXAucHV0KHRvS2V5KG5hbWUpLCBwcm92aWRlcik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBJdGVyYXRvcjxBcmNoaXZlU3RyZWFtUHJvdmlkZXI+IHNlcnZpY2VMb2FkZXJJdGVyYXRvcigpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBTZXJ2aWNlTG9hZGVySXRlcmF0b3I8PihBcmNoaXZlU3RyZWFtUHJvdmlkZXIuY2xhc3MpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyB0b0tleShmaW5hbCBTdHJpbmcgbmFtZSkgeworICAgICAgICByZXR1cm4gbmFtZS50b1VwcGVyQ2FzZShMb2NhbGUuUk9PVCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBzb3J0ZWQgbWFwIGZyb20gaW5wdXQgc3RyZWFtIHByb3ZpZGVyIG5hbWVzIHRvIHByb3ZpZGVyCisgICAgICogb2JqZWN0cy4KKyAgICAgKgorICAgICAqIDxwPgorICAgICAqIFRoZSBtYXAgcmV0dXJuZWQgYnkgdGhpcyBtZXRob2Qgd2lsbCBoYXZlIG9uZSBlbnRyeSBmb3IgZWFjaCBwcm92aWRlciBmb3IKKyAgICAgKiB3aGljaCBzdXBwb3J0IGlzIGF2YWlsYWJsZSBpbiB0aGUgY3VycmVudCBKYXZhIHZpcnR1YWwgbWFjaGluZS4gSWYgdHdvIG9yCisgICAgICogbW9yZSBzdXBwb3J0ZWQgcHJvdmlkZXIgaGF2ZSB0aGUgc2FtZSBuYW1lIHRoZW4gdGhlIHJlc3VsdGluZyBtYXAgd2lsbAorICAgICAqIGNvbnRhaW4ganVzdCBvbmUgb2YgdGhlbTsgd2hpY2ggb25lIGl0IHdpbGwgY29udGFpbiBpcyBub3Qgc3BlY2lmaWVkLgorICAgICAqIDwvcD4KKyAgICAgKgorICAgICAqIDxwPgorICAgICAqIFRoZSBpbnZvY2F0aW9uIG9mIHRoaXMgbWV0aG9kLCBhbmQgdGhlIHN1YnNlcXVlbnQgdXNlIG9mIHRoZSByZXN1bHRpbmcKKyAgICAgKiBtYXAsIG1heSBjYXVzZSB0aW1lLWNvbnN1bWluZyBkaXNrIG9yIG5ldHdvcmsgSS9PIG9wZXJhdGlvbnMgdG8gb2NjdXIuCisgICAgICogVGhpcyBtZXRob2QgaXMgcHJvdmlkZWQgZm9yIGFwcGxpY2F0aW9ucyB0aGF0IG5lZWQgdG8gZW51bWVyYXRlIGFsbCBvZgorICAgICAqIHRoZSBhdmFpbGFibGUgcHJvdmlkZXJzLCBmb3IgZXhhbXBsZSB0byBhbGxvdyB1c2VyIHByb3ZpZGVyIHNlbGVjdGlvbi4KKyAgICAgKiA8L3A+CisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIG1ldGhvZCBtYXkgcmV0dXJuIGRpZmZlcmVudCByZXN1bHRzIGF0IGRpZmZlcmVudCB0aW1lcyBpZiBuZXcKKyAgICAgKiBwcm92aWRlcnMgYXJlIGR5bmFtaWNhbGx5IG1hZGUgYXZhaWxhYmxlIHRvIHRoZSBjdXJyZW50IEphdmEgdmlydHVhbAorICAgICAqIG1hY2hpbmUuCisgICAgICogPC9wPgorICAgICAqCisgICAgICogQHJldHVybiBBbiBpbW11dGFibGUsIG1hcCBmcm9tIG5hbWVzIHRvIHByb3ZpZGVyIG9iamVjdHMKKyAgICAgKiBAc2luY2UgMS4xMworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU29ydGVkTWFwPFN0cmluZywgQXJjaGl2ZVN0cmVhbVByb3ZpZGVyPiBmaW5kQXZhaWxhYmxlQXJjaGl2ZUlucHV0U3RyZWFtUHJvdmlkZXJzKCkgeworICAgICAgICByZXR1cm4gQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb248U29ydGVkTWFwPFN0cmluZywgQXJjaGl2ZVN0cmVhbVByb3ZpZGVyPj4oKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBTb3J0ZWRNYXA8U3RyaW5nLCBBcmNoaXZlU3RyZWFtUHJvdmlkZXI+IHJ1bigpIHsKKyAgICAgICAgICAgICAgICBUcmVlTWFwPFN0cmluZywgQXJjaGl2ZVN0cmVhbVByb3ZpZGVyPiBtYXAgPSBuZXcgVHJlZU1hcDw+KCk7CisgICAgICAgICAgICAgICAgcHV0QWxsKFNJTkdMRVRPTi5nZXRJbnB1dFN0cmVhbUFyY2hpdmVOYW1lcygpLCBTSU5HTEVUT04sIG1hcCk7CisgICAgICAgICAgICAgICAgZm9yIChBcmNoaXZlU3RyZWFtUHJvdmlkZXIgcHJvdmlkZXIgOiBmaW5kQXJjaGl2ZVN0cmVhbVByb3ZpZGVycygpKSB7CisgICAgICAgICAgICAgICAgICAgIHB1dEFsbChwcm92aWRlci5nZXRJbnB1dFN0cmVhbUFyY2hpdmVOYW1lcygpLCBwcm92aWRlciwgbWFwKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIG1hcDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBzb3J0ZWQgbWFwIGZyb20gb3V0cHV0IHN0cmVhbSBwcm92aWRlciBuYW1lcyB0byBwcm92aWRlcgorICAgICAqIG9iamVjdHMuCisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgbWFwIHJldHVybmVkIGJ5IHRoaXMgbWV0aG9kIHdpbGwgaGF2ZSBvbmUgZW50cnkgZm9yIGVhY2ggcHJvdmlkZXIgZm9yCisgICAgICogd2hpY2ggc3VwcG9ydCBpcyBhdmFpbGFibGUgaW4gdGhlIGN1cnJlbnQgSmF2YSB2aXJ0dWFsIG1hY2hpbmUuIElmIHR3byBvcgorICAgICAqIG1vcmUgc3VwcG9ydGVkIHByb3ZpZGVyIGhhdmUgdGhlIHNhbWUgbmFtZSB0aGVuIHRoZSByZXN1bHRpbmcgbWFwIHdpbGwKKyAgICAgKiBjb250YWluIGp1c3Qgb25lIG9mIHRoZW07IHdoaWNoIG9uZSBpdCB3aWxsIGNvbnRhaW4gaXMgbm90IHNwZWNpZmllZC4KKyAgICAgKiA8L3A+CisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgaW52b2NhdGlvbiBvZiB0aGlzIG1ldGhvZCwgYW5kIHRoZSBzdWJzZXF1ZW50IHVzZSBvZiB0aGUgcmVzdWx0aW5nCisgICAgICogbWFwLCBtYXkgY2F1c2UgdGltZS1jb25zdW1pbmcgZGlzayBvciBuZXR3b3JrIEkvTyBvcGVyYXRpb25zIHRvIG9jY3VyLgorICAgICAqIFRoaXMgbWV0aG9kIGlzIHByb3ZpZGVkIGZvciBhcHBsaWNhdGlvbnMgdGhhdCBuZWVkIHRvIGVudW1lcmF0ZSBhbGwgb2YKKyAgICAgKiB0aGUgYXZhaWxhYmxlIHByb3ZpZGVycywgZm9yIGV4YW1wbGUgdG8gYWxsb3cgdXNlciBwcm92aWRlciBzZWxlY3Rpb24uCisgICAgICogPC9wPgorICAgICAqCisgICAgICogPHA+CisgICAgICogVGhpcyBtZXRob2QgbWF5IHJldHVybiBkaWZmZXJlbnQgcmVzdWx0cyBhdCBkaWZmZXJlbnQgdGltZXMgaWYgbmV3CisgICAgICogcHJvdmlkZXJzIGFyZSBkeW5hbWljYWxseSBtYWRlIGF2YWlsYWJsZSB0byB0aGUgY3VycmVudCBKYXZhIHZpcnR1YWwKKyAgICAgKiBtYWNoaW5lLgorICAgICAqIDwvcD4KKyAgICAgKgorICAgICAqIEByZXR1cm4gQW4gaW1tdXRhYmxlLCBtYXAgZnJvbSBuYW1lcyB0byBwcm92aWRlciBvYmplY3RzCisgICAgICogQHNpbmNlIDEuMTMKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFNvcnRlZE1hcDxTdHJpbmcsIEFyY2hpdmVTdHJlYW1Qcm92aWRlcj4gZmluZEF2YWlsYWJsZUFyY2hpdmVPdXRwdXRTdHJlYW1Qcm92aWRlcnMoKSB7CisgICAgICAgIHJldHVybiBBY2Nlc3NDb250cm9sbGVyLmRvUHJpdmlsZWdlZChuZXcgUHJpdmlsZWdlZEFjdGlvbjxTb3J0ZWRNYXA8U3RyaW5nLCBBcmNoaXZlU3RyZWFtUHJvdmlkZXI+PigpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIFNvcnRlZE1hcDxTdHJpbmcsIEFyY2hpdmVTdHJlYW1Qcm92aWRlcj4gcnVuKCkgeworICAgICAgICAgICAgICAgIFRyZWVNYXA8U3RyaW5nLCBBcmNoaXZlU3RyZWFtUHJvdmlkZXI+IG1hcCA9IG5ldyBUcmVlTWFwPD4oKTsKKyAgICAgICAgICAgICAgICBwdXRBbGwoU0lOR0xFVE9OLmdldE91dHB1dFN0cmVhbUFyY2hpdmVOYW1lcygpLCBTSU5HTEVUT04sIG1hcCk7CisgICAgICAgICAgICAgICAgZm9yIChBcmNoaXZlU3RyZWFtUHJvdmlkZXIgcHJvdmlkZXIgOiBmaW5kQXJjaGl2ZVN0cmVhbVByb3ZpZGVycygpKSB7CisgICAgICAgICAgICAgICAgICAgIHB1dEFsbChwcm92aWRlci5nZXRPdXRwdXRTdHJlYW1BcmNoaXZlTmFtZXMoKSwgcHJvdmlkZXIsIG1hcCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBtYXA7CisgICAgICAgICAgICB9CisgICAgICAgIH0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhbiBpbnN0YW5jZSB1c2luZyB0aGUgcGxhdGZvcm0gZGVmYXVsdCBlbmNvZGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgQXJjaGl2ZVN0cmVhbUZhY3RvcnkoKSB7CisgICAgICAgIHRoaXMobnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlIGFuIGluc3RhbmNlIHVzaW5nIHRoZSBzcGVjaWZpZWQgZW5jb2RpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZW5jb2RpbmcgdGhlIGVuY29kaW5nIHRvIGJlIHVzZWQuCisgICAgICoKKyAgICAgKiBAc2luY2UgMS4xMAorICAgICAqLworICAgIHB1YmxpYyBBcmNoaXZlU3RyZWFtRmFjdG9yeShmaW5hbCBTdHJpbmcgZW5jb2RpbmcpIHsKKyAgICAgICAgc3VwZXIoKTsKKyAgICAgICAgdGhpcy5lbmNvZGluZyA9IGVuY29kaW5nOworICAgICAgICAvLyBBbHNvIHNldCB0aGUgb3JpZ2luYWwgZmllbGQgc28gY2FuIGNvbnRpbnVlIHRvIHVzZSBpdC4KKyAgICAgICAgdGhpcy5lbnRyeUVuY29kaW5nID0gZW5jb2Rpbmc7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZW5jb2RpbmcgdG8gdXNlIGZvciBhcmosIGphciwgemlwLCBkdW1wLCBjcGlvIGFuZCB0YXIKKyAgICAgKiBmaWxlcywgb3IgbnVsbCBmb3IgdGhlIGFyY2hpdmVyIGRlZmF1bHQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGVudHJ5IGVuY29kaW5nLCBvciBudWxsIGZvciB0aGUgYXJjaGl2ZXIgZGVmYXVsdAorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEVudHJ5RW5jb2RpbmcoKSB7CisgICAgICAgIHJldHVybiBlbnRyeUVuY29kaW5nOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGVuY29kaW5nIHRvIHVzZSBmb3IgYXJqLCBqYXIsIHppcCwgZHVtcCwgY3BpbyBhbmQgdGFyIGZpbGVzLiBVc2UgbnVsbCBmb3IgdGhlIGFyY2hpdmVyIGRlZmF1bHQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZW50cnlFbmNvZGluZyB0aGUgZW50cnkgZW5jb2RpbmcsIG51bGwgdXNlcyB0aGUgYXJjaGl2ZXIgZGVmYXVsdC4KKyAgICAgKiBAc2luY2UgMS41CisgICAgICogQGRlcHJlY2F0ZWQgMS4xMCB1c2Uge0BsaW5rICNBcmNoaXZlU3RyZWFtRmFjdG9yeShTdHJpbmcpfSB0byBzcGVjaWZ5IHRoZSBlbmNvZGluZworICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoZSBjb25zdHJ1Y3RvciB7QGxpbmsgI0FyY2hpdmVTdHJlYW1GYWN0b3J5KFN0cmluZyl9CisgICAgICogd2FzIHVzZWQgdG8gc3BlY2lmeSB0aGUgZmFjdG9yeSBlbmNvZGluZy4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyB2b2lkIHNldEVudHJ5RW5jb2RpbmcoZmluYWwgU3RyaW5nIGVudHJ5RW5jb2RpbmcpIHsKKyAgICAgICAgLy8gTm90ZTogdGhpcyBkb2VzIG5vdCBkZXRlY3QgbmV3IEFyY2hpdmVTdHJlYW1GYWN0b3J5KG51bGwpIGJ1dCB0aGF0IGRvZXMgbm90IHNldCB0aGUgZW5jb2RpbmcgYW55d2F5CisgICAgICAgIGlmIChlbmNvZGluZyAhPSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJDYW5ub3Qgb3ZlcmlkZSBlbmNvZGluZyBzZXQgYnkgdGhlIGNvbnN0cnVjdG9yIik7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5lbnRyeUVuY29kaW5nID0gZW50cnlFbmNvZGluZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIGFyY2hpdmUgaW5wdXQgc3RyZWFtIGZyb20gYW4gYXJjaGl2ZXIgbmFtZSBhbmQgYW4gaW5wdXQgc3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtIGFyY2hpdmVyTmFtZSB0aGUgYXJjaGl2ZSBuYW1lLAorICAgICAqIGkuZS4ge0B2YWx1ZSAjQVJ9LCB7QHZhbHVlICNBUkp9LCB7QHZhbHVlICNaSVB9LCB7QHZhbHVlICNUQVJ9LCB7QHZhbHVlICNKQVJ9LCB7QHZhbHVlICNDUElPfSwge0B2YWx1ZSAjRFVNUH0gb3Ige0B2YWx1ZSAjU0VWRU5fWn0KKyAgICAgKiBAcGFyYW0gaW4gdGhlIGlucHV0IHN0cmVhbQorICAgICAqIEByZXR1cm4gdGhlIGFyY2hpdmUgaW5wdXQgc3RyZWFtCisgICAgICogQHRocm93cyBBcmNoaXZlRXhjZXB0aW9uIGlmIHRoZSBhcmNoaXZlciBuYW1lIGlzIG5vdCBrbm93bgorICAgICAqIEB0aHJvd3MgU3RyZWFtaW5nTm90U3VwcG9ydGVkRXhjZXB0aW9uIGlmIHRoZSBmb3JtYXQgY2Fubm90IGJlCisgICAgICogcmVhZCBmcm9tIGEgc3RyZWFtCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIGFyY2hpdmVyIG5hbWUgb3Igc3RyZWFtIGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgQXJjaGl2ZUlucHV0U3RyZWFtIGNyZWF0ZUFyY2hpdmVJbnB1dFN0cmVhbShmaW5hbCBTdHJpbmcgYXJjaGl2ZXJOYW1lLCBmaW5hbCBJbnB1dFN0cmVhbSBpbikKKyAgICAgICAgICAgIHRocm93cyBBcmNoaXZlRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGNyZWF0ZUFyY2hpdmVJbnB1dFN0cmVhbShhcmNoaXZlck5hbWUsIGluLCBlbnRyeUVuY29kaW5nKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQXJjaGl2ZUlucHV0U3RyZWFtIGNyZWF0ZUFyY2hpdmVJbnB1dFN0cmVhbShmaW5hbCBTdHJpbmcgYXJjaGl2ZXJOYW1lLCBmaW5hbCBJbnB1dFN0cmVhbSBpbiwKKyAgICAgICAgICAgIGZpbmFsIFN0cmluZyBhY3R1YWxFbmNvZGluZykgdGhyb3dzIEFyY2hpdmVFeGNlcHRpb24geworCisgICAgICAgIGlmIChhcmNoaXZlck5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiQXJjaGl2ZXJuYW1lIG11c3Qgbm90IGJlIG51bGwuIik7CisgICAgICAgIH0KKworICAgICAgICBpZiAoaW4gPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSW5wdXRTdHJlYW0gbXVzdCBub3QgYmUgbnVsbC4iKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChBUi5lcXVhbHNJZ25vcmVDYXNlKGFyY2hpdmVyTmFtZSkpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgQXJBcmNoaXZlSW5wdXRTdHJlYW0oaW4pOworICAgICAgICB9CisgICAgICAgIGlmIChBUkouZXF1YWxzSWdub3JlQ2FzZShhcmNoaXZlck5hbWUpKSB7CisgICAgICAgICAgICBpZiAoYWN0dWFsRW5jb2RpbmcgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQXJqQXJjaGl2ZUlucHV0U3RyZWFtKGluLCBhY3R1YWxFbmNvZGluZyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbmV3IEFyakFyY2hpdmVJbnB1dFN0cmVhbShpbik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKFpJUC5lcXVhbHNJZ25vcmVDYXNlKGFyY2hpdmVyTmFtZSkpIHsKKyAgICAgICAgICAgIGlmIChhY3R1YWxFbmNvZGluZyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBaaXBBcmNoaXZlSW5wdXRTdHJlYW0oaW4sIGFjdHVhbEVuY29kaW5nKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBuZXcgWmlwQXJjaGl2ZUlucHV0U3RyZWFtKGluKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoVEFSLmVxdWFsc0lnbm9yZUNhc2UoYXJjaGl2ZXJOYW1lKSkgeworICAgICAgICAgICAgaWYgKGFjdHVhbEVuY29kaW5nICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFRhckFyY2hpdmVJbnB1dFN0cmVhbShpbiwgYWN0dWFsRW5jb2RpbmcpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIG5ldyBUYXJBcmNoaXZlSW5wdXRTdHJlYW0oaW4pOworICAgICAgICB9CisgICAgICAgIGlmIChKQVIuZXF1YWxzSWdub3JlQ2FzZShhcmNoaXZlck5hbWUpKSB7CisgICAgICAgICAgICBpZiAoYWN0dWFsRW5jb2RpbmcgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgSmFyQXJjaGl2ZUlucHV0U3RyZWFtKGluLCBhY3R1YWxFbmNvZGluZyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbmV3IEphckFyY2hpdmVJbnB1dFN0cmVhbShpbik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKENQSU8uZXF1YWxzSWdub3JlQ2FzZShhcmNoaXZlck5hbWUpKSB7CisgICAgICAgICAgICBpZiAoYWN0dWFsRW5jb2RpbmcgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQ3Bpb0FyY2hpdmVJbnB1dFN0cmVhbShpbiwgYWN0dWFsRW5jb2RpbmcpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIG5ldyBDcGlvQXJjaGl2ZUlucHV0U3RyZWFtKGluKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoRFVNUC5lcXVhbHNJZ25vcmVDYXNlKGFyY2hpdmVyTmFtZSkpIHsKKyAgICAgICAgICAgIGlmIChhY3R1YWxFbmNvZGluZyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBEdW1wQXJjaGl2ZUlucHV0U3RyZWFtKGluLCBhY3R1YWxFbmNvZGluZyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbmV3IER1bXBBcmNoaXZlSW5wdXRTdHJlYW0oaW4pOworICAgICAgICB9CisgICAgICAgIGlmIChTRVZFTl9aLmVxdWFsc0lnbm9yZUNhc2UoYXJjaGl2ZXJOYW1lKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFN0cmVhbWluZ05vdFN1cHBvcnRlZEV4Y2VwdGlvbihTRVZFTl9aKTsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIEFyY2hpdmVTdHJlYW1Qcm92aWRlciBhcmNoaXZlU3RyZWFtUHJvdmlkZXIgPSBnZXRBcmNoaXZlSW5wdXRTdHJlYW1Qcm92aWRlcnMoKS5nZXQodG9LZXkoYXJjaGl2ZXJOYW1lKSk7CisgICAgICAgIGlmIChhcmNoaXZlU3RyZWFtUHJvdmlkZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGFyY2hpdmVTdHJlYW1Qcm92aWRlci5jcmVhdGVBcmNoaXZlSW5wdXRTdHJlYW0oYXJjaGl2ZXJOYW1lLCBpbiwgYWN0dWFsRW5jb2RpbmcpOworICAgICAgICB9CisKKyAgICAgICAgdGhyb3cgbmV3IEFyY2hpdmVFeGNlcHRpb24oIkFyY2hpdmVyOiAiICsgYXJjaGl2ZXJOYW1lICsgIiBub3QgZm91bmQuIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBhcmNoaXZlIG91dHB1dCBzdHJlYW0gZnJvbSBhbiBhcmNoaXZlciBuYW1lIGFuZCBhbiBvdXRwdXQgc3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtIGFyY2hpdmVyTmFtZSB0aGUgYXJjaGl2ZSBuYW1lLAorICAgICAqIGkuZS4ge0B2YWx1ZSAjQVJ9LCB7QHZhbHVlICNaSVB9LCB7QHZhbHVlICNUQVJ9LCB7QHZhbHVlICNKQVJ9IG9yIHtAdmFsdWUgI0NQSU99CisgICAgICogQHBhcmFtIG91dCB0aGUgb3V0cHV0IHN0cmVhbQorICAgICAqIEByZXR1cm4gdGhlIGFyY2hpdmUgb3V0cHV0IHN0cmVhbQorICAgICAqIEB0aHJvd3MgQXJjaGl2ZUV4Y2VwdGlvbiBpZiB0aGUgYXJjaGl2ZXIgbmFtZSBpcyBub3Qga25vd24KKyAgICAgKiBAdGhyb3dzIFN0cmVhbWluZ05vdFN1cHBvcnRlZEV4Y2VwdGlvbiBpZiB0aGUgZm9ybWF0IGNhbm5vdCBiZQorICAgICAqIHdyaXR0ZW4gdG8gYSBzdHJlYW0KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgYXJjaGl2ZXIgbmFtZSBvciBzdHJlYW0gaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBBcmNoaXZlT3V0cHV0U3RyZWFtIGNyZWF0ZUFyY2hpdmVPdXRwdXRTdHJlYW0oZmluYWwgU3RyaW5nIGFyY2hpdmVyTmFtZSwgZmluYWwgT3V0cHV0U3RyZWFtIG91dCkKKyAgICAgICAgICAgIHRocm93cyBBcmNoaXZlRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGNyZWF0ZUFyY2hpdmVPdXRwdXRTdHJlYW0oYXJjaGl2ZXJOYW1lLCBvdXQsIGVudHJ5RW5jb2RpbmcpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBBcmNoaXZlT3V0cHV0U3RyZWFtIGNyZWF0ZUFyY2hpdmVPdXRwdXRTdHJlYW0oCisgICAgICAgICAgICBmaW5hbCBTdHJpbmcgYXJjaGl2ZXJOYW1lLCBmaW5hbCBPdXRwdXRTdHJlYW0gb3V0LCBmaW5hbCBTdHJpbmcgYWN0dWFsRW5jb2RpbmcpCisgICAgICAgICAgICB0aHJvd3MgQXJjaGl2ZUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChhcmNoaXZlck5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiQXJjaGl2ZXJuYW1lIG11c3Qgbm90IGJlIG51bGwuIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG91dCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJPdXRwdXRTdHJlYW0gbXVzdCBub3QgYmUgbnVsbC4iKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChBUi5lcXVhbHNJZ25vcmVDYXNlKGFyY2hpdmVyTmFtZSkpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgQXJBcmNoaXZlT3V0cHV0U3RyZWFtKG91dCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKFpJUC5lcXVhbHNJZ25vcmVDYXNlKGFyY2hpdmVyTmFtZSkpIHsKKyAgICAgICAgICAgIGZpbmFsIFppcEFyY2hpdmVPdXRwdXRTdHJlYW0gemlwID0gbmV3IFppcEFyY2hpdmVPdXRwdXRTdHJlYW0ob3V0KTsKKyAgICAgICAgICAgIGlmIChhY3R1YWxFbmNvZGluZyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgemlwLnNldEVuY29kaW5nKGFjdHVhbEVuY29kaW5nKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiB6aXA7CisgICAgICAgIH0KKyAgICAgICAgaWYgKFRBUi5lcXVhbHNJZ25vcmVDYXNlKGFyY2hpdmVyTmFtZSkpIHsKKyAgICAgICAgICAgIGlmIChhY3R1YWxFbmNvZGluZyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBUYXJBcmNoaXZlT3V0cHV0U3RyZWFtKG91dCwgYWN0dWFsRW5jb2RpbmcpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIG5ldyBUYXJBcmNoaXZlT3V0cHV0U3RyZWFtKG91dCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKEpBUi5lcXVhbHNJZ25vcmVDYXNlKGFyY2hpdmVyTmFtZSkpIHsKKyAgICAgICAgICAgIGlmIChhY3R1YWxFbmNvZGluZyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBKYXJBcmNoaXZlT3V0cHV0U3RyZWFtKG91dCwgYWN0dWFsRW5jb2RpbmcpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIG5ldyBKYXJBcmNoaXZlT3V0cHV0U3RyZWFtKG91dCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKENQSU8uZXF1YWxzSWdub3JlQ2FzZShhcmNoaXZlck5hbWUpKSB7CisgICAgICAgICAgICBpZiAoYWN0dWFsRW5jb2RpbmcgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQ3Bpb0FyY2hpdmVPdXRwdXRTdHJlYW0ob3V0LCBhY3R1YWxFbmNvZGluZyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbmV3IENwaW9BcmNoaXZlT3V0cHV0U3RyZWFtKG91dCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKFNFVkVOX1ouZXF1YWxzSWdub3JlQ2FzZShhcmNoaXZlck5hbWUpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgU3RyZWFtaW5nTm90U3VwcG9ydGVkRXhjZXB0aW9uKFNFVkVOX1opOworICAgICAgICB9CisKKyAgICAgICAgZmluYWwgQXJjaGl2ZVN0cmVhbVByb3ZpZGVyIGFyY2hpdmVTdHJlYW1Qcm92aWRlciA9IGdldEFyY2hpdmVPdXRwdXRTdHJlYW1Qcm92aWRlcnMoKS5nZXQodG9LZXkoYXJjaGl2ZXJOYW1lKSk7CisgICAgICAgIGlmIChhcmNoaXZlU3RyZWFtUHJvdmlkZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGFyY2hpdmVTdHJlYW1Qcm92aWRlci5jcmVhdGVBcmNoaXZlT3V0cHV0U3RyZWFtKGFyY2hpdmVyTmFtZSwgb3V0LCBhY3R1YWxFbmNvZGluZyk7CisgICAgICAgIH0KKworICAgICAgICB0aHJvdyBuZXcgQXJjaGl2ZUV4Y2VwdGlvbigiQXJjaGl2ZXI6ICIgKyBhcmNoaXZlck5hbWUgKyAiIG5vdCBmb3VuZC4iKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYW4gYXJjaGl2ZSBpbnB1dCBzdHJlYW0gZnJvbSBhbiBpbnB1dCBzdHJlYW0sIGF1dG9kZXRlY3RpbmcKKyAgICAgKiB0aGUgYXJjaGl2ZSB0eXBlIGZyb20gdGhlIGZpcnN0IGZldyBieXRlcyBvZiB0aGUgc3RyZWFtLiBUaGUgSW5wdXRTdHJlYW0KKyAgICAgKiBtdXN0IHN1cHBvcnQgbWFya3MsIGxpa2UgQnVmZmVyZWRJbnB1dFN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbiB0aGUgaW5wdXQgc3RyZWFtCisgICAgICogQHJldHVybiB0aGUgYXJjaGl2ZSBpbnB1dCBzdHJlYW0KKyAgICAgKiBAdGhyb3dzIEFyY2hpdmVFeGNlcHRpb24gaWYgdGhlIGFyY2hpdmVyIG5hbWUgaXMgbm90IGtub3duCisgICAgICogQHRocm93cyBTdHJlYW1pbmdOb3RTdXBwb3J0ZWRFeGNlcHRpb24gaWYgdGhlIGZvcm1hdCBjYW5ub3QgYmUKKyAgICAgKiByZWFkIGZyb20gYSBzdHJlYW0KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgc3RyZWFtIGlzIG51bGwgb3IgZG9lcyBub3Qgc3VwcG9ydCBtYXJrCisgICAgICovCisgICAgcHVibGljIEFyY2hpdmVJbnB1dFN0cmVhbSBjcmVhdGVBcmNoaXZlSW5wdXRTdHJlYW0oZmluYWwgSW5wdXRTdHJlYW0gaW4pCisgICAgICAgICAgICB0aHJvd3MgQXJjaGl2ZUV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBjcmVhdGVBcmNoaXZlSW5wdXRTdHJlYW0oZGV0ZWN0KGluKSwgaW4pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRyeSB0byBkZXRlcm1pbmUgdGhlIHR5cGUgb2YgQXJjaGl2ZXIKKyAgICAgKiBAcGFyYW0gaW4gaW5wdXQgc3RyZWFtCisgICAgICogQHJldHVybiB0eXBlIG9mIGFyY2hpdmVyIGlmIGZvdW5kCisgICAgICogQHRocm93cyBBcmNoaXZlRXhjZXB0aW9uIGlmIGFuIGFyY2hpdmVyIGNhbm5vdCBiZSBkZXRlY3RlZCBpbiB0aGUgc3RyZWFtCisgICAgICogQHNpbmNlIDEuMTQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBkZXRlY3QoSW5wdXRTdHJlYW0gaW4pIHRocm93cyBBcmNoaXZlRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGluID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlN0cmVhbSBtdXN0IG5vdCBiZSBudWxsLiIpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKCFpbi5tYXJrU3VwcG9ydGVkKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIk1hcmsgaXMgbm90IHN1cHBvcnRlZC4iKTsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIGJ5dGVbXSBzaWduYXR1cmUgPSBuZXcgYnl0ZVtTSUdOQVRVUkVfU0laRV07CisgICAgICAgIGluLm1hcmsoc2lnbmF0dXJlLmxlbmd0aCk7CisgICAgICAgIGludCBzaWduYXR1cmVMZW5ndGggPSAtMTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNpZ25hdHVyZUxlbmd0aCA9IElPVXRpbHMucmVhZEZ1bGx5KGluLCBzaWduYXR1cmUpOworICAgICAgICAgICAgaW4ucmVzZXQoKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFyY2hpdmVFeGNlcHRpb24oIklPRXhjZXB0aW9uIHdoaWxlIHJlYWRpbmcgc2lnbmF0dXJlLiIsIGUpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKFppcEFyY2hpdmVJbnB1dFN0cmVhbS5tYXRjaGVzKHNpZ25hdHVyZSwgc2lnbmF0dXJlTGVuZ3RoKSkgeworICAgICAgICAgICAgcmV0dXJuIFpJUDsKKyAgICAgICAgfSBlbHNlIGlmIChKYXJBcmNoaXZlSW5wdXRTdHJlYW0ubWF0Y2hlcyhzaWduYXR1cmUsIHNpZ25hdHVyZUxlbmd0aCkpIHsKKyAgICAgICAgICAgIHJldHVybiBKQVI7CisgICAgICAgIH0gZWxzZSBpZiAoQXJBcmNoaXZlSW5wdXRTdHJlYW0ubWF0Y2hlcyhzaWduYXR1cmUsIHNpZ25hdHVyZUxlbmd0aCkpIHsKKyAgICAgICAgICAgIHJldHVybiBBUjsKKyAgICAgICAgfSBlbHNlIGlmIChDcGlvQXJjaGl2ZUlucHV0U3RyZWFtLm1hdGNoZXMoc2lnbmF0dXJlLCBzaWduYXR1cmVMZW5ndGgpKSB7CisgICAgICAgICAgICByZXR1cm4gQ1BJTzsKKyAgICAgICAgfSBlbHNlIGlmIChBcmpBcmNoaXZlSW5wdXRTdHJlYW0ubWF0Y2hlcyhzaWduYXR1cmUsIHNpZ25hdHVyZUxlbmd0aCkpIHsKKyAgICAgICAgICAgIHJldHVybiBBUko7CisgICAgICAgIH0gZWxzZSBpZiAoU2V2ZW5aRmlsZS5tYXRjaGVzKHNpZ25hdHVyZSwgc2lnbmF0dXJlTGVuZ3RoKSkgeworICAgICAgICAgICAgcmV0dXJuIFNFVkVOX1o7CisgICAgICAgIH0KKworICAgICAgICAvLyBEdW1wIG5lZWRzIGEgYmlnZ2VyIGJ1ZmZlciB0byBjaGVjayB0aGUgc2lnbmF0dXJlOworICAgICAgICBmaW5hbCBieXRlW10gZHVtcHNpZyA9IG5ldyBieXRlW0RVTVBfU0lHTkFUVVJFX1NJWkVdOworICAgICAgICBpbi5tYXJrKGR1bXBzaWcubGVuZ3RoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNpZ25hdHVyZUxlbmd0aCA9IElPVXRpbHMucmVhZEZ1bGx5KGluLCBkdW1wc2lnKTsKKyAgICAgICAgICAgIGluLnJlc2V0KCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBcmNoaXZlRXhjZXB0aW9uKCJJT0V4Y2VwdGlvbiB3aGlsZSByZWFkaW5nIGR1bXAgc2lnbmF0dXJlIiwgZSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKER1bXBBcmNoaXZlSW5wdXRTdHJlYW0ubWF0Y2hlcyhkdW1wc2lnLCBzaWduYXR1cmVMZW5ndGgpKSB7CisgICAgICAgICAgICByZXR1cm4gRFVNUDsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFRhciBuZWVkcyBhbiBldmVuIGJpZ2dlciBidWZmZXIgdG8gY2hlY2sgdGhlIHNpZ25hdHVyZTsgcmVhZCB0aGUgZmlyc3QgYmxvY2sKKyAgICAgICAgZmluYWwgYnl0ZVtdIHRhckhlYWRlciA9IG5ldyBieXRlW1RBUl9IRUFERVJfU0laRV07CisgICAgICAgIGluLm1hcmsodGFySGVhZGVyLmxlbmd0aCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzaWduYXR1cmVMZW5ndGggPSBJT1V0aWxzLnJlYWRGdWxseShpbiwgdGFySGVhZGVyKTsKKyAgICAgICAgICAgIGluLnJlc2V0KCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBcmNoaXZlRXhjZXB0aW9uKCJJT0V4Y2VwdGlvbiB3aGlsZSByZWFkaW5nIHRhciBzaWduYXR1cmUiLCBlKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoVGFyQXJjaGl2ZUlucHV0U3RyZWFtLm1hdGNoZXModGFySGVhZGVyLCBzaWduYXR1cmVMZW5ndGgpKSB7CisgICAgICAgICAgICByZXR1cm4gVEFSOworICAgICAgICB9CisKKyAgICAgICAgLy8gQ09NUFJFU1MtMTE3IC0gaW1wcm92ZSBhdXRvLXJlY29nbml0aW9uCisgICAgICAgIGlmIChzaWduYXR1cmVMZW5ndGggPj0gVEFSX0hFQURFUl9TSVpFKSB7CisgICAgICAgICAgICBUYXJBcmNoaXZlSW5wdXRTdHJlYW0gdGFpcyA9IG51bGw7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHRhaXMgPSBuZXcgVGFyQXJjaGl2ZUlucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbSh0YXJIZWFkZXIpKTsKKyAgICAgICAgICAgICAgICAvLyBDT01QUkVTUy0xOTEgLSB2ZXJpZnkgdGhlIGhlYWRlciBjaGVja3N1bQorICAgICAgICAgICAgICAgIGlmICh0YWlzLmdldE5leHRUYXJFbnRyeSgpLmlzQ2hlY2tTdW1PSygpKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBUQVI7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoZmluYWwgRXhjZXB0aW9uIGUpIHsgLy8gTk9QTUQgLy8gTk9TT05BUgorICAgICAgICAgICAgICAgIC8vIGNhbiBnZW5lcmF0ZSBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gYXMgd2VsbAorICAgICAgICAgICAgICAgIC8vIGFzIElPRXhjZXB0aW9uCisgICAgICAgICAgICAgICAgLy8gYXV0b2RldGVjdGlvbiwgc2ltcGx5IG5vdCBhIFRBUgorICAgICAgICAgICAgICAgIC8vIGlnbm9yZWQKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgSU9VdGlscy5jbG9zZVF1aWV0bHkodGFpcyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgdGhyb3cgbmV3IEFyY2hpdmVFeGNlcHRpb24oIk5vIEFyY2hpdmVyIGZvdW5kIGZvciB0aGUgc3RyZWFtIHNpZ25hdHVyZSIpOworICAgIH0KKworICAgIHB1YmxpYyBTb3J0ZWRNYXA8U3RyaW5nLCBBcmNoaXZlU3RyZWFtUHJvdmlkZXI+IGdldEFyY2hpdmVJbnB1dFN0cmVhbVByb3ZpZGVycygpIHsKKyAgICAgICAgaWYgKGFyY2hpdmVJbnB1dFN0cmVhbVByb3ZpZGVycyA9PSBudWxsKSB7CisgICAgICAgICAgICBhcmNoaXZlSW5wdXRTdHJlYW1Qcm92aWRlcnMgPSBDb2xsZWN0aW9ucworICAgICAgICAgICAgICAgICAgICAudW5tb2RpZmlhYmxlU29ydGVkTWFwKGZpbmRBdmFpbGFibGVBcmNoaXZlSW5wdXRTdHJlYW1Qcm92aWRlcnMoKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGFyY2hpdmVJbnB1dFN0cmVhbVByb3ZpZGVyczsKKyAgICB9CisKKyAgICBwdWJsaWMgU29ydGVkTWFwPFN0cmluZywgQXJjaGl2ZVN0cmVhbVByb3ZpZGVyPiBnZXRBcmNoaXZlT3V0cHV0U3RyZWFtUHJvdmlkZXJzKCkgeworICAgICAgICBpZiAoYXJjaGl2ZU91dHB1dFN0cmVhbVByb3ZpZGVycyA9PSBudWxsKSB7CisgICAgICAgICAgICBhcmNoaXZlT3V0cHV0U3RyZWFtUHJvdmlkZXJzID0gQ29sbGVjdGlvbnMKKyAgICAgICAgICAgICAgICAgICAgLnVubW9kaWZpYWJsZVNvcnRlZE1hcChmaW5kQXZhaWxhYmxlQXJjaGl2ZU91dHB1dFN0cmVhbVByb3ZpZGVycygpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYXJjaGl2ZU91dHB1dFN0cmVhbVByb3ZpZGVyczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU2V0PFN0cmluZz4gZ2V0SW5wdXRTdHJlYW1BcmNoaXZlTmFtZXMoKSB7CisgICAgICAgIHJldHVybiBTZXRzLm5ld0hhc2hTZXQoQVIsIEFSSiwgWklQLCBUQVIsIEpBUiwgQ1BJTywgRFVNUCwgU0VWRU5fWik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNldDxTdHJpbmc+IGdldE91dHB1dFN0cmVhbUFyY2hpdmVOYW1lcygpIHsKKyAgICAgICAgcmV0dXJuIFNldHMubmV3SGFzaFNldChBUiwgWklQLCBUQVIsIEpBUiwgQ1BJTywgU0VWRU5fWik7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvQXJjaGl2ZVN0cmVhbVByb3ZpZGVyLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvQXJjaGl2ZVN0cmVhbVByb3ZpZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWIxODYyYwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9BcmNoaXZlU3RyZWFtUHJvdmlkZXIuamF2YQpAQCAtMCwwICsxLDEwNCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVyczsKKworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLlNldDsKKworLyoqCisgKiBDcmVhdGVzIEFyY2hpdmUge0BsaW5rIEFyY2hpdmVJbnB1dFN0cmVhbX1zIGFuZCB7QGxpbmsgQXJjaGl2ZU91dHB1dFN0cmVhbX1zLgorICoKKyAqIEBzaW5jZSAxLjEzCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgQXJjaGl2ZVN0cmVhbVByb3ZpZGVyIHsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gYXJjaGl2ZSBpbnB1dCBzdHJlYW0gZnJvbSBhbiBhcmNoaXZlciBuYW1lIGFuZCBhbiBpbnB1dAorICAgICAqIHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICB0aGUgYXJjaGl2ZSBuYW1lLCBpLmUuCisgICAgICogICAgICAgICAgICB7QHZhbHVlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZVN0cmVhbUZhY3RvcnkjQVJ9LAorICAgICAqICAgICAgICAgICAge0B2YWx1ZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLkFyY2hpdmVTdHJlYW1GYWN0b3J5I0FSSn0sCisgICAgICogICAgICAgICAgICB7QHZhbHVlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZVN0cmVhbUZhY3RvcnkjWklQfSwKKyAgICAgKiAgICAgICAgICAgIHtAdmFsdWUgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5BcmNoaXZlU3RyZWFtRmFjdG9yeSNUQVJ9LAorICAgICAqICAgICAgICAgICAge0B2YWx1ZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLkFyY2hpdmVTdHJlYW1GYWN0b3J5I0pBUn0sCisgICAgICogICAgICAgICAgICB7QHZhbHVlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZVN0cmVhbUZhY3RvcnkjQ1BJT30sCisgICAgICogICAgICAgICAgICB7QHZhbHVlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZVN0cmVhbUZhY3RvcnkjRFVNUH0KKyAgICAgKiAgICAgICAgICAgIG9yCisgICAgICogICAgICAgICAgICB7QHZhbHVlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZVN0cmVhbUZhY3RvcnkjU0VWRU5fWn0KKyAgICAgKiBAcGFyYW0gaW4KKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnB1dCBzdHJlYW0KKyAgICAgKiBAcGFyYW0gZW5jb2RpbmcKKyAgICAgKiAgICAgICAgICAgIGVuY29kaW5nIG5hbWUgb3IgbnVsbCBmb3IgdGhlIGRlZmF1bHQKKyAgICAgKiBAcmV0dXJuIHRoZSBhcmNoaXZlIGlucHV0IHN0cmVhbQorICAgICAqIEB0aHJvd3MgQXJjaGl2ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBhcmNoaXZlciBuYW1lIGlzIG5vdCBrbm93bgorICAgICAqIEB0aHJvd3MgU3RyZWFtaW5nTm90U3VwcG9ydGVkRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGZvcm1hdCBjYW5ub3QgYmUgcmVhZCBmcm9tIGEgc3RyZWFtCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgYXJjaGl2ZXIgbmFtZSBvciBzdHJlYW0gaXMgbnVsbAorICAgICAqLworICAgIEFyY2hpdmVJbnB1dFN0cmVhbSBjcmVhdGVBcmNoaXZlSW5wdXRTdHJlYW0oZmluYWwgU3RyaW5nIG5hbWUsIGZpbmFsIElucHV0U3RyZWFtIGluLCBmaW5hbCBTdHJpbmcgZW5jb2RpbmcpCisgICAgICAgICAgICB0aHJvd3MgQXJjaGl2ZUV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gYXJjaGl2ZSBvdXRwdXQgc3RyZWFtIGZyb20gYW4gYXJjaGl2ZXIgbmFtZSBhbmQgYW4gb3V0cHV0CisgICAgICogc3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcmNoaXZlIG5hbWUsIGkuZS4KKyAgICAgKiAgICAgICAgICAgIHtAdmFsdWUgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5BcmNoaXZlU3RyZWFtRmFjdG9yeSNBUn0sCisgICAgICogICAgICAgICAgICB7QHZhbHVlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZVN0cmVhbUZhY3RvcnkjWklQfSwKKyAgICAgKiAgICAgICAgICAgIHtAdmFsdWUgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5BcmNoaXZlU3RyZWFtRmFjdG9yeSNUQVJ9LAorICAgICAqICAgICAgICAgICAge0B2YWx1ZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLkFyY2hpdmVTdHJlYW1GYWN0b3J5I0pBUn0KKyAgICAgKiAgICAgICAgICAgIG9yCisgICAgICogICAgICAgICAgICB7QHZhbHVlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZVN0cmVhbUZhY3RvcnkjQ1BJT30KKyAgICAgKiBAcGFyYW0gb3V0CisgICAgICogICAgICAgICAgICB0aGUgb3V0cHV0IHN0cmVhbQorICAgICAqIEBwYXJhbSBlbmNvZGluZworICAgICAqICAgICAgICAgICAgZW5jb2RpbmcgbmFtZSBvciBudWxsIGZvciB0aGUgZGVmYXVsdAorICAgICAqIEByZXR1cm4gdGhlIGFyY2hpdmUgb3V0cHV0IHN0cmVhbQorICAgICAqIEB0aHJvd3MgQXJjaGl2ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBhcmNoaXZlciBuYW1lIGlzIG5vdCBrbm93bgorICAgICAqIEB0aHJvd3MgU3RyZWFtaW5nTm90U3VwcG9ydGVkRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGZvcm1hdCBjYW5ub3QgYmUgd3JpdHRlbiB0byBhIHN0cmVhbQorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGFyY2hpdmVyIG5hbWUgb3Igc3RyZWFtIGlzIG51bGwKKyAgICAgKi8KKyAgICBBcmNoaXZlT3V0cHV0U3RyZWFtIGNyZWF0ZUFyY2hpdmVPdXRwdXRTdHJlYW0oZmluYWwgU3RyaW5nIG5hbWUsIGZpbmFsIE91dHB1dFN0cmVhbSBvdXQsIGZpbmFsIFN0cmluZyBlbmNvZGluZykKKyAgICAgICAgICAgIHRocm93cyBBcmNoaXZlRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyBhbGwgdGhlIGlucHV0IHN0cmVhbSBhcmNoaXZlIG5hbWVzIGZvciB0aGlzIHByb3ZpZGVyCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFsbCB0aGUgaW5wdXQgYXJjaGl2ZSBuYW1lcyBmb3IgdGhpcyBwcm92aWRlcgorICAgICAqLworICAgIFNldDxTdHJpbmc+IGdldElucHV0U3RyZWFtQXJjaGl2ZU5hbWVzKCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGFsbCB0aGUgb3V0cHV0IHN0cmVhbSBhcmNoaXZlIG5hbWVzIGZvciB0aGlzIHByb3ZpZGVyCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFsbCB0aGUgb3V0cHV0IGFyY2hpdmUgbmFtZXMgZm9yIHRoaXMgcHJvdmlkZXIKKyAgICAgKi8KKyAgICBTZXQ8U3RyaW5nPiBnZXRPdXRwdXRTdHJlYW1BcmNoaXZlTmFtZXMoKTsKKworfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL0VudHJ5U3RyZWFtT2Zmc2V0cy5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL0VudHJ5U3RyZWFtT2Zmc2V0cy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE3M2QwNzkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvRW50cnlTdHJlYW1PZmZzZXRzLmphdmEKQEAgLTAsMCArMSw0NiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnM7CisKKworLyoqCisgKiBQcm92aWRlcyBpbmZvcm1hdGlvbiBhYm91dCBBcmNoaXZlRW50cnkgc3RyZWFtIG9mZnNldHMuCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgRW50cnlTdHJlYW1PZmZzZXRzIHsKKworICAgIC8qKiBTcGVjaWFsIHZhbHVlIGluZGljYXRpbmcgdGhhdCB0aGUgb2Zmc2V0IGlzIHVua25vd24uICovCisgICAgbG9uZyBPRkZTRVRfVU5LTk9XTiA9IC0xOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgb2Zmc2V0IG9mIGRhdGEgc3RyZWFtIHdpdGhpbiB0aGUgYXJjaGl2ZSBmaWxlLAorICAgICAqCisgICAgICogQHJldHVybgorICAgICAqICAgICAgdGhlIG9mZnNldCBvZiBlbnRyeSBkYXRhIHN0cmVhbSwge0Bjb2RlIE9GRlNFVF9VTktOT1dOfSBpZiBub3Qga25vd24uCisgICAgICovCisgICAgbG9uZyBnZXREYXRhT2Zmc2V0KCk7CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgc3RyZWFtIGlzIGNvbnRpZ3VvdXMsIGkuZS4gbm90IHNwbGl0IGFtb25nCisgICAgICogc2V2ZXJhbCBhcmNoaXZlIHBhcnRzLCBpbnRlcnNwZXJzZWQgd2l0aCBjb250cm9sIGJsb2NrcywgZXRjLgorICAgICAqCisgICAgICogQHJldHVybgorICAgICAqICAgICAgdHJ1ZSBpZiBzdHJlYW0gaXMgY29udGlndW91cywgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIGJvb2xlYW4gaXNTdHJlYW1Db250aWd1b3VzKCk7Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvTGlzdGVyLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvTGlzdGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDdhOGU5YwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9MaXN0ZXIuamF2YQpAQCAtMCwwICsxLDk2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVyczsKKworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEubmlvLmZpbGUuRmlsZXM7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5zZXZlbnouU2V2ZW5aRmlsZTsKKworLyoqCisgKiBTaW1wbGUgY29tbWFuZCBsaW5lIGFwcGxpY2F0aW9uIHRoYXQgbGlzdHMgdGhlIGNvbnRlbnRzIG9mIGFuIGFyY2hpdmUuCisgKgorICogPHA+VGhlIG5hbWUgb2YgdGhlIGFyY2hpdmUgbXVzdCBiZSBnaXZlbiBhcyBhIGNvbW1hbmQgbGluZSBhcmd1bWVudC48L3A+CisgKiA8cD5UaGUgb3B0aW9uYWwgc2Vjb25kIGFyZ3VtZW50IGRlZmluZXMgdGhlIGFyY2hpdmUgdHlwZSwgaW4gY2FzZSB0aGUgZm9ybWF0IGlzIG5vdCByZWNvZ25pemVkLjwvcD4KKyAqCisgKiBAc2luY2UgMS4xCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBMaXN0ZXIgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEFyY2hpdmVTdHJlYW1GYWN0b3J5IGZhY3RvcnkgPSBuZXcgQXJjaGl2ZVN0cmVhbUZhY3RvcnkoKTsKKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBpZiAoYXJncy5sZW5ndGggPT0gMCkgeworICAgICAgICAgICAgdXNhZ2UoKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkFuYWx5c2luZyAiICsgYXJnc1swXSk7CisgICAgICAgIGZpbmFsIEZpbGUgZiA9IG5ldyBGaWxlKGFyZ3NbMF0pOworICAgICAgICBpZiAoIWYuaXNGaWxlKCkpIHsKKyAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbihmICsgIiBkb2Vzbid0IGV4aXN0IG9yIGlzIGEgZGlyZWN0b3J5Iik7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nIGZvcm1hdCA9IGFyZ3MubGVuZ3RoID4gMSA/IGFyZ3NbMV0gOiBkZXRlY3RGb3JtYXQoZik7CisgICAgICAgIGlmIChBcmNoaXZlU3RyZWFtRmFjdG9yeS5TRVZFTl9aLmVxdWFsc0lnbm9yZUNhc2UoZm9ybWF0KSkgeworICAgICAgICAgICAgbGlzdDd6KGYpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgbGlzdFN0cmVhbShmLCBhcmdzKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgbGlzdFN0cmVhbShGaWxlIGYsIFN0cmluZ1tdIGFyZ3MpIHRocm93cyBBcmNoaXZlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRyeSAoZmluYWwgSW5wdXRTdHJlYW0gZmlzID0gbmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0oRmlsZXMubmV3SW5wdXRTdHJlYW0oZi50b1BhdGgoKSkpOworICAgICAgICAgICAgICAgIGZpbmFsIEFyY2hpdmVJbnB1dFN0cmVhbSBhaXMgPSBjcmVhdGVBcmNoaXZlSW5wdXRTdHJlYW0oYXJncywgZmlzKSkgeworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJDcmVhdGVkICIgKyBhaXMudG9TdHJpbmcoKSk7CisgICAgICAgICAgICBBcmNoaXZlRW50cnkgYWU7CisgICAgICAgICAgICB3aGlsZSAoKGFlID0gYWlzLmdldE5leHRFbnRyeSgpKSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKGFlLmdldE5hbWUoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBBcmNoaXZlSW5wdXRTdHJlYW0gY3JlYXRlQXJjaGl2ZUlucHV0U3RyZWFtKGZpbmFsIFN0cmluZ1tdIGFyZ3MsIGZpbmFsIElucHV0U3RyZWFtIGZpcykKKyAgICAgICAgICAgIHRocm93cyBBcmNoaXZlRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGFyZ3MubGVuZ3RoID4gMSkgeworICAgICAgICAgICAgcmV0dXJuIGZhY3RvcnkuY3JlYXRlQXJjaGl2ZUlucHV0U3RyZWFtKGFyZ3NbMV0sIGZpcyk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhY3RvcnkuY3JlYXRlQXJjaGl2ZUlucHV0U3RyZWFtKGZpcyk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGRldGVjdEZvcm1hdChGaWxlIGYpIHRocm93cyBBcmNoaXZlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRyeSAoZmluYWwgSW5wdXRTdHJlYW0gZmlzID0gbmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0oRmlsZXMubmV3SW5wdXRTdHJlYW0oZi50b1BhdGgoKSkpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFjdG9yeS5kZXRlY3QoZmlzKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgbGlzdDd6KEZpbGUgZikgdGhyb3dzIEFyY2hpdmVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IChTZXZlblpGaWxlIHogPSBuZXcgU2V2ZW5aRmlsZShmKSkgeworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJDcmVhdGVkICIgKyB6LnRvU3RyaW5nKCkpOworICAgICAgICAgICAgQXJjaGl2ZUVudHJ5IGFlOworICAgICAgICAgICAgd2hpbGUgKChhZSA9IHouZ2V0TmV4dEVudHJ5KCkpICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oYWUuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgdXNhZ2UoKSB7CisgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiUGFyYW1ldGVyczogYXJjaGl2ZS1uYW1lIFthcmNoaXZlLXR5cGVdIik7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvU3RyZWFtaW5nTm90U3VwcG9ydGVkRXhjZXB0aW9uLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvU3RyZWFtaW5nTm90U3VwcG9ydGVkRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWYxMmE3YQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9TdHJlYW1pbmdOb3RTdXBwb3J0ZWRFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDUxIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVyczsKKworLyoqCisgKiBFeGNlcHRpb24gdGhyb3duIGJ5IEFyY2hpdmVTdHJlYW1GYWN0b3J5IGlmIGEgZm9ybWF0IGlzIHJlcXVlc3RlZC9kZXRlY3RlZCB0aGF0IGRvZXNuJ3Qgc3VwcG9ydCBzdHJlYW1pbmcuCisgKgorICogQHNpbmNlIDEuOAorICovCitwdWJsaWMgY2xhc3MgU3RyZWFtaW5nTm90U3VwcG9ydGVkRXhjZXB0aW9uIGV4dGVuZHMgQXJjaGl2ZUV4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxTDsKKworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGZvcm1hdDsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgU3RyZWFtaW5nTm90U3VwcG9ydGVkRXhjZXB0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIGZvcm1hdCB0aGUgZm9ybWF0IHRoYXQgaGFzIGJlZW4gcmVxdWVzdGVkL2RldGVjdGVkLgorICAgICAqLworICAgIHB1YmxpYyBTdHJlYW1pbmdOb3RTdXBwb3J0ZWRFeGNlcHRpb24oZmluYWwgU3RyaW5nIGZvcm1hdCkgeworICAgICAgICBzdXBlcigiVGhlICIgKyBmb3JtYXQgKyAiIGRvZXNuJ3Qgc3VwcG9ydCBzdHJlYW1pbmcuIik7CisgICAgICAgIHRoaXMuZm9ybWF0ID0gZm9ybWF0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGZvcm1hdCB0aGF0IGhhcyBiZWVuIHJlcXVlc3RlZC9kZXRlY3RlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGZvcm1hdCB0aGF0IGhhcyBiZWVuIHJlcXVlc3RlZC9kZXRlY3RlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEZvcm1hdCgpIHsKKyAgICAgICAgcmV0dXJuIGZvcm1hdDsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9hci9BckFyY2hpdmVFbnRyeS5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2FyL0FyQXJjaGl2ZUVudHJ5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGY5NTk1YQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9hci9BckFyY2hpdmVFbnRyeS5qYXZhCkBAIC0wLDAgKzEsMTg3IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5hcjsKKworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLnV0aWwuRGF0ZTsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZUVudHJ5OworCisvKioKKyAqIFJlcHJlc2VudHMgYW4gYXJjaGl2ZSBlbnRyeSBpbiB0aGUgImFyIiBmb3JtYXQuCisgKgorICogRWFjaCBBUiBhcmNoaXZlIHN0YXJ0cyB3aXRoICIhJmx0O2FyY2gmZ3Q7IiBmb2xsb3dlZCBieSBhIExGLiBBZnRlciB0aGVzZSA4IGJ5dGVzCisgKiB0aGUgYXJjaGl2ZSBlbnRyaWVzIGFyZSBsaXN0ZWQuIFRoZSBmb3JtYXQgb2YgYW4gZW50cnkgaGVhZGVyIGlzIGFzIGl0IGZvbGxvd3M6CisgKgorICogPHByZT4KKyAqIFNUQVJUIEJZVEUgICBFTkQgQllURSAgICBOQU1FICAgICAgICAgICAgICAgICAgICBGT1JNQVQgICAgICBMRU5HVEgKKyAqIDAgICAgICAgICAgICAxNSAgICAgICAgICBGaWxlIG5hbWUgICAgICAgICAgICAgICBBU0NJSSAgICAgICAxNgorICogMTYgICAgICAgICAgIDI3ICAgICAgICAgIE1vZGlmaWNhdGlvbiB0aW1lc3RhbXAgIERlY2ltYWwgICAgIDEyCisgKiAyOCAgICAgICAgICAgMzMgICAgICAgICAgT3duZXIgSUQgICAgICAgICAgICAgICAgRGVjaW1hbCAgICAgNgorICogMzQgICAgICAgICAgIDM5ICAgICAgICAgIEdyb3VwIElEICAgICAgICAgICAgICAgIERlY2ltYWwgICAgIDYKKyAqIDQwICAgICAgICAgICA0NyAgICAgICAgICBGaWxlIG1vZGUgICAgICAgICAgICAgICBPY3RhbCAgICAgICA4CisgKiA0OCAgICAgICAgICAgNTcgICAgICAgICAgRmlsZSBzaXplIChieXRlcykgICAgICAgRGVjaW1hbCAgICAgMTAKKyAqIDU4ICAgICAgICAgICA1OSAgICAgICAgICBGaWxlIG1hZ2ljICAgICAgICAgICAgICBcMTQwXDAxMiAgICAyCisgKiA8L3ByZT4KKyAqCisgKiBUaGlzIHNwZWNpZmllcyB0aGF0IGFuIGFyIGFyY2hpdmUgZW50cnkgaGVhZGVyIGNvbnRhaW5zIDYwIGJ5dGVzLgorICoKKyAqIER1ZSB0byB0aGUgbGltaXRhdGlvbiBvZiB0aGUgZmlsZSBuYW1lIGxlbmd0aCB0byAxNiBieXRlcyBHTlUgYW5kCisgKiBCU0QgaGFzIHRoZWlyIG93biB2YXJpYW50cyBvZiB0aGlzIGZvcm1hdC4gQ3VycmVudGx5IENvbW1vbnMKKyAqIENvbXByZXNzIGNhbiByZWFkIGJ1dCBub3Qgd3JpdGUgdGhlIEdOVSB2YXJpYW50LiAgSXQgZnVsbHkgc3VwcG9ydHMKKyAqIHRoZSBCU0QgdmFyaWFudC4KKyAqCisgKiBAc2VlIDxhIGhyZWY9Imh0dHBzOi8vd3d3LmZyZWVic2Qub3JnL2NnaS9tYW4uY2dpP3F1ZXJ5PWFyJnNla3Rpb249NSI+YXIgbWFuIHBhZ2U8L2E+CisgKgorICogQEltbXV0YWJsZQorICovCitwdWJsaWMgY2xhc3MgQXJBcmNoaXZlRW50cnkgaW1wbGVtZW50cyBBcmNoaXZlRW50cnkgeworCisgICAgLyoqIFRoZSBoZWFkZXIgZm9yIGVhY2ggZW50cnkgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBIRUFERVIgPSAiITxhcmNoPlxuIjsKKworICAgIC8qKiBUaGUgdHJhaWxlciBmb3IgZWFjaCBlbnRyeSAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFRSQUlMRVIgPSAiYFwwMTIiOworCisgICAgLyoqCisgICAgICogU1ZSNC9HTlUgYWRkcyBhIHRyYWlsaW5nIC8gdG8gbmFtZXM7IEJTRCBkb2VzIG5vdC4KKyAgICAgKiBUaGV5IGFsc28gdmFyeSBpbiBob3cgbmFtZXMgbG9uZ2VyIHRoYW4gMTYgY2hhcmFjdGVycyBhcmUgcmVwcmVzZW50ZWQuCisgICAgICogKE5vdCB5ZXQgZnVsbHkgc3VwcG9ydGVkIGJ5IHRoaXMgaW1wbGVtZW50YXRpb24pCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgbmFtZTsKKyAgICBwcml2YXRlIGZpbmFsIGludCB1c2VySWQ7CisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgZ3JvdXBJZDsKKyAgICBwcml2YXRlIGZpbmFsIGludCBtb2RlOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX01PREUgPSAzMzE4ODsgLy8gPSAob2N0YWwpIDAxMDA2NDQKKyAgICBwcml2YXRlIGZpbmFsIGxvbmcgbGFzdE1vZGlmaWVkOworICAgIHByaXZhdGUgZmluYWwgbG9uZyBsZW5ndGg7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBuZXcgaW5zdGFuY2UgdXNpbmcgYSBjb3VwbGUgb2YgZGVmYXVsdCB2YWx1ZXMuCisgICAgICoKKyAgICAgKiA8cD5TZXRzIHVzZXJJZCBhbmQgZ3JvdXBJZCB0byAwLCB0aGUgb2N0YWwgZmlsZSBtb2RlIHRvIDY0NCBhbmQKKyAgICAgKiB0aGUgbGFzdCBtb2RpZmllZCB0aW1lIHRvIHRoZSBjdXJyZW50IHRpbWUuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgbmFtZSBvZiB0aGUgZW50cnkKKyAgICAgKiBAcGFyYW0gbGVuZ3RoIGxlbmd0aCBvZiB0aGUgZW50cnkgaW4gYnl0ZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgQXJBcmNoaXZlRW50cnkoZmluYWwgU3RyaW5nIG5hbWUsIGZpbmFsIGxvbmcgbGVuZ3RoKSB7CisgICAgICAgIHRoaXMobmFtZSwgbGVuZ3RoLCAwLCAwLCBERUZBVUxUX01PREUsCisgICAgICAgICAgICAgU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgLyAxMDAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBuZXcgaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSBuYW1lIG9mIHRoZSBlbnRyeQorICAgICAqIEBwYXJhbSBsZW5ndGggbGVuZ3RoIG9mIHRoZSBlbnRyeSBpbiBieXRlcworICAgICAqIEBwYXJhbSB1c2VySWQgbnVtZXJpYyB1c2VyIGlkCisgICAgICogQHBhcmFtIGdyb3VwSWQgbnVtZXJpYyBncm91cCBpZAorICAgICAqIEBwYXJhbSBtb2RlIGZpbGUgbW9kZQorICAgICAqIEBwYXJhbSBsYXN0TW9kaWZpZWQgbGFzdCBtb2RpZmllZCB0aW1lIGluIHNlY29uZHMgc2luY2UgdGhlIGVwb2NoCisgICAgICovCisgICAgcHVibGljIEFyQXJjaGl2ZUVudHJ5KGZpbmFsIFN0cmluZyBuYW1lLCBmaW5hbCBsb25nIGxlbmd0aCwgZmluYWwgaW50IHVzZXJJZCwgZmluYWwgaW50IGdyb3VwSWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBtb2RlLCBmaW5hbCBsb25nIGxhc3RNb2RpZmllZCkgeworICAgICAgICB0aGlzLm5hbWUgPSBuYW1lOworICAgICAgICB0aGlzLmxlbmd0aCA9IGxlbmd0aDsKKyAgICAgICAgdGhpcy51c2VySWQgPSB1c2VySWQ7CisgICAgICAgIHRoaXMuZ3JvdXBJZCA9IGdyb3VwSWQ7CisgICAgICAgIHRoaXMubW9kZSA9IG1vZGU7CisgICAgICAgIHRoaXMubGFzdE1vZGlmaWVkID0gbGFzdE1vZGlmaWVkOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIG5ldyBpbnN0YW5jZSB1c2luZyB0aGUgYXR0cmlidXRlcyBvZiB0aGUgZ2l2ZW4gZmlsZQorICAgICAqIEBwYXJhbSBpbnB1dEZpbGUgdGhlIGZpbGUgdG8gY3JlYXRlIGFuIGVudHJ5IGZyb20KKyAgICAgKiBAcGFyYW0gZW50cnlOYW1lIHRoZSBuYW1lIG9mIHRoZSBlbnRyeQorICAgICAqLworICAgIHB1YmxpYyBBckFyY2hpdmVFbnRyeShmaW5hbCBGaWxlIGlucHV0RmlsZSwgZmluYWwgU3RyaW5nIGVudHJ5TmFtZSkgeworICAgICAgICAvLyBUT0RPIHNvcnQgb3V0IG1vZGUKKyAgICAgICAgdGhpcyhlbnRyeU5hbWUsIGlucHV0RmlsZS5pc0ZpbGUoKSA/IGlucHV0RmlsZS5sZW5ndGgoKSA6IDAsCisgICAgICAgICAgICAgMCwgMCwgREVGQVVMVF9NT0RFLCBpbnB1dEZpbGUubGFzdE1vZGlmaWVkKCkgLyAxMDAwKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgbG9uZyBnZXRTaXplKCkgeworICAgICAgICByZXR1cm4gdGhpcy5nZXRMZW5ndGgoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7CisgICAgICAgIHJldHVybiBuYW1lOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0VXNlcklkKCkgeworICAgICAgICByZXR1cm4gdXNlcklkOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0R3JvdXBJZCgpIHsKKyAgICAgICAgcmV0dXJuIGdyb3VwSWQ7CisgICAgfQorCisgICAgcHVibGljIGludCBnZXRNb2RlKCkgeworICAgICAgICByZXR1cm4gbW9kZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMYXN0IG1vZGlmaWVkIHRpbWUgaW4gc2Vjb25kcyBzaW5jZSB0aGUgZXBvY2guCisgICAgICogQHJldHVybiB0aGUgbGFzdCBtb2RpZmllZCBkYXRlCisgICAgICovCisgICAgcHVibGljIGxvbmcgZ2V0TGFzdE1vZGlmaWVkKCkgeworICAgICAgICByZXR1cm4gbGFzdE1vZGlmaWVkOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBEYXRlIGdldExhc3RNb2RpZmllZERhdGUoKSB7CisgICAgICAgIHJldHVybiBuZXcgRGF0ZSgxMDAwICogZ2V0TGFzdE1vZGlmaWVkKCkpOworICAgIH0KKworICAgIHB1YmxpYyBsb25nIGdldExlbmd0aCgpIHsKKyAgICAgICAgcmV0dXJuIGxlbmd0aDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0RpcmVjdG9yeSgpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIGZpbmFsIGludCBwcmltZSA9IDMxOworICAgICAgICBpbnQgcmVzdWx0ID0gMTsKKyAgICAgICAgcmVzdWx0ID0gcHJpbWUgKiByZXN1bHQgKyAobmFtZSA9PSBudWxsID8gMCA6IG5hbWUuaGFzaENvZGUoKSk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIE9iamVjdCBvYmopIHsKKyAgICAgICAgaWYgKHRoaXMgPT0gb2JqKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAob2JqID09IG51bGwgfHwgZ2V0Q2xhc3MoKSAhPSBvYmouZ2V0Q2xhc3MoKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIGZpbmFsIEFyQXJjaGl2ZUVudHJ5IG90aGVyID0gKEFyQXJjaGl2ZUVudHJ5KSBvYmo7CisgICAgICAgIGlmIChuYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBvdGhlci5uYW1lID09IG51bGw7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gbmFtZS5lcXVhbHMob3RoZXIubmFtZSk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvYXIvQXJBcmNoaXZlSW5wdXRTdHJlYW0uamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9hci9BckFyY2hpdmVJbnB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIwNmQzODgKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvYXIvQXJBcmNoaXZlSW5wdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDQwNyBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuYXI7CisKK2ltcG9ydCBqYXZhLmlvLkVPRkV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLkFyY2hpdmVFbnRyeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLkFyY2hpdmVJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuQXJjaGl2ZVV0aWxzOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5JT1V0aWxzOworCisvKioKKyAqIEltcGxlbWVudHMgdGhlICJhciIgYXJjaGl2ZSBmb3JtYXQgYXMgYW4gaW5wdXQgc3RyZWFtLgorICoKKyAqIEBOb3RUaHJlYWRTYWZlCisgKgorICovCitwdWJsaWMgY2xhc3MgQXJBcmNoaXZlSW5wdXRTdHJlYW0gZXh0ZW5kcyBBcmNoaXZlSW5wdXRTdHJlYW0geworCisgICAgcHJpdmF0ZSBmaW5hbCBJbnB1dFN0cmVhbSBpbnB1dDsKKyAgICBwcml2YXRlIGxvbmcgb2Zmc2V0ID0gMDsKKyAgICBwcml2YXRlIGJvb2xlYW4gY2xvc2VkOworCisgICAgLyoKKyAgICAgKiBJZiBnZXROZXh0RW54dHJ5IGhhcyBiZWVuIGNhbGxlZCwgdGhlIGVudHJ5IG1ldGFkYXRhIGlzIHN0b3JlZCBpbgorICAgICAqIGN1cnJlbnRFbnRyeS4KKyAgICAgKi8KKyAgICBwcml2YXRlIEFyQXJjaGl2ZUVudHJ5IGN1cnJlbnRFbnRyeSA9IG51bGw7CisKKyAgICAvLyBTdG9yYWdlIGFyZWEgZm9yIGV4dHJhIGxvbmcgbmFtZXMgKEdOVSBhcikKKyAgICBwcml2YXRlIGJ5dGVbXSBuYW1lYnVmZmVyID0gbnVsbDsKKworICAgIC8qCisgICAgICogVGhlIG9mZnNldCB3aGVyZSB0aGUgY3VycmVudCBlbnRyeSBzdGFydGVkLiAtMSBpZiBubyBlbnRyeSBoYXMgYmVlbgorICAgICAqIGNhbGxlZAorICAgICAqLworICAgIHByaXZhdGUgbG9uZyBlbnRyeU9mZnNldCA9IC0xOworCisgICAgLy8gb2Zmc2V0cyBhbmQgbGVuZ3RoIG9mIG1ldGEgZGF0YSBwYXJ0cworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBOQU1FX09GRlNFVCA9IDA7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE5BTUVfTEVOID0gMTY7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IExBU1RfTU9ESUZJRURfT0ZGU0VUID0gTkFNRV9MRU47CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IExBU1RfTU9ESUZJRURfTEVOID0gMTI7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFVTRVJfSURfT0ZGU0VUID0gTEFTVF9NT0RJRklFRF9PRkZTRVQgKyBMQVNUX01PRElGSUVEX0xFTjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVVNFUl9JRF9MRU4gPSA2OworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBHUk9VUF9JRF9PRkZTRVQgPSBVU0VSX0lEX09GRlNFVCArIFVTRVJfSURfTEVOOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBHUk9VUF9JRF9MRU4gPSA2OworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBGSUxFX01PREVfT0ZGU0VUID0gR1JPVVBfSURfT0ZGU0VUICsgR1JPVVBfSURfTEVOOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBGSUxFX01PREVfTEVOID0gODsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTEVOR1RIX09GRlNFVCA9IEZJTEVfTU9ERV9PRkZTRVQgKyBGSUxFX01PREVfTEVOOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBMRU5HVEhfTEVOID0gMTA7CisKKyAgICAvLyBjYWNoZWQgYnVmZmVyIGZvciBtZXRhIGRhdGEgLSBtdXN0IG9ubHkgYmUgdXNlZCBsb2NhbGx5IGluIHRoZSBjbGFzcyAoQ09NUFJFU1MtMTcyIC0gcmVkdWNlIGdhcmJhZ2UgY29sbGVjdGlvbikKKyAgICBwcml2YXRlIGZpbmFsIGJ5dGVbXSBtZXRhRGF0YSA9CisgICAgICAgIG5ldyBieXRlW05BTUVfTEVOICsgTEFTVF9NT0RJRklFRF9MRU4gKyBVU0VSX0lEX0xFTiArIEdST1VQX0lEX0xFTiArIEZJTEVfTU9ERV9MRU4gKyBMRU5HVEhfTEVOXTsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYW4gQXIgaW5wdXQgc3RyZWFtIHdpdGggdGhlIHJlZmVyZW5jZWQgc3RyZWFtCisgICAgICoKKyAgICAgKiBAcGFyYW0gcElucHV0CisgICAgICogICAgICAgICAgICB0aGUgYXIgaW5wdXQgc3RyZWFtCisgICAgICovCisgICAgcHVibGljIEFyQXJjaGl2ZUlucHV0U3RyZWFtKGZpbmFsIElucHV0U3RyZWFtIHBJbnB1dCkgeworICAgICAgICBpbnB1dCA9IHBJbnB1dDsKKyAgICAgICAgY2xvc2VkID0gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmV4dCBBUiBlbnRyeSBpbiB0aGlzIHN0cmVhbS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5leHQgQVIgZW50cnkuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBlbnRyeSBjb3VsZCBub3QgYmUgcmVhZAorICAgICAqLworICAgIHB1YmxpYyBBckFyY2hpdmVFbnRyeSBnZXROZXh0QXJFbnRyeSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChjdXJyZW50RW50cnkgIT0gbnVsbCkgeworICAgICAgICAgICAgZmluYWwgbG9uZyBlbnRyeUVuZCA9IGVudHJ5T2Zmc2V0ICsgY3VycmVudEVudHJ5LmdldExlbmd0aCgpOworICAgICAgICAgICAgbG9uZyBza2lwcGVkID0gSU9VdGlscy5za2lwKGlucHV0LCBlbnRyeUVuZCAtIG9mZnNldCk7CisgICAgICAgICAgICB0cmFja1JlYWRCeXRlcyhza2lwcGVkKTsKKyAgICAgICAgICAgIGN1cnJlbnRFbnRyeSA9IG51bGw7CisgICAgICAgIH0KKworICAgICAgICBpZiAob2Zmc2V0ID09IDApIHsKKyAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBleHBlY3RlZCA9IEFyY2hpdmVVdGlscy50b0FzY2lpQnl0ZXMoQXJBcmNoaXZlRW50cnkuSEVBREVSKTsKKyAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSByZWFsaXplZCA9IG5ldyBieXRlW2V4cGVjdGVkLmxlbmd0aF07CisgICAgICAgICAgICBmaW5hbCBpbnQgcmVhZCA9IElPVXRpbHMucmVhZEZ1bGx5KGlucHV0LCByZWFsaXplZCk7CisgICAgICAgICAgICB0cmFja1JlYWRCeXRlcyhyZWFkKTsKKyAgICAgICAgICAgIGlmIChyZWFkICE9IGV4cGVjdGVkLmxlbmd0aCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiZmFpbGVkIHRvIHJlYWQgaGVhZGVyLiBPY2N1cmVkIGF0IGJ5dGU6ICIgKyBnZXRCeXRlc1JlYWQoKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGV4cGVjdGVkLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgaWYgKGV4cGVjdGVkW2ldICE9IHJlYWxpemVkW2ldKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiaW52YWxpZCBoZWFkZXIgIiArIEFyY2hpdmVVdGlscy50b0FzY2lpU3RyaW5nKHJlYWxpemVkKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgaWYgKG9mZnNldCAlIDIgIT0gMCkgeworICAgICAgICAgICAgaWYgKGlucHV0LnJlYWQoKSA8IDApIHsKKyAgICAgICAgICAgICAgICAvLyBoaXQgZW9mCisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cmFja1JlYWRCeXRlcygxKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChpbnB1dC5hdmFpbGFibGUoKSA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHsKKyAgICAgICAgICAgIGZpbmFsIGludCByZWFkID0gSU9VdGlscy5yZWFkRnVsbHkoaW5wdXQsIG1ldGFEYXRhKTsKKyAgICAgICAgICAgIHRyYWNrUmVhZEJ5dGVzKHJlYWQpOworICAgICAgICAgICAgaWYgKHJlYWQgPCBtZXRhRGF0YS5sZW5ndGgpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oInRydW5jYXRlZCBhciBhcmNoaXZlIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB7CisgICAgICAgICAgICBmaW5hbCBieXRlW10gZXhwZWN0ZWQgPSBBcmNoaXZlVXRpbHMudG9Bc2NpaUJ5dGVzKEFyQXJjaGl2ZUVudHJ5LlRSQUlMRVIpOworICAgICAgICAgICAgZmluYWwgYnl0ZVtdIHJlYWxpemVkID0gbmV3IGJ5dGVbZXhwZWN0ZWQubGVuZ3RoXTsKKyAgICAgICAgICAgIGZpbmFsIGludCByZWFkID0gSU9VdGlscy5yZWFkRnVsbHkoaW5wdXQsIHJlYWxpemVkKTsKKyAgICAgICAgICAgIHRyYWNrUmVhZEJ5dGVzKHJlYWQpOworICAgICAgICAgICAgaWYgKHJlYWQgIT0gZXhwZWN0ZWQubGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJmYWlsZWQgdG8gcmVhZCBlbnRyeSB0cmFpbGVyLiBPY2N1cmVkIGF0IGJ5dGU6ICIgKyBnZXRCeXRlc1JlYWQoKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGV4cGVjdGVkLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgaWYgKGV4cGVjdGVkW2ldICE9IHJlYWxpemVkW2ldKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiaW52YWxpZCBlbnRyeSB0cmFpbGVyLiBub3QgcmVhZCB0aGUgY29udGVudD8gT2NjdXJlZCBhdCBieXRlOiAiICsgZ2V0Qnl0ZXNSZWFkKCkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGVudHJ5T2Zmc2V0ID0gb2Zmc2V0OworCisvLyAgICAgICAgR05VIGFyIHVzZXMgYSAnLycgdG8gbWFyayB0aGUgZW5kIG9mIHRoZSBmaWxlbmFtZTsgdGhpcyBhbGxvd3MgZm9yIHRoZSB1c2Ugb2Ygc3BhY2VzIHdpdGhvdXQgdGhlIHVzZSBvZiBhbiBleHRlbmRlZCBmaWxlbmFtZS4KKworICAgICAgICAvLyBlbnRyeSBuYW1lIGlzIHN0b3JlZCBhcyBBU0NJSSBzdHJpbmcKKyAgICAgICAgU3RyaW5nIHRlbXAgPSBBcmNoaXZlVXRpbHMudG9Bc2NpaVN0cmluZyhtZXRhRGF0YSwgTkFNRV9PRkZTRVQsIE5BTUVfTEVOKS50cmltKCk7CisgICAgICAgIGlmIChpc0dOVVN0cmluZ1RhYmxlKHRlbXApKSB7IC8vIEdOVSBleHRlbmRlZCBmaWxlbmFtZXMgZW50cnkKKyAgICAgICAgICAgIGN1cnJlbnRFbnRyeSA9IHJlYWRHTlVTdHJpbmdUYWJsZShtZXRhRGF0YSwgTEVOR1RIX09GRlNFVCwgTEVOR1RIX0xFTik7CisgICAgICAgICAgICByZXR1cm4gZ2V0TmV4dEFyRW50cnkoKTsKKyAgICAgICAgfQorCisgICAgICAgIGxvbmcgbGVuID0gYXNMb25nKG1ldGFEYXRhLCBMRU5HVEhfT0ZGU0VULCBMRU5HVEhfTEVOKTsKKyAgICAgICAgaWYgKHRlbXAuZW5kc1dpdGgoIi8iKSkgeyAvLyBHTlUgdGVybWluYXRvcgorICAgICAgICAgICAgdGVtcCA9IHRlbXAuc3Vic3RyaW5nKDAsIHRlbXAubGVuZ3RoKCkgLSAxKTsKKyAgICAgICAgfSBlbHNlIGlmIChpc0dOVUxvbmdOYW1lKHRlbXApKSB7CisgICAgICAgICAgICBmaW5hbCBpbnQgb2ZmID0gSW50ZWdlci5wYXJzZUludCh0ZW1wLnN1YnN0cmluZygxKSk7Ly8gZ2V0IHRoZSBvZmZzZXQKKyAgICAgICAgICAgIHRlbXAgPSBnZXRFeHRlbmRlZE5hbWUob2ZmKTsgLy8gY29udmVydCB0byB0aGUgbG9uZyBuYW1lCisgICAgICAgIH0gZWxzZSBpZiAoaXNCU0RMb25nTmFtZSh0ZW1wKSkgeworICAgICAgICAgICAgdGVtcCA9IGdldEJTRExvbmdOYW1lKHRlbXApOworICAgICAgICAgICAgLy8gZW50cnkgbGVuZ3RoIGNvbnRhaW5lZCB0aGUgbGVuZ3RoIG9mIHRoZSBmaWxlIG5hbWUgaW4KKyAgICAgICAgICAgIC8vIGFkZGl0aW9uIHRvIHRoZSByZWFsIGxlbmd0aCBvZiB0aGUgZW50cnkuCisgICAgICAgICAgICAvLyBhc3N1bWUgZmlsZSBuYW1lIHdhcyBBU0NJSSwgdGhlcmUgaXMgbm8gInN0YW5kYXJkIiBvdGhlcndpc2UKKyAgICAgICAgICAgIGZpbmFsIGludCBuYW1lTGVuID0gdGVtcC5sZW5ndGgoKTsKKyAgICAgICAgICAgIGxlbiAtPSBuYW1lTGVuOworICAgICAgICAgICAgZW50cnlPZmZzZXQgKz0gbmFtZUxlbjsKKyAgICAgICAgfQorCisgICAgICAgIGN1cnJlbnRFbnRyeSA9IG5ldyBBckFyY2hpdmVFbnRyeSh0ZW1wLCBsZW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc0ludChtZXRhRGF0YSwgVVNFUl9JRF9PRkZTRVQsIFVTRVJfSURfTEVOLCB0cnVlKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzSW50KG1ldGFEYXRhLCBHUk9VUF9JRF9PRkZTRVQsIEdST1VQX0lEX0xFTiwgdHJ1ZSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc0ludChtZXRhRGF0YSwgRklMRV9NT0RFX09GRlNFVCwgRklMRV9NT0RFX0xFTiwgOCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc0xvbmcobWV0YURhdGEsIExBU1RfTU9ESUZJRURfT0ZGU0VULCBMQVNUX01PRElGSUVEX0xFTikpOworICAgICAgICByZXR1cm4gY3VycmVudEVudHJ5OworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCBhbiBleHRlbmRlZCBuYW1lIGZyb20gdGhlIEdOVSBleHRlbmRlZCBuYW1lIGJ1ZmZlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvZmZzZXQgcG9pbnRlciB0byBlbnRyeSB3aXRoaW4gdGhlIGJ1ZmZlcgorICAgICAqIEByZXR1cm4gdGhlIGV4dGVuZGVkIGZpbGUgbmFtZTsgd2l0aG91dCB0cmFpbGluZyAiLyIgaWYgcHJlc2VudC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIG5hbWUgbm90IGZvdW5kIG9yIGJ1ZmZlciBub3Qgc2V0IHVwCisgICAgICovCisgICAgcHJpdmF0ZSBTdHJpbmcgZ2V0RXh0ZW5kZWROYW1lKGZpbmFsIGludCBvZmZzZXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChuYW1lYnVmZmVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiQ2Fubm90IHByb2Nlc3MgR05VIGxvbmcgZmlsZW5hbWUgYXMgbm8gLy8gcmVjb3JkIHdhcyBmb3VuZCIpOworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSBvZmZzZXQ7IGkgPCBuYW1lYnVmZmVyLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBpZiAobmFtZWJ1ZmZlcltpXSA9PSAnXDAxMicgfHwgbmFtZWJ1ZmZlcltpXSA9PSAwKSB7CisgICAgICAgICAgICAgICAgaWYgKG5hbWVidWZmZXJbaSAtIDFdID09ICcvJykgeworICAgICAgICAgICAgICAgICAgICBpLS07IC8vIGRyb3AgdHJhaWxpbmcgLworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gQXJjaGl2ZVV0aWxzLnRvQXNjaWlTdHJpbmcobmFtZWJ1ZmZlciwgb2Zmc2V0LCBpIC0gb2Zmc2V0KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkZhaWxlZCB0byByZWFkIGVudHJ5OiAiICsgb2Zmc2V0KTsKKyAgICB9CisKKyAgICBwcml2YXRlIGxvbmcgYXNMb25nKGZpbmFsIGJ5dGVbXSBieXRlQXJyYXksIGludCBvZmZzZXQsIGludCBsZW4pIHsKKyAgICAgICAgcmV0dXJuIExvbmcucGFyc2VMb25nKEFyY2hpdmVVdGlscy50b0FzY2lpU3RyaW5nKGJ5dGVBcnJheSwgb2Zmc2V0LCBsZW4pLnRyaW0oKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnQgYXNJbnQoZmluYWwgYnl0ZVtdIGJ5dGVBcnJheSwgaW50IG9mZnNldCwgaW50IGxlbikgeworICAgICAgICByZXR1cm4gYXNJbnQoYnl0ZUFycmF5LCBvZmZzZXQsIGxlbiwgMTAsIGZhbHNlKTsKKyAgICB9CisKKyAgICBwcml2YXRlIGludCBhc0ludChmaW5hbCBieXRlW10gYnl0ZUFycmF5LCBpbnQgb2Zmc2V0LCBpbnQgbGVuLCBmaW5hbCBib29sZWFuIHRyZWF0QmxhbmtBc1plcm8pIHsKKyAgICAgICAgcmV0dXJuIGFzSW50KGJ5dGVBcnJheSwgb2Zmc2V0LCBsZW4sIDEwLCB0cmVhdEJsYW5rQXNaZXJvKTsKKyAgICB9CisKKyAgICBwcml2YXRlIGludCBhc0ludChmaW5hbCBieXRlW10gYnl0ZUFycmF5LCBpbnQgb2Zmc2V0LCBpbnQgbGVuLCBmaW5hbCBpbnQgYmFzZSkgeworICAgICAgICByZXR1cm4gYXNJbnQoYnl0ZUFycmF5LCBvZmZzZXQsIGxlbiwgYmFzZSwgZmFsc2UpOworICAgIH0KKworICAgIHByaXZhdGUgaW50IGFzSW50KGZpbmFsIGJ5dGVbXSBieXRlQXJyYXksIGludCBvZmZzZXQsIGludCBsZW4sIGZpbmFsIGludCBiYXNlLCBmaW5hbCBib29sZWFuIHRyZWF0QmxhbmtBc1plcm8pIHsKKyAgICAgICAgZmluYWwgU3RyaW5nIHN0cmluZyA9IEFyY2hpdmVVdGlscy50b0FzY2lpU3RyaW5nKGJ5dGVBcnJheSwgb2Zmc2V0LCBsZW4pLnRyaW0oKTsKKyAgICAgICAgaWYgKHN0cmluZy5sZW5ndGgoKSA9PSAwICYmIHRyZWF0QmxhbmtBc1plcm8pIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgICAgIHJldHVybiBJbnRlZ2VyLnBhcnNlSW50KHN0cmluZywgYmFzZSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiAobm9uLUphdmFkb2MpCisgICAgICoKKyAgICAgKiBAc2VlCisgICAgICogb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5BcmNoaXZlSW5wdXRTdHJlYW0jZ2V0TmV4dEVudHJ5KCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQXJjaGl2ZUVudHJ5IGdldE5leHRFbnRyeSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBnZXROZXh0QXJFbnRyeSgpOworICAgIH0KKworICAgIC8qCisgICAgICogKG5vbi1KYXZhZG9jKQorICAgICAqCisgICAgICogQHNlZSBqYXZhLmlvLklucHV0U3RyZWFtI2Nsb3NlKCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICghY2xvc2VkKSB7CisgICAgICAgICAgICBjbG9zZWQgPSB0cnVlOworICAgICAgICAgICAgaW5wdXQuY2xvc2UoKTsKKyAgICAgICAgfQorICAgICAgICBjdXJyZW50RW50cnkgPSBudWxsOworICAgIH0KKworICAgIC8qCisgICAgICogKG5vbi1KYXZhZG9jKQorICAgICAqCisgICAgICogQHNlZSBqYXZhLmlvLklucHV0U3RyZWFtI3JlYWQoYnl0ZVtdLCBpbnQsIGludCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHJlYWQoZmluYWwgYnl0ZVtdIGIsIGZpbmFsIGludCBvZmYsIGZpbmFsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChjdXJyZW50RW50cnkgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiTm8gY3VycmVudCBhciBlbnRyeSIpOworICAgICAgICB9CisgICAgICAgIGZpbmFsIGxvbmcgZW50cnlFbmQgPSBlbnRyeU9mZnNldCArIGN1cnJlbnRFbnRyeS5nZXRMZW5ndGgoKTsKKyAgICAgICAgaWYgKGxlbiA8IDAgfHwgb2Zmc2V0ID49IGVudHJ5RW5kKSB7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICAgICAgZmluYWwgaW50IHRvUmVhZCA9IChpbnQpIE1hdGgubWluKGxlbiwgZW50cnlFbmQgLSBvZmZzZXQpOworICAgICAgICBmaW5hbCBpbnQgcmV0ID0gdGhpcy5pbnB1dC5yZWFkKGIsIG9mZiwgdG9SZWFkKTsKKyAgICAgICAgdHJhY2tSZWFkQnl0ZXMocmV0KTsKKyAgICAgICAgcmV0dXJuIHJldDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgaWYgdGhlIHNpZ25hdHVyZSBtYXRjaGVzIEFTQ0lJICIhJmx0O2FyY2gmZ3Q7IiBmb2xsb3dlZCBieSBhIHNpbmdsZSBMRgorICAgICAqIGNvbnRyb2wgY2hhcmFjdGVyCisgICAgICoKKyAgICAgKiBAcGFyYW0gc2lnbmF0dXJlCisgICAgICogICAgICAgICAgICB0aGUgYnl0ZXMgdG8gY2hlY2sKKyAgICAgKiBAcGFyYW0gbGVuZ3RoCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRvIGNoZWNrCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGlzIHN0cmVhbSBpcyBhbiBBciBhcmNoaXZlIHN0cmVhbSwgZmFsc2Ugb3RoZXJ3aXNlCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIG1hdGNoZXMoZmluYWwgYnl0ZVtdIHNpZ25hdHVyZSwgZmluYWwgaW50IGxlbmd0aCkgeworICAgICAgICAvLyAzYzIxIDcyNjEgNjg2MyAwYTNlCisKKyAgICAgICAgcmV0dXJuIGxlbmd0aCA+PSA4ICYmIHNpZ25hdHVyZVswXSA9PSAweDIxICYmCisgICAgICAgICAgICAgICAgc2lnbmF0dXJlWzFdID09IDB4M2MgJiYgc2lnbmF0dXJlWzJdID09IDB4NjEgJiYKKyAgICAgICAgICAgICAgICBzaWduYXR1cmVbM10gPT0gMHg3MiAmJiBzaWduYXR1cmVbNF0gPT0gMHg2MyAmJgorICAgICAgICAgICAgICAgIHNpZ25hdHVyZVs1XSA9PSAweDY4ICYmIHNpZ25hdHVyZVs2XSA9PSAweDNlICYmCisgICAgICAgICAgICAgICAgc2lnbmF0dXJlWzddID09IDB4MGE7CisgICAgfQorCisgICAgc3RhdGljIGZpbmFsIFN0cmluZyBCU0RfTE9OR05BTUVfUFJFRklYID0gIiMxLyI7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEJTRF9MT05HTkFNRV9QUkVGSVhfTEVOID0KKyAgICAgICAgQlNEX0xPTkdOQU1FX1BSRUZJWC5sZW5ndGgoKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQlNEX0xPTkdOQU1FX1BBVFRFUk4gPQorICAgICAgICAiXiIgKyBCU0RfTE9OR05BTUVfUFJFRklYICsgIlxcZCsiOworCisgICAgLyoqCisgICAgICogRG9lcyB0aGUgbmFtZSBsb29rIGxpa2UgaXQgaXMgYSBsb25nIG5hbWUgKG9yIGEgbmFtZSBjb250YWluaW5nCisgICAgICogc3BhY2VzKSBhcyBlbmNvZGVkIGJ5IEJTRCBhcj8KKyAgICAgKgorICAgICAqIDxwPkZyb20gdGhlIEZyZWVCU0QgYXIoNSkgbWFuIHBhZ2U6PC9wPgorICAgICAqIDxwcmU+CisgICAgICogQlNEICAgSW4gdGhlIEJTRCB2YXJpYW50LCBuYW1lcyB0aGF0IGFyZSBzaG9ydGVyIHRoYW4gMTYKKyAgICAgKiAgICAgICBjaGFyYWN0ZXJzIGFuZCB3aXRob3V0IGVtYmVkZGVkIHNwYWNlcyBhcmUgc3RvcmVkCisgICAgICogICAgICAgZGlyZWN0bHkgaW4gdGhpcyBmaWVsZC4gIElmIGEgbmFtZSBoYXMgYW4gZW1iZWRkZWQKKyAgICAgKiAgICAgICBzcGFjZSwgb3IgaWYgaXQgaXMgbG9uZ2VyIHRoYW4gMTYgY2hhcmFjdGVycywgdGhlbgorICAgICAqICAgICAgIHRoZSBzdHJpbmcgIiMxLyIgZm9sbG93ZWQgYnkgdGhlIGRlY2ltYWwgcmVwcmVzZW4tCisgICAgICogICAgICAgdGF0aW9uIG9mIHRoZSBsZW5ndGggb2YgdGhlIGZpbGUgbmFtZSBpcyBwbGFjZWQgaW4KKyAgICAgKiAgICAgICB0aGlzIGZpZWxkLiBUaGUgYWN0dWFsIGZpbGUgbmFtZSBpcyBzdG9yZWQgaW1tZWRpLQorICAgICAqICAgICAgIGF0ZWx5IGFmdGVyIHRoZSBhcmNoaXZlIGhlYWRlci4gIFRoZSBjb250ZW50IG9mIHRoZQorICAgICAqICAgICAgIGFyY2hpdmUgbWVtYmVyIGZvbGxvd3MgdGhlIGZpbGUgbmFtZS4gIFRoZSBhcl9zaXplCisgICAgICogICAgICAgZmllbGQgb2YgdGhlIGhlYWRlciAoc2VlIGJlbG93KSB3aWxsIHRoZW4gaG9sZCB0aGUKKyAgICAgKiAgICAgICBzdW0gb2YgdGhlIHNpemUgb2YgdGhlIGZpbGUgbmFtZSBhbmQgdGhlIHNpemUgb2YKKyAgICAgKiAgICAgICB0aGUgbWVtYmVyLgorICAgICAqIDwvcHJlPgorICAgICAqCisgICAgICogQHNpbmNlIDEuMworICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNCU0RMb25nTmFtZShmaW5hbCBTdHJpbmcgbmFtZSkgeworICAgICAgICByZXR1cm4gbmFtZSAhPSBudWxsICYmIG5hbWUubWF0Y2hlcyhCU0RfTE9OR05BTUVfUEFUVEVSTik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgdGhlIHJlYWwgbmFtZSBmcm9tIHRoZSBjdXJyZW50IHN0cmVhbSBhc3N1bWluZyB0aGUgdmVyeQorICAgICAqIGZpcnN0IGJ5dGVzIHRvIGJlIHJlYWQgYXJlIHRoZSByZWFsIGZpbGUgbmFtZS4KKyAgICAgKgorICAgICAqIEBzZWUgI2lzQlNETG9uZ05hbWUKKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjMKKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyBnZXRCU0RMb25nTmFtZShmaW5hbCBTdHJpbmcgYnNkTG9uZ05hbWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIGludCBuYW1lTGVuID0KKyAgICAgICAgICAgIEludGVnZXIucGFyc2VJbnQoYnNkTG9uZ05hbWUuc3Vic3RyaW5nKEJTRF9MT05HTkFNRV9QUkVGSVhfTEVOKSk7CisgICAgICAgIGZpbmFsIGJ5dGVbXSBuYW1lID0gbmV3IGJ5dGVbbmFtZUxlbl07CisgICAgICAgIGZpbmFsIGludCByZWFkID0gSU9VdGlscy5yZWFkRnVsbHkoaW5wdXQsIG5hbWUpOworICAgICAgICB0cmFja1JlYWRCeXRlcyhyZWFkKTsKKyAgICAgICAgaWYgKHJlYWQgIT0gbmFtZUxlbikgeworICAgICAgICAgICAgdGhyb3cgbmV3IEVPRkV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBBcmNoaXZlVXRpbHMudG9Bc2NpaVN0cmluZyhuYW1lKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgR05VX1NUUklOR19UQUJMRV9OQU1FID0gIi8vIjsKKworICAgIC8qKgorICAgICAqIElzIHRoaXMgdGhlIG5hbWUgb2YgdGhlICJBcmNoaXZlIFN0cmluZyBUYWJsZSIgYXMgdXNlZCBieQorICAgICAqIFNWUjQvR05VIHRvIHN0b3JlIGxvbmcgZmlsZSBuYW1lcz8KKyAgICAgKgorICAgICAqIDxwPkdOVSBhciBzdG9yZXMgbXVsdGlwbGUgZXh0ZW5kZWQgZmlsZW5hbWVzIGluIHRoZSBkYXRhIHNlY3Rpb24KKyAgICAgKiBvZiBhIGZpbGUgd2l0aCB0aGUgbmFtZSAiLy8iLCB0aGlzIHJlY29yZCBpcyByZWZlcnJlZCB0byBieQorICAgICAqIGZ1dHVyZSBoZWFkZXJzLjwvcD4KKyAgICAgKgorICAgICAqIDxwPkEgaGVhZGVyIHJlZmVyZW5jZXMgYW4gZXh0ZW5kZWQgZmlsZW5hbWUgYnkgc3RvcmluZyBhICIvIgorICAgICAqIGZvbGxvd2VkIGJ5IGEgZGVjaW1hbCBvZmZzZXQgdG8gdGhlIHN0YXJ0IG9mIHRoZSBmaWxlbmFtZSBpbgorICAgICAqIHRoZSBleHRlbmRlZCBmaWxlbmFtZSBkYXRhIHNlY3Rpb24uPC9wPgorICAgICAqCisgICAgICogPHA+VGhlIGZvcm1hdCBvZiB0aGUgIi8vIiBmaWxlIGl0c2VsZiBpcyBzaW1wbHkgYSBsaXN0IG9mIHRoZQorICAgICAqIGxvbmcgZmlsZW5hbWVzLCBlYWNoIHNlcGFyYXRlZCBieSBvbmUgb3IgbW9yZSBMRgorICAgICAqIGNoYXJhY3RlcnMuIE5vdGUgdGhhdCB0aGUgZGVjaW1hbCBvZmZzZXRzIGFyZSBudW1iZXIgb2YKKyAgICAgKiBjaGFyYWN0ZXJzLCBub3QgbGluZSBvciBzdHJpbmcgbnVtYmVyIHdpdGhpbiB0aGUgIi8vIiBmaWxlLjwvcD4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzR05VU3RyaW5nVGFibGUoZmluYWwgU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgcmV0dXJuIEdOVV9TVFJJTkdfVEFCTEVfTkFNRS5lcXVhbHMobmFtZSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRyYWNrUmVhZEJ5dGVzKGZpbmFsIGxvbmcgcmVhZCkgeworICAgICAgICBjb3VudChyZWFkKTsKKyAgICAgICAgaWYgKHJlYWQgPiAwKSB7CisgICAgICAgICAgICBvZmZzZXQgKz0gcmVhZDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIHRoZSBHTlUgYXJjaGl2ZSBTdHJpbmcgVGFibGUuCisgICAgICoKKyAgICAgKiBAc2VlICNpc0dOVVN0cmluZ1RhYmxlCisgICAgICovCisgICAgcHJpdmF0ZSBBckFyY2hpdmVFbnRyeSByZWFkR05VU3RyaW5nVGFibGUoZmluYWwgYnl0ZVtdIGxlbmd0aCwgZmluYWwgaW50IG9mZnNldCwgZmluYWwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgaW50IGJ1ZmZsZW4gPSBhc0ludChsZW5ndGgsIG9mZnNldCwgbGVuKTsgLy8gQXNzdW1lIGxlbmd0aCB3aWxsIGZpdCBpbiBhbiBpbnQKKyAgICAgICAgbmFtZWJ1ZmZlciA9IG5ldyBieXRlW2J1ZmZsZW5dOworICAgICAgICBmaW5hbCBpbnQgcmVhZCA9IElPVXRpbHMucmVhZEZ1bGx5KGlucHV0LCBuYW1lYnVmZmVyLCAwLCBidWZmbGVuKTsKKyAgICAgICAgdHJhY2tSZWFkQnl0ZXMocmVhZCk7CisgICAgICAgIGlmIChyZWFkICE9IGJ1ZmZsZW4peworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJGYWlsZWQgdG8gcmVhZCBjb21wbGV0ZSAvLyByZWNvcmQ6IGV4cGVjdGVkPSIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGJ1ZmZsZW4gKyAiIHJlYWQ9IiArIHJlYWQpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgQXJBcmNoaXZlRW50cnkoR05VX1NUUklOR19UQUJMRV9OQU1FLCBidWZmbGVuKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgR05VX0xPTkdOQU1FX1BBVFRFUk4gPSAiXi9cXGQrIjsKKworICAgIC8qKgorICAgICAqIERvZXMgdGhlIG5hbWUgbG9vayBsaWtlIGl0IGlzIGEgbG9uZyBuYW1lIChvciBhIG5hbWUgY29udGFpbmluZworICAgICAqIHNwYWNlcykgYXMgZW5jb2RlZCBieSBTVlI0L0dOVSBhcj8KKyAgICAgKgorICAgICAqIEBzZWUgI2lzR05VU3RyaW5nVGFibGUKKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gaXNHTlVMb25nTmFtZShmaW5hbCBTdHJpbmcgbmFtZSkgeworICAgICAgICByZXR1cm4gbmFtZSAhPSBudWxsICYmIG5hbWUubWF0Y2hlcyhHTlVfTE9OR05BTUVfUEFUVEVSTik7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2FyL0FyQXJjaGl2ZU91dHB1dFN0cmVhbS5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2FyL0FyQXJjaGl2ZU91dHB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU3YWNiNzEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvYXIvQXJBcmNoaXZlT3V0cHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwyMzcgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLmFyOworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLkFyY2hpdmVFbnRyeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLkFyY2hpdmVPdXRwdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLkFyY2hpdmVVdGlsczsKKworLyoqCisgKiBJbXBsZW1lbnRzIHRoZSAiYXIiIGFyY2hpdmUgZm9ybWF0IGFzIGFuIG91dHB1dCBzdHJlYW0uCisgKgorICogQE5vdFRocmVhZFNhZmUKKyAqLworcHVibGljIGNsYXNzIEFyQXJjaGl2ZU91dHB1dFN0cmVhbSBleHRlbmRzIEFyY2hpdmVPdXRwdXRTdHJlYW0geworICAgIC8qKiBGYWlsIGlmIGEgbG9uZyBmaWxlIG5hbWUgaXMgcmVxdWlyZWQgaW4gdGhlIGFyY2hpdmUuICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR0ZJTEVfRVJST1IgPSAwOworCisgICAgLyoqIEJTRCBhciBleHRlbnNpb25zIGFyZSB1c2VkIHRvIHN0b3JlIGxvbmcgZmlsZSBuYW1lcyBpbiB0aGUgYXJjaGl2ZS4gKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HRklMRV9CU0QgPSAxOworCisgICAgcHJpdmF0ZSBmaW5hbCBPdXRwdXRTdHJlYW0gb3V0OworICAgIHByaXZhdGUgbG9uZyBlbnRyeU9mZnNldCA9IDA7CisgICAgcHJpdmF0ZSBBckFyY2hpdmVFbnRyeSBwcmV2RW50cnk7CisgICAgcHJpdmF0ZSBib29sZWFuIGhhdmVVbmNsb3NlZEVudHJ5ID0gZmFsc2U7CisgICAgcHJpdmF0ZSBpbnQgbG9uZ0ZpbGVNb2RlID0gTE9OR0ZJTEVfRVJST1I7CisKKyAgICAvKiogaW5kaWNhdGVzIGlmIHRoaXMgYXJjaGl2ZSBpcyBmaW5pc2hlZCAqLworICAgIHByaXZhdGUgYm9vbGVhbiBmaW5pc2hlZCA9IGZhbHNlOworCisgICAgcHVibGljIEFyQXJjaGl2ZU91dHB1dFN0cmVhbSggZmluYWwgT3V0cHV0U3RyZWFtIHBPdXQgKSB7CisgICAgICAgIHRoaXMub3V0ID0gcE91dDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIGxvbmcgZmlsZSBtb2RlLgorICAgICAqIFRoaXMgY2FuIGJlIExPTkdGSUxFX0VSUk9SKDApIG9yIExPTkdGSUxFX0JTRCgxKS4KKyAgICAgKiBUaGlzIHNwZWNpZmllcyB0aGUgdHJlYXRtZW50IG9mIGxvbmcgZmlsZSBuYW1lcyAobmFtZXMgJmd0Oz0gMTYpLgorICAgICAqIERlZmF1bHQgaXMgTE9OR0ZJTEVfRVJST1IuCisgICAgICogQHBhcmFtIGxvbmdGaWxlTW9kZSB0aGUgbW9kZSB0byB1c2UKKyAgICAgKiBAc2luY2UgMS4zCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TG9uZ0ZpbGVNb2RlKGZpbmFsIGludCBsb25nRmlsZU1vZGUpIHsKKyAgICAgICAgdGhpcy5sb25nRmlsZU1vZGUgPSBsb25nRmlsZU1vZGU7CisgICAgfQorCisgICAgcHJpdmF0ZSBsb25nIHdyaXRlQXJjaGl2ZUhlYWRlcigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIGJ5dGUgW10gaGVhZGVyID0gQXJjaGl2ZVV0aWxzLnRvQXNjaWlCeXRlcyhBckFyY2hpdmVFbnRyeS5IRUFERVIpOworICAgICAgICBvdXQud3JpdGUoaGVhZGVyKTsKKyAgICAgICAgcmV0dXJuIGhlYWRlci5sZW5ndGg7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY2xvc2VBcmNoaXZlRW50cnkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZihmaW5pc2hlZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJTdHJlYW0gaGFzIGFscmVhZHkgYmVlbiBmaW5pc2hlZCIpOworICAgICAgICB9CisgICAgICAgIGlmIChwcmV2RW50cnkgPT0gbnVsbCB8fCAhaGF2ZVVuY2xvc2VkRW50cnkpeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJObyBjdXJyZW50IGVudHJ5IHRvIGNsb3NlIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGVudHJ5T2Zmc2V0ICUgMiAhPSAwKSB7CisgICAgICAgICAgICBvdXQud3JpdGUoJ1xuJyk7IC8vIFBhZCBieXRlCisgICAgICAgIH0KKyAgICAgICAgaGF2ZVVuY2xvc2VkRW50cnkgPSBmYWxzZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBwdXRBcmNoaXZlRW50cnkoIGZpbmFsIEFyY2hpdmVFbnRyeSBwRW50cnkgKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZihmaW5pc2hlZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJTdHJlYW0gaGFzIGFscmVhZHkgYmVlbiBmaW5pc2hlZCIpOworICAgICAgICB9CisKKyAgICAgICAgZmluYWwgQXJBcmNoaXZlRW50cnkgcEFyRW50cnkgPSAoQXJBcmNoaXZlRW50cnkpcEVudHJ5OworICAgICAgICBpZiAocHJldkVudHJ5ID09IG51bGwpIHsKKyAgICAgICAgICAgIHdyaXRlQXJjaGl2ZUhlYWRlcigpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaWYgKHByZXZFbnRyeS5nZXRMZW5ndGgoKSAhPSBlbnRyeU9mZnNldCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigibGVuZ3RoIGRvZXMgbm90IG1hdGNoIGVudHJ5ICgiICsgcHJldkVudHJ5LmdldExlbmd0aCgpICsgIiAhPSAiICsgZW50cnlPZmZzZXQpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoaGF2ZVVuY2xvc2VkRW50cnkpIHsKKyAgICAgICAgICAgICAgICBjbG9zZUFyY2hpdmVFbnRyeSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHJldkVudHJ5ID0gcEFyRW50cnk7CisKKyAgICAgICAgd3JpdGVFbnRyeUhlYWRlcihwQXJFbnRyeSk7CisKKyAgICAgICAgZW50cnlPZmZzZXQgPSAwOworICAgICAgICBoYXZlVW5jbG9zZWRFbnRyeSA9IHRydWU7CisgICAgfQorCisgICAgcHJpdmF0ZSBsb25nIGZpbGwoIGZpbmFsIGxvbmcgcE9mZnNldCwgZmluYWwgbG9uZyBwTmV3T2Zmc2V0LCBmaW5hbCBjaGFyIHBGaWxsICkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgbG9uZyBkaWZmID0gcE5ld09mZnNldCAtIHBPZmZzZXQ7CisKKyAgICAgICAgaWYgKGRpZmYgPiAwKSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGRpZmY7IGkrKykgeworICAgICAgICAgICAgICAgIHdyaXRlKHBGaWxsKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBwTmV3T2Zmc2V0OworICAgIH0KKworICAgIHByaXZhdGUgbG9uZyB3cml0ZSggZmluYWwgU3RyaW5nIGRhdGEgKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBieXRlW10gYnl0ZXMgPSBkYXRhLmdldEJ5dGVzKCJhc2NpaSIpOworICAgICAgICB3cml0ZShieXRlcyk7CisgICAgICAgIHJldHVybiBieXRlcy5sZW5ndGg7CisgICAgfQorCisgICAgcHJpdmF0ZSBsb25nIHdyaXRlRW50cnlIZWFkZXIoIGZpbmFsIEFyQXJjaGl2ZUVudHJ5IHBFbnRyeSApIHRocm93cyBJT0V4Y2VwdGlvbiB7CisKKyAgICAgICAgbG9uZyBvZmZzZXQgPSAwOworICAgICAgICBib29sZWFuIG11c3RBcHBlbmROYW1lID0gZmFsc2U7CisKKyAgICAgICAgZmluYWwgU3RyaW5nIG4gPSBwRW50cnkuZ2V0TmFtZSgpOworICAgICAgICBpZiAoTE9OR0ZJTEVfRVJST1IgPT0gbG9uZ0ZpbGVNb2RlICYmIG4ubGVuZ3RoKCkgPiAxNikgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJmaWxlbmFtZSB0b28gbG9uZywgPiAxNiBjaGFyczogIituKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoTE9OR0ZJTEVfQlNEID09IGxvbmdGaWxlTW9kZSAmJgorICAgICAgICAgICAgKG4ubGVuZ3RoKCkgPiAxNiB8fCBuLmNvbnRhaW5zKCIgIikpKSB7CisgICAgICAgICAgICBtdXN0QXBwZW5kTmFtZSA9IHRydWU7CisgICAgICAgICAgICBvZmZzZXQgKz0gd3JpdGUoQXJBcmNoaXZlSW5wdXRTdHJlYW0uQlNEX0xPTkdOQU1FX1BSRUZJWAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgU3RyaW5nLnZhbHVlT2Yobi5sZW5ndGgoKSkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgb2Zmc2V0ICs9IHdyaXRlKG4pOworICAgICAgICB9CisKKyAgICAgICAgb2Zmc2V0ID0gZmlsbChvZmZzZXQsIDE2LCAnICcpOworICAgICAgICBmaW5hbCBTdHJpbmcgbSA9ICIiICsgcEVudHJ5LmdldExhc3RNb2RpZmllZCgpOworICAgICAgICBpZiAobS5sZW5ndGgoKSA+IDEyKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIm1vZGlmaWVkIHRvbyBsb25nIik7CisgICAgICAgIH0KKyAgICAgICAgb2Zmc2V0ICs9IHdyaXRlKG0pOworCisgICAgICAgIG9mZnNldCA9IGZpbGwob2Zmc2V0LCAyOCwgJyAnKTsKKyAgICAgICAgZmluYWwgU3RyaW5nIHUgPSAiIiArIHBFbnRyeS5nZXRVc2VySWQoKTsKKyAgICAgICAgaWYgKHUubGVuZ3RoKCkgPiA2KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oInVzZXJpZCB0b28gbG9uZyIpOworICAgICAgICB9CisgICAgICAgIG9mZnNldCArPSB3cml0ZSh1KTsKKworICAgICAgICBvZmZzZXQgPSBmaWxsKG9mZnNldCwgMzQsICcgJyk7CisgICAgICAgIGZpbmFsIFN0cmluZyBnID0gIiIgKyBwRW50cnkuZ2V0R3JvdXBJZCgpOworICAgICAgICBpZiAoZy5sZW5ndGgoKSA+IDYpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiZ3JvdXBpZCB0b28gbG9uZyIpOworICAgICAgICB9CisgICAgICAgIG9mZnNldCArPSB3cml0ZShnKTsKKworICAgICAgICBvZmZzZXQgPSBmaWxsKG9mZnNldCwgNDAsICcgJyk7CisgICAgICAgIGZpbmFsIFN0cmluZyBmbSA9ICIiICsgSW50ZWdlci50b1N0cmluZyhwRW50cnkuZ2V0TW9kZSgpLCA4KTsKKyAgICAgICAgaWYgKGZtLmxlbmd0aCgpID4gOCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJmaWxlbW9kZSB0b28gbG9uZyIpOworICAgICAgICB9CisgICAgICAgIG9mZnNldCArPSB3cml0ZShmbSk7CisKKyAgICAgICAgb2Zmc2V0ID0gZmlsbChvZmZzZXQsIDQ4LCAnICcpOworICAgICAgICBmaW5hbCBTdHJpbmcgcyA9CisgICAgICAgICAgICBTdHJpbmcudmFsdWVPZihwRW50cnkuZ2V0TGVuZ3RoKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICsgKG11c3RBcHBlbmROYW1lID8gbi5sZW5ndGgoKSA6IDApKTsKKyAgICAgICAgaWYgKHMubGVuZ3RoKCkgPiAxMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJzaXplIHRvbyBsb25nIik7CisgICAgICAgIH0KKyAgICAgICAgb2Zmc2V0ICs9IHdyaXRlKHMpOworCisgICAgICAgIG9mZnNldCA9IGZpbGwob2Zmc2V0LCA1OCwgJyAnKTsKKworICAgICAgICBvZmZzZXQgKz0gd3JpdGUoQXJBcmNoaXZlRW50cnkuVFJBSUxFUik7CisKKyAgICAgICAgaWYgKG11c3RBcHBlbmROYW1lKSB7CisgICAgICAgICAgICBvZmZzZXQgKz0gd3JpdGUobik7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gb2Zmc2V0OworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGZpbmFsIGJ5dGVbXSBiLCBmaW5hbCBpbnQgb2ZmLCBmaW5hbCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvdXQud3JpdGUoYiwgb2ZmLCBsZW4pOworICAgICAgICBjb3VudChsZW4pOworICAgICAgICBlbnRyeU9mZnNldCArPSBsZW47CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2FsbHMgZmluaXNoIGlmIG5lY2Vzc2FyeSwgYW5kIHRoZW4gY2xvc2VzIHRoZSBPdXRwdXRTdHJlYW0KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAoIWZpbmlzaGVkKSB7CisgICAgICAgICAgICAgICAgZmluaXNoKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICAgICAgICAgIHByZXZFbnRyeSA9IG51bGw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQXJjaGl2ZUVudHJ5IGNyZWF0ZUFyY2hpdmVFbnRyeShmaW5hbCBGaWxlIGlucHV0RmlsZSwgZmluYWwgU3RyaW5nIGVudHJ5TmFtZSkKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmKGZpbmlzaGVkKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlN0cmVhbSBoYXMgYWxyZWFkeSBiZWVuIGZpbmlzaGVkIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBBckFyY2hpdmVFbnRyeShpbnB1dEZpbGUsIGVudHJ5TmFtZSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZmluaXNoKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYoaGF2ZVVuY2xvc2VkRW50cnkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiVGhpcyBhcmNoaXZlIGNvbnRhaW5zIHVuY2xvc2VkIGVudHJpZXMuIik7CisgICAgICAgIH0gZWxzZSBpZihmaW5pc2hlZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJUaGlzIGFyY2hpdmUgaGFzIGFscmVhZHkgYmVlbiBmaW5pc2hlZCIpOworICAgICAgICB9CisgICAgICAgIGZpbmlzaGVkID0gdHJ1ZTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvYXIvcGFja2FnZS5odG1sIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2FyL3BhY2thZ2UuaHRtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45YzgwZjk2Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2FyL3BhY2thZ2UuaHRtbApAQCAtMCwwICsxLDI0IEBACis8aHRtbD4KKzwhLS0KKworICAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAgIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAgIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKworICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorCisgICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKworLS0+CisgIDxib2R5PgorICAgIDxwPlByb3ZpZGVzIHN0cmVhbSBjbGFzc2VzIGZvciByZWFkaW5nIGFuZCB3cml0aW5nIGFyY2hpdmVzIHVzaW5nCisgICAgICB0aGUgQVIgZm9ybWF0LjwvcD4KKyAgPC9ib2R5PgorPC9odG1sPgpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2Fyai9BcmpBcmNoaXZlRW50cnkuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9hcmovQXJqQXJjaGl2ZUVudHJ5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWI4NDdkYgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9hcmovQXJqQXJjaGl2ZUVudHJ5LmphdmEKQEAgLTAsMCArMSwxNjQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5hcmo7CisKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS51dGlsLkRhdGU7CitpbXBvcnQgamF2YS51dGlsLnJlZ2V4Lk1hdGNoZXI7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLkFyY2hpdmVFbnRyeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcC5aaXBVdGlsOworCisvKioKKyAqIEFuIGVudHJ5IGluIGFuIEFSSiBhcmNoaXZlLgorICoKKyAqIEBOb3RUaHJlYWRTYWZlCisgKiBAc2luY2UgMS42CisgKi8KK3B1YmxpYyBjbGFzcyBBcmpBcmNoaXZlRW50cnkgaW1wbGVtZW50cyBBcmNoaXZlRW50cnkgeworICAgIHByaXZhdGUgZmluYWwgTG9jYWxGaWxlSGVhZGVyIGxvY2FsRmlsZUhlYWRlcjsKKworICAgIHB1YmxpYyBBcmpBcmNoaXZlRW50cnkoKSB7CisgICAgICAgIGxvY2FsRmlsZUhlYWRlciA9IG5ldyBMb2NhbEZpbGVIZWFkZXIoKTsKKyAgICB9CisKKyAgICBBcmpBcmNoaXZlRW50cnkoZmluYWwgTG9jYWxGaWxlSGVhZGVyIGxvY2FsRmlsZUhlYWRlcikgeworICAgICAgICB0aGlzLmxvY2FsRmlsZUhlYWRlciA9IGxvY2FsRmlsZUhlYWRlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhpcyBlbnRyeSdzIG5hbWUuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCByZXR1cm5zIHRoZSByYXcgbmFtZSBhcyBpdCBpcyBzdG9yZWQgaW5zaWRlIG9mIHRoZSBhcmNoaXZlLjwvcD4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhpcyBlbnRyeSdzIG5hbWUuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgeworICAgICAgICBpZiAoKGxvY2FsRmlsZUhlYWRlci5hcmpGbGFncyAmIExvY2FsRmlsZUhlYWRlci5GbGFncy5QQVRIU1lNKSAhPSAwKSB7CisgICAgICAgICAgICByZXR1cm4gbG9jYWxGaWxlSGVhZGVyLm5hbWUucmVwbGFjZUFsbCgiLyIsCisgICAgICAgICAgICAgICAgICAgIE1hdGNoZXIucXVvdGVSZXBsYWNlbWVudChGaWxlLnNlcGFyYXRvcikpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBsb2NhbEZpbGVIZWFkZXIubmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhpcyBlbnRyeSdzIGZpbGUgc2l6ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhpcyBlbnRyeSdzIGZpbGUgc2l6ZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgbG9uZyBnZXRTaXplKCkgeworICAgICAgICByZXR1cm4gbG9jYWxGaWxlSGVhZGVyLm9yaWdpbmFsU2l6ZTsKKyAgICB9CisKKyAgICAvKiogVHJ1ZSBpZiB0aGUgZW50cnkgcmVmZXJzIHRvIGEgZGlyZWN0b3J5LgorICAgICAqCisgICAgICogQHJldHVybiBUcnVlIGlmIHRoZSBlbnRyeSByZWZlcnMgdG8gYSBkaXJlY3RvcnkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0RpcmVjdG9yeSgpIHsKKyAgICAgICAgcmV0dXJuIGxvY2FsRmlsZUhlYWRlci5maWxlVHlwZSA9PSBMb2NhbEZpbGVIZWFkZXIuRmlsZVR5cGVzLkRJUkVDVE9SWTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgbGFzdCBtb2RpZmllZCBkYXRlIG9mIHRoZSBlbnRyeS4KKyAgICAgKgorICAgICAqIDxwPk5vdGUgdGhlIGludGVycHJldGF0aW9uIG9mIHRpbWUgaXMgZGlmZmVyZW50IGRlcGVuZGluZyBvbgorICAgICAqIHRoZSBIb3N0T1MgdGhhdCBoYXMgY3JlYXRlZCB0aGUgYXJjaGl2ZS4gIFdoaWxlIGFuIE9TIHRoYXQgaXMKKyAgICAgKiB7QGxpbmsgI2lzSG9zdE9zVW5peCBjb25zaWRlcmVkIHRvIGJlIFVuaXh9IHN0b3JlcyB0aW1lIGluIGEKKyAgICAgKiB0aW1lem9uZSBpbmRlcGVuZGVudCBtYW5uZXIsIG90aGVyIHBsYXRmb3JtcyBvbmx5IHVzZSB0aGUgbG9jYWwKKyAgICAgKiB0aW1lLiAgSS5lLiBpZiBhbiBhcmNoaXZlIGhhcyBiZWVuIGNyZWF0ZWQgYXQgbWlkbmlnaHQgVVRDIG9uIGEKKyAgICAgKiBtYWNoaW5lIGluIHRpbWV6b25lIFVUQyB0aGlzIG1ldGhvZCB3aWxsIHJldHVybiBtaWRuaWdodAorICAgICAqIHJlZ2FyZGxlc3Mgb2YgdGltZXpvbmUgaWYgdGhlIGFyY2hpdmUgaGFzIGJlZW4gY3JlYXRlZCBvbiBhCisgICAgICogbm9uLVVuaXggc3lzdGVtIGFuZCBhIHRpbWUgdGFraW5nIHRoZSBjdXJyZW50IHRpbWV6b25lIGludG8KKyAgICAgKiBhY2NvdW50IGlmIHRoZSBhcmNoaXZlIGhhcyBiZWVlbiBjcmVhdGVkIG9uIFVuaXguPC9wPgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbGFzdCBtb2RpZmllZCBkYXRlCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIERhdGUgZ2V0TGFzdE1vZGlmaWVkRGF0ZSgpIHsKKyAgICAgICAgZmluYWwgbG9uZyB0cyA9IGlzSG9zdE9zVW5peCgpID8gbG9jYWxGaWxlSGVhZGVyLmRhdGVUaW1lTW9kaWZpZWQgKiAxMDAwTAorICAgICAgICAgICAgOiBaaXBVdGlsLmRvc1RvSmF2YVRpbWUoMHhGRkZGRkZGRkwgJiBsb2NhbEZpbGVIZWFkZXIuZGF0ZVRpbWVNb2RpZmllZCk7CisgICAgICAgIHJldHVybiBuZXcgRGF0ZSh0cyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmlsZSBtb2RlIG9mIHRoaXMgZW50cnkuCisgICAgICoKKyAgICAgKiA8cD5UaGUgZm9ybWF0IGRlcGVuZHMgb24gdGhlIGhvc3Qgb3MgdGhhdCBjcmVhdGVkIHRoZSBlbnRyeS48L3A+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBmaWxlIG1vZGUKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldE1vZGUoKSB7CisgICAgICAgIHJldHVybiBsb2NhbEZpbGVIZWFkZXIuZmlsZUFjY2Vzc01vZGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmlsZSBtb2RlIG9mIHRoaXMgZW50cnkgYXMgVW5peCBzdGF0IHZhbHVlLgorICAgICAqCisgICAgICogPHA+V2lsbCBvbmx5IGJlIG5vbi16ZXJvIG9mIHRoZSBob3N0IG9zIHdhcyBVTklYLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgVW5peCBtb2RlCisgICAgICovCisgICAgcHVibGljIGludCBnZXRVbml4TW9kZSgpIHsKKyAgICAgICAgcmV0dXJuIGlzSG9zdE9zVW5peCgpID8gZ2V0TW9kZSgpIDogMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgb3BlcmF0aW5nIHN5c3RlbSB0aGUgYXJjaGl2ZSBoYXMgYmVlbiBjcmVhdGVkIG9uLgorICAgICAqIEBzZWUgSG9zdE9zCisgICAgICogQHJldHVybiB0aGUgaG9zdCBPUyBjb2RlCisgICAgICovCisgICAgcHVibGljIGludCBnZXRIb3N0T3MoKSB7CisgICAgICAgIHJldHVybiBsb2NhbEZpbGVIZWFkZXIuaG9zdE9TOworICAgIH0KKworICAgIC8qKgorICAgICAqIElzIHRoZSBvcGVyYXRpbmcgc3lzdGVtIHRoZSBhcmNoaXZlIGhhcyBiZWVuIGNyZWF0ZWQgb24gb25lCisgICAgICogdGhhdCBpcyBjb25zaWRlcmVkIGEgVU5JWCBPUyBieSBhcmo/CisgICAgICogQHJldHVybiB3aGV0aGVyIHRoZSBvcGVyYXRpbmcgc3lzdGVtIHRoZSBhcmNoaXZlIGhhcyBiZWVuCisgICAgICogY3JlYXRlZCBvbiBpcyBjb25zaWRlcmVkIGEgVU5JWCBPUyBieSBhcmoKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0hvc3RPc1VuaXgoKSB7CisgICAgICAgIHJldHVybiBnZXRIb3N0T3MoKSA9PSBIb3N0T3MuVU5JWCB8fCBnZXRIb3N0T3MoKSA9PSBIb3N0T3MuTkVYVDsKKyAgICB9CisKKyAgICBpbnQgZ2V0TWV0aG9kKCkgeworICAgICAgICByZXR1cm4gbG9jYWxGaWxlSGVhZGVyLm1ldGhvZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUga25vd24gdmFsdWVzIGZvciBIb3N0T3MuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBIb3N0T3MgeworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBET1MgPSAwOworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQUklNT1MgPSAxOworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBVTklYID0gMjsKKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQU1JR0EgPSAzOworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQUNfT1MgPSA0OworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPU18yID0gNTsKKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQVBQTEVfR1MgPSA2OworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBVEFSSV9TVCA9IDc7CisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE5FWFQgPSA4OworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWQVhfVk1TID0gOTsKKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgV0lOOTUgPSAxMDsKKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgV0lOMzIgPSAxMTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9hcmovQXJqQXJjaGl2ZUlucHV0U3RyZWFtLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvYXJqL0FyakFyY2hpdmVJbnB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMyMmQ0YzAKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvYXJqL0FyakFyY2hpdmVJbnB1dFN0cmVhbS5qYXZhCkBAIC0wLDAgKzEsMzUzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuYXJqOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkRhdGFJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLkNSQzMyOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5BcmNoaXZlRW50cnk7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5BcmNoaXZlRXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZUlucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5Cb3VuZGVkSW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLkNSQzMyVmVyaWZ5aW5nSW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLklPVXRpbHM7CisKKy8qKgorICogSW1wbGVtZW50cyB0aGUgImFyaiIgYXJjaGl2ZSBmb3JtYXQgYXMgYW4gSW5wdXRTdHJlYW0uCisgKiA8cD4KKyAqIDxhIGhyZWY9Imh0dHA6Ly9mYXJtYW5hZ2VyLmNvbS9zdm4vdHJ1bmsvcGx1Z2lucy9tdWx0aWFyYy9hcmMuZG9jL2Fyai50eHQiPlJlZmVyZW5jZTwvYT4KKyAqIEBOb3RUaHJlYWRTYWZlCisgKiBAc2luY2UgMS42CisgKi8KK3B1YmxpYyBjbGFzcyBBcmpBcmNoaXZlSW5wdXRTdHJlYW0gZXh0ZW5kcyBBcmNoaXZlSW5wdXRTdHJlYW0geworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBBUkpfTUFHSUNfMSA9IDB4NjA7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEFSSl9NQUdJQ18yID0gMHhFQTsKKyAgICBwcml2YXRlIGZpbmFsIERhdGFJbnB1dFN0cmVhbSBpbjsKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBjaGFyc2V0TmFtZTsKKyAgICBwcml2YXRlIGZpbmFsIE1haW5IZWFkZXIgbWFpbkhlYWRlcjsKKyAgICBwcml2YXRlIExvY2FsRmlsZUhlYWRlciBjdXJyZW50TG9jYWxGaWxlSGVhZGVyID0gbnVsbDsKKyAgICBwcml2YXRlIElucHV0U3RyZWFtIGN1cnJlbnRJbnB1dFN0cmVhbSA9IG51bGw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIHRoZSBBcmpJbnB1dFN0cmVhbSwgdGFraW5nIG93bmVyc2hpcCBvZiB0aGUgaW5wdXRTdHJlYW0gdGhhdCBpcyBwYXNzZWQgaW4uCisgICAgICogQHBhcmFtIGlucHV0U3RyZWFtIHRoZSB1bmRlcmx5aW5nIHN0cmVhbSwgd2hvc2Ugb3duZXJzaGlwIGlzIHRha2VuCisgICAgICogQHBhcmFtIGNoYXJzZXROYW1lIHRoZSBjaGFyc2V0IHVzZWQgZm9yIGZpbGUgbmFtZXMgYW5kIGNvbW1lbnRzCisgICAgICogICBpbiB0aGUgYXJjaGl2ZS4gTWF5IGJlIHtAY29kZSBudWxsfSB0byB1c2UgdGhlIHBsYXRmb3JtIGRlZmF1bHQuCisgICAgICogQHRocm93cyBBcmNoaXZlRXhjZXB0aW9uIGlmIGFuIGV4Y2VwdGlvbiBvY2N1cnMgd2hpbGUgcmVhZGluZworICAgICAqLworICAgIHB1YmxpYyBBcmpBcmNoaXZlSW5wdXRTdHJlYW0oZmluYWwgSW5wdXRTdHJlYW0gaW5wdXRTdHJlYW0sCisgICAgICAgICAgICBmaW5hbCBTdHJpbmcgY2hhcnNldE5hbWUpIHRocm93cyBBcmNoaXZlRXhjZXB0aW9uIHsKKyAgICAgICAgaW4gPSBuZXcgRGF0YUlucHV0U3RyZWFtKGlucHV0U3RyZWFtKTsKKyAgICAgICAgdGhpcy5jaGFyc2V0TmFtZSA9IGNoYXJzZXROYW1lOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbWFpbkhlYWRlciA9IHJlYWRNYWluSGVhZGVyKCk7CisgICAgICAgICAgICBpZiAoKG1haW5IZWFkZXIuYXJqRmxhZ3MgJiBNYWluSGVhZGVyLkZsYWdzLkdBUkJMRUQpICE9IDApIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXJjaGl2ZUV4Y2VwdGlvbigiRW5jcnlwdGVkIEFSSiBmaWxlcyBhcmUgdW5zdXBwb3J0ZWQiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICgobWFpbkhlYWRlci5hcmpGbGFncyAmIE1haW5IZWFkZXIuRmxhZ3MuVk9MVU1FKSAhPSAwKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFyY2hpdmVFeGNlcHRpb24oIk11bHRpLXZvbHVtZSBBUkogZmlsZXMgYXJlIHVuc3VwcG9ydGVkIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIElPRXhjZXB0aW9uIGlvRXhjZXB0aW9uKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXJjaGl2ZUV4Y2VwdGlvbihpb0V4Y2VwdGlvbi5nZXRNZXNzYWdlKCksIGlvRXhjZXB0aW9uKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgdGhlIEFyaklucHV0U3RyZWFtLCB0YWtpbmcgb3duZXJzaGlwIG9mIHRoZSBpbnB1dFN0cmVhbSB0aGF0IGlzIHBhc3NlZCBpbiwKKyAgICAgKiBhbmQgdXNpbmcgdGhlIENQNDM3IGNoYXJhY3RlciBlbmNvZGluZy4KKyAgICAgKiBAcGFyYW0gaW5wdXRTdHJlYW0gdGhlIHVuZGVybHlpbmcgc3RyZWFtLCB3aG9zZSBvd25lcnNoaXAgaXMgdGFrZW4KKyAgICAgKiBAdGhyb3dzIEFyY2hpdmVFeGNlcHRpb24gaWYgYW4gZXhjZXB0aW9uIG9jY3VycyB3aGlsZSByZWFkaW5nCisgICAgICovCisgICAgcHVibGljIEFyakFyY2hpdmVJbnB1dFN0cmVhbShmaW5hbCBJbnB1dFN0cmVhbSBpbnB1dFN0cmVhbSkKKyAgICAgICAgICAgIHRocm93cyBBcmNoaXZlRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcyhpbnB1dFN0cmVhbSwgIkNQNDM3Iik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbi5jbG9zZSgpOworICAgIH0KKworICAgIHByaXZhdGUgaW50IHJlYWQ4KGZpbmFsIERhdGFJbnB1dFN0cmVhbSBkYXRhSW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIGludCB2YWx1ZSA9IGRhdGFJbi5yZWFkVW5zaWduZWRCeXRlKCk7CisgICAgICAgIGNvdW50KDEpOworICAgICAgICByZXR1cm4gdmFsdWU7CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnQgcmVhZDE2KGZpbmFsIERhdGFJbnB1dFN0cmVhbSBkYXRhSW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIGludCB2YWx1ZSA9IGRhdGFJbi5yZWFkVW5zaWduZWRTaG9ydCgpOworICAgICAgICBjb3VudCgyKTsKKyAgICAgICAgcmV0dXJuIEludGVnZXIucmV2ZXJzZUJ5dGVzKHZhbHVlKSA+Pj4gMTY7CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnQgcmVhZDMyKGZpbmFsIERhdGFJbnB1dFN0cmVhbSBkYXRhSW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIGludCB2YWx1ZSA9IGRhdGFJbi5yZWFkSW50KCk7CisgICAgICAgIGNvdW50KDQpOworICAgICAgICByZXR1cm4gSW50ZWdlci5yZXZlcnNlQnl0ZXModmFsdWUpOworICAgIH0KKworICAgIHByaXZhdGUgU3RyaW5nIHJlYWRTdHJpbmcoZmluYWwgRGF0YUlucHV0U3RyZWFtIGRhdGFJbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJ1ZmZlciA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgaW50IG5leHRCeXRlOworICAgICAgICB3aGlsZSAoKG5leHRCeXRlID0gZGF0YUluLnJlYWRVbnNpZ25lZEJ5dGUoKSkgIT0gMCkgeworICAgICAgICAgICAgYnVmZmVyLndyaXRlKG5leHRCeXRlKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoY2hhcnNldE5hbWUgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmcoYnVmZmVyLnRvQnl0ZUFycmF5KCksIGNoYXJzZXROYW1lKTsKKyAgICAgICAgfQorICAgICAgICAvLyBpbnRlbnRpb25hbGx5IHVzaW5nIHRoZSBkZWZhdWx0IGVuY29kaW5nIGFzIHRoYXQncyB0aGUgY29udHJhY3QgZm9yIGEgbnVsbCBjaGFyc2V0TmFtZQorICAgICAgICByZXR1cm4gbmV3IFN0cmluZyhidWZmZXIudG9CeXRlQXJyYXkoKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHJlYWRGdWxseShmaW5hbCBEYXRhSW5wdXRTdHJlYW0gZGF0YUluLCBmaW5hbCBieXRlW10gYikKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZGF0YUluLnJlYWRGdWxseShiKTsKKyAgICAgICAgY291bnQoYi5sZW5ndGgpOworICAgIH0KKworICAgIHByaXZhdGUgYnl0ZVtdIHJlYWRIZWFkZXIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBib29sZWFuIGZvdW5kID0gZmFsc2U7CisgICAgICAgIGJ5dGVbXSBiYXNpY0hlYWRlckJ5dGVzID0gbnVsbDsKKyAgICAgICAgZG8geworICAgICAgICAgICAgaW50IGZpcnN0ID0gMDsKKyAgICAgICAgICAgIGludCBzZWNvbmQgPSByZWFkOChpbik7CisgICAgICAgICAgICBkbyB7CisgICAgICAgICAgICAgICAgZmlyc3QgPSBzZWNvbmQ7CisgICAgICAgICAgICAgICAgc2Vjb25kID0gcmVhZDgoaW4pOworICAgICAgICAgICAgfSB3aGlsZSAoZmlyc3QgIT0gQVJKX01BR0lDXzEgJiYgc2Vjb25kICE9IEFSSl9NQUdJQ18yKTsKKyAgICAgICAgICAgIGZpbmFsIGludCBiYXNpY0hlYWRlclNpemUgPSByZWFkMTYoaW4pOworICAgICAgICAgICAgaWYgKGJhc2ljSGVhZGVyU2l6ZSA9PSAwKSB7CisgICAgICAgICAgICAgICAgLy8gZW5kIG9mIGFyY2hpdmUKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChiYXNpY0hlYWRlclNpemUgPD0gMjYwMCkgeworICAgICAgICAgICAgICAgIGJhc2ljSGVhZGVyQnl0ZXMgPSBuZXcgYnl0ZVtiYXNpY0hlYWRlclNpemVdOworICAgICAgICAgICAgICAgIHJlYWRGdWxseShpbiwgYmFzaWNIZWFkZXJCeXRlcyk7CisgICAgICAgICAgICAgICAgZmluYWwgbG9uZyBiYXNpY0hlYWRlckNyYzMyID0gcmVhZDMyKGluKSAmIDB4RkZGRkZGRkZMOworICAgICAgICAgICAgICAgIGZpbmFsIENSQzMyIGNyYzMyID0gbmV3IENSQzMyKCk7CisgICAgICAgICAgICAgICAgY3JjMzIudXBkYXRlKGJhc2ljSGVhZGVyQnl0ZXMpOworICAgICAgICAgICAgICAgIGlmIChiYXNpY0hlYWRlckNyYzMyID09IGNyYzMyLmdldFZhbHVlKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgZm91bmQgPSB0cnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSB3aGlsZSAoIWZvdW5kKTsKKyAgICAgICAgcmV0dXJuIGJhc2ljSGVhZGVyQnl0ZXM7CisgICAgfQorCisgICAgcHJpdmF0ZSBNYWluSGVhZGVyIHJlYWRNYWluSGVhZGVyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGJhc2ljSGVhZGVyQnl0ZXMgPSByZWFkSGVhZGVyKCk7CisgICAgICAgIGlmIChiYXNpY0hlYWRlckJ5dGVzID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiQXJjaGl2ZSBlbmRzIHdpdGhvdXQgYW55IGhlYWRlcnMiKTsKKyAgICAgICAgfQorICAgICAgICBmaW5hbCBEYXRhSW5wdXRTdHJlYW0gYmFzaWNIZWFkZXIgPSBuZXcgRGF0YUlucHV0U3RyZWFtKAorICAgICAgICAgICAgICAgIG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShiYXNpY0hlYWRlckJ5dGVzKSk7CisKKyAgICAgICAgZmluYWwgaW50IGZpcnN0SGVhZGVyU2l6ZSA9IGJhc2ljSGVhZGVyLnJlYWRVbnNpZ25lZEJ5dGUoKTsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGZpcnN0SGVhZGVyQnl0ZXMgPSBuZXcgYnl0ZVtmaXJzdEhlYWRlclNpemUgLSAxXTsKKyAgICAgICAgYmFzaWNIZWFkZXIucmVhZEZ1bGx5KGZpcnN0SGVhZGVyQnl0ZXMpOworICAgICAgICBmaW5hbCBEYXRhSW5wdXRTdHJlYW0gZmlyc3RIZWFkZXIgPSBuZXcgRGF0YUlucHV0U3RyZWFtKAorICAgICAgICAgICAgICAgIG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShmaXJzdEhlYWRlckJ5dGVzKSk7CisKKyAgICAgICAgZmluYWwgTWFpbkhlYWRlciBoZHIgPSBuZXcgTWFpbkhlYWRlcigpOworICAgICAgICBoZHIuYXJjaGl2ZXJWZXJzaW9uTnVtYmVyID0gZmlyc3RIZWFkZXIucmVhZFVuc2lnbmVkQnl0ZSgpOworICAgICAgICBoZHIubWluVmVyc2lvblRvRXh0cmFjdCA9IGZpcnN0SGVhZGVyLnJlYWRVbnNpZ25lZEJ5dGUoKTsKKyAgICAgICAgaGRyLmhvc3RPUyA9IGZpcnN0SGVhZGVyLnJlYWRVbnNpZ25lZEJ5dGUoKTsKKyAgICAgICAgaGRyLmFyakZsYWdzID0gZmlyc3RIZWFkZXIucmVhZFVuc2lnbmVkQnl0ZSgpOworICAgICAgICBoZHIuc2VjdXJpdHlWZXJzaW9uID0gZmlyc3RIZWFkZXIucmVhZFVuc2lnbmVkQnl0ZSgpOworICAgICAgICBoZHIuZmlsZVR5cGUgPSBmaXJzdEhlYWRlci5yZWFkVW5zaWduZWRCeXRlKCk7CisgICAgICAgIGhkci5yZXNlcnZlZCA9IGZpcnN0SGVhZGVyLnJlYWRVbnNpZ25lZEJ5dGUoKTsKKyAgICAgICAgaGRyLmRhdGVUaW1lQ3JlYXRlZCA9IHJlYWQzMihmaXJzdEhlYWRlcik7CisgICAgICAgIGhkci5kYXRlVGltZU1vZGlmaWVkID0gcmVhZDMyKGZpcnN0SGVhZGVyKTsKKyAgICAgICAgaGRyLmFyY2hpdmVTaXplID0gMHhmZmZmRkZGRkwgJiByZWFkMzIoZmlyc3RIZWFkZXIpOworICAgICAgICBoZHIuc2VjdXJpdHlFbnZlbG9wZUZpbGVQb3NpdGlvbiA9IHJlYWQzMihmaXJzdEhlYWRlcik7CisgICAgICAgIGhkci5maWxlU3BlY1Bvc2l0aW9uID0gcmVhZDE2KGZpcnN0SGVhZGVyKTsKKyAgICAgICAgaGRyLnNlY3VyaXR5RW52ZWxvcGVMZW5ndGggPSByZWFkMTYoZmlyc3RIZWFkZXIpOworICAgICAgICBwdXNoZWRCYWNrQnl0ZXMoMjApOyAvLyBjb3VudCBoYXMgYWxyZWFkeSBjb3VudGVkIHRoZW0gdmlhIHJlYWRGdWxseQorICAgICAgICBoZHIuZW5jcnlwdGlvblZlcnNpb24gPSBmaXJzdEhlYWRlci5yZWFkVW5zaWduZWRCeXRlKCk7CisgICAgICAgIGhkci5sYXN0Q2hhcHRlciA9IGZpcnN0SGVhZGVyLnJlYWRVbnNpZ25lZEJ5dGUoKTsKKworICAgICAgICBpZiAoZmlyc3RIZWFkZXJTaXplID49IDMzKSB7CisgICAgICAgICAgICBoZHIuYXJqUHJvdGVjdGlvbkZhY3RvciA9IGZpcnN0SGVhZGVyLnJlYWRVbnNpZ25lZEJ5dGUoKTsKKyAgICAgICAgICAgIGhkci5hcmpGbGFnczIgPSBmaXJzdEhlYWRlci5yZWFkVW5zaWduZWRCeXRlKCk7CisgICAgICAgICAgICBmaXJzdEhlYWRlci5yZWFkVW5zaWduZWRCeXRlKCk7CisgICAgICAgICAgICBmaXJzdEhlYWRlci5yZWFkVW5zaWduZWRCeXRlKCk7CisgICAgICAgIH0KKworICAgICAgICBoZHIubmFtZSA9IHJlYWRTdHJpbmcoYmFzaWNIZWFkZXIpOworICAgICAgICBoZHIuY29tbWVudCA9IHJlYWRTdHJpbmcoYmFzaWNIZWFkZXIpOworCisgICAgICAgIGZpbmFsICBpbnQgZXh0ZW5kZWRIZWFkZXJTaXplID0gcmVhZDE2KGluKTsKKyAgICAgICAgaWYgKGV4dGVuZGVkSGVhZGVyU2l6ZSA+IDApIHsKKyAgICAgICAgICAgIGhkci5leHRlbmRlZEhlYWRlckJ5dGVzID0gbmV3IGJ5dGVbZXh0ZW5kZWRIZWFkZXJTaXplXTsKKyAgICAgICAgICAgIHJlYWRGdWxseShpbiwgaGRyLmV4dGVuZGVkSGVhZGVyQnl0ZXMpOworICAgICAgICAgICAgZmluYWwgbG9uZyBleHRlbmRlZEhlYWRlckNyYzMyID0gMHhmZmZmRkZGRkwgJiByZWFkMzIoaW4pOworICAgICAgICAgICAgZmluYWwgQ1JDMzIgY3JjMzIgPSBuZXcgQ1JDMzIoKTsKKyAgICAgICAgICAgIGNyYzMyLnVwZGF0ZShoZHIuZXh0ZW5kZWRIZWFkZXJCeXRlcyk7CisgICAgICAgICAgICBpZiAoZXh0ZW5kZWRIZWFkZXJDcmMzMiAhPSBjcmMzMi5nZXRWYWx1ZSgpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJFeHRlbmRlZCBoZWFkZXIgQ1JDMzIgdmVyaWZpY2F0aW9uIGZhaWx1cmUiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBoZHI7CisgICAgfQorCisgICAgcHJpdmF0ZSBMb2NhbEZpbGVIZWFkZXIgcmVhZExvY2FsRmlsZUhlYWRlcigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIGJ5dGVbXSBiYXNpY0hlYWRlckJ5dGVzID0gcmVhZEhlYWRlcigpOworICAgICAgICBpZiAoYmFzaWNIZWFkZXJCeXRlcyA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICB0cnkgKGZpbmFsIERhdGFJbnB1dFN0cmVhbSBiYXNpY0hlYWRlciA9IG5ldyBEYXRhSW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJhc2ljSGVhZGVyQnl0ZXMpKSkgeworCisgICAgICAgICAgICBmaW5hbCBpbnQgZmlyc3RIZWFkZXJTaXplID0gYmFzaWNIZWFkZXIucmVhZFVuc2lnbmVkQnl0ZSgpOworICAgICAgICAgICAgZmluYWwgYnl0ZVtdIGZpcnN0SGVhZGVyQnl0ZXMgPSBuZXcgYnl0ZVtmaXJzdEhlYWRlclNpemUgLSAxXTsKKyAgICAgICAgICAgIGJhc2ljSGVhZGVyLnJlYWRGdWxseShmaXJzdEhlYWRlckJ5dGVzKTsKKyAgICAgICAgICAgIHRyeSAoZmluYWwgRGF0YUlucHV0U3RyZWFtIGZpcnN0SGVhZGVyID0gbmV3IERhdGFJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oZmlyc3RIZWFkZXJCeXRlcykpKSB7CisKKyAgICAgICAgICAgICAgICBmaW5hbCBMb2NhbEZpbGVIZWFkZXIgbG9jYWxGaWxlSGVhZGVyID0gbmV3IExvY2FsRmlsZUhlYWRlcigpOworICAgICAgICAgICAgICAgIGxvY2FsRmlsZUhlYWRlci5hcmNoaXZlclZlcnNpb25OdW1iZXIgPSBmaXJzdEhlYWRlci5yZWFkVW5zaWduZWRCeXRlKCk7CisgICAgICAgICAgICAgICAgbG9jYWxGaWxlSGVhZGVyLm1pblZlcnNpb25Ub0V4dHJhY3QgPSBmaXJzdEhlYWRlci5yZWFkVW5zaWduZWRCeXRlKCk7CisgICAgICAgICAgICAgICAgbG9jYWxGaWxlSGVhZGVyLmhvc3RPUyA9IGZpcnN0SGVhZGVyLnJlYWRVbnNpZ25lZEJ5dGUoKTsKKyAgICAgICAgICAgICAgICBsb2NhbEZpbGVIZWFkZXIuYXJqRmxhZ3MgPSBmaXJzdEhlYWRlci5yZWFkVW5zaWduZWRCeXRlKCk7CisgICAgICAgICAgICAgICAgbG9jYWxGaWxlSGVhZGVyLm1ldGhvZCA9IGZpcnN0SGVhZGVyLnJlYWRVbnNpZ25lZEJ5dGUoKTsKKyAgICAgICAgICAgICAgICBsb2NhbEZpbGVIZWFkZXIuZmlsZVR5cGUgPSBmaXJzdEhlYWRlci5yZWFkVW5zaWduZWRCeXRlKCk7CisgICAgICAgICAgICAgICAgbG9jYWxGaWxlSGVhZGVyLnJlc2VydmVkID0gZmlyc3RIZWFkZXIucmVhZFVuc2lnbmVkQnl0ZSgpOworICAgICAgICAgICAgICAgIGxvY2FsRmlsZUhlYWRlci5kYXRlVGltZU1vZGlmaWVkID0gcmVhZDMyKGZpcnN0SGVhZGVyKTsKKyAgICAgICAgICAgICAgICBsb2NhbEZpbGVIZWFkZXIuY29tcHJlc3NlZFNpemUgPSAweGZmZmZGRkZGTCAmIHJlYWQzMihmaXJzdEhlYWRlcik7CisgICAgICAgICAgICAgICAgbG9jYWxGaWxlSGVhZGVyLm9yaWdpbmFsU2l6ZSA9IDB4ZmZmZkZGRkZMICYgcmVhZDMyKGZpcnN0SGVhZGVyKTsKKyAgICAgICAgICAgICAgICBsb2NhbEZpbGVIZWFkZXIub3JpZ2luYWxDcmMzMiA9IDB4ZmZmZkZGRkZMICYgcmVhZDMyKGZpcnN0SGVhZGVyKTsKKyAgICAgICAgICAgICAgICBsb2NhbEZpbGVIZWFkZXIuZmlsZVNwZWNQb3NpdGlvbiA9IHJlYWQxNihmaXJzdEhlYWRlcik7CisgICAgICAgICAgICAgICAgbG9jYWxGaWxlSGVhZGVyLmZpbGVBY2Nlc3NNb2RlID0gcmVhZDE2KGZpcnN0SGVhZGVyKTsKKyAgICAgICAgICAgICAgICBwdXNoZWRCYWNrQnl0ZXMoMjApOworICAgICAgICAgICAgICAgIGxvY2FsRmlsZUhlYWRlci5maXJzdENoYXB0ZXIgPSBmaXJzdEhlYWRlci5yZWFkVW5zaWduZWRCeXRlKCk7CisgICAgICAgICAgICAgICAgbG9jYWxGaWxlSGVhZGVyLmxhc3RDaGFwdGVyID0gZmlyc3RIZWFkZXIucmVhZFVuc2lnbmVkQnl0ZSgpOworCisgICAgICAgICAgICAgICAgcmVhZEV4dHJhRGF0YShmaXJzdEhlYWRlclNpemUsIGZpcnN0SGVhZGVyLCBsb2NhbEZpbGVIZWFkZXIpOworCisgICAgICAgICAgICAgICAgbG9jYWxGaWxlSGVhZGVyLm5hbWUgPSByZWFkU3RyaW5nKGJhc2ljSGVhZGVyKTsKKyAgICAgICAgICAgICAgICBsb2NhbEZpbGVIZWFkZXIuY29tbWVudCA9IHJlYWRTdHJpbmcoYmFzaWNIZWFkZXIpOworCisgICAgICAgICAgICAgICAgZmluYWwgQXJyYXlMaXN0PGJ5dGVbXT4gZXh0ZW5kZWRIZWFkZXJzID0gbmV3IEFycmF5TGlzdDw+KCk7CisgICAgICAgICAgICAgICAgaW50IGV4dGVuZGVkSGVhZGVyU2l6ZTsKKyAgICAgICAgICAgICAgICB3aGlsZSAoKGV4dGVuZGVkSGVhZGVyU2l6ZSA9IHJlYWQxNihpbikpID4gMCkgeworICAgICAgICAgICAgICAgICAgICBmaW5hbCBieXRlW10gZXh0ZW5kZWRIZWFkZXJCeXRlcyA9IG5ldyBieXRlW2V4dGVuZGVkSGVhZGVyU2l6ZV07CisgICAgICAgICAgICAgICAgICAgIHJlYWRGdWxseShpbiwgZXh0ZW5kZWRIZWFkZXJCeXRlcyk7CisgICAgICAgICAgICAgICAgICAgIGZpbmFsIGxvbmcgZXh0ZW5kZWRIZWFkZXJDcmMzMiA9IDB4ZmZmZkZGRkZMICYgcmVhZDMyKGluKTsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgQ1JDMzIgY3JjMzIgPSBuZXcgQ1JDMzIoKTsKKyAgICAgICAgICAgICAgICAgICAgY3JjMzIudXBkYXRlKGV4dGVuZGVkSGVhZGVyQnl0ZXMpOworICAgICAgICAgICAgICAgICAgICBpZiAoZXh0ZW5kZWRIZWFkZXJDcmMzMiAhPSBjcmMzMi5nZXRWYWx1ZSgpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkV4dGVuZGVkIGhlYWRlciBDUkMzMiB2ZXJpZmljYXRpb24gZmFpbHVyZSIpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGV4dGVuZGVkSGVhZGVycy5hZGQoZXh0ZW5kZWRIZWFkZXJCeXRlcyk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGxvY2FsRmlsZUhlYWRlci5leHRlbmRlZEhlYWRlcnMgPSBleHRlbmRlZEhlYWRlcnMudG9BcnJheShuZXcgYnl0ZVtleHRlbmRlZEhlYWRlcnMuc2l6ZSgpXVtdKTsKKworICAgICAgICAgICAgICAgIHJldHVybiBsb2NhbEZpbGVIZWFkZXI7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcmVhZEV4dHJhRGF0YShmaW5hbCBpbnQgZmlyc3RIZWFkZXJTaXplLCBmaW5hbCBEYXRhSW5wdXRTdHJlYW0gZmlyc3RIZWFkZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgTG9jYWxGaWxlSGVhZGVyIGxvY2FsRmlsZUhlYWRlcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGZpcnN0SGVhZGVyU2l6ZSA+PSAzMykgeworICAgICAgICAgICAgbG9jYWxGaWxlSGVhZGVyLmV4dGVuZGVkRmlsZVBvc2l0aW9uID0gcmVhZDMyKGZpcnN0SGVhZGVyKTsKKyAgICAgICAgICAgIGlmIChmaXJzdEhlYWRlclNpemUgPj0gNDUpIHsKKyAgICAgICAgICAgICAgICBsb2NhbEZpbGVIZWFkZXIuZGF0ZVRpbWVBY2Nlc3NlZCA9IHJlYWQzMihmaXJzdEhlYWRlcik7CisgICAgICAgICAgICAgICAgbG9jYWxGaWxlSGVhZGVyLmRhdGVUaW1lQ3JlYXRlZCA9IHJlYWQzMihmaXJzdEhlYWRlcik7CisgICAgICAgICAgICAgICAgbG9jYWxGaWxlSGVhZGVyLm9yaWdpbmFsU2l6ZUV2ZW5Gb3JWb2x1bWVzID0gcmVhZDMyKGZpcnN0SGVhZGVyKTsKKyAgICAgICAgICAgICAgICBwdXNoZWRCYWNrQnl0ZXMoMTIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcHVzaGVkQmFja0J5dGVzKDQpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIHRoZSBzaWduYXR1cmUgbWF0Y2hlcyB3aGF0IGlzIGV4cGVjdGVkIGZvciBhbiBhcmogZmlsZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzaWduYXR1cmUKKyAgICAgKiAgICAgICAgICAgIHRoZSBieXRlcyB0byBjaGVjaworICAgICAqIEBwYXJhbSBsZW5ndGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gY2hlY2sKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoaXMgc3RyZWFtIGlzIGFuIGFyaiBhcmNoaXZlIHN0cmVhbSwgZmFsc2Ugb3RoZXJ3aXNlCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIG1hdGNoZXMoZmluYWwgYnl0ZVtdIHNpZ25hdHVyZSwgZmluYWwgaW50IGxlbmd0aCkgeworICAgICAgICByZXR1cm4gbGVuZ3RoID49IDIgJiYKKyAgICAgICAgICAgICAgICAoMHhmZiAmIHNpZ25hdHVyZVswXSkgPT0gQVJKX01BR0lDXzEgJiYKKyAgICAgICAgICAgICAgICAoMHhmZiAmIHNpZ25hdHVyZVsxXSkgPT0gQVJKX01BR0lDXzI7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgYXJjaGl2ZSdzIHJlY29yZGVkIG5hbWUuCisgICAgICogQHJldHVybiB0aGUgYXJjaGl2ZSdzIG5hbWUKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEFyY2hpdmVOYW1lKCkgeworICAgICAgICByZXR1cm4gbWFpbkhlYWRlci5uYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGFyY2hpdmUncyBjb21tZW50LgorICAgICAqIEByZXR1cm4gdGhlIGFyY2hpdmUncyBjb21tZW50CisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRBcmNoaXZlQ29tbWVudCgpIHsKKyAgICAgICAgcmV0dXJuIG1haW5IZWFkZXIuY29tbWVudDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQXJqQXJjaGl2ZUVudHJ5IGdldE5leHRFbnRyeSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChjdXJyZW50SW5wdXRTdHJlYW0gIT0gbnVsbCkgeworICAgICAgICAgICAgLy8gcmV0dXJuIHZhbHVlIGlnbm9yZWQgYXMgSU9VdGlscy5za2lwIGVuc3VyZXMgdGhlIHN0cmVhbSBpcyBkcmFpbmVkIGNvbXBsZXRlbHkKKyAgICAgICAgICAgIElPVXRpbHMuc2tpcChjdXJyZW50SW5wdXRTdHJlYW0sIExvbmcuTUFYX1ZBTFVFKTsKKyAgICAgICAgICAgIGN1cnJlbnRJbnB1dFN0cmVhbS5jbG9zZSgpOworICAgICAgICAgICAgY3VycmVudExvY2FsRmlsZUhlYWRlciA9IG51bGw7CisgICAgICAgICAgICBjdXJyZW50SW5wdXRTdHJlYW0gPSBudWxsOworICAgICAgICB9CisKKyAgICAgICAgY3VycmVudExvY2FsRmlsZUhlYWRlciA9IHJlYWRMb2NhbEZpbGVIZWFkZXIoKTsKKyAgICAgICAgaWYgKGN1cnJlbnRMb2NhbEZpbGVIZWFkZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgY3VycmVudElucHV0U3RyZWFtID0gbmV3IEJvdW5kZWRJbnB1dFN0cmVhbShpbiwgY3VycmVudExvY2FsRmlsZUhlYWRlci5jb21wcmVzc2VkU2l6ZSk7CisgICAgICAgICAgICBpZiAoY3VycmVudExvY2FsRmlsZUhlYWRlci5tZXRob2QgPT0gTG9jYWxGaWxlSGVhZGVyLk1ldGhvZHMuU1RPUkVEKSB7CisgICAgICAgICAgICAgICAgY3VycmVudElucHV0U3RyZWFtID0gbmV3IENSQzMyVmVyaWZ5aW5nSW5wdXRTdHJlYW0oY3VycmVudElucHV0U3RyZWFtLAorICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudExvY2FsRmlsZUhlYWRlci5vcmlnaW5hbFNpemUsIGN1cnJlbnRMb2NhbEZpbGVIZWFkZXIub3JpZ2luYWxDcmMzMik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbmV3IEFyakFyY2hpdmVFbnRyeShjdXJyZW50TG9jYWxGaWxlSGVhZGVyKTsKKyAgICAgICAgfQorICAgICAgICBjdXJyZW50SW5wdXRTdHJlYW0gPSBudWxsOworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBjYW5SZWFkRW50cnlEYXRhKGZpbmFsIEFyY2hpdmVFbnRyeSBhZSkgeworICAgICAgICByZXR1cm4gYWUgaW5zdGFuY2VvZiBBcmpBcmNoaXZlRW50cnkKKyAgICAgICAgICAgICYmICgoQXJqQXJjaGl2ZUVudHJ5KSBhZSkuZ2V0TWV0aG9kKCkgPT0gTG9jYWxGaWxlSGVhZGVyLk1ldGhvZHMuU1RPUkVEOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZChmaW5hbCBieXRlW10gYiwgZmluYWwgaW50IG9mZiwgZmluYWwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGN1cnJlbnRMb2NhbEZpbGVIZWFkZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiTm8gY3VycmVudCBhcmogZW50cnkiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoY3VycmVudExvY2FsRmlsZUhlYWRlci5tZXRob2QgIT0gTG9jYWxGaWxlSGVhZGVyLk1ldGhvZHMuU1RPUkVEKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlVuc3VwcG9ydGVkIGNvbXByZXNzaW9uIG1ldGhvZCAiICsgY3VycmVudExvY2FsRmlsZUhlYWRlci5tZXRob2QpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBjdXJyZW50SW5wdXRTdHJlYW0ucmVhZChiLCBvZmYsIGxlbik7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2Fyai9Mb2NhbEZpbGVIZWFkZXIuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9hcmovTG9jYWxGaWxlSGVhZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmVjYjI5NwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9hcmovTG9jYWxGaWxlSGVhZGVyLmphdmEKQEAgLTAsMCArMSwxMjMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5hcmo7CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCitjbGFzcyBMb2NhbEZpbGVIZWFkZXIgeworICAgIGludCBhcmNoaXZlclZlcnNpb25OdW1iZXI7CisgICAgaW50IG1pblZlcnNpb25Ub0V4dHJhY3Q7CisgICAgaW50IGhvc3RPUzsKKyAgICBpbnQgYXJqRmxhZ3M7CisgICAgaW50IG1ldGhvZDsKKyAgICBpbnQgZmlsZVR5cGU7CisgICAgaW50IHJlc2VydmVkOworICAgIGludCBkYXRlVGltZU1vZGlmaWVkOworICAgIGxvbmcgY29tcHJlc3NlZFNpemU7CisgICAgbG9uZyBvcmlnaW5hbFNpemU7CisgICAgbG9uZyBvcmlnaW5hbENyYzMyOworICAgIGludCBmaWxlU3BlY1Bvc2l0aW9uOworICAgIGludCBmaWxlQWNjZXNzTW9kZTsKKyAgICBpbnQgZmlyc3RDaGFwdGVyOworICAgIGludCBsYXN0Q2hhcHRlcjsKKworICAgIGludCBleHRlbmRlZEZpbGVQb3NpdGlvbjsKKyAgICBpbnQgZGF0ZVRpbWVBY2Nlc3NlZDsKKyAgICBpbnQgZGF0ZVRpbWVDcmVhdGVkOworICAgIGludCBvcmlnaW5hbFNpemVFdmVuRm9yVm9sdW1lczsKKworICAgIFN0cmluZyBuYW1lOworICAgIFN0cmluZyBjb21tZW50OworCisgICAgYnl0ZVtdW10gZXh0ZW5kZWRIZWFkZXJzID0gbnVsbDsKKworICAgIHN0YXRpYyBjbGFzcyBGbGFncyB7CisgICAgICAgIHN0YXRpYyBmaW5hbCBpbnQgR0FSQkxFRCA9IDB4MDE7CisgICAgICAgIHN0YXRpYyBmaW5hbCBpbnQgVk9MVU1FID0gMHgwNDsKKyAgICAgICAgc3RhdGljIGZpbmFsIGludCBFWFRGSUxFID0gMHgwODsKKyAgICAgICAgc3RhdGljIGZpbmFsIGludCBQQVRIU1lNID0gMHgxMDsKKyAgICAgICAgc3RhdGljIGZpbmFsIGludCBCQUNLVVAgPSAweDIwOworICAgIH0KKworICAgIHN0YXRpYyBjbGFzcyBGaWxlVHlwZXMgeworICAgICAgICBzdGF0aWMgZmluYWwgaW50IEJJTkFSWSA9IDA7CisgICAgICAgIHN0YXRpYyBmaW5hbCBpbnQgU0VWRU5fQklUX1RFWFQgPSAxOworICAgICAgICBzdGF0aWMgZmluYWwgaW50IERJUkVDVE9SWSA9IDM7CisgICAgICAgIHN0YXRpYyBmaW5hbCBpbnQgVk9MVU1FX0xBQkVMID0gNDsKKyAgICAgICAgc3RhdGljIGZpbmFsIGludCBDSEFQVEVSX0xBQkVMID0gNTsKKyAgICB9CisKKyAgICBzdGF0aWMgY2xhc3MgTWV0aG9kcyB7CisgICAgICAgIHN0YXRpYyBmaW5hbCBpbnQgU1RPUkVEID0gMDsKKyAgICAgICAgc3RhdGljIGZpbmFsIGludCBDT01QUkVTU0VEX01PU1QgPSAxOworICAgICAgICBzdGF0aWMgZmluYWwgaW50IENPTVBSRVNTRURfRkFTVEVTVCA9IDQ7CisgICAgICAgIHN0YXRpYyBmaW5hbCBpbnQgTk9fREFUQV9OT19DUkMgPSA4OworICAgICAgICBzdGF0aWMgZmluYWwgaW50IE5PX0RBVEEgPSA5OworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIGZpbmFsIFN0cmluZ0J1aWxkZXIgYnVpbGRlciA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgIGJ1aWxkZXIuYXBwZW5kKCJMb2NhbEZpbGVIZWFkZXIgW2FyY2hpdmVyVmVyc2lvbk51bWJlcj0iKTsKKyAgICAgICAgYnVpbGRlci5hcHBlbmQoYXJjaGl2ZXJWZXJzaW9uTnVtYmVyKTsKKyAgICAgICAgYnVpbGRlci5hcHBlbmQoIiwgbWluVmVyc2lvblRvRXh0cmFjdD0iKTsKKyAgICAgICAgYnVpbGRlci5hcHBlbmQobWluVmVyc2lvblRvRXh0cmFjdCk7CisgICAgICAgIGJ1aWxkZXIuYXBwZW5kKCIsIGhvc3RPUz0iKTsKKyAgICAgICAgYnVpbGRlci5hcHBlbmQoaG9zdE9TKTsKKyAgICAgICAgYnVpbGRlci5hcHBlbmQoIiwgYXJqRmxhZ3M9Iik7CisgICAgICAgIGJ1aWxkZXIuYXBwZW5kKGFyakZsYWdzKTsKKyAgICAgICAgYnVpbGRlci5hcHBlbmQoIiwgbWV0aG9kPSIpOworICAgICAgICBidWlsZGVyLmFwcGVuZChtZXRob2QpOworICAgICAgICBidWlsZGVyLmFwcGVuZCgiLCBmaWxlVHlwZT0iKTsKKyAgICAgICAgYnVpbGRlci5hcHBlbmQoZmlsZVR5cGUpOworICAgICAgICBidWlsZGVyLmFwcGVuZCgiLCByZXNlcnZlZD0iKTsKKyAgICAgICAgYnVpbGRlci5hcHBlbmQocmVzZXJ2ZWQpOworICAgICAgICBidWlsZGVyLmFwcGVuZCgiLCBkYXRlVGltZU1vZGlmaWVkPSIpOworICAgICAgICBidWlsZGVyLmFwcGVuZChkYXRlVGltZU1vZGlmaWVkKTsKKyAgICAgICAgYnVpbGRlci5hcHBlbmQoIiwgY29tcHJlc3NlZFNpemU9Iik7CisgICAgICAgIGJ1aWxkZXIuYXBwZW5kKGNvbXByZXNzZWRTaXplKTsKKyAgICAgICAgYnVpbGRlci5hcHBlbmQoIiwgb3JpZ2luYWxTaXplPSIpOworICAgICAgICBidWlsZGVyLmFwcGVuZChvcmlnaW5hbFNpemUpOworICAgICAgICBidWlsZGVyLmFwcGVuZCgiLCBvcmlnaW5hbENyYzMyPSIpOworICAgICAgICBidWlsZGVyLmFwcGVuZChvcmlnaW5hbENyYzMyKTsKKyAgICAgICAgYnVpbGRlci5hcHBlbmQoIiwgZmlsZVNwZWNQb3NpdGlvbj0iKTsKKyAgICAgICAgYnVpbGRlci5hcHBlbmQoZmlsZVNwZWNQb3NpdGlvbik7CisgICAgICAgIGJ1aWxkZXIuYXBwZW5kKCIsIGZpbGVBY2Nlc3NNb2RlPSIpOworICAgICAgICBidWlsZGVyLmFwcGVuZChmaWxlQWNjZXNzTW9kZSk7CisgICAgICAgIGJ1aWxkZXIuYXBwZW5kKCIsIGZpcnN0Q2hhcHRlcj0iKTsKKyAgICAgICAgYnVpbGRlci5hcHBlbmQoZmlyc3RDaGFwdGVyKTsKKyAgICAgICAgYnVpbGRlci5hcHBlbmQoIiwgbGFzdENoYXB0ZXI9Iik7CisgICAgICAgIGJ1aWxkZXIuYXBwZW5kKGxhc3RDaGFwdGVyKTsKKyAgICAgICAgYnVpbGRlci5hcHBlbmQoIiwgZXh0ZW5kZWRGaWxlUG9zaXRpb249Iik7CisgICAgICAgIGJ1aWxkZXIuYXBwZW5kKGV4dGVuZGVkRmlsZVBvc2l0aW9uKTsKKyAgICAgICAgYnVpbGRlci5hcHBlbmQoIiwgZGF0ZVRpbWVBY2Nlc3NlZD0iKTsKKyAgICAgICAgYnVpbGRlci5hcHBlbmQoZGF0ZVRpbWVBY2Nlc3NlZCk7CisgICAgICAgIGJ1aWxkZXIuYXBwZW5kKCIsIGRhdGVUaW1lQ3JlYXRlZD0iKTsKKyAgICAgICAgYnVpbGRlci5hcHBlbmQoZGF0ZVRpbWVDcmVhdGVkKTsKKyAgICAgICAgYnVpbGRlci5hcHBlbmQoIiwgb3JpZ2luYWxTaXplRXZlbkZvclZvbHVtZXM9Iik7CisgICAgICAgIGJ1aWxkZXIuYXBwZW5kKG9yaWdpbmFsU2l6ZUV2ZW5Gb3JWb2x1bWVzKTsKKyAgICAgICAgYnVpbGRlci5hcHBlbmQoIiwgbmFtZT0iKTsKKyAgICAgICAgYnVpbGRlci5hcHBlbmQobmFtZSk7CisgICAgICAgIGJ1aWxkZXIuYXBwZW5kKCIsIGNvbW1lbnQ9Iik7CisgICAgICAgIGJ1aWxkZXIuYXBwZW5kKGNvbW1lbnQpOworICAgICAgICBidWlsZGVyLmFwcGVuZCgiLCBleHRlbmRlZEhlYWRlcnM9Iik7CisgICAgICAgIGJ1aWxkZXIuYXBwZW5kKEFycmF5cy50b1N0cmluZyhleHRlbmRlZEhlYWRlcnMpKTsKKyAgICAgICAgYnVpbGRlci5hcHBlbmQoIl0iKTsKKyAgICAgICAgcmV0dXJuIGJ1aWxkZXIudG9TdHJpbmcoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvYXJqL01haW5IZWFkZXIuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9hcmovTWFpbkhlYWRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdhOWYyMTIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvYXJqL01haW5IZWFkZXIuamF2YQpAQCAtMCwwICsxLDEwMiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICoKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLmFyajsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CisKK2NsYXNzIE1haW5IZWFkZXIgeworICAgIGludCBhcmNoaXZlclZlcnNpb25OdW1iZXI7CisgICAgaW50IG1pblZlcnNpb25Ub0V4dHJhY3Q7CisgICAgaW50IGhvc3RPUzsKKyAgICBpbnQgYXJqRmxhZ3M7CisgICAgaW50IHNlY3VyaXR5VmVyc2lvbjsKKyAgICBpbnQgZmlsZVR5cGU7CisgICAgaW50IHJlc2VydmVkOworICAgIGludCBkYXRlVGltZUNyZWF0ZWQ7CisgICAgaW50IGRhdGVUaW1lTW9kaWZpZWQ7CisgICAgbG9uZyBhcmNoaXZlU2l6ZTsKKyAgICBpbnQgc2VjdXJpdHlFbnZlbG9wZUZpbGVQb3NpdGlvbjsKKyAgICBpbnQgZmlsZVNwZWNQb3NpdGlvbjsKKyAgICBpbnQgc2VjdXJpdHlFbnZlbG9wZUxlbmd0aDsKKyAgICBpbnQgZW5jcnlwdGlvblZlcnNpb247CisgICAgaW50IGxhc3RDaGFwdGVyOworICAgIGludCBhcmpQcm90ZWN0aW9uRmFjdG9yOworICAgIGludCBhcmpGbGFnczI7CisgICAgU3RyaW5nIG5hbWU7CisgICAgU3RyaW5nIGNvbW1lbnQ7CisgICAgYnl0ZVtdIGV4dGVuZGVkSGVhZGVyQnl0ZXMgPSBudWxsOworCisgICAgc3RhdGljIGNsYXNzIEZsYWdzIHsKKyAgICAgICAgc3RhdGljIGZpbmFsIGludCBHQVJCTEVEID0gMHgwMTsKKyAgICAgICAgc3RhdGljIGZpbmFsIGludCBPTERfU0VDVVJFRF9ORVdfQU5TSV9QQUdFID0gMHgwMjsKKyAgICAgICAgc3RhdGljIGZpbmFsIGludCBWT0xVTUUgPSAweDA0OworICAgICAgICBzdGF0aWMgZmluYWwgaW50IEFSSlBST1QgPSAweDA4OworICAgICAgICBzdGF0aWMgZmluYWwgaW50IFBBVEhTWU0gPSAweDEwOworICAgICAgICBzdGF0aWMgZmluYWwgaW50IEJBQ0tVUCA9IDB4MjA7CisgICAgICAgIHN0YXRpYyBmaW5hbCBpbnQgU0VDVVJFRCA9IDB4NDA7CisgICAgICAgIHN0YXRpYyBmaW5hbCBpbnQgQUxUTkFNRSA9IDB4ODA7CisgICAgfQorCisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICBmaW5hbCBTdHJpbmdCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICBidWlsZGVyLmFwcGVuZCgiTWFpbkhlYWRlciBbYXJjaGl2ZXJWZXJzaW9uTnVtYmVyPSIpOworICAgICAgICBidWlsZGVyLmFwcGVuZChhcmNoaXZlclZlcnNpb25OdW1iZXIpOworICAgICAgICBidWlsZGVyLmFwcGVuZCgiLCBtaW5WZXJzaW9uVG9FeHRyYWN0PSIpOworICAgICAgICBidWlsZGVyLmFwcGVuZChtaW5WZXJzaW9uVG9FeHRyYWN0KTsKKyAgICAgICAgYnVpbGRlci5hcHBlbmQoIiwgaG9zdE9TPSIpOworICAgICAgICBidWlsZGVyLmFwcGVuZChob3N0T1MpOworICAgICAgICBidWlsZGVyLmFwcGVuZCgiLCBhcmpGbGFncz0iKTsKKyAgICAgICAgYnVpbGRlci5hcHBlbmQoYXJqRmxhZ3MpOworICAgICAgICBidWlsZGVyLmFwcGVuZCgiLCBzZWN1cml0eVZlcnNpb249Iik7CisgICAgICAgIGJ1aWxkZXIuYXBwZW5kKHNlY3VyaXR5VmVyc2lvbik7CisgICAgICAgIGJ1aWxkZXIuYXBwZW5kKCIsIGZpbGVUeXBlPSIpOworICAgICAgICBidWlsZGVyLmFwcGVuZChmaWxlVHlwZSk7CisgICAgICAgIGJ1aWxkZXIuYXBwZW5kKCIsIHJlc2VydmVkPSIpOworICAgICAgICBidWlsZGVyLmFwcGVuZChyZXNlcnZlZCk7CisgICAgICAgIGJ1aWxkZXIuYXBwZW5kKCIsIGRhdGVUaW1lQ3JlYXRlZD0iKTsKKyAgICAgICAgYnVpbGRlci5hcHBlbmQoZGF0ZVRpbWVDcmVhdGVkKTsKKyAgICAgICAgYnVpbGRlci5hcHBlbmQoIiwgZGF0ZVRpbWVNb2RpZmllZD0iKTsKKyAgICAgICAgYnVpbGRlci5hcHBlbmQoZGF0ZVRpbWVNb2RpZmllZCk7CisgICAgICAgIGJ1aWxkZXIuYXBwZW5kKCIsIGFyY2hpdmVTaXplPSIpOworICAgICAgICBidWlsZGVyLmFwcGVuZChhcmNoaXZlU2l6ZSk7CisgICAgICAgIGJ1aWxkZXIuYXBwZW5kKCIsIHNlY3VyaXR5RW52ZWxvcGVGaWxlUG9zaXRpb249Iik7CisgICAgICAgIGJ1aWxkZXIuYXBwZW5kKHNlY3VyaXR5RW52ZWxvcGVGaWxlUG9zaXRpb24pOworICAgICAgICBidWlsZGVyLmFwcGVuZCgiLCBmaWxlU3BlY1Bvc2l0aW9uPSIpOworICAgICAgICBidWlsZGVyLmFwcGVuZChmaWxlU3BlY1Bvc2l0aW9uKTsKKyAgICAgICAgYnVpbGRlci5hcHBlbmQoIiwgc2VjdXJpdHlFbnZlbG9wZUxlbmd0aD0iKTsKKyAgICAgICAgYnVpbGRlci5hcHBlbmQoc2VjdXJpdHlFbnZlbG9wZUxlbmd0aCk7CisgICAgICAgIGJ1aWxkZXIuYXBwZW5kKCIsIGVuY3J5cHRpb25WZXJzaW9uPSIpOworICAgICAgICBidWlsZGVyLmFwcGVuZChlbmNyeXB0aW9uVmVyc2lvbik7CisgICAgICAgIGJ1aWxkZXIuYXBwZW5kKCIsIGxhc3RDaGFwdGVyPSIpOworICAgICAgICBidWlsZGVyLmFwcGVuZChsYXN0Q2hhcHRlcik7CisgICAgICAgIGJ1aWxkZXIuYXBwZW5kKCIsIGFyalByb3RlY3Rpb25GYWN0b3I9Iik7CisgICAgICAgIGJ1aWxkZXIuYXBwZW5kKGFyalByb3RlY3Rpb25GYWN0b3IpOworICAgICAgICBidWlsZGVyLmFwcGVuZCgiLCBhcmpGbGFnczI9Iik7CisgICAgICAgIGJ1aWxkZXIuYXBwZW5kKGFyakZsYWdzMik7CisgICAgICAgIGJ1aWxkZXIuYXBwZW5kKCIsIG5hbWU9Iik7CisgICAgICAgIGJ1aWxkZXIuYXBwZW5kKG5hbWUpOworICAgICAgICBidWlsZGVyLmFwcGVuZCgiLCBjb21tZW50PSIpOworICAgICAgICBidWlsZGVyLmFwcGVuZChjb21tZW50KTsKKyAgICAgICAgYnVpbGRlci5hcHBlbmQoIiwgZXh0ZW5kZWRIZWFkZXJCeXRlcz0iKTsKKyAgICAgICAgYnVpbGRlci5hcHBlbmQoQXJyYXlzLnRvU3RyaW5nKGV4dGVuZGVkSGVhZGVyQnl0ZXMpKTsKKyAgICAgICAgYnVpbGRlci5hcHBlbmQoIl0iKTsKKyAgICAgICAgcmV0dXJuIGJ1aWxkZXIudG9TdHJpbmcoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvYXJqL3BhY2thZ2UuaHRtbCBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9hcmovcGFja2FnZS5odG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRlMThmNjEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvYXJqL3BhY2thZ2UuaHRtbApAQCAtMCwwICsxLDI0IEBACis8aHRtbD4KKzwhLS0KKworICAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAgIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAgIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKworICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorCisgICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKworLS0+CisgIDxib2R5PgorICAgIDxwPlByb3ZpZGVzIHN0cmVhbSBjbGFzc2VzIGZvciByZWFkaW5nIGFyY2hpdmVzIHVzaW5nCisgICAgICB0aGUgQVJKIGZvcm1hdC48L3A+CisgIDwvYm9keT4KKzwvaHRtbD4KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9jcGlvL0NwaW9BcmNoaXZlRW50cnkuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9jcGlvL0NwaW9BcmNoaXZlRW50cnkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43OWU3NTQyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2NwaW8vQ3Bpb0FyY2hpdmVFbnRyeS5qYXZhCkBAIC0wLDAgKzEsOTMzIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5jcGlvOworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldDsKK2ltcG9ydCBqYXZhLnV0aWwuRGF0ZTsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZUVudHJ5OworCisvKioKKyAqIEEgY3BpbyBhcmNoaXZlIGNvbnNpc3RzIG9mIGEgc2VxdWVuY2Ugb2YgZmlsZXMuIFRoZXJlIGFyZSBzZXZlcmFsIHR5cGVzIG9mCisgKiBoZWFkZXJzIGRlZmlkZWQgaW4gdHdvIGNhdGVnb3JpZXMgb2YgbmV3IGFuZCBvbGQgZm9ybWF0LiBUaGUgaGVhZGVycyBhcmUKKyAqIHJlY29nbml6ZWQgYnkgbWFnaWMgbnVtYmVyczoKKyAqCisgKiA8dWw+CisgKiA8bGk+IjA3MDcwMSIgQVNDSUkgZm9yIG5ldyBwb3J0YWJsZSBmb3JtYXQ8L2xpPgorICogPGxpPiIwNzA3MDIiIEFTQ0lJIGZvciBuZXcgcG9ydGFibGUgZm9ybWF0IHdpdGggQ1JDPC9saT4KKyAqIDxsaT4iMDcwNzA3IiBBU0NJSSBmb3Igb2xkIGFzY2lpIChhbHNvIGtub3duIGFzIFBvcnRhYmxlIEFTQ0lJLCBvZGMgb3Igb2xkCisgKiBjaGFyYWN0ZXIgZm9ybWF0PC9saT4KKyAqIDxsaT4wNzA3MDcgYmluYXJ5IGZvciBvbGQgYmluYXJ5PC9saT4KKyAqIDwvdWw+CisgKgorICogPHA+VGhlIG9sZCBiaW5hcnkgZm9ybWF0IGlzIGxpbWl0ZWQgdG8gMTYgYml0cyBmb3IgdXNlciBpZCwgZ3JvdXAKKyAqIGlkLCBkZXZpY2UsIGFuZCBpbm9kZSBudW1iZXJzLiBJdCBpcyBsaW1pdGVkIHRvIDQgZ2lnYWJ5dGUgZmlsZQorICogc2l6ZXMuCisgKgorICogVGhlIG9sZCBBU0NJSSBmb3JtYXQgaXMgbGltaXRlZCB0byAxOCBiaXRzIGZvciB0aGUgdXNlciBpZCwgZ3JvdXAKKyAqIGlkLCBkZXZpY2UsIGFuZCBpbm9kZSBudW1iZXJzLiBJdCBpcyBsaW1pdGVkIHRvIDggZ2lnYWJ5dGUgZmlsZQorICogc2l6ZXMuCisgKgorICogVGhlIG5ldyBBU0NJSSBmb3JtYXQgaXMgbGltaXRlZCB0byA0IGdpZ2FieXRlIGZpbGUgc2l6ZXMuCisgKgorICogQ1BJTyAyLjUga25vd3MgYWxzbyBhYm91dCB0YXIsIGJ1dCBpdCBpcyBub3QgcmVjb2duaXplZCBoZXJlLjwvcD4KKyAqCisgKgorICogPGgzPk9MRCBGT1JNQVQ8L2gzPgorICoKKyAqIDxwPkVhY2ggZmlsZSBoYXMgYSA3NiAoYXNjaWkpIC8gMjYgKGJpbmFyeSkgYnl0ZSBoZWFkZXIsIGEgdmFyaWFibGUKKyAqIGxlbmd0aCwgTlVMIHRlcm1pbmF0ZWQgZmlsZW5hbWUsIGFuZCB2YXJpYWJsZSBsZW5ndGggZmlsZSBkYXRhLiBBCisgKiBoZWFkZXIgZm9yIGEgZmlsZW5hbWUgIlRSQUlMRVIhISEiIGluZGljYXRlcyB0aGUgZW5kIG9mIHRoZQorICogYXJjaGl2ZS48L3A+CisgKgorICogPHA+QWxsIHRoZSBmaWVsZHMgaW4gdGhlIGhlYWRlciBhcmUgSVNPIDY0NiAoYXBwcm94aW1hdGVseSBBU0NJSSkKKyAqIHN0cmluZ3Mgb2Ygb2N0YWwgbnVtYmVycywgbGVmdCBwYWRkZWQsIG5vdCBOVUwgdGVybWluYXRlZC48L3A+CisgKgorICogPHByZT4KKyAqIEZJRUxETkFNRSAgICAgICAgTk9URVMKKyAqIGNfbWFnaWMgICAgICAgICAgVGhlIGludGVnZXIgdmFsdWUgb2N0YWwgMDcwNzA3LiAgVGhpcyB2YWx1ZSBjYW4gYmUgdXNlZCB0byBkZXRlci0KKyAqICAgICAgICAgICAgICAgICAgbWluZSB3aGV0aGVyIHRoaXMgYXJjaGl2ZSBpcyB3cml0dGVuIHdpdGggbGl0dGxlLWVuZGlhbiBvciBiaWctCisgKiAgICAgICAgICAgICAgICAgIGVuZGlhbiBpbnRlZ2Vycy4KKyAqIGNfZGV2ICAgICAgICAgICAgRGV2aWNlIHRoYXQgY29udGFpbnMgYSBkaXJlY3RvcnkgZW50cnkgZm9yIHRoaXMgZmlsZQorICogY19pbm8gICAgICAgICAgICBJLW5vZGUgbnVtYmVyIHRoYXQgaWRlbnRpZmllcyB0aGUgaW5wdXQgZmlsZSB0byB0aGUgZmlsZSBzeXN0ZW0KKyAqIGNfbW9kZSAgICAgICAgICAgVGhlIG1vZGUgc3BlY2lmaWVzIGJvdGggdGhlIHJlZ3VsYXIgcGVybWlzc2lvbnMgYW5kIHRoZSBmaWxlIHR5cGUuCisgKiBjX3VpZCAgICAgICAgICAgIE51bWVyaWMgVXNlciBJRCBvZiB0aGUgb3duZXIgb2YgdGhlIGlucHV0IGZpbGUKKyAqIGNfZ2lkICAgICAgICAgICAgTnVtZXJpYyBHcm91cCBJRCBvZiB0aGUgb3duZXIgb2YgdGhlIGlucHV0IGZpbGUKKyAqIGNfbmxpbmsgICAgICAgICAgTnVtYmVyIG9mIGxpbmtzIHRoYXQgYXJlIGNvbm5lY3RlZCB0byB0aGUgaW5wdXQgZmlsZQorICogY19yZGV2ICAgICAgICAgICBGb3IgYmxvY2sgc3BlY2lhbCBhbmQgY2hhcmFjdGVyIHNwZWNpYWwgZW50cmllcywgdGhpcyBmaWVsZAorICogICAgICAgICAgICAgICAgICBjb250YWlucyB0aGUgYXNzb2NpYXRlZCBkZXZpY2UgbnVtYmVyLiAgRm9yIGFsbCBvdGhlciBlbnRyeSB0eXBlcywKKyAqICAgICAgICAgICAgICAgICAgaXQgc2hvdWxkIGJlIHNldCB0byB6ZXJvIGJ5IHdyaXRlcnMgYW5kIGlnbm9yZWQgYnkgcmVhZGVycy4KKyAqIGNfbXRpbWVbMl0gICAgICAgTW9kaWZpY2F0aW9uIHRpbWUgb2YgdGhlIGZpbGUsIGluZGljYXRlZCBhcyB0aGUgbnVtYmVyIG9mIHNlY29uZHMKKyAqICAgICAgICAgICAgICAgICAgc2luY2UgdGhlIHN0YXJ0IG9mIHRoZSBlcG9jaCwgMDA6MDA6MDAgVVRDIEphbnVhcnkgMSwgMTk3MC4gIFRoZQorICogICAgICAgICAgICAgICAgICBmb3VyLWJ5dGUgaW50ZWdlciBpcyBzdG9yZWQgd2l0aCB0aGUgbW9zdC1zaWduaWZpY2FudCAxNiBiaXRzCisgKiAgICAgICAgICAgICAgICAgIGZpcnN0IGZvbGxvd2VkIGJ5IHRoZSBsZWFzdC1zaWduaWZpY2FudCAxNiBiaXRzLiAgRWFjaCBvZiB0aGUgdHdvCisgKiAgICAgICAgICAgICAgICAgIDE2IGJpdCB2YWx1ZXMgYXJlIHN0b3JlZCBpbiBtYWNoaW5lLW5hdGl2ZSBieXRlIG9yZGVyLgorICogY19uYW1lc2l6ZSAgICAgICBMZW5ndGggb2YgdGhlIHBhdGggbmFtZSwgaW5jbHVkaW5nIHRoZSB0ZXJtaW5hdGluZyBudWxsIGJ5dGUKKyAqIGNfZmlsZXNpemVbMl0gICAgTGVuZ3RoIG9mIHRoZSBmaWxlIGluIGJ5dGVzLiBUaGlzIGlzIHRoZSBsZW5ndGggb2YgdGhlIGRhdGEKKyAqICAgICAgICAgICAgICAgICAgc2VjdGlvbiB0aGF0IGZvbGxvd3MgdGhlIGhlYWRlciBzdHJ1Y3R1cmUuIE11c3QgYmUgMCBmb3IKKyAqICAgICAgICAgICAgICAgICAgRklGT3MgYW5kIGRpcmVjdG9yaWVzCisgKgorICogQWxsIGZpZWxkcyBhcmUgdW5zaWduZWQgc2hvcnQgZmllbGRzIHdpdGggMTYtYml0IGludGVnZXIgdmFsdWVzCisgKiBhcGFydCBmcm9tIGNfbXRpbWUgYW5kIGNfZmlsZXNpemUgd2hpY2ggYXJlIDMyLWJpdCBpbnRlZ2VyIHZhbHVlcworICogPC9wcmU+CisgKgorICogPHA+SWYgbmVjZXNzYXJ5LCB0aGUgZmlsZW5hbWUgYW5kIGZpbGUgZGF0YSBhcmUgcGFkZGVkIHdpdGggYSBOVUwgYnl0ZSB0byBhbiBldmVuIGxlbmd0aDwvcD4KKyAqCisgKiA8cD5TcGVjaWFsIGZpbGVzLCBkaXJlY3RvcmllcywgYW5kIHRoZSB0cmFpbGVyIGFyZSByZWNvcmRlZCB3aXRoCisgKiB0aGUgaF9maWxlc2l6ZSBmaWVsZCBlcXVhbCB0byAwLjwvcD4KKyAqCisgKiA8cD5JbiB0aGUgQVNDSUkgdmVyc2lvbiBvZiB0aGlzIGZvcm1hdCwgdGhlIDE2LWJpdCBlbnRyaWVzIGFyZSByZXByZXNlbnRlZCBhcyA2LWJ5dGUgb2N0YWwgbnVtYmVycywKKyAqIGFuZCB0aGUgMzItYml0IGVudHJpZXMgYXJlIHJlcHJlc2VudGVkIGFzIDExLWJ5dGUgb2N0YWwgbnVtYmVycy4gTm8gcGFkZGluZyBpcyBhZGRlZC48L3A+CisgKgorICogPGgzPk5FVyBGT1JNQVQ8L2gzPgorICoKKyAqIDxwPkVhY2ggZmlsZSBoYXMgYSAxMTAgYnl0ZSBoZWFkZXIsIGEgdmFyaWFibGUgbGVuZ3RoLCBOVUwKKyAqIHRlcm1pbmF0ZWQgZmlsZW5hbWUsIGFuZCB2YXJpYWJsZSBsZW5ndGggZmlsZSBkYXRhLiBBIGhlYWRlciBmb3IgYQorICogZmlsZW5hbWUgIlRSQUlMRVIhISEiIGluZGljYXRlcyB0aGUgZW5kIG9mIHRoZSBhcmNoaXZlLiBBbGwgdGhlCisgKiBmaWVsZHMgaW4gdGhlIGhlYWRlciBhcmUgSVNPIDY0NiAoYXBwcm94aW1hdGVseSBBU0NJSSkgc3RyaW5ncyBvZgorICogaGV4YWRlY2ltYWwgbnVtYmVycywgbGVmdCBwYWRkZWQsIG5vdCBOVUwgdGVybWluYXRlZC48L3A+CisgKgorICogPHByZT4KKyAqIEZJRUxETkFNRSAgICAgICAgTk9URVMKKyAqIGNfbWFnaWNbNl0gICAgICAgVGhlIHN0cmluZyAwNzA3MDEgZm9yIG5ldyBBU0NJSSwgdGhlIHN0cmluZyAwNzA3MDIgZm9yIG5ldyBBU0NJSSB3aXRoIENSQworICogY19pbm9bOF0KKyAqIGNfbW9kZVs4XQorICogY191aWRbOF0KKyAqIGNfZ2lkWzhdCisgKiBjX25saW5rWzhdCisgKiBjX210aW1bOF0KKyAqIGNfZmlsZXNpemVbOF0gICAgbXVzdCBiZSAwIGZvciBGSUZPcyBhbmQgZGlyZWN0b3JpZXMKKyAqIGNfbWFqWzhdCisgKiBjX21pbls4XQorICogY19ybWFqWzhdICAgICAgICBvbmx5IHZhbGlkIGZvciBjaHIgYW5kIGJsayBzcGVjaWFsIGZpbGVzCisgKiBjX3JtaW5bOF0gICAgICAgIG9ubHkgdmFsaWQgZm9yIGNociBhbmQgYmxrIHNwZWNpYWwgZmlsZXMKKyAqIGNfbmFtZXNpemVbOF0gICAgY291bnQgaW5jbHVkZXMgdGVybWluYXRpbmcgTlVMIGluIHBhdGhuYW1lCisgKiBjX2NoZWNrWzhdICAgICAgIDAgZm9yICJuZXciIHBvcnRhYmxlIGZvcm1hdDsgZm9yIENSQyBmb3JtYXQKKyAqICAgICAgICAgICAgICAgICAgdGhlIHN1bSBvZiBhbGwgdGhlIGJ5dGVzIGluIHRoZSBmaWxlCisgKiA8L3ByZT4KKyAqCisgKiA8cD5OZXcgQVNDSUkgRm9ybWF0IFRoZSAibmV3IiBBU0NJSSBmb3JtYXQgdXNlcyA4LWJ5dGUgaGV4YWRlY2ltYWwKKyAqIGZpZWxkcyBmb3IgYWxsIG51bWJlcnMgYW5kIHNlcGFyYXRlcyBkZXZpY2UgbnVtYmVycyBpbnRvIHNlcGFyYXRlCisgKiBmaWVsZHMgZm9yIG1ham9yIGFuZCBtaW5vciBudW1iZXJzLjwvcD4KKyAqCisgKiA8cD5UaGUgcGF0aG5hbWUgaXMgZm9sbG93ZWQgYnkgTlVMIGJ5dGVzIHNvIHRoYXQgdGhlIHRvdGFsIHNpemUgb2YKKyAqIHRoZSBmaXhlZCBoZWFkZXIgcGx1cyBwYXRobmFtZSBpcyBhIG11bHRpcGxlIG9mIGZvdXIuIExpa2V3aXNlLCB0aGUKKyAqIGZpbGUgZGF0YSBpcyBwYWRkZWQgdG8gYSBtdWx0aXBsZSBvZiBmb3VyIGJ5dGVzLjwvcD4KKyAqCisgKiA8cD5UaGlzIGNsYXNzIHVzZXMgbXV0YWJsZSBmaWVsZHMgYW5kIGlzIG5vdCBjb25zaWRlcmVkIHRvIGJlCisgKiB0aHJlYWRzYWZlLjwvcD4KKyAqCisgKiA8cD5CYXNlZCBvbiBjb2RlIGZyb20gdGhlIGpSUE0gcHJvamVjdCAoaHR0cDovL2pycG0uc291cmNlZm9yZ2UubmV0KS48L3A+CisgKgorICogPHA+VGhlIE1BR0lDIG51bWJlcnMgYW5kIG90aGVyIGNvbnN0YW50cyBhcmUgZGVmaW5lZCBpbiB7QGxpbmsgQ3Bpb0NvbnN0YW50c308L3A+CisgKgorICogPHA+CisgKiBOLkIuIGRvZXMgbm90IGhhbmRsZSB0aGUgY3BpbyAidGFyIiBmb3JtYXQKKyAqIDwvcD4KKyAqIEBOb3RUaHJlYWRTYWZlCisgKiBAc2VlIDxhIGhyZWY9Imh0dHBzOi8vcGVvcGxlLmZyZWVic2Qub3JnL35raWVudHpsZS9saWJhcmNoaXZlL21hbi9jcGlvLjUudHh0Ij5odHRwczovL3Blb3BsZS5mcmVlYnNkLm9yZy9+a2llbnR6bGUvbGliYXJjaGl2ZS9tYW4vY3Bpby41LnR4dDwvYT4KKyAqLworcHVibGljIGNsYXNzIENwaW9BcmNoaXZlRW50cnkgaW1wbGVtZW50cyBDcGlvQ29uc3RhbnRzLCBBcmNoaXZlRW50cnkgeworCisgICAgLy8gSGVhZGVyIGRlc2NyaXB0aW9uIGZpZWxkcyAtIHNob3VsZCBiZSBzYW1lIHRocm91Z2hvdXQgYW4gYXJjaGl2ZQorCisgICAgLyoqCisgICAgICogU2VlIGNvbnN0cnVjdG9yIGRvY3VtZW5hdGlvbiBmb3IgcG9zc2libGUgdmFsdWVzLgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgc2hvcnQgZmlsZUZvcm1hdDsKKworICAgIC8qKiBUaGUgbnVtYmVyIG9mIGJ5dGVzIGluIGVhY2ggaGVhZGVyIHJlY29yZDsgZGVwZW5kcyBvbiB0aGUgZmlsZSBmb3JtYXQgKi8KKyAgICBwcml2YXRlIGZpbmFsIGludCBoZWFkZXJTaXplOworCisgICAgLyoqIFRoZSBib3VuZGFyeSB0byB3aGljaCB0aGUgaGVhZGVyIGFuZCBkYXRhIGVsZW1lbnRzIGFyZSBhbGlnbmVkOiAwLCAyIG9yIDQgYnl0ZXMgKi8KKyAgICBwcml2YXRlIGZpbmFsIGludCBhbGlnbm1lbnRCb3VuZGFyeTsKKworICAgIC8vIEhlYWRlciBmaWVsZHMKKworICAgIHByaXZhdGUgbG9uZyBjaGtzdW0gPSAwOworCisgICAgLyoqIE51bWJlciBvZiBieXRlcyBpbiB0aGUgZmlsZSAqLworICAgIHByaXZhdGUgbG9uZyBmaWxlc2l6ZSA9IDA7CisKKyAgICBwcml2YXRlIGxvbmcgZ2lkID0gMDsKKworICAgIHByaXZhdGUgbG9uZyBpbm9kZSA9IDA7CisKKyAgICBwcml2YXRlIGxvbmcgbWFqID0gMDsKKworICAgIHByaXZhdGUgbG9uZyBtaW4gPSAwOworCisgICAgcHJpdmF0ZSBsb25nIG1vZGUgPSAwOworCisgICAgcHJpdmF0ZSBsb25nIG10aW1lID0gMDsKKworICAgIHByaXZhdGUgU3RyaW5nIG5hbWU7CisKKyAgICBwcml2YXRlIGxvbmcgbmxpbmsgPSAwOworCisgICAgcHJpdmF0ZSBsb25nIHJtYWogPSAwOworCisgICAgcHJpdmF0ZSBsb25nIHJtaW4gPSAwOworCisgICAgcHJpdmF0ZSBsb25nIHVpZCA9IDA7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgQ3Bpb0FyY2hpdmVFbnRyeSB3aXRoIGEgc3BlY2lmaWVkIGZvcm1hdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmb3JtYXQKKyAgICAgKiAgICAgICAgICAgIFRoZSBjcGlvIGZvcm1hdCBmb3IgdGhpcyBlbnRyeS4KKyAgICAgKiA8cD4KKyAgICAgKiBQb3NzaWJsZSBmb3JtYXQgdmFsdWVzIGFyZToKKyAgICAgKiA8cHJlPgorICAgICAqIENwaW9Db25zdGFudHMuRk9STUFUX05FVworICAgICAqIENwaW9Db25zdGFudHMuRk9STUFUX05FV19DUkMKKyAgICAgKiBDcGlvQ29uc3RhbnRzLkZPUk1BVF9PTERfQklOQVJZCisgICAgICogQ3Bpb0NvbnN0YW50cy5GT1JNQVRfT0xEX0FTQ0lJCisgICAgICogPC9wcmU+CisgICAgICovCisgICAgcHVibGljIENwaW9BcmNoaXZlRW50cnkoZmluYWwgc2hvcnQgZm9ybWF0KSB7CisgICAgICAgIHN3aXRjaCAoZm9ybWF0KSB7CisgICAgICAgIGNhc2UgRk9STUFUX05FVzoKKyAgICAgICAgICAgIHRoaXMuaGVhZGVyU2l6ZSA9IDExMDsKKyAgICAgICAgICAgIHRoaXMuYWxpZ25tZW50Qm91bmRhcnkgPSA0OworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgRk9STUFUX05FV19DUkM6CisgICAgICAgICAgICB0aGlzLmhlYWRlclNpemUgPSAxMTA7CisgICAgICAgICAgICB0aGlzLmFsaWdubWVudEJvdW5kYXJ5ID0gNDsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIEZPUk1BVF9PTERfQVNDSUk6CisgICAgICAgICAgICB0aGlzLmhlYWRlclNpemUgPSA3NjsKKyAgICAgICAgICAgIHRoaXMuYWxpZ25tZW50Qm91bmRhcnkgPSAwOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgRk9STUFUX09MRF9CSU5BUlk6CisgICAgICAgICAgICB0aGlzLmhlYWRlclNpemUgPSAyNjsKKyAgICAgICAgICAgIHRoaXMuYWxpZ25tZW50Qm91bmRhcnkgPSAyOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJVbmtub3duIGhlYWRlciB0eXBlIik7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5maWxlRm9ybWF0ID0gZm9ybWF0OworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBDcGlvQXJjaGl2ZUVudHJ5IHdpdGggYSBzcGVjaWZpZWQgbmFtZS4gVGhlIGZvcm1hdCBvZgorICAgICAqIHRoaXMgZW50cnkgd2lsbCBiZSB0aGUgbmV3IGZvcm1hdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICBUaGUgbmFtZSBvZiB0aGlzIGVudHJ5LgorICAgICAqLworICAgIHB1YmxpYyBDcGlvQXJjaGl2ZUVudHJ5KGZpbmFsIFN0cmluZyBuYW1lKSB7CisgICAgICAgIHRoaXMoRk9STUFUX05FVywgbmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIENwaW9BcmNoaXZlRW50cnkgd2l0aCBhIHNwZWNpZmllZCBuYW1lLgorICAgICAqCisgICAgICogQHBhcmFtIGZvcm1hdAorICAgICAqICAgICAgICAgICAgVGhlIGNwaW8gZm9ybWF0IGZvciB0aGlzIGVudHJ5LgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICBUaGUgbmFtZSBvZiB0aGlzIGVudHJ5LgorICAgICAqIDxwPgorICAgICAqIFBvc3NpYmxlIGZvcm1hdCB2YWx1ZXMgYXJlOgorICAgICAqIDxwcmU+CisgICAgICogQ3Bpb0NvbnN0YW50cy5GT1JNQVRfTkVXCisgICAgICogQ3Bpb0NvbnN0YW50cy5GT1JNQVRfTkVXX0NSQworICAgICAqIENwaW9Db25zdGFudHMuRk9STUFUX09MRF9CSU5BUlkKKyAgICAgKiBDcGlvQ29uc3RhbnRzLkZPUk1BVF9PTERfQVNDSUkKKyAgICAgKiA8L3ByZT4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjEKKyAgICAgKi8KKyAgICBwdWJsaWMgQ3Bpb0FyY2hpdmVFbnRyeShmaW5hbCBzaG9ydCBmb3JtYXQsIGZpbmFsIFN0cmluZyBuYW1lKSB7CisgICAgICAgIHRoaXMoZm9ybWF0KTsKKyAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgQ3Bpb0FyY2hpdmVFbnRyeSB3aXRoIGEgc3BlY2lmaWVkIG5hbWUuIFRoZSBmb3JtYXQgb2YKKyAgICAgKiB0aGlzIGVudHJ5IHdpbGwgYmUgdGhlIG5ldyBmb3JtYXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgVGhlIG5hbWUgb2YgdGhpcyBlbnRyeS4KKyAgICAgKiBAcGFyYW0gc2l6ZQorICAgICAqICAgICAgICAgICAgVGhlIHNpemUgb2YgdGhpcyBlbnRyeQorICAgICAqLworICAgIHB1YmxpYyBDcGlvQXJjaGl2ZUVudHJ5KGZpbmFsIFN0cmluZyBuYW1lLCBmaW5hbCBsb25nIHNpemUpIHsKKyAgICAgICAgdGhpcyhuYW1lKTsKKyAgICAgICAgdGhpcy5zZXRTaXplKHNpemUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBDcGlvQXJjaGl2ZUVudHJ5IHdpdGggYSBzcGVjaWZpZWQgbmFtZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmb3JtYXQKKyAgICAgKiAgICAgICAgICAgIFRoZSBjcGlvIGZvcm1hdCBmb3IgdGhpcyBlbnRyeS4KKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgVGhlIG5hbWUgb2YgdGhpcyBlbnRyeS4KKyAgICAgKiBAcGFyYW0gc2l6ZQorICAgICAqICAgICAgICAgICAgVGhlIHNpemUgb2YgdGhpcyBlbnRyeQorICAgICAqIDxwPgorICAgICAqIFBvc3NpYmxlIGZvcm1hdCB2YWx1ZXMgYXJlOgorICAgICAqIDxwcmU+CisgICAgICogQ3Bpb0NvbnN0YW50cy5GT1JNQVRfTkVXCisgICAgICogQ3Bpb0NvbnN0YW50cy5GT1JNQVRfTkVXX0NSQworICAgICAqIENwaW9Db25zdGFudHMuRk9STUFUX09MRF9CSU5BUlkKKyAgICAgKiBDcGlvQ29uc3RhbnRzLkZPUk1BVF9PTERfQVNDSUkKKyAgICAgKiA8L3ByZT4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjEKKyAgICAgKi8KKyAgICBwdWJsaWMgQ3Bpb0FyY2hpdmVFbnRyeShmaW5hbCBzaG9ydCBmb3JtYXQsIGZpbmFsIFN0cmluZyBuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGxvbmcgc2l6ZSkgeworICAgICAgICB0aGlzKGZvcm1hdCwgbmFtZSk7CisgICAgICAgIHRoaXMuc2V0U2l6ZShzaXplKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgQ3Bpb0FyY2hpdmVFbnRyeSB3aXRoIGEgc3BlY2lmaWVkIG5hbWUgZm9yIGEKKyAgICAgKiBzcGVjaWZpZWQgZmlsZS4gVGhlIGZvcm1hdCBvZiB0aGlzIGVudHJ5IHdpbGwgYmUgdGhlIG5ldworICAgICAqIGZvcm1hdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbnB1dEZpbGUKKyAgICAgKiAgICAgICAgICAgIFRoZSBmaWxlIHRvIGdhdGhlciBpbmZvcm1hdGlvbiBmcm9tLgorICAgICAqIEBwYXJhbSBlbnRyeU5hbWUKKyAgICAgKiAgICAgICAgICAgIFRoZSBuYW1lIG9mIHRoaXMgZW50cnkuCisgICAgICovCisgICAgcHVibGljIENwaW9BcmNoaXZlRW50cnkoZmluYWwgRmlsZSBpbnB1dEZpbGUsIGZpbmFsIFN0cmluZyBlbnRyeU5hbWUpIHsKKyAgICAgICAgdGhpcyhGT1JNQVRfTkVXLCBpbnB1dEZpbGUsIGVudHJ5TmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIENwaW9BcmNoaXZlRW50cnkgd2l0aCBhIHNwZWNpZmllZCBuYW1lIGZvciBhCisgICAgICogc3BlY2lmaWVkIGZpbGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZm9ybWF0CisgICAgICogICAgICAgICAgICBUaGUgY3BpbyBmb3JtYXQgZm9yIHRoaXMgZW50cnkuCisgICAgICogQHBhcmFtIGlucHV0RmlsZQorICAgICAqICAgICAgICAgICAgVGhlIGZpbGUgdG8gZ2F0aGVyIGluZm9ybWF0aW9uIGZyb20uCisgICAgICogQHBhcmFtIGVudHJ5TmFtZQorICAgICAqICAgICAgICAgICAgVGhlIG5hbWUgb2YgdGhpcyBlbnRyeS4KKyAgICAgKiA8cD4KKyAgICAgKiBQb3NzaWJsZSBmb3JtYXQgdmFsdWVzIGFyZToKKyAgICAgKiA8cHJlPgorICAgICAqIENwaW9Db25zdGFudHMuRk9STUFUX05FVworICAgICAqIENwaW9Db25zdGFudHMuRk9STUFUX05FV19DUkMKKyAgICAgKiBDcGlvQ29uc3RhbnRzLkZPUk1BVF9PTERfQklOQVJZCisgICAgICogQ3Bpb0NvbnN0YW50cy5GT1JNQVRfT0xEX0FTQ0lJCisgICAgICogPC9wcmU+CisgICAgICoKKyAgICAgKiBAc2luY2UgMS4xCisgICAgICovCisgICAgcHVibGljIENwaW9BcmNoaXZlRW50cnkoZmluYWwgc2hvcnQgZm9ybWF0LCBmaW5hbCBGaWxlIGlucHV0RmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgZW50cnlOYW1lKSB7CisgICAgICAgIHRoaXMoZm9ybWF0LCBlbnRyeU5hbWUsIGlucHV0RmlsZS5pc0ZpbGUoKSA/IGlucHV0RmlsZS5sZW5ndGgoKSA6IDApOworICAgICAgICBpZiAoaW5wdXRGaWxlLmlzRGlyZWN0b3J5KCkpeworICAgICAgICAgICAgc2V0TW9kZShDX0lTRElSKTsKKyAgICAgICAgfSBlbHNlIGlmIChpbnB1dEZpbGUuaXNGaWxlKCkpeworICAgICAgICAgICAgc2V0TW9kZShDX0lTUkVHKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkNhbm5vdCBkZXRlcm1pbmUgdHlwZSBvZiBmaWxlICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBpbnB1dEZpbGUuZ2V0TmFtZSgpKTsKKyAgICAgICAgfQorICAgICAgICAvLyBUT0RPIHNldCBvdGhlciBmaWVsZHMgYXMgbmVlZGVkCisgICAgICAgIHNldFRpbWUoaW5wdXRGaWxlLmxhc3RNb2RpZmllZCgpIC8gMTAwMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2sgaWYgdGhlIG1ldGhvZCBpcyBhbGxvd2VkIGZvciB0aGUgZGVmaW5lZCBmb3JtYXQuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrTmV3Rm9ybWF0KCkgeworICAgICAgICBpZiAoKHRoaXMuZmlsZUZvcm1hdCAmIEZPUk1BVF9ORVdfTUFTSykgPT0gMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVjayBpZiB0aGUgbWV0aG9kIGlzIGFsbG93ZWQgZm9yIHRoZSBkZWZpbmVkIGZvcm1hdC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgY2hlY2tPbGRGb3JtYXQoKSB7CisgICAgICAgIGlmICgodGhpcy5maWxlRm9ybWF0ICYgRk9STUFUX09MRF9NQVNLKSA9PSAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgY2hlY2tzdW0uCisgICAgICogT25seSBzdXBwb3J0ZWQgZm9yIHRoZSBuZXcgZm9ybWF0cy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gUmV0dXJucyB0aGUgY2hlY2tzdW0uCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBpZiB0aGUgZm9ybWF0IGlzIG5vdCBhIG5ldyBmb3JtYXQKKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBnZXRDaGtzdW0oKSB7CisgICAgICAgIGNoZWNrTmV3Rm9ybWF0KCk7CisgICAgICAgIHJldHVybiB0aGlzLmNoa3N1bSAmIDB4RkZGRkZGRkZMOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgZGV2aWNlIGlkLgorICAgICAqCisgICAgICogQHJldHVybiBSZXR1cm5zIHRoZSBkZXZpY2UgaWQuCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgbWV0aG9kIGlzIGNhbGxlZCBmb3IgYSBDcGlvQXJjaGl2ZUVudHJ5IHdpdGggYSBuZXcKKyAgICAgKiAgICAgICAgICAgICBmb3JtYXQuCisgICAgICovCisgICAgcHVibGljIGxvbmcgZ2V0RGV2aWNlKCkgeworICAgICAgICBjaGVja09sZEZvcm1hdCgpOworICAgICAgICByZXR1cm4gdGhpcy5taW47CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBtYWpvciBkZXZpY2UgaWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFJldHVybnMgdGhlIG1ham9yIGRldmljZSBpZC4KKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBtZXRob2QgaXMgY2FsbGVkIGZvciBhIENwaW9BcmNoaXZlRW50cnkgd2l0aCBhbiBvbGQKKyAgICAgKiAgICAgICAgICAgICBmb3JtYXQuCisgICAgICovCisgICAgcHVibGljIGxvbmcgZ2V0RGV2aWNlTWFqKCkgeworICAgICAgICBjaGVja05ld0Zvcm1hdCgpOworICAgICAgICByZXR1cm4gdGhpcy5tYWo7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBtaW5vciBkZXZpY2UgaWQKKyAgICAgKgorICAgICAqIEByZXR1cm4gUmV0dXJucyB0aGUgbWlub3IgZGV2aWNlIGlkLgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gaWYgZm9ybWF0IGlzIG5vdCBhIG5ldyBmb3JtYXQKKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBnZXREZXZpY2VNaW4oKSB7CisgICAgICAgIGNoZWNrTmV3Rm9ybWF0KCk7CisgICAgICAgIHJldHVybiB0aGlzLm1pbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIGZpbGVzaXplLgorICAgICAqCisgICAgICogQHJldHVybiBSZXR1cm5zIHRoZSBmaWxlc2l6ZS4KKyAgICAgKiBAc2VlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZUVudHJ5I2dldFNpemUoKQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBsb25nIGdldFNpemUoKSB7CisgICAgICAgIHJldHVybiB0aGlzLmZpbGVzaXplOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgZm9ybWF0IGZvciB0aGlzIGVudHJ5LgorICAgICAqCisgICAgICogQHJldHVybiBSZXR1cm5zIHRoZSBmb3JtYXQuCisgICAgICovCisgICAgcHVibGljIHNob3J0IGdldEZvcm1hdCgpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMuZmlsZUZvcm1hdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIGdyb3VwIGlkLgorICAgICAqCisgICAgICogQHJldHVybiBSZXR1cm5zIHRoZSBncm91cCBpZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBnZXRHSUQoKSB7CisgICAgICAgIHJldHVybiB0aGlzLmdpZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIGhlYWRlciBzaXplIGZvciB0aGlzIENQSU8gZm9ybWF0CisgICAgICoKKyAgICAgKiBAcmV0dXJuIFJldHVybnMgdGhlIGhlYWRlciBzaXplIGluIGJ5dGVzLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0SGVhZGVyU2l6ZSgpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMuaGVhZGVyU2l6ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIGFsaWdubWVudCBib3VuZGFyeSBmb3IgdGhpcyBDUElPIGZvcm1hdAorICAgICAqCisgICAgICogQHJldHVybiBSZXR1cm5zIHRoZSBhbGlnbWVudCBib3VuZGFyeSAoMCwgMiwgNCkgaW4gYnl0ZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldEFsaWdubWVudEJvdW5kYXJ5KCkgeworICAgICAgICByZXR1cm4gdGhpcy5hbGlnbm1lbnRCb3VuZGFyeTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIG51bWJlciBvZiBieXRlcyBuZWVkZWQgdG8gcGFkIHRoZSBoZWFkZXIgdG8gdGhlIGFsaWdubWVudCBib3VuZGFyeS4KKyAgICAgKgorICAgICAqIEBkZXByZWNhdGVkIFRoaXMgbWV0aG9kIGRvZXNuJ3QgcHJvcGVybHkgd29yayBmb3IgbXVsdGktYnl0ZSBlbmNvZGluZ3MuIEFuZAorICAgICAqICAgICAgICAgICAgIGNyZWF0ZXMgY29ycnVwdCBhcmNoaXZlcy4gVXNlIHtAbGluayAjZ2V0SGVhZGVyUGFkQ291bnQoQ2hhcnNldCl9CisgICAgICogICAgICAgICAgICAgb3Ige0BsaW5rICNnZXRIZWFkZXJQYWRDb3VudChsb25nKX0gaW4gYW55IGNhc2UuCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGJ5dGVzIG5lZWRlZCB0byBwYWQgdGhlIGhlYWRlciAoMCwxLDIsMykKKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBpbnQgZ2V0SGVhZGVyUGFkQ291bnQoKXsKKyAgICAgICAgcmV0dXJuIGdldEhlYWRlclBhZENvdW50KG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgbnVtYmVyIG9mIGJ5dGVzIG5lZWRlZCB0byBwYWQgdGhlIGhlYWRlciB0byB0aGUgYWxpZ25tZW50IGJvdW5kYXJ5LgorICAgICAqCisgICAgICogQHBhcmFtIGNoYXJzZXQKKyAgICAgKiAgICAgICAgICAgICBUaGUgY2hhcmFjdGVyIHNldCB1c2VkIHRvIGVuY29kZSB0aGUgZW50cnkgbmFtZSBpbiB0aGUgc3RyZWFtLgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyBuZWVkZWQgdG8gcGFkIHRoZSBoZWFkZXIgKDAsMSwyLDMpCisgICAgICogQHNpbmNlIDEuMTgKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldEhlYWRlclBhZENvdW50KENoYXJzZXQgY2hhcnNldCkgeworICAgICAgICBpZiAobmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorICAgICAgICBpZiAoY2hhcnNldCA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gZ2V0SGVhZGVyUGFkQ291bnQobmFtZS5sZW5ndGgoKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGdldEhlYWRlclBhZENvdW50KG5hbWUuZ2V0Qnl0ZXMoY2hhcnNldCkubGVuZ3RoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIG51bWJlciBvZiBieXRlcyBuZWVkZWQgdG8gcGFkIHRoZSBoZWFkZXIgdG8gdGhlIGFsaWdubWVudCBib3VuZGFyeS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lc2l6ZQorICAgICAqICAgICAgICAgICAgVGhlIGxlbmd0aCBvZiB0aGUgbmFtZSBpbiBieXRlcywgYXMgcmVhZCBpbiB0aGUgc3RyZWFtLgorICAgICAqICAgICAgICAgICAgV2l0aG91dCB0aGUgdHJhaWxpbmcgemVybyBieXRlLgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyBuZWVkZWQgdG8gcGFkIHRoZSBoZWFkZXIgKDAsMSwyLDMpCisgICAgICoKKyAgICAgKiBAc2luY2UgMS4xOAorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0SGVhZGVyUGFkQ291bnQobG9uZyBuYW1lc2l6ZSkgeworICAgICAgICBpZiAodGhpcy5hbGlnbm1lbnRCb3VuZGFyeSA9PSAwKSB7IHJldHVybiAwOyB9CisgICAgICAgIGludCBzaXplID0gdGhpcy5oZWFkZXJTaXplICsgMTsgIC8vIE5hbWUgaGFzIHRlcm1pbmF0aW5nIG51bGwKKyAgICAgICAgaWYgKG5hbWUgIT0gbnVsbCkgeworICAgICAgICAgICAgc2l6ZSArPSBuYW1lc2l6ZTsKKyAgICAgICAgfQorICAgICAgICBmaW5hbCBpbnQgcmVtYWluID0gc2l6ZSAlIHRoaXMuYWxpZ25tZW50Qm91bmRhcnk7CisgICAgICAgIGlmIChyZW1haW4gPiAwKSB7CisgICAgICAgICAgICByZXR1cm4gdGhpcy5hbGlnbm1lbnRCb3VuZGFyeSAtIHJlbWFpbjsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIG51bWJlciBvZiBieXRlcyBuZWVkZWQgdG8gcGFkIHRoZSBkYXRhIHRvIHRoZSBhbGlnbm1lbnQgYm91bmRhcnkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgbmVlZGVkIHRvIHBhZCB0aGUgZGF0YSAoMCwxLDIsMykKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldERhdGFQYWRDb3VudCgpeworICAgICAgICBpZiAodGhpcy5hbGlnbm1lbnRCb3VuZGFyeSA9PSAwKSB7IHJldHVybiAwOyB9CisgICAgICAgIGZpbmFsIGxvbmcgc2l6ZSA9IHRoaXMuZmlsZXNpemU7CisgICAgICAgIGZpbmFsIGludCByZW1haW4gPSAoaW50KSAoc2l6ZSAlIHRoaXMuYWxpZ25tZW50Qm91bmRhcnkpOworICAgICAgICBpZiAocmVtYWluID4gMCl7CisgICAgICAgICAgICByZXR1cm4gdGhpcy5hbGlnbm1lbnRCb3VuZGFyeSAtIHJlbWFpbjsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIGlub2RlLgorICAgICAqCisgICAgICogQHJldHVybiBSZXR1cm5zIHRoZSBpbm9kZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBnZXRJbm9kZSgpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMuaW5vZGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBtb2RlIG9mIHRoaXMgZW50cnkgKGUuZy4gZGlyZWN0b3J5LCByZWd1bGFyIGZpbGUpLgorICAgICAqCisgICAgICogQHJldHVybiBSZXR1cm5zIHRoZSBtb2RlLgorICAgICAqLworICAgIHB1YmxpYyBsb25nIGdldE1vZGUoKSB7CisgICAgICAgIHJldHVybiBtb2RlID09IDAgJiYgIUNQSU9fVFJBSUxFUi5lcXVhbHMobmFtZSkgPyBDX0lTUkVHIDogbW9kZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIG5hbWUuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCByZXR1cm5zIHRoZSByYXcgbmFtZSBhcyBpdCBpcyBzdG9yZWQgaW5zaWRlIG9mIHRoZSBhcmNoaXZlLjwvcD4KKyAgICAgKgorICAgICAqIEByZXR1cm4gUmV0dXJucyB0aGUgbmFtZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7CisgICAgICAgIHJldHVybiB0aGlzLm5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBudW1iZXIgb2YgbGlua3MuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFJldHVybnMgdGhlIG51bWJlciBvZiBsaW5rcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBnZXROdW1iZXJPZkxpbmtzKCkgeworICAgICAgICByZXR1cm4gbmxpbmsgPT0gMCA/CisgICAgICAgICAgICBpc0RpcmVjdG9yeSgpID8gMiA6IDEKKyAgICAgICAgICAgIDogbmxpbms7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSByZW1vdGUgZGV2aWNlIGlkLgorICAgICAqCisgICAgICogQHJldHVybiBSZXR1cm5zIHRoZSByZW1vdGUgZGV2aWNlIGlkLgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIG1ldGhvZCBpcyBjYWxsZWQgZm9yIGEgQ3Bpb0FyY2hpdmVFbnRyeSB3aXRoIGEgbmV3CisgICAgICogICAgICAgICAgICAgZm9ybWF0LgorICAgICAqLworICAgIHB1YmxpYyBsb25nIGdldFJlbW90ZURldmljZSgpIHsKKyAgICAgICAgY2hlY2tPbGRGb3JtYXQoKTsKKyAgICAgICAgcmV0dXJuIHRoaXMucm1pbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIHJlbW90ZSBtYWpvciBkZXZpY2UgaWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFJldHVybnMgdGhlIHJlbW90ZSBtYWpvciBkZXZpY2UgaWQuCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgbWV0aG9kIGlzIGNhbGxlZCBmb3IgYSBDcGlvQXJjaGl2ZUVudHJ5IHdpdGggYW4gb2xkCisgICAgICogICAgICAgICAgICAgZm9ybWF0LgorICAgICAqLworICAgIHB1YmxpYyBsb25nIGdldFJlbW90ZURldmljZU1haigpIHsKKyAgICAgICAgY2hlY2tOZXdGb3JtYXQoKTsKKyAgICAgICAgcmV0dXJuIHRoaXMucm1hajsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIHJlbW90ZSBtaW5vciBkZXZpY2UgaWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFJldHVybnMgdGhlIHJlbW90ZSBtaW5vciBkZXZpY2UgaWQuCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgbWV0aG9kIGlzIGNhbGxlZCBmb3IgYSBDcGlvQXJjaGl2ZUVudHJ5IHdpdGggYW4gb2xkCisgICAgICogICAgICAgICAgICAgZm9ybWF0LgorICAgICAqLworICAgIHB1YmxpYyBsb25nIGdldFJlbW90ZURldmljZU1pbigpIHsKKyAgICAgICAgY2hlY2tOZXdGb3JtYXQoKTsKKyAgICAgICAgcmV0dXJuIHRoaXMucm1pbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIHRpbWUgaW4gc2Vjb25kcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gUmV0dXJucyB0aGUgdGltZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBnZXRUaW1lKCkgeworICAgICAgICByZXR1cm4gdGhpcy5tdGltZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRGF0ZSBnZXRMYXN0TW9kaWZpZWREYXRlKCkgeworICAgICAgICByZXR1cm4gbmV3IERhdGUoMTAwMCAqIGdldFRpbWUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSB1c2VyIGlkLgorICAgICAqCisgICAgICogQHJldHVybiBSZXR1cm5zIHRoZSB1c2VyIGlkLgorICAgICAqLworICAgIHB1YmxpYyBsb25nIGdldFVJRCgpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMudWlkOworICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrIGlmIHRoaXMgZW50cnkgcmVwcmVzZW50cyBhIGJsb2NrIGRldmljZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVFJVRSBpZiB0aGlzIGVudHJ5IGlzIGEgYmxvY2sgZGV2aWNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzQmxvY2tEZXZpY2UoKSB7CisgICAgICAgIHJldHVybiBDcGlvVXRpbC5maWxlVHlwZShtb2RlKSA9PSBDX0lTQkxLOworICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrIGlmIHRoaXMgZW50cnkgcmVwcmVzZW50cyBhIGNoYXJhY3RlciBkZXZpY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRSVUUgaWYgdGhpcyBlbnRyeSBpcyBhIGNoYXJhY3RlciBkZXZpY2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNDaGFyYWN0ZXJEZXZpY2UoKSB7CisgICAgICAgIHJldHVybiBDcGlvVXRpbC5maWxlVHlwZShtb2RlKSA9PSBDX0lTQ0hSOworICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrIGlmIHRoaXMgZW50cnkgcmVwcmVzZW50cyBhIGRpcmVjdG9yeS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVFJVRSBpZiB0aGlzIGVudHJ5IGlzIGEgZGlyZWN0b3J5LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGlzRGlyZWN0b3J5KCkgeworICAgICAgICByZXR1cm4gQ3Bpb1V0aWwuZmlsZVR5cGUobW9kZSkgPT0gQ19JU0RJUjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVjayBpZiB0aGlzIGVudHJ5IHJlcHJlc2VudHMgYSBuZXR3b3JrIGRldmljZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVFJVRSBpZiB0aGlzIGVudHJ5IGlzIGEgbmV0d29yayBkZXZpY2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNOZXR3b3JrKCkgeworICAgICAgICByZXR1cm4gQ3Bpb1V0aWwuZmlsZVR5cGUobW9kZSkgPT0gQ19JU05XSzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVjayBpZiB0aGlzIGVudHJ5IHJlcHJlc2VudHMgYSBwaXBlLgorICAgICAqCisgICAgICogQHJldHVybiBUUlVFIGlmIHRoaXMgZW50cnkgaXMgYSBwaXBlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzUGlwZSgpIHsKKyAgICAgICAgcmV0dXJuIENwaW9VdGlsLmZpbGVUeXBlKG1vZGUpID09IENfSVNGSUZPOworICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrIGlmIHRoaXMgZW50cnkgcmVwcmVzZW50cyBhIHJlZ3VsYXIgZmlsZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVFJVRSBpZiB0aGlzIGVudHJ5IGlzIGEgcmVndWxhciBmaWxlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzUmVndWxhckZpbGUoKSB7CisgICAgICAgIHJldHVybiBDcGlvVXRpbC5maWxlVHlwZShtb2RlKSA9PSBDX0lTUkVHOworICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrIGlmIHRoaXMgZW50cnkgcmVwcmVzZW50cyBhIHNvY2tldC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVFJVRSBpZiB0aGlzIGVudHJ5IGlzIGEgc29ja2V0LgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzU29ja2V0KCkgeworICAgICAgICByZXR1cm4gQ3Bpb1V0aWwuZmlsZVR5cGUobW9kZSkgPT0gQ19JU1NPQ0s7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2sgaWYgdGhpcyBlbnRyeSByZXByZXNlbnRzIGEgc3ltYm9saWMgbGluay4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVFJVRSBpZiB0aGlzIGVudHJ5IGlzIGEgc3ltYm9saWMgbGluay4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc1N5bWJvbGljTGluaygpIHsKKyAgICAgICAgcmV0dXJuIENwaW9VdGlsLmZpbGVUeXBlKG1vZGUpID09IENfSVNMTks7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBjaGVja3N1bS4gVGhlIGNoZWNrc3VtIGlzIGNhbGN1bGF0ZWQgYnkgYWRkaW5nIGFsbCBieXRlcyBvZiBhCisgICAgICogZmlsZSB0byB0cmFuc2ZlciAoY3JjICs9IGJ1Zltwb3NdICZhbXA7IDB4RkYpLgorICAgICAqCisgICAgICogQHBhcmFtIGNoa3N1bQorICAgICAqICAgICAgICAgICAgVGhlIGNoZWNrc3VtIHRvIHNldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRDaGtzdW0oZmluYWwgbG9uZyBjaGtzdW0pIHsKKyAgICAgICAgY2hlY2tOZXdGb3JtYXQoKTsKKyAgICAgICAgdGhpcy5jaGtzdW0gPSBjaGtzdW0gJiAweEZGRkZGRkZGTDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIGRldmljZSBpZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZXZpY2UKKyAgICAgKiAgICAgICAgICAgIFRoZSBkZXZpY2UgaWQgdG8gc2V0LgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIG1ldGhvZCBpcyBjYWxsZWQgZm9yIGEgQ3Bpb0FyY2hpdmVFbnRyeSB3aXRoIGEgbmV3CisgICAgICogICAgICAgICAgICAgZm9ybWF0LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldERldmljZShmaW5hbCBsb25nIGRldmljZSkgeworICAgICAgICBjaGVja09sZEZvcm1hdCgpOworICAgICAgICB0aGlzLm1pbiA9IGRldmljZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgbWFqb3IgZGV2aWNlIGlkLgorICAgICAqCisgICAgICogQHBhcmFtIG1hagorICAgICAqICAgICAgICAgICAgVGhlIG1ham9yIGRldmljZSBpZCB0byBzZXQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RGV2aWNlTWFqKGZpbmFsIGxvbmcgbWFqKSB7CisgICAgICAgIGNoZWNrTmV3Rm9ybWF0KCk7CisgICAgICAgIHRoaXMubWFqID0gbWFqOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgbWlub3IgZGV2aWNlIGlkCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWluCisgICAgICogICAgICAgICAgICBUaGUgbWlub3IgZGV2aWNlIGlkIHRvIHNldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXREZXZpY2VNaW4oZmluYWwgbG9uZyBtaW4pIHsKKyAgICAgICAgY2hlY2tOZXdGb3JtYXQoKTsKKyAgICAgICAgdGhpcy5taW4gPSBtaW47CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBmaWxlc2l6ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzaXplCisgICAgICogICAgICAgICAgICBUaGUgZmlsZXNpemUgdG8gc2V0LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFNpemUoZmluYWwgbG9uZyBzaXplKSB7CisgICAgICAgIGlmIChzaXplIDwgMCB8fCBzaXplID4gMHhGRkZGRkZGRkwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImludmFsaWQgZW50cnkgc2l6ZSA8IiArIHNpemUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiPiIpOworICAgICAgICB9CisgICAgICAgIHRoaXMuZmlsZXNpemUgPSBzaXplOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgZ3JvdXAgaWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZ2lkCisgICAgICogICAgICAgICAgICBUaGUgZ3JvdXAgaWQgdG8gc2V0LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEdJRChmaW5hbCBsb25nIGdpZCkgeworICAgICAgICB0aGlzLmdpZCA9IGdpZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIGlub2RlLgorICAgICAqCisgICAgICogQHBhcmFtIGlub2RlCisgICAgICogICAgICAgICAgICBUaGUgaW5vZGUgdG8gc2V0LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldElub2RlKGZpbmFsIGxvbmcgaW5vZGUpIHsKKyAgICAgICAgdGhpcy5pbm9kZSA9IGlub2RlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgbW9kZSBvZiB0aGlzIGVudHJ5IChlLmcuIGRpcmVjdG9yeSwgcmVndWxhciBmaWxlKS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtb2RlCisgICAgICogICAgICAgICAgICBUaGUgbW9kZSB0byBzZXQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TW9kZShmaW5hbCBsb25nIG1vZGUpIHsKKyAgICAgICAgZmluYWwgbG9uZyBtYXNrZWRNb2RlID0gbW9kZSAmIFNfSUZNVDsKKyAgICAgICAgc3dpdGNoICgoaW50KSBtYXNrZWRNb2RlKSB7CisgICAgICAgIGNhc2UgQ19JU0RJUjoKKyAgICAgICAgY2FzZSBDX0lTTE5LOgorICAgICAgICBjYXNlIENfSVNSRUc6CisgICAgICAgIGNhc2UgQ19JU0ZJRk86CisgICAgICAgIGNhc2UgQ19JU0NIUjoKKyAgICAgICAgY2FzZSBDX0lTQkxLOgorICAgICAgICBjYXNlIENfSVNTT0NLOgorICAgICAgICBjYXNlIENfSVNOV0s6CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJVbmtub3duIG1vZGUuICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiRnVsbDogIiArIExvbmcudG9IZXhTdHJpbmcobW9kZSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIE1hc2tlZDogIiArIExvbmcudG9IZXhTdHJpbmcobWFza2VkTW9kZSkpOworICAgICAgICB9CisKKyAgICAgICAgdGhpcy5tb2RlID0gbW9kZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIG5hbWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgVGhlIG5hbWUgdG8gc2V0LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE5hbWUoZmluYWwgU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIG51bWJlciBvZiBsaW5rcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBubGluaworICAgICAqICAgICAgICAgICAgVGhlIG51bWJlciBvZiBsaW5rcyB0byBzZXQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TnVtYmVyT2ZMaW5rcyhmaW5hbCBsb25nIG5saW5rKSB7CisgICAgICAgIHRoaXMubmxpbmsgPSBubGluazsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHJlbW90ZSBkZXZpY2UgaWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGV2aWNlCisgICAgICogICAgICAgICAgICBUaGUgcmVtb3RlIGRldmljZSBpZCB0byBzZXQuCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgbWV0aG9kIGlzIGNhbGxlZCBmb3IgYSBDcGlvQXJjaGl2ZUVudHJ5IHdpdGggYSBuZXcKKyAgICAgKiAgICAgICAgICAgICBmb3JtYXQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UmVtb3RlRGV2aWNlKGZpbmFsIGxvbmcgZGV2aWNlKSB7CisgICAgICAgIGNoZWNrT2xkRm9ybWF0KCk7CisgICAgICAgIHRoaXMucm1pbiA9IGRldmljZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHJlbW90ZSBtYWpvciBkZXZpY2UgaWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcm1hagorICAgICAqICAgICAgICAgICAgVGhlIHJlbW90ZSBtYWpvciBkZXZpY2UgaWQgdG8gc2V0LgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIG1ldGhvZCBpcyBjYWxsZWQgZm9yIGEgQ3Bpb0FyY2hpdmVFbnRyeSB3aXRoIGFuIG9sZAorICAgICAqICAgICAgICAgICAgIGZvcm1hdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRSZW1vdGVEZXZpY2VNYWooZmluYWwgbG9uZyBybWFqKSB7CisgICAgICAgIGNoZWNrTmV3Rm9ybWF0KCk7CisgICAgICAgIHRoaXMucm1haiA9IHJtYWo7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSByZW1vdGUgbWlub3IgZGV2aWNlIGlkLgorICAgICAqCisgICAgICogQHBhcmFtIHJtaW4KKyAgICAgKiAgICAgICAgICAgIFRoZSByZW1vdGUgbWlub3IgZGV2aWNlIGlkIHRvIHNldC4KKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBtZXRob2QgaXMgY2FsbGVkIGZvciBhIENwaW9BcmNoaXZlRW50cnkgd2l0aCBhbiBvbGQKKyAgICAgKiAgICAgICAgICAgICBmb3JtYXQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UmVtb3RlRGV2aWNlTWluKGZpbmFsIGxvbmcgcm1pbikgeworICAgICAgICBjaGVja05ld0Zvcm1hdCgpOworICAgICAgICB0aGlzLnJtaW4gPSBybWluOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgdGltZSBpbiBzZWNvbmRzLgorICAgICAqCisgICAgICogQHBhcmFtIHRpbWUKKyAgICAgKiAgICAgICAgICAgIFRoZSB0aW1lIHRvIHNldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRUaW1lKGZpbmFsIGxvbmcgdGltZSkgeworICAgICAgICB0aGlzLm10aW1lID0gdGltZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHVzZXIgaWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdWlkCisgICAgICogICAgICAgICAgICBUaGUgdXNlciBpZCB0byBzZXQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0VUlEKGZpbmFsIGxvbmcgdWlkKSB7CisgICAgICAgIHRoaXMudWlkID0gdWlkOworICAgIH0KKworICAgIC8qIChub24tSmF2YWRvYykKKyAgICAgKiBAc2VlIGphdmEubGFuZy5PYmplY3QjaGFzaENvZGUoKQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIGZpbmFsIGludCBwcmltZSA9IDMxOworICAgICAgICBpbnQgcmVzdWx0ID0gMTsKKyAgICAgICAgcmVzdWx0ID0gcHJpbWUgKiByZXN1bHQgKyAobmFtZSA9PSBudWxsID8gMCA6IG5hbWUuaGFzaENvZGUoKSk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyogKG5vbi1KYXZhZG9jKQorICAgICAqIEBzZWUgamF2YS5sYW5nLk9iamVjdCNlcXVhbHMoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgT2JqZWN0IG9iaikgeworICAgICAgICBpZiAodGhpcyA9PSBvYmopIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmIChvYmogPT0gbnVsbCB8fCBnZXRDbGFzcygpICE9IG9iai5nZXRDbGFzcygpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgZmluYWwgQ3Bpb0FyY2hpdmVFbnRyeSBvdGhlciA9IChDcGlvQXJjaGl2ZUVudHJ5KSBvYmo7CisgICAgICAgIGlmIChuYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBvdGhlci5uYW1lID09IG51bGw7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gbmFtZS5lcXVhbHMob3RoZXIubmFtZSk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvY3Bpby9DcGlvQXJjaGl2ZUlucHV0U3RyZWFtLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvY3Bpby9DcGlvQXJjaGl2ZUlucHV0U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGNlZGMyNwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9jcGlvL0NwaW9BcmNoaXZlSW5wdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDU4MiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuY3BpbzsKKworaW1wb3J0IGphdmEuaW8uRU9GRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZUVudHJ5OworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZUlucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwLlppcEVuY29kaW5nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwLlppcEVuY29kaW5nSGVscGVyOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5BcmNoaXZlVXRpbHM7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLkNoYXJzZXROYW1lczsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuSU9VdGlsczsKKworLyoqCisgKiBDcGlvQXJjaGl2ZUlucHV0U3RyZWFtIGlzIGEgc3RyZWFtIGZvciByZWFkaW5nIGNwaW8gc3RyZWFtcy4gQWxsIGZvcm1hdHMgb2YKKyAqIGNwaW8gYXJlIHN1cHBvcnRlZCAob2xkIGFzY2lpLCBvbGQgYmluYXJ5LCBuZXcgcG9ydGFibGUgZm9ybWF0IGFuZCB0aGUgbmV3CisgKiBwb3J0YWJsZSBmb3JtYXQgd2l0aCBjcmMpLgorICoKKyAqIDxwPgorICogVGhlIHN0cmVhbSBjYW4gYmUgcmVhZCBieSBleHRyYWN0aW5nIGEgY3BpbyBlbnRyeSAoY29udGFpbmluZyBhbGwKKyAqIGluZm9ybWF0aW9ucyBhYm91dCBhIGVudHJ5KSBhbmQgYWZ0ZXJ3YXJkcyByZWFkaW5nIGZyb20gdGhlIHN0cmVhbSB0aGUgZmlsZQorICogc3BlY2lmaWVkIGJ5IHRoZSBlbnRyeS4KKyAqIDwvcD4KKyAqIDxwcmU+CisgKiBDcGlvQXJjaGl2ZUlucHV0U3RyZWFtIGNwaW9JbiA9IG5ldyBDcGlvQXJjaGl2ZUlucHV0U3RyZWFtKAorICogICAgICAgICBGaWxlcy5uZXdJbnB1dFN0cmVhbShQYXRocy5nZXQoJnF1b3Q7dGVzdC5jcGlvJnF1b3Q7KSkpOworICogQ3Bpb0FyY2hpdmVFbnRyeSBjcGlvRW50cnk7CisgKgorICogd2hpbGUgKChjcGlvRW50cnkgPSBjcGlvSW4uZ2V0TmV4dEVudHJ5KCkpICE9IG51bGwpIHsKKyAqICAgICBTeXN0ZW0ub3V0LnByaW50bG4oY3Bpb0VudHJ5LmdldE5hbWUoKSk7CisgKiAgICAgaW50IHRtcDsKKyAqICAgICBTdHJpbmdCdWlsZGVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgKiAgICAgd2hpbGUgKCh0bXAgPSBjcEluLnJlYWQoKSkgIT0gLTEpIHsKKyAqICAgICAgICAgYnVmLmFwcGVuZCgoY2hhcikgdG1wKTsKKyAqICAgICB9CisgKiAgICAgU3lzdGVtLm91dC5wcmludGxuKGJ1Zi50b1N0cmluZygpKTsKKyAqIH0KKyAqIGNwaW9Jbi5jbG9zZSgpOworICogPC9wcmU+CisgKiA8cD4KKyAqIE5vdGU6IFRoaXMgaW1wbGVtZW50YXRpb24gc2hvdWxkIGJlIGNvbXBhdGlibGUgdG8gY3BpbyAyLjUKKyAqCisgKiA8cD5UaGlzIGNsYXNzIHVzZXMgbXV0YWJsZSBmaWVsZHMgYW5kIGlzIG5vdCBjb25zaWRlcmVkIHRvIGJlIHRocmVhZHNhZmUuCisgKgorICogPHA+QmFzZWQgb24gY29kZSBmcm9tIHRoZSBqUlBNIHByb2plY3QgKGpycG0uc291cmNlZm9yZ2UubmV0KQorICovCisKK3B1YmxpYyBjbGFzcyBDcGlvQXJjaGl2ZUlucHV0U3RyZWFtIGV4dGVuZHMgQXJjaGl2ZUlucHV0U3RyZWFtIGltcGxlbWVudHMKKyAgICAgICAgQ3Bpb0NvbnN0YW50cyB7CisKKyAgICBwcml2YXRlIGJvb2xlYW4gY2xvc2VkID0gZmFsc2U7CisKKyAgICBwcml2YXRlIENwaW9BcmNoaXZlRW50cnkgZW50cnk7CisKKyAgICBwcml2YXRlIGxvbmcgZW50cnlCeXRlc1JlYWQgPSAwOworCisgICAgcHJpdmF0ZSBib29sZWFuIGVudHJ5RU9GID0gZmFsc2U7CisKKyAgICBwcml2YXRlIGZpbmFsIGJ5dGUgdG1wYnVmW10gPSBuZXcgYnl0ZVs0MDk2XTsKKworICAgIHByaXZhdGUgbG9uZyBjcmMgPSAwOworCisgICAgcHJpdmF0ZSBmaW5hbCBJbnB1dFN0cmVhbSBpbjsKKworICAgIC8vIGNhY2hlZCBidWZmZXJzIC0gbXVzdCBvbmx5IGJlIHVzZWQgbG9jYWxseSBpbiB0aGUgY2xhc3MgKENPTVBSRVNTLTE3MiAtIHJlZHVjZSBnYXJiYWdlIGNvbGxlY3Rpb24pCisgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10gdHdvQnl0ZXNCdWYgPSBuZXcgYnl0ZVsyXTsKKyAgICBwcml2YXRlIGZpbmFsIGJ5dGVbXSBmb3VyQnl0ZXNCdWYgPSBuZXcgYnl0ZVs0XTsKKyAgICBwcml2YXRlIGZpbmFsIGJ5dGVbXSBzaXhCeXRlc0J1ZiA9IG5ldyBieXRlWzZdOworCisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgYmxvY2tTaXplOworCisgICAgLyoqCisgICAgICogVGhlIGVuY29kaW5nIHRvIHVzZSBmb3IgZmlsZW5hbWVzIGFuZCBsYWJlbHMuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBaaXBFbmNvZGluZyB6aXBFbmNvZGluZzsKKworICAgIC8vIHRoZSBwcm92aWRlZCBlbmNvZGluZyAoZm9yIHVuaXQgdGVzdHMpCisgICAgZmluYWwgU3RyaW5nIGVuY29kaW5nOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IHRoZSBjcGlvIGlucHV0IHN0cmVhbSB3aXRoIGEgYmxvY2tzaXplIG9mIHtAbGluaworICAgICAqIENwaW9Db25zdGFudHMjQkxPQ0tfU0laRSBCTE9DS19TSVpFfSBhbmQgZXhwZWN0aW5nIEFTQ0lJIGZpbGUKKyAgICAgKiBuYW1lcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbgorICAgICAqICAgICAgICAgICAgVGhlIGNwaW8gc3RyZWFtCisgICAgICovCisgICAgcHVibGljIENwaW9BcmNoaXZlSW5wdXRTdHJlYW0oZmluYWwgSW5wdXRTdHJlYW0gaW4pIHsKKyAgICAgICAgdGhpcyhpbiwgQkxPQ0tfU0laRSwgQ2hhcnNldE5hbWVzLlVTX0FTQ0lJKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3QgdGhlIGNwaW8gaW5wdXQgc3RyZWFtIHdpdGggYSBibG9ja3NpemUgb2Yge0BsaW5rCisgICAgICogQ3Bpb0NvbnN0YW50cyNCTE9DS19TSVpFIEJMT0NLX1NJWkV9LgorICAgICAqCisgICAgICogQHBhcmFtIGluCisgICAgICogICAgICAgICAgICBUaGUgY3BpbyBzdHJlYW0KKyAgICAgKiBAcGFyYW0gZW5jb2RpbmcKKyAgICAgKiAgICAgICAgICAgIFRoZSBlbmNvZGluZyBvZiBmaWxlIG5hbWVzIHRvIGV4cGVjdCAtIHVzZSBudWxsIGZvcgorICAgICAqICAgICAgICAgICAgdGhlIHBsYXRmb3JtJ3MgZGVmYXVsdC4KKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIENwaW9BcmNoaXZlSW5wdXRTdHJlYW0oZmluYWwgSW5wdXRTdHJlYW0gaW4sIGZpbmFsIFN0cmluZyBlbmNvZGluZykgeworICAgICAgICB0aGlzKGluLCBCTE9DS19TSVpFLCBlbmNvZGluZyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IHRoZSBjcGlvIGlucHV0IHN0cmVhbSB3aXRoIGEgYmxvY2tzaXplIG9mIHtAbGluaworICAgICAqIENwaW9Db25zdGFudHMjQkxPQ0tfU0laRSBCTE9DS19TSVpFfSBleHBlY3RpbmcgQVNDSUkgZmlsZQorICAgICAqIG5hbWVzLgorICAgICAqCisgICAgICogQHBhcmFtIGluCisgICAgICogICAgICAgICAgICBUaGUgY3BpbyBzdHJlYW0KKyAgICAgKiBAcGFyYW0gYmxvY2tTaXplCisgICAgICogICAgICAgICAgICBUaGUgYmxvY2sgc2l6ZSBvZiB0aGUgYXJjaGl2ZS4KKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIENwaW9BcmNoaXZlSW5wdXRTdHJlYW0oZmluYWwgSW5wdXRTdHJlYW0gaW4sIGZpbmFsIGludCBibG9ja1NpemUpIHsKKyAgICAgICAgdGhpcyhpbiwgYmxvY2tTaXplLCBDaGFyc2V0TmFtZXMuVVNfQVNDSUkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdCB0aGUgY3BpbyBpbnB1dCBzdHJlYW0gd2l0aCBhIGJsb2Nrc2l6ZSBvZiB7QGxpbmsgQ3Bpb0NvbnN0YW50cyNCTE9DS19TSVpFIEJMT0NLX1NJWkV9LgorICAgICAqCisgICAgICogQHBhcmFtIGluCisgICAgICogICAgICAgICAgICBUaGUgY3BpbyBzdHJlYW0KKyAgICAgKiBAcGFyYW0gYmxvY2tTaXplCisgICAgICogICAgICAgICAgICBUaGUgYmxvY2sgc2l6ZSBvZiB0aGUgYXJjaGl2ZS4KKyAgICAgKiBAcGFyYW0gZW5jb2RpbmcKKyAgICAgKiAgICAgICAgICAgIFRoZSBlbmNvZGluZyBvZiBmaWxlIG5hbWVzIHRvIGV4cGVjdCAtIHVzZSBudWxsIGZvcgorICAgICAqICAgICAgICAgICAgdGhlIHBsYXRmb3JtJ3MgZGVmYXVsdC4KKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIENwaW9BcmNoaXZlSW5wdXRTdHJlYW0oZmluYWwgSW5wdXRTdHJlYW0gaW4sIGZpbmFsIGludCBibG9ja1NpemUsIGZpbmFsIFN0cmluZyBlbmNvZGluZykgeworICAgICAgICB0aGlzLmluID0gaW47CisgICAgICAgIHRoaXMuYmxvY2tTaXplID0gYmxvY2tTaXplOworICAgICAgICB0aGlzLmVuY29kaW5nID0gZW5jb2Rpbmc7CisgICAgICAgIHRoaXMuemlwRW5jb2RpbmcgPSBaaXBFbmNvZGluZ0hlbHBlci5nZXRaaXBFbmNvZGluZyhlbmNvZGluZyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyAwIGFmdGVyIEVPRiBoYXMgcmVhY2hlZCBmb3IgdGhlIGN1cnJlbnQgZW50cnkgZGF0YSwgb3RoZXJ3aXNlCisgICAgICogYWx3YXlzIHJldHVybiAxLgorICAgICAqIDxwPgorICAgICAqIFByb2dyYW1zIHNob3VsZCBub3QgY291bnQgb24gdGhpcyBtZXRob2QgdG8gcmV0dXJuIHRoZSBhY3R1YWwgbnVtYmVyIG9mCisgICAgICogYnl0ZXMgdGhhdCBjb3VsZCBiZSByZWFkIHdpdGhvdXQgYmxvY2tpbmcuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIDEgYmVmb3JlIEVPRiBhbmQgMCBhZnRlciBFT0YgaGFzIHJlYWNoZWQgZm9yIGN1cnJlbnQgZW50cnkuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBlcnJvciBoYXMgb2NjdXJyZWQgb3IgaWYgYSBDUElPIGZpbGUgZXJyb3IgaGFzCisgICAgICogICAgICAgICAgICAgb2NjdXJyZWQKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGF2YWlsYWJsZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGVuc3VyZU9wZW4oKTsKKyAgICAgICAgaWYgKHRoaXMuZW50cnlFT0YpIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgICAgIHJldHVybiAxOworICAgIH0KKworICAgIC8qKgorICAgICAqIENsb3NlcyB0aGUgQ1BJTyBpbnB1dCBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIGhhcyBvY2N1cnJlZAorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCF0aGlzLmNsb3NlZCkgeworICAgICAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgICAgIHRoaXMuY2xvc2VkID0gdHJ1ZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENsb3NlcyB0aGUgY3VycmVudCBDUElPIGVudHJ5IGFuZCBwb3NpdGlvbnMgdGhlIHN0cmVhbSBmb3IgcmVhZGluZyB0aGUKKyAgICAgKiBuZXh0IGVudHJ5LgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBlcnJvciBoYXMgb2NjdXJyZWQgb3IgaWYgYSBDUElPIGZpbGUgZXJyb3IgaGFzCisgICAgICogICAgICAgICAgICAgb2NjdXJyZWQKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgY2xvc2VFbnRyeSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIHRoZSBza2lwIGltcGxlbWVudGF0aW9uIG9mIHRoaXMgY2xhc3Mgd2lsbCBub3Qgc2tpcCBtb3JlCisgICAgICAgIC8vIHRoYW4gSW50ZWdlci5NQVhfVkFMVUUgYnl0ZXMKKyAgICAgICAgd2hpbGUgKHNraXAoKGxvbmcpIEludGVnZXIuTUFYX1ZBTFVFKSA9PSBJbnRlZ2VyLk1BWF9WQUxVRSkgeyAvLyBOT1BNRAorICAgICAgICAgICAgLy8gZG8gbm90aGluZworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2sgdG8gbWFrZSBzdXJlIHRoYXQgdGhpcyBzdHJlYW0gaGFzIG5vdCBiZWVuIGNsb3NlZAorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzdHJlYW0gaXMgYWxyZWFkeSBjbG9zZWQKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgZW5zdXJlT3BlbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICh0aGlzLmNsb3NlZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJTdHJlYW0gY2xvc2VkIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyB0aGUgbmV4dCBDUElPIGZpbGUgZW50cnkgYW5kIHBvc2l0aW9ucyBzdHJlYW0gYXQgdGhlIGJlZ2lubmluZyBvZgorICAgICAqIHRoZSBlbnRyeSBkYXRhLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgQ3Bpb0FyY2hpdmVFbnRyeSBqdXN0IHJlYWQKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIGhhcyBvY2N1cnJlZCBvciBpZiBhIENQSU8gZmlsZSBlcnJvciBoYXMKKyAgICAgKiAgICAgICAgICAgICBvY2N1cnJlZAorICAgICAqLworICAgIHB1YmxpYyBDcGlvQXJjaGl2ZUVudHJ5IGdldE5leHRDUElPRW50cnkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBlbnN1cmVPcGVuKCk7CisgICAgICAgIGlmICh0aGlzLmVudHJ5ICE9IG51bGwpIHsKKyAgICAgICAgICAgIGNsb3NlRW50cnkoKTsKKyAgICAgICAgfQorICAgICAgICByZWFkRnVsbHkodHdvQnl0ZXNCdWYsIDAsIHR3b0J5dGVzQnVmLmxlbmd0aCk7CisgICAgICAgIGlmIChDcGlvVXRpbC5ieXRlQXJyYXkybG9uZyh0d29CeXRlc0J1ZiwgZmFsc2UpID09IE1BR0lDX09MRF9CSU5BUlkpIHsKKyAgICAgICAgICAgIHRoaXMuZW50cnkgPSByZWFkT2xkQmluYXJ5RW50cnkoZmFsc2UpOworICAgICAgICB9IGVsc2UgaWYgKENwaW9VdGlsLmJ5dGVBcnJheTJsb25nKHR3b0J5dGVzQnVmLCB0cnVlKQorICAgICAgICAgICAgICAgICAgID09IE1BR0lDX09MRF9CSU5BUlkpIHsKKyAgICAgICAgICAgIHRoaXMuZW50cnkgPSByZWFkT2xkQmluYXJ5RW50cnkodHJ1ZSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHR3b0J5dGVzQnVmLCAwLCBzaXhCeXRlc0J1ZiwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHdvQnl0ZXNCdWYubGVuZ3RoKTsKKyAgICAgICAgICAgIHJlYWRGdWxseShzaXhCeXRlc0J1ZiwgdHdvQnl0ZXNCdWYubGVuZ3RoLAorICAgICAgICAgICAgICAgICAgICAgIGZvdXJCeXRlc0J1Zi5sZW5ndGgpOworICAgICAgICAgICAgZmluYWwgU3RyaW5nIG1hZ2ljU3RyaW5nID0gQXJjaGl2ZVV0aWxzLnRvQXNjaWlTdHJpbmcoc2l4Qnl0ZXNCdWYpOworICAgICAgICAgICAgc3dpdGNoIChtYWdpY1N0cmluZykgeworICAgICAgICAgICAgICAgIGNhc2UgTUFHSUNfTkVXOgorICAgICAgICAgICAgICAgICAgICB0aGlzLmVudHJ5ID0gcmVhZE5ld0VudHJ5KGZhbHNlKTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgY2FzZSBNQUdJQ19ORVdfQ1JDOgorICAgICAgICAgICAgICAgICAgICB0aGlzLmVudHJ5ID0gcmVhZE5ld0VudHJ5KHRydWUpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlIE1BR0lDX09MRF9BU0NJSToKKyAgICAgICAgICAgICAgICAgICAgdGhpcy5lbnRyeSA9IHJlYWRPbGRBc2NpaUVudHJ5KCk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiVW5rbm93biBtYWdpYyBbIiArIG1hZ2ljU3RyaW5nICsgIl0uIE9jY3VyZWQgYXQgYnl0ZTogIiArIGdldEJ5dGVzUmVhZCgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHRoaXMuZW50cnlCeXRlc1JlYWQgPSAwOworICAgICAgICB0aGlzLmVudHJ5RU9GID0gZmFsc2U7CisgICAgICAgIHRoaXMuY3JjID0gMDsKKworICAgICAgICBpZiAodGhpcy5lbnRyeS5nZXROYW1lKCkuZXF1YWxzKENQSU9fVFJBSUxFUikpIHsKKyAgICAgICAgICAgIHRoaXMuZW50cnlFT0YgPSB0cnVlOworICAgICAgICAgICAgc2tpcFJlbWFpbmRlck9mTGFzdEJsb2NrKCk7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdGhpcy5lbnRyeTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgc2tpcChmaW5hbCBpbnQgYnl0ZXMpIHRocm93cyBJT0V4Y2VwdGlvbnsKKyAgICAgICAgLy8gYnl0ZXMgY2Fubm90IGJlIG1vcmUgdGhhbiAzIGJ5dGVzCisgICAgICAgIGlmIChieXRlcyA+IDApIHsKKyAgICAgICAgICAgIHJlYWRGdWxseShmb3VyQnl0ZXNCdWYsIDAsIGJ5dGVzKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGZyb20gdGhlIGN1cnJlbnQgQ1BJTyBlbnRyeSBpbnRvIGFuIGFycmF5IG9mIGJ5dGVzLiBCbG9ja3MgdW50aWwKKyAgICAgKiBzb21lIGlucHV0IGlzIGF2YWlsYWJsZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBiCisgICAgICogICAgICAgICAgICB0aGUgYnVmZmVyIGludG8gd2hpY2ggdGhlIGRhdGEgaXMgcmVhZAorICAgICAqIEBwYXJhbSBvZmYKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdGFydCBvZmZzZXQgb2YgdGhlIGRhdGEKKyAgICAgKiBAcGFyYW0gbGVuCisgICAgICogICAgICAgICAgICB0aGUgbWF4aW11bSBudW1iZXIgb2YgYnl0ZXMgcmVhZAorICAgICAqIEByZXR1cm4gdGhlIGFjdHVhbCBudW1iZXIgb2YgYnl0ZXMgcmVhZCwgb3IgLTEgaWYgdGhlIGVuZCBvZiB0aGUgZW50cnkgaXMKKyAgICAgKiAgICAgICAgIHJlYWNoZWQKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIGhhcyBvY2N1cnJlZCBvciBpZiBhIENQSU8gZmlsZSBlcnJvciBoYXMKKyAgICAgKiAgICAgICAgICAgICBvY2N1cnJlZAorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZChmaW5hbCBieXRlW10gYiwgZmluYWwgaW50IG9mZiwgZmluYWwgaW50IGxlbikKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGVuc3VyZU9wZW4oKTsKKyAgICAgICAgaWYgKG9mZiA8IDAgfHwgbGVuIDwgMCB8fCBvZmYgPiBiLmxlbmd0aCAtIGxlbikgeworICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oKTsKKyAgICAgICAgfSBlbHNlIGlmIChsZW4gPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICBpZiAodGhpcy5lbnRyeSA9PSBudWxsIHx8IHRoaXMuZW50cnlFT0YpIHsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgICAgICBpZiAodGhpcy5lbnRyeUJ5dGVzUmVhZCA9PSB0aGlzLmVudHJ5LmdldFNpemUoKSkgeworICAgICAgICAgICAgc2tpcChlbnRyeS5nZXREYXRhUGFkQ291bnQoKSk7CisgICAgICAgICAgICB0aGlzLmVudHJ5RU9GID0gdHJ1ZTsKKyAgICAgICAgICAgIGlmICh0aGlzLmVudHJ5LmdldEZvcm1hdCgpID09IEZPUk1BVF9ORVdfQ1JDCisgICAgICAgICAgICAgICAgJiYgdGhpcy5jcmMgIT0gdGhpcy5lbnRyeS5nZXRDaGtzdW0oKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiQ1JDIEVycm9yLiBPY2N1cmVkIGF0IGJ5dGU6ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBnZXRCeXRlc1JlYWQoKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gLTE7IC8vIEVPRiBmb3IgdGhpcyBlbnRyeQorICAgICAgICB9CisgICAgICAgIGZpbmFsIGludCB0bXBsZW5ndGggPSAoaW50KSBNYXRoLm1pbihsZW4sIHRoaXMuZW50cnkuZ2V0U2l6ZSgpCisgICAgICAgICAgICAgICAgLSB0aGlzLmVudHJ5Qnl0ZXNSZWFkKTsKKyAgICAgICAgaWYgKHRtcGxlbmd0aCA8IDApIHsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIGludCB0bXByZWFkID0gcmVhZEZ1bGx5KGIsIG9mZiwgdG1wbGVuZ3RoKTsKKyAgICAgICAgaWYgKHRoaXMuZW50cnkuZ2V0Rm9ybWF0KCkgPT0gRk9STUFUX05FV19DUkMpIHsKKyAgICAgICAgICAgIGZvciAoaW50IHBvcyA9IDA7IHBvcyA8IHRtcHJlYWQ7IHBvcysrKSB7CisgICAgICAgICAgICAgICAgdGhpcy5jcmMgKz0gYltwb3NdICYgMHhGRjsKKyAgICAgICAgICAgICAgICB0aGlzLmNyYyAmPSAweEZGRkZGRkZGTDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAodG1wcmVhZCA+IDApIHsKKyAgICAgICAgICAgIHRoaXMuZW50cnlCeXRlc1JlYWQgKz0gdG1wcmVhZDsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiB0bXByZWFkOworICAgIH0KKworICAgIHByaXZhdGUgZmluYWwgaW50IHJlYWRGdWxseShmaW5hbCBieXRlW10gYiwgZmluYWwgaW50IG9mZiwgZmluYWwgaW50IGxlbikKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIGludCBjb3VudCA9IElPVXRpbHMucmVhZEZ1bGx5KGluLCBiLCBvZmYsIGxlbik7CisgICAgICAgIGNvdW50KGNvdW50KTsKKyAgICAgICAgaWYgKGNvdW50IDwgbGVuKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRU9GRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGNvdW50OworICAgIH0KKworICAgIHByaXZhdGUgbG9uZyByZWFkQmluYXJ5TG9uZyhmaW5hbCBpbnQgbGVuZ3RoLCBmaW5hbCBib29sZWFuIHN3YXBIYWxmV29yZCkKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIGJ5dGUgdG1wW10gPSBuZXcgYnl0ZVtsZW5ndGhdOworICAgICAgICByZWFkRnVsbHkodG1wLCAwLCB0bXAubGVuZ3RoKTsKKyAgICAgICAgcmV0dXJuIENwaW9VdGlsLmJ5dGVBcnJheTJsb25nKHRtcCwgc3dhcEhhbGZXb3JkKTsKKyAgICB9CisKKyAgICBwcml2YXRlIGxvbmcgcmVhZEFzY2lpTG9uZyhmaW5hbCBpbnQgbGVuZ3RoLCBmaW5hbCBpbnQgcmFkaXgpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBieXRlIHRtcEJ1ZmZlcltdID0gbmV3IGJ5dGVbbGVuZ3RoXTsKKyAgICAgICAgcmVhZEZ1bGx5KHRtcEJ1ZmZlciwgMCwgdG1wQnVmZmVyLmxlbmd0aCk7CisgICAgICAgIHJldHVybiBMb25nLnBhcnNlTG9uZyhBcmNoaXZlVXRpbHMudG9Bc2NpaVN0cmluZyh0bXBCdWZmZXIpLCByYWRpeCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBDcGlvQXJjaGl2ZUVudHJ5IHJlYWROZXdFbnRyeShmaW5hbCBib29sZWFuIGhhc0NyYykKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIENwaW9BcmNoaXZlRW50cnkgcmV0OworICAgICAgICBpZiAoaGFzQ3JjKSB7CisgICAgICAgICAgICByZXQgPSBuZXcgQ3Bpb0FyY2hpdmVFbnRyeShGT1JNQVRfTkVXX0NSQyk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXQgPSBuZXcgQ3Bpb0FyY2hpdmVFbnRyeShGT1JNQVRfTkVXKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldC5zZXRJbm9kZShyZWFkQXNjaWlMb25nKDgsIDE2KSk7CisgICAgICAgIGZpbmFsIGxvbmcgbW9kZSA9IHJlYWRBc2NpaUxvbmcoOCwgMTYpOworICAgICAgICBpZiAoQ3Bpb1V0aWwuZmlsZVR5cGUobW9kZSkgIT0gMCl7IC8vIG1vZGUgaXMgaW5pdGlhbGlzZWQgdG8gMAorICAgICAgICAgICAgcmV0LnNldE1vZGUobW9kZSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0LnNldFVJRChyZWFkQXNjaWlMb25nKDgsIDE2KSk7CisgICAgICAgIHJldC5zZXRHSUQocmVhZEFzY2lpTG9uZyg4LCAxNikpOworICAgICAgICByZXQuc2V0TnVtYmVyT2ZMaW5rcyhyZWFkQXNjaWlMb25nKDgsIDE2KSk7CisgICAgICAgIHJldC5zZXRUaW1lKHJlYWRBc2NpaUxvbmcoOCwgMTYpKTsKKyAgICAgICAgcmV0LnNldFNpemUocmVhZEFzY2lpTG9uZyg4LCAxNikpOworICAgICAgICByZXQuc2V0RGV2aWNlTWFqKHJlYWRBc2NpaUxvbmcoOCwgMTYpKTsKKyAgICAgICAgcmV0LnNldERldmljZU1pbihyZWFkQXNjaWlMb25nKDgsIDE2KSk7CisgICAgICAgIHJldC5zZXRSZW1vdGVEZXZpY2VNYWoocmVhZEFzY2lpTG9uZyg4LCAxNikpOworICAgICAgICByZXQuc2V0UmVtb3RlRGV2aWNlTWluKHJlYWRBc2NpaUxvbmcoOCwgMTYpKTsKKyAgICAgICAgZmluYWwgbG9uZyBuYW1lc2l6ZSA9IHJlYWRBc2NpaUxvbmcoOCwgMTYpOworICAgICAgICByZXQuc2V0Q2hrc3VtKHJlYWRBc2NpaUxvbmcoOCwgMTYpKTsKKyAgICAgICAgZmluYWwgU3RyaW5nIG5hbWUgPSByZWFkQ1N0cmluZygoaW50KSBuYW1lc2l6ZSk7CisgICAgICAgIHJldC5zZXROYW1lKG5hbWUpOworICAgICAgICBpZiAoQ3Bpb1V0aWwuZmlsZVR5cGUobW9kZSkgPT0gMCAmJiAhbmFtZS5lcXVhbHMoQ1BJT19UUkFJTEVSKSl7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIk1vZGUgMCBvbmx5IGFsbG93ZWQgaW4gdGhlIHRyYWlsZXIuIEZvdW5kIGVudHJ5IG5hbWU6ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIEFyY2hpdmVVdGlscy5zYW5pdGl6ZShuYW1lKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiBPY2N1cmVkIGF0IGJ5dGU6ICIgKyBnZXRCeXRlc1JlYWQoKSk7CisgICAgICAgIH0KKyAgICAgICAgc2tpcChyZXQuZ2V0SGVhZGVyUGFkQ291bnQobmFtZXNpemUgLSAxKSk7CisKKyAgICAgICAgcmV0dXJuIHJldDsKKyAgICB9CisKKyAgICBwcml2YXRlIENwaW9BcmNoaXZlRW50cnkgcmVhZE9sZEFzY2lpRW50cnkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBDcGlvQXJjaGl2ZUVudHJ5IHJldCA9IG5ldyBDcGlvQXJjaGl2ZUVudHJ5KEZPUk1BVF9PTERfQVNDSUkpOworCisgICAgICAgIHJldC5zZXREZXZpY2UocmVhZEFzY2lpTG9uZyg2LCA4KSk7CisgICAgICAgIHJldC5zZXRJbm9kZShyZWFkQXNjaWlMb25nKDYsIDgpKTsKKyAgICAgICAgZmluYWwgbG9uZyBtb2RlID0gcmVhZEFzY2lpTG9uZyg2LCA4KTsKKyAgICAgICAgaWYgKENwaW9VdGlsLmZpbGVUeXBlKG1vZGUpICE9IDApIHsKKyAgICAgICAgICAgIHJldC5zZXRNb2RlKG1vZGUpOworICAgICAgICB9CisgICAgICAgIHJldC5zZXRVSUQocmVhZEFzY2lpTG9uZyg2LCA4KSk7CisgICAgICAgIHJldC5zZXRHSUQocmVhZEFzY2lpTG9uZyg2LCA4KSk7CisgICAgICAgIHJldC5zZXROdW1iZXJPZkxpbmtzKHJlYWRBc2NpaUxvbmcoNiwgOCkpOworICAgICAgICByZXQuc2V0UmVtb3RlRGV2aWNlKHJlYWRBc2NpaUxvbmcoNiwgOCkpOworICAgICAgICByZXQuc2V0VGltZShyZWFkQXNjaWlMb25nKDExLCA4KSk7CisgICAgICAgIGZpbmFsIGxvbmcgbmFtZXNpemUgPSByZWFkQXNjaWlMb25nKDYsIDgpOworICAgICAgICByZXQuc2V0U2l6ZShyZWFkQXNjaWlMb25nKDExLCA4KSk7CisgICAgICAgIGZpbmFsIFN0cmluZyBuYW1lID0gcmVhZENTdHJpbmcoKGludCkgbmFtZXNpemUpOworICAgICAgICByZXQuc2V0TmFtZShuYW1lKTsKKyAgICAgICAgaWYgKENwaW9VdGlsLmZpbGVUeXBlKG1vZGUpID09IDAgJiYgIW5hbWUuZXF1YWxzKENQSU9fVFJBSUxFUikpeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJNb2RlIDAgb25seSBhbGxvd2VkIGluIHRoZSB0cmFpbGVyLiBGb3VuZCBlbnRyeTogIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgQXJjaGl2ZVV0aWxzLnNhbml0aXplKG5hbWUpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIE9jY3VyZWQgYXQgYnl0ZTogIiArIGdldEJ5dGVzUmVhZCgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiByZXQ7CisgICAgfQorCisgICAgcHJpdmF0ZSBDcGlvQXJjaGl2ZUVudHJ5IHJlYWRPbGRCaW5hcnlFbnRyeShmaW5hbCBib29sZWFuIHN3YXBIYWxmV29yZCkKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIENwaW9BcmNoaXZlRW50cnkgcmV0ID0gbmV3IENwaW9BcmNoaXZlRW50cnkoRk9STUFUX09MRF9CSU5BUlkpOworCisgICAgICAgIHJldC5zZXREZXZpY2UocmVhZEJpbmFyeUxvbmcoMiwgc3dhcEhhbGZXb3JkKSk7CisgICAgICAgIHJldC5zZXRJbm9kZShyZWFkQmluYXJ5TG9uZygyLCBzd2FwSGFsZldvcmQpKTsKKyAgICAgICAgZmluYWwgbG9uZyBtb2RlID0gcmVhZEJpbmFyeUxvbmcoMiwgc3dhcEhhbGZXb3JkKTsKKyAgICAgICAgaWYgKENwaW9VdGlsLmZpbGVUeXBlKG1vZGUpICE9IDApeworICAgICAgICAgICAgcmV0LnNldE1vZGUobW9kZSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0LnNldFVJRChyZWFkQmluYXJ5TG9uZygyLCBzd2FwSGFsZldvcmQpKTsKKyAgICAgICAgcmV0LnNldEdJRChyZWFkQmluYXJ5TG9uZygyLCBzd2FwSGFsZldvcmQpKTsKKyAgICAgICAgcmV0LnNldE51bWJlck9mTGlua3MocmVhZEJpbmFyeUxvbmcoMiwgc3dhcEhhbGZXb3JkKSk7CisgICAgICAgIHJldC5zZXRSZW1vdGVEZXZpY2UocmVhZEJpbmFyeUxvbmcoMiwgc3dhcEhhbGZXb3JkKSk7CisgICAgICAgIHJldC5zZXRUaW1lKHJlYWRCaW5hcnlMb25nKDQsIHN3YXBIYWxmV29yZCkpOworICAgICAgICBmaW5hbCBsb25nIG5hbWVzaXplID0gcmVhZEJpbmFyeUxvbmcoMiwgc3dhcEhhbGZXb3JkKTsKKyAgICAgICAgcmV0LnNldFNpemUocmVhZEJpbmFyeUxvbmcoNCwgc3dhcEhhbGZXb3JkKSk7CisgICAgICAgIGZpbmFsIFN0cmluZyBuYW1lID0gcmVhZENTdHJpbmcoKGludCkgbmFtZXNpemUpOworICAgICAgICByZXQuc2V0TmFtZShuYW1lKTsKKyAgICAgICAgaWYgKENwaW9VdGlsLmZpbGVUeXBlKG1vZGUpID09IDAgJiYgIW5hbWUuZXF1YWxzKENQSU9fVFJBSUxFUikpeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJNb2RlIDAgb25seSBhbGxvd2VkIGluIHRoZSB0cmFpbGVyLiBGb3VuZCBlbnRyeTogIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgQXJjaGl2ZVV0aWxzLnNhbml0aXplKG5hbWUpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiT2NjdXJlZCBhdCBieXRlOiAiICsgZ2V0Qnl0ZXNSZWFkKCkpOworICAgICAgICB9CisgICAgICAgIHNraXAocmV0LmdldEhlYWRlclBhZENvdW50KG5hbWVzaXplIC0gMSkpOworCisgICAgICAgIHJldHVybiByZXQ7CisgICAgfQorCisgICAgcHJpdmF0ZSBTdHJpbmcgcmVhZENTdHJpbmcoZmluYWwgaW50IGxlbmd0aCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gZG9uJ3QgaW5jbHVkZSB0cmFpbGluZyBOVUwgaW4gZmlsZSBuYW1lIHRvIGRlY29kZQorICAgICAgICBmaW5hbCBieXRlIHRtcEJ1ZmZlcltdID0gbmV3IGJ5dGVbbGVuZ3RoIC0gMV07CisgICAgICAgIHJlYWRGdWxseSh0bXBCdWZmZXIsIDAsIHRtcEJ1ZmZlci5sZW5ndGgpOworICAgICAgICB0aGlzLmluLnJlYWQoKTsKKyAgICAgICAgcmV0dXJuIHppcEVuY29kaW5nLmRlY29kZSh0bXBCdWZmZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNraXBzIHNwZWNpZmllZCBudW1iZXIgb2YgYnl0ZXMgaW4gdGhlIGN1cnJlbnQgQ1BJTyBlbnRyeS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRvIHNraXAKKyAgICAgKiBAcmV0dXJuIHRoZSBhY3R1YWwgbnVtYmVyIG9mIGJ5dGVzIHNraXBwZWQKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIGhhcyBvY2N1cnJlZAorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgbiAmbHQ7IDAKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgbG9uZyBza2lwKGZpbmFsIGxvbmcgbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKG4gPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJuZWdhdGl2ZSBza2lwIGxlbmd0aCIpOworICAgICAgICB9CisgICAgICAgIGVuc3VyZU9wZW4oKTsKKyAgICAgICAgZmluYWwgaW50IG1heCA9IChpbnQpIE1hdGgubWluKG4sIEludGVnZXIuTUFYX1ZBTFVFKTsKKyAgICAgICAgaW50IHRvdGFsID0gMDsKKworICAgICAgICB3aGlsZSAodG90YWwgPCBtYXgpIHsKKyAgICAgICAgICAgIGludCBsZW4gPSBtYXggLSB0b3RhbDsKKyAgICAgICAgICAgIGlmIChsZW4gPiB0aGlzLnRtcGJ1Zi5sZW5ndGgpIHsKKyAgICAgICAgICAgICAgICBsZW4gPSB0aGlzLnRtcGJ1Zi5sZW5ndGg7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBsZW4gPSByZWFkKHRoaXMudG1wYnVmLCAwLCBsZW4pOworICAgICAgICAgICAgaWYgKGxlbiA9PSAtMSkgeworICAgICAgICAgICAgICAgIHRoaXMuZW50cnlFT0YgPSB0cnVlOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdG90YWwgKz0gbGVuOworICAgICAgICB9CisgICAgICAgIHJldHVybiB0b3RhbDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQXJjaGl2ZUVudHJ5IGdldE5leHRFbnRyeSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBnZXROZXh0Q1BJT0VudHJ5KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2tpcHMgdGhlIHBhZGRpbmcgemVyb3Mgd3JpdHRlbiBhZnRlciB0aGUgVFJBSUxFUiEhISBlbnRyeS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgc2tpcFJlbWFpbmRlck9mTGFzdEJsb2NrKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgbG9uZyByZWFkRnJvbUxhc3RCbG9jayA9IGdldEJ5dGVzUmVhZCgpICUgYmxvY2tTaXplOworICAgICAgICBsb25nIHJlbWFpbmluZ0J5dGVzID0gcmVhZEZyb21MYXN0QmxvY2sgPT0gMCA/IDAKKyAgICAgICAgICAgIDogYmxvY2tTaXplIC0gcmVhZEZyb21MYXN0QmxvY2s7CisgICAgICAgIHdoaWxlIChyZW1haW5pbmdCeXRlcyA+IDApIHsKKyAgICAgICAgICAgIGZpbmFsIGxvbmcgc2tpcHBlZCA9IHNraXAoYmxvY2tTaXplIC0gcmVhZEZyb21MYXN0QmxvY2spOworICAgICAgICAgICAgaWYgKHNraXBwZWQgPD0gMCkgeworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmVtYWluaW5nQnl0ZXMgLT0gc2tpcHBlZDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrcyBpZiB0aGUgc2lnbmF0dXJlIG1hdGNoZXMgb25lIG9mIHRoZSBmb2xsb3dpbmcgbWFnaWMgdmFsdWVzOgorICAgICAqCisgICAgICogU3RyaW5nczoKKyAgICAgKgorICAgICAqICIwNzA3MDEiIC0gTUFHSUNfTkVXCisgICAgICogIjA3MDcwMiIgLSBNQUdJQ19ORVdfQ1JDCisgICAgICogIjA3MDcwNyIgLSBNQUdJQ19PTERfQVNDSUkKKyAgICAgKgorICAgICAqIE9jdGFsIEJpbmFyeSB2YWx1ZToKKyAgICAgKgorICAgICAqIDA3MDcwNyAtIE1BR0lDX09MRF9CSU5BUlkgKGhlbGQgYXMgYSBzaG9ydCkgPSAweDcxQzcgb3IgMHhDNzcxCisgICAgICogQHBhcmFtIHNpZ25hdHVyZSBkYXRhIHRvIG1hdGNoCisgICAgICogQHBhcmFtIGxlbmd0aCBsZW5ndGggb2YgZGF0YQorICAgICAqIEByZXR1cm4gd2hldGhlciB0aGUgYnVmZmVyIHNlZW1zIHRvIGNvbnRhaW4gQ1BJTyBkYXRhCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIG1hdGNoZXMoZmluYWwgYnl0ZVtdIHNpZ25hdHVyZSwgZmluYWwgaW50IGxlbmd0aCkgeworICAgICAgICBpZiAobGVuZ3RoIDwgNikgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgLy8gQ2hlY2sgYmluYXJ5IHZhbHVlcworICAgICAgICBpZiAoc2lnbmF0dXJlWzBdID09IDB4NzEgJiYgKHNpZ25hdHVyZVsxXSAmIDB4RkYpID09IDB4YzcpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmIChzaWduYXR1cmVbMV0gPT0gMHg3MSAmJiAoc2lnbmF0dXJlWzBdICYgMHhGRikgPT0gMHhjNykgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKworICAgICAgICAvLyBDaGVjayBBc2NpaSAoU3RyaW5nKSB2YWx1ZXMKKyAgICAgICAgLy8gMzAzNyAzMDM3IDMwbm4KKyAgICAgICAgaWYgKHNpZ25hdHVyZVswXSAhPSAweDMwKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHNpZ25hdHVyZVsxXSAhPSAweDM3KSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHNpZ25hdHVyZVsyXSAhPSAweDMwKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHNpZ25hdHVyZVszXSAhPSAweDM3KSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHNpZ25hdHVyZVs0XSAhPSAweDMwKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgLy8gQ2hlY2sgbGFzdCBieXRlCisgICAgICAgIGlmIChzaWduYXR1cmVbNV0gPT0gMHgzMSkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHNpZ25hdHVyZVs1XSA9PSAweDMyKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoc2lnbmF0dXJlWzVdID09IDB4MzcpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9jcGlvL0NwaW9BcmNoaXZlT3V0cHV0U3RyZWFtLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvY3Bpby9DcGlvQXJjaGl2ZU91dHB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYzMTc2NTMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvY3Bpby9DcGlvQXJjaGl2ZU91dHB1dFN0cmVhbS5qYXZhCkBAIC0wLDAgKzEsNTgwIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5jcGlvOworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5BcmNoaXZlRW50cnk7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5BcmNoaXZlT3V0cHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwLlppcEVuY29kaW5nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwLlppcEVuY29kaW5nSGVscGVyOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5BcmNoaXZlVXRpbHM7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLkNoYXJzZXROYW1lczsKKworLyoqCisgKiBDcGlvQXJjaGl2ZU91dHB1dFN0cmVhbSBpcyBhIHN0cmVhbSBmb3Igd3JpdGluZyBDUElPIHN0cmVhbXMuIEFsbCBmb3JtYXRzIG9mCisgKiBDUElPIGFyZSBzdXBwb3J0ZWQgKG9sZCBBU0NJSSwgb2xkIGJpbmFyeSwgbmV3IHBvcnRhYmxlIGZvcm1hdCBhbmQgdGhlIG5ldworICogcG9ydGFibGUgZm9ybWF0IHdpdGggQ1JDKS4KKyAqCisgKiA8cD5BbiBlbnRyeSBjYW4gYmUgd3JpdHRlbiBieSBjcmVhdGluZyBhbiBpbnN0YW5jZSBvZiBDcGlvQXJjaGl2ZUVudHJ5IGFuZCBmaWxsCisgKiBpdCB3aXRoIHRoZSBuZWNlc3NhcnkgdmFsdWVzIGFuZCBwdXQgaXQgaW50byB0aGUgQ1BJTyBzdHJlYW0uIEFmdGVyd2FyZHMKKyAqIHdyaXRlIHRoZSBjb250ZW50cyBvZiB0aGUgZmlsZSBpbnRvIHRoZSBDUElPIHN0cmVhbS4gRWl0aGVyIGNsb3NlIHRoZSBzdHJlYW0KKyAqIGJ5IGNhbGxpbmcgZmluaXNoKCkgb3IgcHV0IGEgbmV4dCBlbnRyeSBpbnRvIHRoZSBjcGlvIHN0cmVhbS48L3A+CisgKgorICogPHByZT4KKyAqIENwaW9BcmNoaXZlT3V0cHV0U3RyZWFtIG91dCA9IG5ldyBDcGlvQXJjaGl2ZU91dHB1dFN0cmVhbSgKKyAqICAgICAgICAgbmV3IEZpbGVPdXRwdXRTdHJlYW0obmV3IEZpbGUoInRlc3QuY3BpbyIpKSk7CisgKiBDcGlvQXJjaGl2ZUVudHJ5IGVudHJ5ID0gbmV3IENwaW9BcmNoaXZlRW50cnkoKTsKKyAqIGVudHJ5LnNldE5hbWUoInRlc3RmaWxlIik7CisgKiBTdHJpbmcgY29udGVudHMgPSAmcXVvdDsxMjM0NSZxdW90OzsKKyAqIGVudHJ5LnNldEZpbGVTaXplKGNvbnRlbnRzLmxlbmd0aCgpKTsKKyAqIGVudHJ5LnNldE1vZGUoQ3Bpb0NvbnN0YW50cy5DX0lTUkVHKTsgLy8gcmVndWxhciBmaWxlCisgKiAuLi4gc2V0IG90aGVyIGF0dHJpYnV0ZXMsIGUuZy4gdGltZSwgbnVtYmVyIG9mIGxpbmtzCisgKiBvdXQucHV0QXJjaGl2ZUVudHJ5KGVudHJ5KTsKKyAqIG91dC53cml0ZSh0ZXN0Q29udGVudHMuZ2V0Qnl0ZXMoKSk7CisgKiBvdXQuY2xvc2UoKTsKKyAqIDwvcHJlPgorICoKKyAqIDxwPk5vdGU6IFRoaXMgaW1wbGVtZW50YXRpb24gc2hvdWxkIGJlIGNvbXBhdGlibGUgdG8gY3BpbyAyLjU8L3A+CisgKgorICogPHA+VGhpcyBjbGFzcyB1c2VzIG11dGFibGUgZmllbGRzIGFuZCBpcyBub3QgY29uc2lkZXJlZCB0aHJlYWRzYWZlLjwvcD4KKyAqCisgKiA8cD5iYXNlZCBvbiBjb2RlIGZyb20gdGhlIGpSUE0gcHJvamVjdCAoanJwbS5zb3VyY2Vmb3JnZS5uZXQpPC9wPgorICovCitwdWJsaWMgY2xhc3MgQ3Bpb0FyY2hpdmVPdXRwdXRTdHJlYW0gZXh0ZW5kcyBBcmNoaXZlT3V0cHV0U3RyZWFtIGltcGxlbWVudHMKKyAgICAgICAgQ3Bpb0NvbnN0YW50cyB7CisKKyAgICBwcml2YXRlIENwaW9BcmNoaXZlRW50cnkgZW50cnk7CisKKyAgICBwcml2YXRlIGJvb2xlYW4gY2xvc2VkID0gZmFsc2U7CisKKyAgICAvKiogaW5kaWNhdGVzIGlmIHRoaXMgYXJjaGl2ZSBpcyBmaW5pc2hlZCAqLworICAgIHByaXZhdGUgYm9vbGVhbiBmaW5pc2hlZDsKKworICAgIC8qKgorICAgICAqIFNlZSB7QGxpbmsgQ3Bpb0FyY2hpdmVFbnRyeSNzZXRGb3JtYXQoc2hvcnQpfSBmb3IgcG9zc2libGUgdmFsdWVzLgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgc2hvcnQgZW50cnlGb3JtYXQ7CisKKyAgICBwcml2YXRlIGZpbmFsIEhhc2hNYXA8U3RyaW5nLCBDcGlvQXJjaGl2ZUVudHJ5PiBuYW1lcyA9CisgICAgICAgIG5ldyBIYXNoTWFwPD4oKTsKKworICAgIHByaXZhdGUgbG9uZyBjcmMgPSAwOworCisgICAgcHJpdmF0ZSBsb25nIHdyaXR0ZW47CisKKyAgICBwcml2YXRlIGZpbmFsIE91dHB1dFN0cmVhbSBvdXQ7CisKKyAgICBwcml2YXRlIGZpbmFsIGludCBibG9ja1NpemU7CisKKyAgICBwcml2YXRlIGxvbmcgbmV4dEFydGlmaWNhbERldmljZUFuZElub2RlID0gMTsKKworICAgIC8qKgorICAgICAqIFRoZSBlbmNvZGluZyB0byB1c2UgZm9yIGZpbGVuYW1lcyBhbmQgbGFiZWxzLgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgWmlwRW5jb2RpbmcgemlwRW5jb2Rpbmc7CisKKyAgICAvLyB0aGUgcHJvdmlkZWQgZW5jb2RpbmcgKGZvciB1bml0IHRlc3RzKQorICAgIGZpbmFsIFN0cmluZyBlbmNvZGluZzsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdCB0aGUgY3BpbyBvdXRwdXQgc3RyZWFtIHdpdGggYSBzcGVjaWZpZWQgZm9ybWF0LCBhCisgICAgICogYmxvY2tzaXplIG9mIHtAbGluayBDcGlvQ29uc3RhbnRzI0JMT0NLX1NJWkUgQkxPQ0tfU0laRX0gYW5kCisgICAgICogdXNpbmcgQVNDSUkgYXMgdGhlIGZpbGUgbmFtZSBlbmNvZGluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvdXQKKyAgICAgKiAgICAgICAgICAgIFRoZSBjcGlvIHN0cmVhbQorICAgICAqIEBwYXJhbSBmb3JtYXQKKyAgICAgKiAgICAgICAgICAgIFRoZSBmb3JtYXQgb2YgdGhlIHN0cmVhbQorICAgICAqLworICAgIHB1YmxpYyBDcGlvQXJjaGl2ZU91dHB1dFN0cmVhbShmaW5hbCBPdXRwdXRTdHJlYW0gb3V0LCBmaW5hbCBzaG9ydCBmb3JtYXQpIHsKKyAgICAgICAgdGhpcyhvdXQsIGZvcm1hdCwgQkxPQ0tfU0laRSwgQ2hhcnNldE5hbWVzLlVTX0FTQ0lJKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3QgdGhlIGNwaW8gb3V0cHV0IHN0cmVhbSB3aXRoIGEgc3BlY2lmaWVkIGZvcm1hdCB1c2luZworICAgICAqIEFTQ0lJIGFzIHRoZSBmaWxlIG5hbWUgZW5jb2RpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3V0CisgICAgICogICAgICAgICAgICBUaGUgY3BpbyBzdHJlYW0KKyAgICAgKiBAcGFyYW0gZm9ybWF0CisgICAgICogICAgICAgICAgICBUaGUgZm9ybWF0IG9mIHRoZSBzdHJlYW0KKyAgICAgKiBAcGFyYW0gYmxvY2tTaXplCisgICAgICogICAgICAgICAgICBUaGUgYmxvY2sgc2l6ZSBvZiB0aGUgYXJjaGl2ZS4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjEKKyAgICAgKi8KKyAgICBwdWJsaWMgQ3Bpb0FyY2hpdmVPdXRwdXRTdHJlYW0oZmluYWwgT3V0cHV0U3RyZWFtIG91dCwgZmluYWwgc2hvcnQgZm9ybWF0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgYmxvY2tTaXplKSB7CisgICAgICAgIHRoaXMob3V0LCBmb3JtYXQsIGJsb2NrU2l6ZSwgQ2hhcnNldE5hbWVzLlVTX0FTQ0lJKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3QgdGhlIGNwaW8gb3V0cHV0IHN0cmVhbSB3aXRoIGEgc3BlY2lmaWVkIGZvcm1hdCB1c2luZworICAgICAqIEFTQ0lJIGFzIHRoZSBmaWxlIG5hbWUgZW5jb2RpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3V0CisgICAgICogICAgICAgICAgICBUaGUgY3BpbyBzdHJlYW0KKyAgICAgKiBAcGFyYW0gZm9ybWF0CisgICAgICogICAgICAgICAgICBUaGUgZm9ybWF0IG9mIHRoZSBzdHJlYW0KKyAgICAgKiBAcGFyYW0gYmxvY2tTaXplCisgICAgICogICAgICAgICAgICBUaGUgYmxvY2sgc2l6ZSBvZiB0aGUgYXJjaGl2ZS4KKyAgICAgKiBAcGFyYW0gZW5jb2RpbmcKKyAgICAgKiAgICAgICAgICAgIFRoZSBlbmNvZGluZyBvZiBmaWxlIG5hbWVzIHRvIHdyaXRlIC0gdXNlIG51bGwgZm9yCisgICAgICogICAgICAgICAgICB0aGUgcGxhdGZvcm0ncyBkZWZhdWx0LgorICAgICAqCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBDcGlvQXJjaGl2ZU91dHB1dFN0cmVhbShmaW5hbCBPdXRwdXRTdHJlYW0gb3V0LCBmaW5hbCBzaG9ydCBmb3JtYXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBibG9ja1NpemUsIGZpbmFsIFN0cmluZyBlbmNvZGluZykgeworICAgICAgICB0aGlzLm91dCA9IG91dDsKKyAgICAgICAgc3dpdGNoIChmb3JtYXQpIHsKKyAgICAgICAgY2FzZSBGT1JNQVRfTkVXOgorICAgICAgICBjYXNlIEZPUk1BVF9ORVdfQ1JDOgorICAgICAgICBjYXNlIEZPUk1BVF9PTERfQVNDSUk6CisgICAgICAgIGNhc2UgRk9STUFUX09MRF9CSU5BUlk6CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlVua25vd24gZm9ybWF0OiAiK2Zvcm1hdCk7CisKKyAgICAgICAgfQorICAgICAgICB0aGlzLmVudHJ5Rm9ybWF0ID0gZm9ybWF0OworICAgICAgICB0aGlzLmJsb2NrU2l6ZSA9IGJsb2NrU2l6ZTsKKyAgICAgICAgdGhpcy5lbmNvZGluZyA9IGVuY29kaW5nOworICAgICAgICB0aGlzLnppcEVuY29kaW5nID0gWmlwRW5jb2RpbmdIZWxwZXIuZ2V0WmlwRW5jb2RpbmcoZW5jb2RpbmcpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdCB0aGUgY3BpbyBvdXRwdXQgc3RyZWFtLiBUaGUgZm9ybWF0IGZvciB0aGlzIENQSU8gc3RyZWFtIGlzIHRoZQorICAgICAqICJuZXciIGZvcm1hdCB1c2luZyBBU0NJSSBlbmNvZGluZyBmb3IgZmlsZSBuYW1lcworICAgICAqCisgICAgICogQHBhcmFtIG91dAorICAgICAqICAgICAgICAgICAgVGhlIGNwaW8gc3RyZWFtCisgICAgICovCisgICAgcHVibGljIENwaW9BcmNoaXZlT3V0cHV0U3RyZWFtKGZpbmFsIE91dHB1dFN0cmVhbSBvdXQpIHsKKyAgICAgICAgdGhpcyhvdXQsIEZPUk1BVF9ORVcpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdCB0aGUgY3BpbyBvdXRwdXQgc3RyZWFtLiBUaGUgZm9ybWF0IGZvciB0aGlzIENQSU8gc3RyZWFtIGlzIHRoZQorICAgICAqICJuZXciIGZvcm1hdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvdXQKKyAgICAgKiAgICAgICAgICAgIFRoZSBjcGlvIHN0cmVhbQorICAgICAqIEBwYXJhbSBlbmNvZGluZworICAgICAqICAgICAgICAgICAgVGhlIGVuY29kaW5nIG9mIGZpbGUgbmFtZXMgdG8gd3JpdGUgLSB1c2UgbnVsbCBmb3IKKyAgICAgKiAgICAgICAgICAgIHRoZSBwbGF0Zm9ybSdzIGRlZmF1bHQuCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBDcGlvQXJjaGl2ZU91dHB1dFN0cmVhbShmaW5hbCBPdXRwdXRTdHJlYW0gb3V0LCBmaW5hbCBTdHJpbmcgZW5jb2RpbmcpIHsKKyAgICAgICAgdGhpcyhvdXQsIEZPUk1BVF9ORVcsIEJMT0NLX1NJWkUsIGVuY29kaW5nKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVjayB0byBtYWtlIHN1cmUgdGhhdCB0aGlzIHN0cmVhbSBoYXMgbm90IGJlZW4gY2xvc2VkCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHN0cmVhbSBpcyBhbHJlYWR5IGNsb3NlZAorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBlbnN1cmVPcGVuKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHRoaXMuY2xvc2VkKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlN0cmVhbSBjbG9zZWQiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEJlZ2lucyB3cml0aW5nIGEgbmV3IENQSU8gZmlsZSBlbnRyeSBhbmQgcG9zaXRpb25zIHRoZSBzdHJlYW0gdG8gdGhlCisgICAgICogc3RhcnQgb2YgdGhlIGVudHJ5IGRhdGEuIENsb3NlcyB0aGUgY3VycmVudCBlbnRyeSBpZiBzdGlsbCBhY3RpdmUuIFRoZQorICAgICAqIGN1cnJlbnQgdGltZSB3aWxsIGJlIHVzZWQgaWYgdGhlIGVudHJ5IGhhcyBubyBzZXQgbW9kaWZpY2F0aW9uIHRpbWUgYW5kCisgICAgICogdGhlIGRlZmF1bHQgaGVhZGVyIGZvcm1hdCB3aWxsIGJlIHVzZWQgaWYgbm8gb3RoZXIgZm9ybWF0IGlzIHNwZWNpZmllZCBpbgorICAgICAqIHRoZSBlbnRyeS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlbnRyeQorICAgICAqICAgICAgICAgICAgdGhlIENQSU8gY3Bpb0VudHJ5IHRvIGJlIHdyaXR0ZW4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIGhhcyBvY2N1cnJlZCBvciBpZiBhIENQSU8gZmlsZSBlcnJvciBoYXMKKyAgICAgKiAgICAgICAgICAgICBvY2N1cnJlZAorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIGlmIGVudHJ5IGlzIG5vdCBhbiBpbnN0YW5jZSBvZiBDcGlvQXJjaGl2ZUVudHJ5CisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcHV0QXJjaGl2ZUVudHJ5KGZpbmFsIEFyY2hpdmVFbnRyeSBlbnRyeSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYoZmluaXNoZWQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiU3RyZWFtIGhhcyBhbHJlYWR5IGJlZW4gZmluaXNoZWQiKTsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIENwaW9BcmNoaXZlRW50cnkgZSA9IChDcGlvQXJjaGl2ZUVudHJ5KSBlbnRyeTsKKyAgICAgICAgZW5zdXJlT3BlbigpOworICAgICAgICBpZiAodGhpcy5lbnRyeSAhPSBudWxsKSB7CisgICAgICAgICAgICBjbG9zZUFyY2hpdmVFbnRyeSgpOyAvLyBjbG9zZSBwcmV2aW91cyBlbnRyeQorICAgICAgICB9CisgICAgICAgIGlmIChlLmdldFRpbWUoKSA9PSAtMSkgeworICAgICAgICAgICAgZS5zZXRUaW1lKFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpIC8gMTAwMCk7CisgICAgICAgIH0KKworICAgICAgICBmaW5hbCBzaG9ydCBmb3JtYXQgPSBlLmdldEZvcm1hdCgpOworICAgICAgICBpZiAoZm9ybWF0ICE9IHRoaXMuZW50cnlGb3JtYXQpeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJIZWFkZXIgZm9ybWF0OiAiK2Zvcm1hdCsiIGRvZXMgbm90IG1hdGNoIGV4aXN0aW5nIGZvcm1hdDogIit0aGlzLmVudHJ5Rm9ybWF0KTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICh0aGlzLm5hbWVzLnB1dChlLmdldE5hbWUoKSwgZSkgIT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJkdXBsaWNhdGUgZW50cnk6ICIgKyBlLmdldE5hbWUoKSk7CisgICAgICAgIH0KKworICAgICAgICB3cml0ZUhlYWRlcihlKTsKKyAgICAgICAgdGhpcy5lbnRyeSA9IGU7CisgICAgICAgIHRoaXMud3JpdHRlbiA9IDA7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlSGVhZGVyKGZpbmFsIENwaW9BcmNoaXZlRW50cnkgZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3dpdGNoIChlLmdldEZvcm1hdCgpKSB7CisgICAgICAgIGNhc2UgRk9STUFUX05FVzoKKyAgICAgICAgICAgIG91dC53cml0ZShBcmNoaXZlVXRpbHMudG9Bc2NpaUJ5dGVzKE1BR0lDX05FVykpOworICAgICAgICAgICAgY291bnQoNik7CisgICAgICAgICAgICB3cml0ZU5ld0VudHJ5KGUpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgRk9STUFUX05FV19DUkM6CisgICAgICAgICAgICBvdXQud3JpdGUoQXJjaGl2ZVV0aWxzLnRvQXNjaWlCeXRlcyhNQUdJQ19ORVdfQ1JDKSk7CisgICAgICAgICAgICBjb3VudCg2KTsKKyAgICAgICAgICAgIHdyaXRlTmV3RW50cnkoZSk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBGT1JNQVRfT0xEX0FTQ0lJOgorICAgICAgICAgICAgb3V0LndyaXRlKEFyY2hpdmVVdGlscy50b0FzY2lpQnl0ZXMoTUFHSUNfT0xEX0FTQ0lJKSk7CisgICAgICAgICAgICBjb3VudCg2KTsKKyAgICAgICAgICAgIHdyaXRlT2xkQXNjaWlFbnRyeShlKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIEZPUk1BVF9PTERfQklOQVJZOgorICAgICAgICAgICAgZmluYWwgYm9vbGVhbiBzd2FwSGFsZldvcmQgPSB0cnVlOworICAgICAgICAgICAgd3JpdGVCaW5hcnlMb25nKE1BR0lDX09MRF9CSU5BUlksIDIsIHN3YXBIYWxmV29yZCk7CisgICAgICAgICAgICB3cml0ZU9sZEJpbmFyeUVudHJ5KGUsIHN3YXBIYWxmV29yZCk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigidW5rbm93biBmb3JtYXQgIiArIGUuZ2V0Rm9ybWF0KCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlTmV3RW50cnkoZmluYWwgQ3Bpb0FyY2hpdmVFbnRyeSBlbnRyeSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgbG9uZyBpbm9kZSA9IGVudHJ5LmdldElub2RlKCk7CisgICAgICAgIGxvbmcgZGV2TWluID0gZW50cnkuZ2V0RGV2aWNlTWluKCk7CisgICAgICAgIGlmIChDUElPX1RSQUlMRVIuZXF1YWxzKGVudHJ5LmdldE5hbWUoKSkpIHsKKyAgICAgICAgICAgIGlub2RlID0gZGV2TWluID0gMDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGlmIChpbm9kZSA9PSAwICYmIGRldk1pbiA9PSAwKSB7CisgICAgICAgICAgICAgICAgaW5vZGUgPSBuZXh0QXJ0aWZpY2FsRGV2aWNlQW5kSW5vZGUgJiAweEZGRkZGRkZGOworICAgICAgICAgICAgICAgIGRldk1pbiA9IChuZXh0QXJ0aWZpY2FsRGV2aWNlQW5kSW5vZGUrKyA+PiAzMikgJiAweEZGRkZGRkZGOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBuZXh0QXJ0aWZpY2FsRGV2aWNlQW5kSW5vZGUgPQorICAgICAgICAgICAgICAgICAgICBNYXRoLm1heChuZXh0QXJ0aWZpY2FsRGV2aWNlQW5kSW5vZGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlub2RlICsgMHgxMDAwMDAwMDBMICogZGV2TWluKSArIDE7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB3cml0ZUFzY2lpTG9uZyhpbm9kZSwgOCwgMTYpOworICAgICAgICB3cml0ZUFzY2lpTG9uZyhlbnRyeS5nZXRNb2RlKCksIDgsIDE2KTsKKyAgICAgICAgd3JpdGVBc2NpaUxvbmcoZW50cnkuZ2V0VUlEKCksIDgsIDE2KTsKKyAgICAgICAgd3JpdGVBc2NpaUxvbmcoZW50cnkuZ2V0R0lEKCksIDgsIDE2KTsKKyAgICAgICAgd3JpdGVBc2NpaUxvbmcoZW50cnkuZ2V0TnVtYmVyT2ZMaW5rcygpLCA4LCAxNik7CisgICAgICAgIHdyaXRlQXNjaWlMb25nKGVudHJ5LmdldFRpbWUoKSwgOCwgMTYpOworICAgICAgICB3cml0ZUFzY2lpTG9uZyhlbnRyeS5nZXRTaXplKCksIDgsIDE2KTsKKyAgICAgICAgd3JpdGVBc2NpaUxvbmcoZW50cnkuZ2V0RGV2aWNlTWFqKCksIDgsIDE2KTsKKyAgICAgICAgd3JpdGVBc2NpaUxvbmcoZGV2TWluLCA4LCAxNik7CisgICAgICAgIHdyaXRlQXNjaWlMb25nKGVudHJ5LmdldFJlbW90ZURldmljZU1haigpLCA4LCAxNik7CisgICAgICAgIHdyaXRlQXNjaWlMb25nKGVudHJ5LmdldFJlbW90ZURldmljZU1pbigpLCA4LCAxNik7CisgICAgICAgIGJ5dGVbXSBuYW1lID0gZW5jb2RlKGVudHJ5LmdldE5hbWUoKSk7CisgICAgICAgIHdyaXRlQXNjaWlMb25nKG5hbWUubGVuZ3RoICsgMUwsIDgsIDE2KTsKKyAgICAgICAgd3JpdGVBc2NpaUxvbmcoZW50cnkuZ2V0Q2hrc3VtKCksIDgsIDE2KTsKKyAgICAgICAgd3JpdGVDU3RyaW5nKG5hbWUpOworICAgICAgICBwYWQoZW50cnkuZ2V0SGVhZGVyUGFkQ291bnQobmFtZS5sZW5ndGgpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgd3JpdGVPbGRBc2NpaUVudHJ5KGZpbmFsIENwaW9BcmNoaXZlRW50cnkgZW50cnkpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBsb25nIGlub2RlID0gZW50cnkuZ2V0SW5vZGUoKTsKKyAgICAgICAgbG9uZyBkZXZpY2UgPSBlbnRyeS5nZXREZXZpY2UoKTsKKyAgICAgICAgaWYgKENQSU9fVFJBSUxFUi5lcXVhbHMoZW50cnkuZ2V0TmFtZSgpKSkgeworICAgICAgICAgICAgaW5vZGUgPSBkZXZpY2UgPSAwOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaWYgKGlub2RlID09IDAgJiYgZGV2aWNlID09IDApIHsKKyAgICAgICAgICAgICAgICBpbm9kZSA9IG5leHRBcnRpZmljYWxEZXZpY2VBbmRJbm9kZSAmIDA3Nzc3Nzc7CisgICAgICAgICAgICAgICAgZGV2aWNlID0gKG5leHRBcnRpZmljYWxEZXZpY2VBbmRJbm9kZSsrID4+IDE4KSAmIDA3Nzc3Nzc7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIG5leHRBcnRpZmljYWxEZXZpY2VBbmRJbm9kZSA9CisgICAgICAgICAgICAgICAgICAgIE1hdGgubWF4KG5leHRBcnRpZmljYWxEZXZpY2VBbmRJbm9kZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5vZGUgKyAwMTAwMDAwMCAqIGRldmljZSkgKyAxOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgd3JpdGVBc2NpaUxvbmcoZGV2aWNlLCA2LCA4KTsKKyAgICAgICAgd3JpdGVBc2NpaUxvbmcoaW5vZGUsIDYsIDgpOworICAgICAgICB3cml0ZUFzY2lpTG9uZyhlbnRyeS5nZXRNb2RlKCksIDYsIDgpOworICAgICAgICB3cml0ZUFzY2lpTG9uZyhlbnRyeS5nZXRVSUQoKSwgNiwgOCk7CisgICAgICAgIHdyaXRlQXNjaWlMb25nKGVudHJ5LmdldEdJRCgpLCA2LCA4KTsKKyAgICAgICAgd3JpdGVBc2NpaUxvbmcoZW50cnkuZ2V0TnVtYmVyT2ZMaW5rcygpLCA2LCA4KTsKKyAgICAgICAgd3JpdGVBc2NpaUxvbmcoZW50cnkuZ2V0UmVtb3RlRGV2aWNlKCksIDYsIDgpOworICAgICAgICB3cml0ZUFzY2lpTG9uZyhlbnRyeS5nZXRUaW1lKCksIDExLCA4KTsKKyAgICAgICAgYnl0ZVtdIG5hbWUgPSBlbmNvZGUoZW50cnkuZ2V0TmFtZSgpKTsKKyAgICAgICAgd3JpdGVBc2NpaUxvbmcobmFtZS5sZW5ndGggKyAxTCwgNiwgOCk7CisgICAgICAgIHdyaXRlQXNjaWlMb25nKGVudHJ5LmdldFNpemUoKSwgMTEsIDgpOworICAgICAgICB3cml0ZUNTdHJpbmcobmFtZSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlT2xkQmluYXJ5RW50cnkoZmluYWwgQ3Bpb0FyY2hpdmVFbnRyeSBlbnRyeSwKKyAgICAgICAgICAgIGZpbmFsIGJvb2xlYW4gc3dhcEhhbGZXb3JkKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBsb25nIGlub2RlID0gZW50cnkuZ2V0SW5vZGUoKTsKKyAgICAgICAgbG9uZyBkZXZpY2UgPSBlbnRyeS5nZXREZXZpY2UoKTsKKyAgICAgICAgaWYgKENQSU9fVFJBSUxFUi5lcXVhbHMoZW50cnkuZ2V0TmFtZSgpKSkgeworICAgICAgICAgICAgaW5vZGUgPSBkZXZpY2UgPSAwOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaWYgKGlub2RlID09IDAgJiYgZGV2aWNlID09IDApIHsKKyAgICAgICAgICAgICAgICBpbm9kZSA9IG5leHRBcnRpZmljYWxEZXZpY2VBbmRJbm9kZSAmIDB4RkZGRjsKKyAgICAgICAgICAgICAgICBkZXZpY2UgPSAobmV4dEFydGlmaWNhbERldmljZUFuZElub2RlKysgPj4gMTYpICYgMHhGRkZGOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBuZXh0QXJ0aWZpY2FsRGV2aWNlQW5kSW5vZGUgPQorICAgICAgICAgICAgICAgICAgICBNYXRoLm1heChuZXh0QXJ0aWZpY2FsRGV2aWNlQW5kSW5vZGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlub2RlICsgMHgxMDAwMCAqIGRldmljZSkgKyAxOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgd3JpdGVCaW5hcnlMb25nKGRldmljZSwgMiwgc3dhcEhhbGZXb3JkKTsKKyAgICAgICAgd3JpdGVCaW5hcnlMb25nKGlub2RlLCAyLCBzd2FwSGFsZldvcmQpOworICAgICAgICB3cml0ZUJpbmFyeUxvbmcoZW50cnkuZ2V0TW9kZSgpLCAyLCBzd2FwSGFsZldvcmQpOworICAgICAgICB3cml0ZUJpbmFyeUxvbmcoZW50cnkuZ2V0VUlEKCksIDIsIHN3YXBIYWxmV29yZCk7CisgICAgICAgIHdyaXRlQmluYXJ5TG9uZyhlbnRyeS5nZXRHSUQoKSwgMiwgc3dhcEhhbGZXb3JkKTsKKyAgICAgICAgd3JpdGVCaW5hcnlMb25nKGVudHJ5LmdldE51bWJlck9mTGlua3MoKSwgMiwgc3dhcEhhbGZXb3JkKTsKKyAgICAgICAgd3JpdGVCaW5hcnlMb25nKGVudHJ5LmdldFJlbW90ZURldmljZSgpLCAyLCBzd2FwSGFsZldvcmQpOworICAgICAgICB3cml0ZUJpbmFyeUxvbmcoZW50cnkuZ2V0VGltZSgpLCA0LCBzd2FwSGFsZldvcmQpOworICAgICAgICBieXRlW10gbmFtZSA9IGVuY29kZShlbnRyeS5nZXROYW1lKCkpOworICAgICAgICB3cml0ZUJpbmFyeUxvbmcobmFtZS5sZW5ndGggKyAxTCwgMiwgc3dhcEhhbGZXb3JkKTsKKyAgICAgICAgd3JpdGVCaW5hcnlMb25nKGVudHJ5LmdldFNpemUoKSwgNCwgc3dhcEhhbGZXb3JkKTsKKyAgICAgICAgd3JpdGVDU3RyaW5nKG5hbWUpOworICAgICAgICBwYWQoZW50cnkuZ2V0SGVhZGVyUGFkQ291bnQobmFtZS5sZW5ndGgpKTsKKyAgICB9CisKKyAgICAvKihub24tSmF2YWRvYykKKyAgICAgKgorICAgICAqIEBzZWUKKyAgICAgKiBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLkFyY2hpdmVPdXRwdXRTdHJlYW0jY2xvc2VBcmNoaXZlRW50cnkKKyAgICAgKiAoKQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlQXJjaGl2ZUVudHJ5KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYoZmluaXNoZWQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiU3RyZWFtIGhhcyBhbHJlYWR5IGJlZW4gZmluaXNoZWQiKTsKKyAgICAgICAgfQorCisgICAgICAgIGVuc3VyZU9wZW4oKTsKKworICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJUcnlpbmcgdG8gY2xvc2Ugbm9uLWV4aXN0ZW50IGVudHJ5Iik7CisgICAgICAgIH0KKworICAgICAgICBpZiAodGhpcy5lbnRyeS5nZXRTaXplKCkgIT0gdGhpcy53cml0dGVuKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oImludmFsaWQgZW50cnkgc2l6ZSAoZXhwZWN0ZWQgIgorICAgICAgICAgICAgICAgICAgICArIHRoaXMuZW50cnkuZ2V0U2l6ZSgpICsgIiBidXQgZ290ICIgKyB0aGlzLndyaXR0ZW4KKyAgICAgICAgICAgICAgICAgICAgKyAiIGJ5dGVzKSIpOworICAgICAgICB9CisgICAgICAgIHBhZCh0aGlzLmVudHJ5LmdldERhdGFQYWRDb3VudCgpKTsKKyAgICAgICAgaWYgKHRoaXMuZW50cnkuZ2V0Rm9ybWF0KCkgPT0gRk9STUFUX05FV19DUkMKKyAgICAgICAgICAgICYmIHRoaXMuY3JjICE9IHRoaXMuZW50cnkuZ2V0Q2hrc3VtKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiQ1JDIEVycm9yIik7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5lbnRyeSA9IG51bGw7CisgICAgICAgIHRoaXMuY3JjID0gMDsKKyAgICAgICAgdGhpcy53cml0dGVuID0gMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgYW4gYXJyYXkgb2YgYnl0ZXMgdG8gdGhlIGN1cnJlbnQgQ1BJTyBlbnRyeSBkYXRhLiBUaGlzIG1ldGhvZCB3aWxsCisgICAgICogYmxvY2sgdW50aWwgYWxsIHRoZSBieXRlcyBhcmUgd3JpdHRlbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBiCisgICAgICogICAgICAgICAgICB0aGUgZGF0YSB0byBiZSB3cml0dGVuCisgICAgICogQHBhcmFtIG9mZgorICAgICAqICAgICAgICAgICAgdGhlIHN0YXJ0IG9mZnNldCBpbiB0aGUgZGF0YQorICAgICAqIEBwYXJhbSBsZW4KKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCBhcmUgd3JpdHRlbgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXJyb3IgaGFzIG9jY3VycmVkIG9yIGlmIGEgQ1BJTyBmaWxlIGVycm9yIGhhcworICAgICAqICAgICAgICAgICAgIG9jY3VycmVkCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGUoZmluYWwgYnl0ZVtdIGIsIGZpbmFsIGludCBvZmYsIGZpbmFsIGludCBsZW4pCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBlbnN1cmVPcGVuKCk7CisgICAgICAgIGlmIChvZmYgPCAwIHx8IGxlbiA8IDAgfHwgb2ZmID4gYi5sZW5ndGggLSBsZW4pIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCk7CisgICAgICAgIH0gZWxzZSBpZiAobGVuID09IDApIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIGlmICh0aGlzLmVudHJ5ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigibm8gY3VycmVudCBDUElPIGVudHJ5Iik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHRoaXMud3JpdHRlbiArIGxlbiA+IHRoaXMuZW50cnkuZ2V0U2l6ZSgpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oImF0dGVtcHQgdG8gd3JpdGUgcGFzdCBlbmQgb2YgU1RPUkVEIGVudHJ5Iik7CisgICAgICAgIH0KKyAgICAgICAgb3V0LndyaXRlKGIsIG9mZiwgbGVuKTsKKyAgICAgICAgdGhpcy53cml0dGVuICs9IGxlbjsKKyAgICAgICAgaWYgKHRoaXMuZW50cnkuZ2V0Rm9ybWF0KCkgPT0gRk9STUFUX05FV19DUkMpIHsKKyAgICAgICAgICAgIGZvciAoaW50IHBvcyA9IDA7IHBvcyA8IGxlbjsgcG9zKyspIHsKKyAgICAgICAgICAgICAgICB0aGlzLmNyYyArPSBiW3Bvc10gJiAweEZGOworICAgICAgICAgICAgICAgIHRoaXMuY3JjICY9IDB4RkZGRkZGRkZMOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGNvdW50KGxlbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmluaXNoZXMgd3JpdGluZyB0aGUgY29udGVudHMgb2YgdGhlIENQSU8gb3V0cHV0IHN0cmVhbSB3aXRob3V0IGNsb3NpbmcKKyAgICAgKiB0aGUgdW5kZXJseWluZyBzdHJlYW0uIFVzZSB0aGlzIG1ldGhvZCB3aGVuIGFwcGx5aW5nIG11bHRpcGxlIGZpbHRlcnMgaW4KKyAgICAgKiBzdWNjZXNzaW9uIHRvIHRoZSBzYW1lIG91dHB1dCBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQgb3IgaWYgYSBDUElPIGZpbGUgZXJyb3IgaGFzCisgICAgICogICAgICAgICAgICAgb2NjdXJyZWQKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBmaW5pc2goKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBlbnN1cmVPcGVuKCk7CisgICAgICAgIGlmIChmaW5pc2hlZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJUaGlzIGFyY2hpdmUgaGFzIGFscmVhZHkgYmVlbiBmaW5pc2hlZCIpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHRoaXMuZW50cnkgIT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJUaGlzIGFyY2hpdmUgY29udGFpbnMgdW5jbG9zZWQgZW50cmllcy4iKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmVudHJ5ID0gbmV3IENwaW9BcmNoaXZlRW50cnkodGhpcy5lbnRyeUZvcm1hdCk7CisgICAgICAgIHRoaXMuZW50cnkuc2V0TmFtZShDUElPX1RSQUlMRVIpOworICAgICAgICB0aGlzLmVudHJ5LnNldE51bWJlck9mTGlua3MoMSk7CisgICAgICAgIHdyaXRlSGVhZGVyKHRoaXMuZW50cnkpOworICAgICAgICBjbG9zZUFyY2hpdmVFbnRyeSgpOworCisgICAgICAgIGZpbmFsIGludCBsZW5ndGhPZkxhc3RCbG9jayA9IChpbnQpIChnZXRCeXRlc1dyaXR0ZW4oKSAlIGJsb2NrU2l6ZSk7CisgICAgICAgIGlmIChsZW5ndGhPZkxhc3RCbG9jayAhPSAwKSB7CisgICAgICAgICAgICBwYWQoYmxvY2tTaXplIC0gbGVuZ3RoT2ZMYXN0QmxvY2spOworICAgICAgICB9CisKKyAgICAgICAgZmluaXNoZWQgPSB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENsb3NlcyB0aGUgQ1BJTyBvdXRwdXQgc3RyZWFtIGFzIHdlbGwgYXMgdGhlIHN0cmVhbSBiZWluZyBmaWx0ZXJlZC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXJyb3IgaGFzIG9jY3VycmVkIG9yIGlmIGEgQ1BJTyBmaWxlIGVycm9yIGhhcworICAgICAqICAgICAgICAgICAgIG9jY3VycmVkCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKCFmaW5pc2hlZCkgeworICAgICAgICAgICAgICAgIGZpbmlzaCgpOworICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKCF0aGlzLmNsb3NlZCkgeworICAgICAgICAgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICAgICAgICAgIHRoaXMuY2xvc2VkID0gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBwYWQoZmluYWwgaW50IGNvdW50KSB0aHJvd3MgSU9FeGNlcHRpb257CisgICAgICAgIGlmIChjb3VudCA+IDApeworICAgICAgICAgICAgZmluYWwgYnl0ZSBidWZmW10gPSBuZXcgYnl0ZVtjb3VudF07CisgICAgICAgICAgICBvdXQud3JpdGUoYnVmZik7CisgICAgICAgICAgICBjb3VudChjb3VudCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgd3JpdGVCaW5hcnlMb25nKGZpbmFsIGxvbmcgbnVtYmVyLCBmaW5hbCBpbnQgbGVuZ3RoLAorICAgICAgICAgICAgZmluYWwgYm9vbGVhbiBzd2FwSGFsZldvcmQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIGJ5dGUgdG1wW10gPSBDcGlvVXRpbC5sb25nMmJ5dGVBcnJheShudW1iZXIsIGxlbmd0aCwgc3dhcEhhbGZXb3JkKTsKKyAgICAgICAgb3V0LndyaXRlKHRtcCk7CisgICAgICAgIGNvdW50KHRtcC5sZW5ndGgpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB3cml0ZUFzY2lpTG9uZyhmaW5hbCBsb25nIG51bWJlciwgZmluYWwgaW50IGxlbmd0aCwKKyAgICAgICAgICAgIGZpbmFsIGludCByYWRpeCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgU3RyaW5nQnVpbGRlciB0bXAgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICBTdHJpbmcgdG1wU3RyOworICAgICAgICBpZiAocmFkaXggPT0gMTYpIHsKKyAgICAgICAgICAgIHRtcC5hcHBlbmQoTG9uZy50b0hleFN0cmluZyhudW1iZXIpKTsKKyAgICAgICAgfSBlbHNlIGlmIChyYWRpeCA9PSA4KSB7CisgICAgICAgICAgICB0bXAuYXBwZW5kKExvbmcudG9PY3RhbFN0cmluZyhudW1iZXIpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRtcC5hcHBlbmQoTG9uZy50b1N0cmluZyhudW1iZXIpKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICh0bXAubGVuZ3RoKCkgPD0gbGVuZ3RoKSB7CisgICAgICAgICAgICBmaW5hbCBpbnQgaW5zZXJ0TGVuZ3RoID0gbGVuZ3RoIC0gdG1wLmxlbmd0aCgpOworICAgICAgICAgICAgZm9yIChpbnQgcG9zID0gMDsgcG9zIDwgaW5zZXJ0TGVuZ3RoOyBwb3MrKykgeworICAgICAgICAgICAgICAgIHRtcC5pbnNlcnQoMCwgIjAiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRtcFN0ciA9IHRtcC50b1N0cmluZygpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdG1wU3RyID0gdG1wLnN1YnN0cmluZyh0bXAubGVuZ3RoKCkgLSBsZW5ndGgpOworICAgICAgICB9CisgICAgICAgIGZpbmFsIGJ5dGVbXSBiID0gQXJjaGl2ZVV0aWxzLnRvQXNjaWlCeXRlcyh0bXBTdHIpOworICAgICAgICBvdXQud3JpdGUoYik7CisgICAgICAgIGNvdW50KGIubGVuZ3RoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFbmNvZGVzIHRoZSBnaXZlbiBzdHJpbmcgdXNpbmcgdGhlIGNvbmZpZ3VyZWQgZW5jb2RpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RyIHRoZSBTdHJpbmcgdG8gd3JpdGUKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHRoZSBzdHJpbmcgY291bGRuJ3QgYmUgd3JpdHRlbgorICAgICAqIEByZXR1cm4gcmVzdWx0IG9mIGVuY29kaW5nIHRoZSBzdHJpbmcKKyAgICAgKi8KKyAgICBwcml2YXRlIGJ5dGVbXSBlbmNvZGUoZmluYWwgU3RyaW5nIHN0cikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgQnl0ZUJ1ZmZlciBidWYgPSB6aXBFbmNvZGluZy5lbmNvZGUoc3RyKTsKKyAgICAgICAgZmluYWwgaW50IGxlbiA9IGJ1Zi5saW1pdCgpIC0gYnVmLnBvc2l0aW9uKCk7CisgICAgICAgIHJldHVybiBBcnJheXMuY29weU9mUmFuZ2UoYnVmLmFycmF5KCksIGJ1Zi5hcnJheU9mZnNldCgpLCBidWYuYXJyYXlPZmZzZXQoKSArIGxlbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIGFuIGVuY29kZWQgc3RyaW5nIHRvIHRoZSBzdHJlYW0gZm9sbG93ZWQgYnkgXDAKKyAgICAgKiBAcGFyYW0gc3RyIHRoZSBTdHJpbmcgdG8gd3JpdGUKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHRoZSBzdHJpbmcgY291bGRuJ3QgYmUgd3JpdHRlbgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCB3cml0ZUNTdHJpbmcoYnl0ZVtdIHN0cikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgb3V0LndyaXRlKHN0cik7CisgICAgICAgIG91dC53cml0ZSgnXDAnKTsKKyAgICAgICAgY291bnQoc3RyLmxlbmd0aCArIDEpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgQXJjaGl2ZUVudHJ5LiBUaGUgZW50cnlOYW1lIG11c3QgYmUgYW4gQVNDSUkgZW5jb2RlZCBzdHJpbmcuCisgICAgICoKKyAgICAgKiBAc2VlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZU91dHB1dFN0cmVhbSNjcmVhdGVBcmNoaXZlRW50cnkoamF2YS5pby5GaWxlLCBqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBBcmNoaXZlRW50cnkgY3JlYXRlQXJjaGl2ZUVudHJ5KGZpbmFsIEZpbGUgaW5wdXRGaWxlLCBmaW5hbCBTdHJpbmcgZW50cnlOYW1lKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYoZmluaXNoZWQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiU3RyZWFtIGhhcyBhbHJlYWR5IGJlZW4gZmluaXNoZWQiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IENwaW9BcmNoaXZlRW50cnkoaW5wdXRGaWxlLCBlbnRyeU5hbWUpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2NwaW8vQ3Bpb0NvbnN0YW50cy5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2NwaW8vQ3Bpb0NvbnN0YW50cy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVmYmEyODIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvY3Bpby9DcGlvQ29uc3RhbnRzLmphdmEKQEAgLTAsMCArMSwxNDMgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLmNwaW87CisKKy8qKgorICogQWxsIGNvbnN0YW50cyBuZWVkZWQgYnkgQ1BJTy4KKyAqCisgKiBiYXNlZCBvbiBjb2RlIGZyb20gdGhlIGpSUE0gcHJvamVjdCAoanJwbS5zb3VyY2Vmb3JnZS5uZXQpCisgKgorICovCitwdWJsaWMgaW50ZXJmYWNlIENwaW9Db25zdGFudHMgeworICAgIC8qKiBtYWdpYyBudW1iZXIgb2YgYSBjcGlvIGVudHJ5IGluIHRoZSBuZXcgZm9ybWF0ICovCisgICAgU3RyaW5nIE1BR0lDX05FVyA9ICIwNzA3MDEiOworCisgICAgLyoqIG1hZ2ljIG51bWJlciBvZiBhIGNwaW8gZW50cnkgaW4gdGhlIG5ldyBmb3JtYXQgd2l0aCBjcmMgKi8KKyAgICBTdHJpbmcgTUFHSUNfTkVXX0NSQyA9ICIwNzA3MDIiOworCisgICAgLyoqIG1hZ2ljIG51bWJlciBvZiBhIGNwaW8gZW50cnkgaW4gdGhlIG9sZCBhc2NpaSBmb3JtYXQgKi8KKyAgICBTdHJpbmcgTUFHSUNfT0xEX0FTQ0lJID0gIjA3MDcwNyI7CisKKyAgICAvKiogbWFnaWMgbnVtYmVyIG9mIGEgY3BpbyBlbnRyeSBpbiB0aGUgb2xkIGJpbmFyeSBmb3JtYXQgKi8KKyAgICBpbnQgTUFHSUNfT0xEX0JJTkFSWSA9IDA3MDcwNzsKKworICAgIC8vIFRoZXNlIEZPUk1BVF8gY29uc3RhbnRzIGFyZSBpbnRlcm5hbCB0byB0aGUgY29kZQorCisgICAgLyoqIHdyaXRlL3JlYWQgYSBDcGlvQXJjaGl2ZUVudHJ5IGluIHRoZSBuZXcgZm9ybWF0ICovCisgICAgc2hvcnQgRk9STUFUX05FVyA9IDE7CisKKyAgICAvKiogd3JpdGUvcmVhZCBhIENwaW9BcmNoaXZlRW50cnkgaW4gdGhlIG5ldyBmb3JtYXQgd2l0aCBjcmMgKi8KKyAgICBzaG9ydCBGT1JNQVRfTkVXX0NSQyA9IDI7CisKKyAgICAvKiogd3JpdGUvcmVhZCBhIENwaW9BcmNoaXZlRW50cnkgaW4gdGhlIG9sZCBhc2NpaSBmb3JtYXQgKi8KKyAgICBzaG9ydCBGT1JNQVRfT0xEX0FTQ0lJID0gNDsKKworICAgIC8qKiB3cml0ZS9yZWFkIGEgQ3Bpb0FyY2hpdmVFbnRyeSBpbiB0aGUgb2xkIGJpbmFyeSBmb3JtYXQgKi8KKyAgICBzaG9ydCBGT1JNQVRfT0xEX0JJTkFSWSA9IDg7CisKKyAgICAvKiogTWFzayBmb3IgYm90aCBuZXcgZm9ybWF0cyAqLworICAgIHNob3J0IEZPUk1BVF9ORVdfTUFTSyA9IDM7CisKKyAgICAvKiogTWFzayBmb3IgYm90aCBvbGQgZm9ybWF0cyAqLworICAgIHNob3J0IEZPUk1BVF9PTERfTUFTSyA9IDEyOworCisgICAgLyoKKyAgICAgKiBDb25zdGFudHMgZm9yIHRoZSBNT0RFIGJpdHMKKyAgICAgKi8KKworICAgIC8qKiBNYXNrIGZvciBhbGwgZmlsZSB0eXBlIGJpdHMuICovCisgICAgaW50IFNfSUZNVCAgID0gMDE3MDAwMDsKKworIC8vIGh0dHA6Ly93d3cub3Blbmdyb3VwLm9yZy9vbmxpbmVwdWJzLzk2OTk5MTk3OTkvYmFzZWRlZnMvY3Bpby5oLmh0bWwKKyAvLyBoYXMgYSBsaXN0IG9mIHRoZSBDX3h4eCBjb25zdGF0bnRzCisKKyAgICAvKiogRGVmaW5lcyBhIHNvY2tldCAqLworICAgIGludCBDX0lTU09DSyA9IDAxNDAwMDA7CisKKyAgICAvKiogRGVmaW5lcyBhIHN5bWJvbGljIGxpbmsgKi8KKyAgICBpbnQgQ19JU0xOSyAgPSAwMTIwMDAwOworCisgICAgLyoqIEhQL1VYIG5ldHdvcmsgc3BlY2lhbCAoQ19JU0NURykgKi8KKyAgICBpbnQgQ19JU05XSyAgPSAwMTEwMDAwOworCisgICAgLyoqIERlZmluZXMgYSByZWd1bGFyIGZpbGUgKi8KKyAgICBpbnQgQ19JU1JFRyAgPSAwMTAwMDAwOworCisgICAgLyoqIERlZmluZXMgYSBibG9jayBkZXZpY2UgKi8KKyAgICBpbnQgQ19JU0JMSyAgPSAwMDYwMDAwOworCisgICAgLyoqIERlZmluZXMgYSBkaXJlY3RvcnkgKi8KKyAgICBpbnQgQ19JU0RJUiAgPSAwMDQwMDAwOworCisgICAgLyoqIERlZmluZXMgYSBjaGFyYWN0ZXIgZGV2aWNlICovCisgICAgaW50IENfSVNDSFIgID0gMDAyMDAwMDsKKworICAgIC8qKiBEZWZpbmVzIGEgcGlwZSAqLworICAgIGludCBDX0lTRklGTyA9IDAwMTAwMDA7CisKKworICAgIC8qKiBTZXQgdXNlciBJRCAqLworICAgIGludCBDX0lTVUlEICA9IDAwMDQwMDA7CisKKyAgICAvKiogU2V0IGdyb3VwIElEICovCisgICAgaW50IENfSVNHSUQgID0gMDAwMjAwMDsKKworICAgIC8qKiBPbiBkaXJlY3RvcmllcywgcmVzdHJpY3RlZCBkZWxldGlvbiBmbGFnLiAqLworICAgIGludCBDX0lTVlRYICA9IDAwMDEwMDA7CisKKworICAgIC8qKiBQZXJtaXRzIHRoZSBvd25lciBvZiBhIGZpbGUgdG8gcmVhZCB0aGUgZmlsZSAqLworICAgIGludCBDX0lSVVNSICA9IDAwMDA0MDA7CisKKyAgICAvKiogUGVybWl0cyB0aGUgb3duZXIgb2YgYSBmaWxlIHRvIHdyaXRlIHRvIHRoZSBmaWxlICovCisgICAgaW50IENfSVdVU1IgID0gMDAwMDIwMDsKKworICAgIC8qKiBQZXJtaXRzIHRoZSBvd25lciBvZiBhIGZpbGUgdG8gZXhlY3V0ZSB0aGUgZmlsZSBvciB0byBzZWFyY2ggdGhlIGRpcmVjdG9yeSAqLworICAgIGludCBDX0lYVVNSICA9IDAwMDAxMDA7CisKKworICAgIC8qKiBQZXJtaXRzIGEgZmlsZSdzIGdyb3VwIHRvIHJlYWQgdGhlIGZpbGUgKi8KKyAgICBpbnQgQ19JUkdSUCAgPSAwMDAwMDQwOworCisgICAgLyoqIFBlcm1pdHMgYSBmaWxlJ3MgZ3JvdXAgdG8gd3JpdGUgdG8gdGhlIGZpbGUgKi8KKyAgICBpbnQgQ19JV0dSUCAgPSAwMDAwMDIwOworCisgICAgLyoqIFBlcm1pdHMgYSBmaWxlJ3MgZ3JvdXAgdG8gZXhlY3V0ZSB0aGUgZmlsZSBvciB0byBzZWFyY2ggdGhlIGRpcmVjdG9yeSAqLworICAgIGludCBDX0lYR1JQICA9IDAwMDAwMTA7CisKKworICAgIC8qKiBQZXJtaXRzIG90aGVycyB0byByZWFkIHRoZSBmaWxlICovCisgICAgaW50IENfSVJPVEggID0gMDAwMDAwNDsKKworICAgIC8qKiBQZXJtaXRzIG90aGVycyB0byB3cml0ZSB0byB0aGUgZmlsZSAqLworICAgIGludCBDX0lXT1RIICA9IDAwMDAwMDI7CisKKyAgICAvKiogUGVybWl0cyBvdGhlcnMgdG8gZXhlY3V0ZSB0aGUgZmlsZSBvciB0byBzZWFyY2ggdGhlIGRpcmVjdG9yeSAqLworICAgIGludCBDX0lYT1RIICA9IDAwMDAwMDE7CisKKyAgICAvKiogVGhlIHNwZWNpYWwgdHJhaWxlciBtYXJrZXIgKi8KKyAgICBTdHJpbmcgQ1BJT19UUkFJTEVSID0gIlRSQUlMRVIhISEiOworCisgICAgLyoqCisgICAgICogVGhlIGRlZmF1bHQgYmxvY2sgc2l6ZS4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjEKKyAgICAgKi8KKyAgICBpbnQgQkxPQ0tfU0laRSA9IDUxMjsKK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9jcGlvL0NwaW9VdGlsLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvY3Bpby9DcGlvVXRpbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY1M2VhNDQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvY3Bpby9DcGlvVXRpbC5qYXZhCkBAIC0wLDAgKzEsMTE0IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5jcGlvOworCisvKioKKyAqIFBhY2thZ2UgcHJpdmF0ZSB1dGlsaXR5IGNsYXNzIGZvciBDcGlvCisgKgorICogQEltbXV0YWJsZQorICovCitjbGFzcyBDcGlvVXRpbCB7CisKKyAgICAvKioKKyAgICAgKiBFeHRyYWN0cyB0aGUgZmlsZSB0eXBlIGJpdHMgZnJvbSBhIG1vZGUuCisgICAgICovCisgICAgc3RhdGljIGxvbmcgZmlsZVR5cGUoZmluYWwgbG9uZyBtb2RlKSB7CisgICAgICAgIHJldHVybiBtb2RlICYgQ3Bpb0NvbnN0YW50cy5TX0lGTVQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydHMgYSBieXRlIGFycmF5IHRvIGEgbG9uZy4gSGFsZndvcmRzIGNhbiBiZSBzd2FwcGVkIGJ5IHNldHRpbmcKKyAgICAgKiBzd2FwSGFsZldvcmQ9dHJ1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBudW1iZXIKKyAgICAgKiAgICAgICAgICAgIEFuIGFycmF5IG9mIGJ5dGVzIGNvbnRhaW5pbmcgYSBudW1iZXIKKyAgICAgKiBAcGFyYW0gc3dhcEhhbGZXb3JkCisgICAgICogICAgICAgICAgICBTd2FwIGhhbGZ3b3JkcyAoWzBdWzFdWzJdWzNdLT5bMV1bMF1bM11bMl0pCisgICAgICogQHJldHVybiBUaGUgbG9uZyB2YWx1ZQorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gaWYgbnVtYmVyIGxlbmd0aCBpcyBub3QgYSBtdWx0aXBsZSBvZiAyCisgICAgICovCisgICAgc3RhdGljIGxvbmcgYnl0ZUFycmF5MmxvbmcoZmluYWwgYnl0ZVtdIG51bWJlciwgZmluYWwgYm9vbGVhbiBzd2FwSGFsZldvcmQpIHsKKyAgICAgICAgaWYgKG51bWJlci5sZW5ndGggJSAyICE9IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgbG9uZyByZXQgPSAwOworICAgICAgICBpbnQgcG9zID0gMDsKKyAgICAgICAgZmluYWwgYnl0ZSB0bXBfbnVtYmVyW10gPSBuZXcgYnl0ZVtudW1iZXIubGVuZ3RoXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShudW1iZXIsIDAsIHRtcF9udW1iZXIsIDAsIG51bWJlci5sZW5ndGgpOworCisgICAgICAgIGlmICghc3dhcEhhbGZXb3JkKSB7CisgICAgICAgICAgICBieXRlIHRtcCA9IDA7CisgICAgICAgICAgICBmb3IgKHBvcyA9IDA7IHBvcyA8IHRtcF9udW1iZXIubGVuZ3RoOyBwb3MrKykgeworICAgICAgICAgICAgICAgIHRtcCA9IHRtcF9udW1iZXJbcG9zXTsKKyAgICAgICAgICAgICAgICB0bXBfbnVtYmVyW3BvcysrXSA9IHRtcF9udW1iZXJbcG9zXTsKKyAgICAgICAgICAgICAgICB0bXBfbnVtYmVyW3Bvc10gPSB0bXA7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICByZXQgPSB0bXBfbnVtYmVyWzBdICYgMHhGRjsKKyAgICAgICAgZm9yIChwb3MgPSAxOyBwb3MgPCB0bXBfbnVtYmVyLmxlbmd0aDsgcG9zKyspIHsKKyAgICAgICAgICAgIHJldCA8PD0gODsKKyAgICAgICAgICAgIHJldCB8PSB0bXBfbnVtYmVyW3Bvc10gJiAweEZGOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydHMgYSBsb25nIG51bWJlciB0byBhIGJ5dGUgYXJyYXkKKyAgICAgKiBIYWxmd29yZHMgY2FuIGJlIHN3YXBwZWQgYnkgc2V0dGluZyBzd2FwSGFsZldvcmQ9dHJ1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBudW1iZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnB1dCBsb25nIG51bWJlciB0byBiZSBjb252ZXJ0ZWQKKyAgICAgKgorICAgICAqIEBwYXJhbSBsZW5ndGgKKyAgICAgKiAgICAgICAgICAgIFRoZSBsZW5ndGggb2YgdGhlIHJldHVybmVkIGFycmF5CisgICAgICogQHBhcmFtIHN3YXBIYWxmV29yZAorICAgICAqICAgICAgICAgICAgU3dhcCBoYWxmd29yZHMgKFswXVsxXVsyXVszXS0+WzFdWzBdWzNdWzJdKQorICAgICAqIEByZXR1cm4gVGhlIGxvbmcgdmFsdWUKKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGlmIHRoZSBsZW5ndGggaXMgbm90IGEgcG9zaXRpdmUgbXVsdGlwbGUgb2YgdHdvCisgICAgICovCisgICAgc3RhdGljIGJ5dGVbXSBsb25nMmJ5dGVBcnJheShmaW5hbCBsb25nIG51bWJlciwgZmluYWwgaW50IGxlbmd0aCwKKyAgICAgICAgICAgIGZpbmFsIGJvb2xlYW4gc3dhcEhhbGZXb3JkKSB7CisgICAgICAgIGZpbmFsIGJ5dGVbXSByZXQgPSBuZXcgYnl0ZVtsZW5ndGhdOworICAgICAgICBpbnQgcG9zID0gMDsKKyAgICAgICAgbG9uZyB0bXBfbnVtYmVyID0gMDsKKworICAgICAgICBpZiAobGVuZ3RoICUgMiAhPSAwIHx8IGxlbmd0aCA8IDIpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgdG1wX251bWJlciA9IG51bWJlcjsKKyAgICAgICAgZm9yIChwb3MgPSBsZW5ndGggLSAxOyBwb3MgPj0gMDsgcG9zLS0pIHsKKyAgICAgICAgICAgIHJldFtwb3NdID0gKGJ5dGUpICh0bXBfbnVtYmVyICYgMHhGRik7CisgICAgICAgICAgICB0bXBfbnVtYmVyID4+PSA4OworICAgICAgICB9CisKKyAgICAgICAgaWYgKCFzd2FwSGFsZldvcmQpIHsKKyAgICAgICAgICAgIGJ5dGUgdG1wID0gMDsKKyAgICAgICAgICAgIGZvciAocG9zID0gMDsgcG9zIDwgbGVuZ3RoOyBwb3MrKykgeworICAgICAgICAgICAgICAgIHRtcCA9IHJldFtwb3NdOworICAgICAgICAgICAgICAgIHJldFtwb3MrK10gPSByZXRbcG9zXTsKKyAgICAgICAgICAgICAgICByZXRbcG9zXSA9IHRtcDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiByZXQ7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2NwaW8vcGFja2FnZS5odG1sIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2NwaW8vcGFja2FnZS5odG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk4NTgyODcKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvY3Bpby9wYWNrYWdlLmh0bWwKQEAgLTAsMCArMSwyNCBAQAorPGh0bWw+Cis8IS0tCisKKyAgIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAgIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisKKyAgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKworICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAgIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisKKy0tPgorICA8Ym9keT4KKyAgICA8cD5Qcm92aWRlcyBzdHJlYW0gY2xhc3NlcyBmb3IgcmVhZGluZyBhbmQgd3JpdGluZyBhcmNoaXZlcyB1c2luZworICAgICAgdGhlIENQSU8gZm9ybWF0LjwvcD4KKyAgPC9ib2R5PgorPC9odG1sPgpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2R1bXAvRGlyZW50LmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvZHVtcC9EaXJlbnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNWFmOTY0Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2R1bXAvRGlyZW50LmphdmEKQEAgLTAsMCArMSw4NyBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuZHVtcDsKKworLyoqCisgKiBEaXJlY3RvcnkgZW50cnkuCisgKi8KK2NsYXNzIERpcmVudCB7CisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgaW5vOworICAgIHByaXZhdGUgZmluYWwgaW50IHBhcmVudElubzsKKyAgICBwcml2YXRlIGZpbmFsIGludCB0eXBlOworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIG5hbWU7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvcgorICAgICAqCisgICAgICogQHBhcmFtIGlubworICAgICAqIEBwYXJhbSBwYXJlbnRJbm8KKyAgICAgKiBAcGFyYW0gdHlwZQorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICovCisgICAgRGlyZW50KGZpbmFsIGludCBpbm8sIGZpbmFsIGludCBwYXJlbnRJbm8sIGZpbmFsIGludCB0eXBlLCBmaW5hbCBTdHJpbmcgbmFtZSkgeworICAgICAgICB0aGlzLmlubyA9IGlubzsKKyAgICAgICAgdGhpcy5wYXJlbnRJbm8gPSBwYXJlbnRJbm87CisgICAgICAgIHRoaXMudHlwZSA9IHR5cGU7CisgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IGluby4KKyAgICAgKiBAcmV0dXJuIHRoZSBpLW5vZGUKKyAgICAgKi8KKyAgICBpbnQgZ2V0SW5vKCkgeworICAgICAgICByZXR1cm4gaW5vOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCBpbm8gb2YgcGFyZW50IGRpcmVjdG9yeS4KKyAgICAgKiBAcmV0dXJuIHRoZSBwYXJlbnQgaS1ub2RlCisgICAgICovCisgICAgaW50IGdldFBhcmVudElubygpIHsKKyAgICAgICAgcmV0dXJuIHBhcmVudElubzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgZW50cnkgdHlwZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBlbnRyeSB0eXBlCisgICAgICovCisgICAgaW50IGdldFR5cGUoKSB7CisgICAgICAgIHJldHVybiB0eXBlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCBuYW1lIG9mIGRpcmVjdG9yeSBlbnRyeS4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIHJldHVybnMgdGhlIHJhdyBuYW1lIGFzIGl0IGlzIHN0b3JlZCBpbnNpZGUgb2YgdGhlIGFyY2hpdmUuPC9wPgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZGlyZWN0b3J5IG5hbWUKKyAgICAgKi8KKyAgICBTdHJpbmcgZ2V0TmFtZSgpIHsKKyAgICAgICAgcmV0dXJuIG5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSBqYXZhLmxhbmcuT2JqZWN0I3RvU3RyaW5nKCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICByZXR1cm4gU3RyaW5nLmZvcm1hdCgiWyVkXTogJXMiLCBpbm8sIG5hbWUpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9kdW1wL0R1bXBBcmNoaXZlQ29uc3RhbnRzLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvZHVtcC9EdW1wQXJjaGl2ZUNvbnN0YW50cy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI0MzBmNGEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvZHVtcC9EdW1wQXJjaGl2ZUNvbnN0YW50cy5qYXZhCkBAIC0wLDAgKzEsOTEgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLmR1bXA7CisKKy8qKgorICogVmFyaW91cyBjb25zdGFudHMgYXNzb2NpYXRlZCB3aXRoIGR1bXAgYXJjaGl2ZXMuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBEdW1wQXJjaGl2ZUNvbnN0YW50cyB7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVFBfU0laRSA9IDEwMjQ7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTlRSRUMgPSAxMDsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBISUdIX0RFTlNJVFlfTlRSRUMgPSAzMjsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPRlNfTUFHSUMgPSA2MDAxMTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBORlNfTUFHSUMgPSA2MDAxMjsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGU19VRlMyX01BR0lDID0gMHgxOTU0MDExOTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDSEVDS1NVTSA9IDg0NDQ2OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExCTFNJWkUgPSAxNjsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOQU1FTEVOID0gNjQ7CisKKyAgICAvKiBkbyBub3QgaW5zdGFudGlhdGUgKi8KKyAgICBwcml2YXRlIER1bXBBcmNoaXZlQ29uc3RhbnRzKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSB0eXBlIG9mIHRhcGUgc2VnbWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgZW51bSBTRUdNRU5UX1RZUEUgeworICAgICAgICBUQVBFKDEpLAorICAgICAgICBJTk9ERSgyKSwKKyAgICAgICAgQklUUygzKSwKKyAgICAgICAgQUREUig0KSwKKyAgICAgICAgRU5EKDUpLAorICAgICAgICBDTFJJKDYpOworCisgICAgICAgIGludCBjb2RlOworCisgICAgICAgIFNFR01FTlRfVFlQRShmaW5hbCBpbnQgY29kZSkgeworICAgICAgICAgICAgdGhpcy5jb2RlID0gY29kZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBzdGF0aWMgU0VHTUVOVF9UWVBFIGZpbmQoZmluYWwgaW50IGNvZGUpIHsKKyAgICAgICAgICAgIGZvciAoZmluYWwgU0VHTUVOVF9UWVBFIHQgOiB2YWx1ZXMoKSkgeworICAgICAgICAgICAgICAgIGlmICh0LmNvZGUgPT0gY29kZSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gdDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIHR5cGUgb2YgY29tcHJlc3Npb24uCisgICAgICovCisgICAgcHVibGljIGVudW0gQ09NUFJFU1NJT05fVFlQRSB7CisgICAgICAgIFpMSUIoMCksCisgICAgICAgIEJaTElCKDEpLAorICAgICAgICBMWk8oMik7CisKKyAgICAgICAgaW50IGNvZGU7CisKKyAgICAgICAgQ09NUFJFU1NJT05fVFlQRShmaW5hbCBpbnQgY29kZSkgeworICAgICAgICAgICAgdGhpcy5jb2RlID0gY29kZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBzdGF0aWMgQ09NUFJFU1NJT05fVFlQRSBmaW5kKGZpbmFsIGludCBjb2RlKSB7CisgICAgICAgICAgICBmb3IgKGZpbmFsIENPTVBSRVNTSU9OX1RZUEUgdCA6IHZhbHVlcygpKSB7CisgICAgICAgICAgICAgICAgaWYgKHQuY29kZSA9PSBjb2RlKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiB0OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvZHVtcC9EdW1wQXJjaGl2ZUVudHJ5LmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvZHVtcC9EdW1wQXJjaGl2ZUVudHJ5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTI4NDUwNQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9kdW1wL0R1bXBBcmNoaXZlRW50cnkuamF2YQpAQCAtMCwwICsxLDg0NSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuZHVtcDsKKworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKK2ltcG9ydCBqYXZhLnV0aWwuRGF0ZTsKK2ltcG9ydCBqYXZhLnV0aWwuRW51bVNldDsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZUVudHJ5OworCisvKioKKyAqIFRoaXMgY2xhc3MgcmVwcmVzZW50cyBhbiBlbnRyeSBpbiBhIER1bXAgYXJjaGl2ZS4gSXQgY29uc2lzdHMKKyAqIG9mIHRoZSBlbnRyeSdzIGhlYWRlciwgdGhlIGVudHJ5J3MgRmlsZSBhbmQgYW55IGV4dGVuZGVkIGF0dHJpYnV0ZXMuCisgKiA8cD4KKyAqIER1bXBFbnRyaWVzIHRoYXQgYXJlIGNyZWF0ZWQgZnJvbSB0aGUgaGVhZGVyIGJ5dGVzIHJlYWQgZnJvbQorICogYW4gYXJjaGl2ZSBhcmUgaW5zdGFudGlhdGVkIHdpdGggdGhlIER1bXBBcmNoaXZlRW50cnkoIGJ5dGVbXSApCisgKiBjb25zdHJ1Y3Rvci4gVGhlc2UgZW50cmllcyB3aWxsIGJlIHVzZWQgd2hlbiBleHRyYWN0aW5nIGZyb20KKyAqIG9yIGxpc3RpbmcgdGhlIGNvbnRlbnRzIG9mIGFuIGFyY2hpdmUuIFRoZXNlIGVudHJpZXMgaGF2ZSB0aGVpcgorICogaGVhZGVyIGZpbGxlZCBpbiB1c2luZyB0aGUgaGVhZGVyIGJ5dGVzLiBUaGV5IGFsc28gc2V0IHRoZSBGaWxlCisgKiB0byBudWxsLCBzaW5jZSB0aGV5IHJlZmVyZW5jZSBhbiBhcmNoaXZlIGVudHJ5IG5vdCBhIGZpbGUuCisgKiA8cD4KKyAqIER1bXBFbnRyaWVzIGNhbiBhbHNvIGJlIGNvbnN0cnVjdGVkIGZyb20gbm90aGluZyBidXQgYSBuYW1lLgorICogVGhpcyBhbGxvd3MgdGhlIHByb2dyYW1tZXIgdG8gY29uc3RydWN0IHRoZSBlbnRyeSBieSBoYW5kLCBmb3IKKyAqIGluc3RhbmNlIHdoZW4gb25seSBhbiBJbnB1dFN0cmVhbSBpcyBhdmFpbGFibGUgZm9yIHdyaXRpbmcgdG8KKyAqIHRoZSBhcmNoaXZlLCBhbmQgdGhlIGhlYWRlciBpbmZvcm1hdGlvbiBpcyBjb25zdHJ1Y3RlZCBmcm9tCisgKiBvdGhlciBpbmZvcm1hdGlvbi4gSW4gdGhpcyBjYXNlIHRoZSBoZWFkZXIgZmllbGRzIGFyZSBzZXQgdG8KKyAqIGRlZmF1bHRzIGFuZCB0aGUgRmlsZSBpcyBzZXQgdG8gbnVsbC4KKyAqCisgKiA8cD4KKyAqIFRoZSBDIHN0cnVjdHVyZSBmb3IgYSBEdW1wIEVudHJ5J3MgaGVhZGVyIGlzOgorICogPHByZT4KKyAqICNkZWZpbmUgVFBfQlNJWkUgICAgMTAyNCAgICAgICAgICAvLyBzaXplIG9mIGVhY2ggZmlsZSBibG9jaworICogI2RlZmluZSBOVFJFQyAgICAgICAxMCAgICAgICAgICAgIC8vIG51bWJlciBvZiBibG9ja3MgdG8gd3JpdGUgYXQgb25jZQorICogI2RlZmluZSBISUdIREVOU0lUWVRSRUMgMzIgICAgICAgIC8vIG51bWJlciBvZiBibG9ja3MgdG8gd3JpdGUgb24gaGlnaC1kZW5zaXR5IHRhcGVzCisgKiAjZGVmaW5lIFRQX05JTkRJUiAgIChUUF9CU0laRS8yKSAgLy8gbnVtYmVyIGlmIGluZGlyZWN0IGlub2RlcyBpbiByZWNvcmQKKyAqICNkZWZpbmUgVFBfTklOT1MgICAgKFRQX05JTkRJUiAvIHNpemVvZiAoaW50MzJfdCkpCisgKiAjZGVmaW5lIExCTFNJWkUgICAgIDE2CisgKiAjZGVmaW5lIE5BTUVMRU4gICAgIDY0CisgKgorICogI2RlZmluZSBPRlNfTUFHSUMgICAgIChpbnQpNjAwMTEgIC8vIG9sZCBmb3JtYXQgbWFnaWMgdmFsdWUKKyAqICNkZWZpbmUgTkZTX01BR0lDICAgICAoaW50KTYwMDEyICAvLyBuZXcgZm9ybWF0IG1hZ2ljIHZhbHVlCisgKiAjZGVmaW5lIEZTX1VGUzJfTUFHSUMgKGludCkweDE5NTQwMTE5CisgKiAjZGVmaW5lIENIRUNLU1VNICAgICAgKGludCk4NDQ0NiAgLy8gY29uc3RhbnQgdXNlZCBpbiBjaGVja3N1bSBhbGdvcml0aG0KKyAqCisgKiBzdHJ1Y3QgIHNfc3BjbCB7CisgKiAgIGludDMyX3QgY190eXBlOyAgICAgICAgICAgICAvLyByZWNvcmQgdHlwZSAoc2VlIGJlbG93KQorICogICBpbnQzMl90IDxiPmNfZGF0ZTwvYj47ICAgICAgICAgICAgIC8vIGRhdGUgb2YgdGhpcyBkdW1wCisgKiAgIGludDMyX3QgPGI+Y19kZGF0ZTwvYj47ICAgICAgICAgICAgLy8gZGF0ZSBvZiBwcmV2aW91cyBkdW1wCisgKiAgIGludDMyX3QgY192b2x1bWU7ICAgICAgICAgICAvLyBkdW1wIHZvbHVtZSBudW1iZXIKKyAqICAgdV9pbnQzMl90IGNfdGFwZWE7ICAgICAgICAgIC8vIGxvZ2ljYWwgYmxvY2sgb2YgdGhpcyByZWNvcmQKKyAqICAgZHVtcF9pbm9fdCBjX2lubzsgICAgICAgICAgIC8vIG51bWJlciBvZiBpbm9kZQorICogICBpbnQzMl90IDxiPmNfbWFnaWM8L2I+OyAgICAgICAgICAgIC8vIG1hZ2ljIG51bWJlciAoc2VlIGFib3ZlKQorICogICBpbnQzMl90IGNfY2hlY2tzdW07ICAgICAgICAgLy8gcmVjb3JkIGNoZWNrc3VtCisgKiAjaWZkZWYgIF9fbGludXhfXworICogICBzdHJ1Y3QgIG5ld19ic2RfaW5vZGUgY19kaW5vZGU7CisgKiAjZWxzZQorICogI2lmZGVmIHN1bm9zCisgKiAgIHN0cnVjdCAgbmV3X2JzZF9pbm9kZSBjX2Rpbm9kZTsKKyAqICNlbHNlCisgKiAgIHN0cnVjdCAgZGlub2RlICBjX2Rpbm9kZTsgICAvLyBvd25lcnNoaXAgYW5kIG1vZGUgb2YgaW5vZGUKKyAqICNlbmRpZgorICogI2VuZGlmCisgKiAgIGludDMyX3QgY19jb3VudDsgICAgICAgICAgICAvLyBudW1iZXIgb2YgdmFsaWQgY19hZGRyIGVudHJpZXMKKyAqICAgdW5pb24gdV9kYXRhIGNfZGF0YTsgICAgICAgIC8vIHNlZSBhYm92ZQorICogICBjaGFyICAgIDxiPmNfbGFiZWxbTEJMU0laRV08L2I+OyAgIC8vIGR1bXAgbGFiZWwKKyAqICAgaW50MzJfdCA8Yj5jX2xldmVsPC9iPjsgICAgICAgICAgICAvLyBsZXZlbCBvZiB0aGlzIGR1bXAKKyAqICAgY2hhciAgICA8Yj5jX2ZpbGVzeXNbTkFNRUxFTl08L2I+OyAvLyBuYW1lIG9mIGR1bXBwZWQgZmlsZSBzeXN0ZW0KKyAqICAgY2hhciAgICA8Yj5jX2RldltOQU1FTEVOXTwvYj47ICAgICAvLyBuYW1lIG9mIGR1bXBwZWQgZGV2aWNlCisgKiAgIGNoYXIgICAgPGI+Y19ob3N0W05BTUVMRU5dPC9iPjsgICAgLy8gbmFtZSBvZiBkdW1wcGVkIGhvc3QKKyAqICAgaW50MzJfdCBjX2ZsYWdzOyAgICAgICAgICAgIC8vIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gKHNlZSBiZWxvdykKKyAqICAgaW50MzJfdCBjX2ZpcnN0cmVjOyAgICAgICAgIC8vIGZpcnN0IHJlY29yZCBvbiB2b2x1bWUKKyAqICAgaW50MzJfdCBjX250cmVjOyAgICAgICAgICAgIC8vIGJsb2Nrc2l6ZSBvbiB2b2x1bWUKKyAqICAgaW50MzJfdCBjX2V4dGF0dHJpYnV0ZXM7ICAgIC8vIGFkZGl0aW9uYWwgaW5vZGUgaW5mbyAoc2VlIGJlbG93KQorICogICBpbnQzMl90IGNfc3BhcmVbMzBdOyAgICAgICAgLy8gcmVzZXJ2ZWQgZm9yIGZ1dHVyZSB1c2VzCisgKiB9IHNfc3BjbDsKKyAqCisgKiAvLworICogLy8gZmxhZyB2YWx1ZXMKKyAqIC8vCisgKiAjZGVmaW5lIERSX05FV0hFQURFUiAgICAgMHgwMDAxICAvLyBuZXcgZm9ybWF0IHRhcGUgaGVhZGVyCisgKiAjZGVmaW5lIERSX05FV0lOT0RFRk1UICAgMHgwMDAyICAvLyBuZXcgZm9ybWF0IGlub2RlcyBvbiB0YXBlCisgKiAjZGVmaW5lIERSX0NPTVBSRVNTRUQgICAgMHgwMDgwICAvLyBkdW1wIHRhcGUgaXMgY29tcHJlc3NlZAorICogI2RlZmluZSBEUl9NRVRBT05MWSAgICAgIDB4MDEwMCAgLy8gb25seSB0aGUgbWV0YWRhdGEgb2YgdGhlIGlub2RlIGhhcyBiZWVuIGR1bXBlZAorICogI2RlZmluZSBEUl9JTk9ERUlORk8gICAgIDB4MDAwMiAgLy8gW1NJQ10gVFNfRU5EIGhlYWRlciBjb250YWlucyBjX2lub3MgaW5mb3JtYXRpb24KKyAqICNkZWZpbmUgRFJfRVhUQVRUUklCVVRFUyAweDgwMDAKKyAqCisgKiAvLworICogLy8gZXh0YXR0cmlidXRlcyBpbm9kZSBpbmZvCisgKiAvLworICogI2RlZmluZSBFWFRfUkVHVUxBUiAgICAgICAgIDAKKyAqICNkZWZpbmUgRVhUX01BQ09TRk5EUklORk8gICAxCisgKiAjZGVmaW5lIEVYVF9NQUNPU1JFU0ZPUksgICAgMgorICogI2RlZmluZSBFWFRfWEFUVFIgICAgICAgICAgIDMKKyAqCisgKiAvLyB1c2VkIGZvciBFQSBvbiB0YXBlCisgKiAjZGVmaW5lIEVYVDJfR09PRF9PTERfSU5PREVfU0laRSAgICAxMjgKKyAqICNkZWZpbmUgRVhUMl9YQVRUUl9NQUdJQyAgICAgICAgMHhFQTAyMDAwMCAgLy8gYmxvY2sgRUEKKyAqICNkZWZpbmUgRVhUMl9YQVRUUl9NQUdJQzIgICAgICAgMHhFQTAyMDAwMSAgLy8gaW4gaW5vZGUgRUEKKyAqIDwvcHJlPgorICogPHA+CisgKiBUaGUgZmllbGRzIGluIDxiPmJvbGQ8L2I+IGFyZSB0aGUgc2FtZSBmb3IgYWxsIGJsb2Nrcy4gKFRoaXMgcGVybWl0dGVkCisgKiBtdWx0aXBsZSBkdW1wcyB0byBiZSB3cml0dGVuIHRvIGEgc2luZ2xlIHRhcGUuKQorICogPC9wPgorICoKKyAqIDxwPgorICogVGhlIEMgc3RydWN0dXJlIGZvciB0aGUgaW5vZGUgKGZpbGUpIGluZm9ybWF0aW9uIGlzOgorICogPHByZT4KKyAqIHN0cnVjdCBic2R0aW1ldmFsIHsgICAgICAgICAgIC8vICAqKioqIGFscGhhLSotbGludXggaXMgZGV2aWFudAorICogICBfX3UzMiAgIHR2X3NlYzsKKyAqICAgX191MzIgICB0dl91c2VjOworICogfTsKKyAqCisgKiAjZGVmaW5lIE5EQUREUiAgICAgIDEyCisgKiAjZGVmaW5lIE5JQUREUiAgICAgICAzCisgKgorICogLy8KKyAqIC8vIFRoaXMgaXMgdGhlIG5ldyAoNC40KSBCU0QgaW5vZGUgc3RydWN0dXJlCisgKiAvLyBjb3BpZWQgZnJvbSB0aGUgRnJlZUJTRCAyLjAgJmx0O3Vmcy91ZnMvZGlub2RlLmgmZ3Q7IGluY2x1ZGUgZmlsZQorICogLy8KKyAqIHN0cnVjdCBuZXdfYnNkX2lub2RlIHsKKyAqICAgX191MTYgICAgICAgZGlfbW9kZTsgICAgICAgICAgIC8vIGZpbGUgdHlwZSwgc3RhbmRhcmQgVW5peCBwZXJtaXNzaW9ucworICogICBfX3MxNiAgICAgICBkaV9ubGluazsgICAgICAgICAgLy8gbnVtYmVyIG9mIGhhcmQgbGlua3MgdG8gZmlsZS4KKyAqICAgdW5pb24geworICogICAgICBfX3UxNiAgICAgICBvbGRpZHNbMl07CisgKiAgICAgIF9fdTMyICAgICAgIGludW1iZXI7CisgKiAgIH0gICAgICAgICAgIGRpX3U7CisgKiAgIHVfcXVhZF90ICAgIGRpX3NpemU7ICAgICAgICAgICAvLyBmaWxlIHNpemUKKyAqICAgc3RydWN0IGJzZHRpbWV2YWwgICBkaV9hdGltZTsgIC8vIHRpbWUgZmlsZSB3YXMgbGFzdCBhY2Nlc3NlZAorICogICBzdHJ1Y3QgYnNkdGltZXZhbCAgIGRpX210aW1lOyAgLy8gdGltZSBmaWxlIHdhcyBsYXN0IG1vZGlmaWVkCisgKiAgIHN0cnVjdCBic2R0aW1ldmFsICAgZGlfY3RpbWU7ICAvLyB0aW1lIGZpbGUgd2FzIGNyZWF0ZWQKKyAqICAgX191MzIgICAgICAgZGlfZGJbTkRBRERSXTsKKyAqICAgX191MzIgICAgICAgZGlfaWJbTklBRERSXTsKKyAqICAgX191MzIgICAgICAgZGlfZmxhZ3M7ICAgICAgICAgIC8vCisgKiAgIF9fczMyICAgICAgIGRpX2Jsb2NrczsgICAgICAgICAvLyBudW1iZXIgb2YgZGlzayBibG9ja3MKKyAqICAgX19zMzIgICAgICAgZGlfZ2VuOyAgICAgICAgICAgIC8vIGdlbmVyYXRpb24gbnVtYmVyCisgKiAgIF9fdTMyICAgICAgIGRpX3VpZDsgICAgICAgICAgICAvLyB1c2VyIGlkIChzZWUgL2V0Yy9wYXNzd2QpCisgKiAgIF9fdTMyICAgICAgIGRpX2dpZDsgICAgICAgICAgICAvLyBncm91cCBpZCAoc2VlIC9ldGMvZ3JvdXApCisgKiAgIF9fczMyICAgICAgIGRpX3NwYXJlWzJdOyAgICAgICAvLyB1bnVzZWQKKyAqIH07CisgKiA8L3ByZT4KKyAqIDxwPgorICogSXQgaXMgaW1wb3J0YW50IHRvIG5vdGUgdGhhdCB0aGUgaGVhZGVyIERPRVMgTk9UIGhhdmUgdGhlIG5hbWUgb2YgdGhlCisgKiBmaWxlLiBJdCBjYW4ndCBzaW5jZSBoYXJkIGxpbmtzIG1lYW4gdGhhdCB5b3UgbWF5IGhhdmUgbXVsdGlwbGUgZmlsZW5hbWVzCisgKiBmb3IgYSBzaW5nbGUgcGh5c2ljYWwgZmlsZS4gWW91IG11c3QgcmVhZCB0aGUgY29udGVudHMgb2YgdGhlIGRpcmVjdG9yeQorICogZW50cmllcyB0byBsZWFybiB0aGUgbWFwcGluZyhzKSBmcm9tIGZpbGVuYW1lIHRvIGlub2RlLgorICogPC9wPgorICoKKyAqIDxwPgorICogVGhlIEMgc3RydWN0dXJlIHRoYXQgaW5kaWNhdGVzIGlmIGEgc3BlY2lmaWMgYmxvY2sgaXMgYSByZWFsIGJsb2NrCisgKiB0aGF0IGNvbnRhaW5zIGRhdGEgb3IgaXMgYSBzcGFyc2UgYmxvY2sgdGhhdCBpcyBub3QgcGVyc2lzdGVkIHRvIHRoZQorICogZGlzayBpczo8L3A+CisgKiA8cHJlPgorICogI2RlZmluZSBUUF9CU0laRSAgICAxMDI0CisgKiAjZGVmaW5lIFRQX05JTkRJUiAgIChUUF9CU0laRS8yKQorICoKKyAqIHVuaW9uIHVfZGF0YSB7CisgKiAgIGNoYXIgICAgc19hZGRyc1tUUF9OSU5ESVJdOyAvLyAxID0mZ3Q7IGRhdGE7IDAgPSZndDsgaG9sZSBpbiBpbm9kZQorICogICBpbnQzMl90IHNfaW5vc1tUUF9OSU5PU107ICAgLy8gdGFibGUgb2YgZmlyc3QgaW5vZGUgb24gZWFjaCB2b2x1bWUKKyAqIH0gdV9kYXRhOworICogPC9wcmU+CisgKgorICogQE5vdFRocmVhZFNhZmUKKyAqLworcHVibGljIGNsYXNzIER1bXBBcmNoaXZlRW50cnkgaW1wbGVtZW50cyBBcmNoaXZlRW50cnkgeworICAgIHByaXZhdGUgU3RyaW5nIG5hbWU7CisgICAgcHJpdmF0ZSBUWVBFIHR5cGUgPSBUWVBFLlVOS05PV047CisgICAgcHJpdmF0ZSBpbnQgbW9kZTsKKyAgICBwcml2YXRlIFNldDxQRVJNSVNTSU9OPiBwZXJtaXNzaW9ucyA9IENvbGxlY3Rpb25zLmVtcHR5U2V0KCk7CisgICAgcHJpdmF0ZSBsb25nIHNpemU7CisgICAgcHJpdmF0ZSBsb25nIGF0aW1lOworICAgIHByaXZhdGUgbG9uZyBtdGltZTsKKyAgICBwcml2YXRlIGludCB1aWQ7CisgICAgcHJpdmF0ZSBpbnQgZ2lkOworCisgICAgLyoqCisgICAgICogQ3VycmVudGx5IHVudXNlZAorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgRHVtcEFyY2hpdmVTdW1tYXJ5IHN1bW1hcnkgPSBudWxsOworCisgICAgLy8gdGhpcyBpbmZvcm1hdGlvbiBpcyBhdmFpbGFibGUgZnJvbSBzdGFuZGFyZCBpbmRleC4KKyAgICBwcml2YXRlIGZpbmFsIFRhcGVTZWdtZW50SGVhZGVyIGhlYWRlciA9IG5ldyBUYXBlU2VnbWVudEhlYWRlcigpOworICAgIHByaXZhdGUgU3RyaW5nIHNpbXBsZU5hbWU7CisgICAgcHJpdmF0ZSBTdHJpbmcgb3JpZ2luYWxOYW1lOworCisgICAgLy8gdGhpcyBpbmZvcm1hdGlvbiBpcyBhdmFpbGFibGUgZnJvbSBRRkEgaW5kZXgKKyAgICBwcml2YXRlIGludCB2b2x1bWU7CisgICAgcHJpdmF0ZSBsb25nIG9mZnNldDsKKyAgICBwcml2YXRlIGludCBpbm87CisgICAgcHJpdmF0ZSBpbnQgbmxpbms7CisgICAgcHJpdmF0ZSBsb25nIGN0aW1lOworICAgIHByaXZhdGUgaW50IGdlbmVyYXRpb247CisgICAgcHJpdmF0ZSBib29sZWFuIGlzRGVsZXRlZDsKKworICAgIC8qKgorICAgICAqIERlZmF1bHQgY29uc3RydWN0b3IuCisgICAgICovCisgICAgcHVibGljIER1bXBBcmNoaXZlRW50cnkoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IgdGFraW5nIG9ubHkgZmlsZW5hbWUuCisgICAgICogQHBhcmFtIG5hbWUgcGF0aG5hbWUKKyAgICAgKiBAcGFyYW0gc2ltcGxlTmFtZSBhY3R1YWwgZmlsZW5hbWUuCisgICAgICovCisgICAgcHVibGljIER1bXBBcmNoaXZlRW50cnkoZmluYWwgU3RyaW5nIG5hbWUsIGZpbmFsIFN0cmluZyBzaW1wbGVOYW1lKSB7CisgICAgICAgIHNldE5hbWUobmFtZSk7CisgICAgICAgIHRoaXMuc2ltcGxlTmFtZSA9IHNpbXBsZU5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IgdGFraW5nIG5hbWUsIGlub2RlIGFuZCB0eXBlLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgdGhlIG5hbWUKKyAgICAgKiBAcGFyYW0gc2ltcGxlTmFtZSB0aGUgc2ltcGxlIG5hbWUKKyAgICAgKiBAcGFyYW0gaW5vIHRoZSBpbm8KKyAgICAgKiBAcGFyYW0gdHlwZSB0aGUgdHlwZQorICAgICAqLworICAgIHByb3RlY3RlZCBEdW1wQXJjaGl2ZUVudHJ5KGZpbmFsIFN0cmluZyBuYW1lLCBmaW5hbCBTdHJpbmcgc2ltcGxlTmFtZSwgZmluYWwgaW50IGlubywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBUWVBFIHR5cGUpIHsKKyAgICAgICAgc2V0VHlwZSh0eXBlKTsKKyAgICAgICAgc2V0TmFtZShuYW1lKTsKKyAgICAgICAgdGhpcy5zaW1wbGVOYW1lID0gc2ltcGxlTmFtZTsKKyAgICAgICAgdGhpcy5pbm8gPSBpbm87CisgICAgICAgIHRoaXMub2Zmc2V0ID0gMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwYXRoIG9mIHRoZSBlbnRyeS4KKyAgICAgKiBAcmV0dXJuIHRoZSBwYXRoIG9mIHRoZSBlbnRyeS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFNpbXBsZU5hbWUoKSB7CisgICAgICAgIHJldHVybiBzaW1wbGVOYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHBhdGggb2YgdGhlIGVudHJ5LgorICAgICAqIEBwYXJhbSBzaW1wbGVOYW1lIHRoZSBzaW1wbGUgbmFtZQorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHNldFNpbXBsZU5hbWUoZmluYWwgU3RyaW5nIHNpbXBsZU5hbWUpIHsKKyAgICAgICAgdGhpcy5zaW1wbGVOYW1lID0gc2ltcGxlTmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBpbm8gb2YgdGhlIGVudHJ5LgorICAgICAqIEByZXR1cm4gdGhlIGlubworICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0SW5vKCkgeworICAgICAgICByZXR1cm4gaGVhZGVyLmdldElubygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgbnVtYmVyIG9mIGhhcmQgbGlua3MgdG8gdGhlIGVudHJ5LgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBoYXJkIGxpbmtzCisgICAgICovCisgICAgcHVibGljIGludCBnZXRObGluaygpIHsKKyAgICAgICAgcmV0dXJuIG5saW5rOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgbnVtYmVyIG9mIGhhcmQgbGlua3MuCisgICAgICogQHBhcmFtIG5saW5rIHRoZSBudW1iZXIgb2YgaGFyZCBsaW5rcworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE5saW5rKGZpbmFsIGludCBubGluaykgeworICAgICAgICB0aGlzLm5saW5rID0gbmxpbms7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IGZpbGUgY3JlYXRpb24gdGltZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBjcmVhdGlvbiB0aW1lCisgICAgICovCisgICAgcHVibGljIERhdGUgZ2V0Q3JlYXRpb25UaW1lKCkgeworICAgICAgICByZXR1cm4gbmV3IERhdGUoY3RpbWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgZmlsZSBjcmVhdGlvbiB0aW1lLgorICAgICAqIEBwYXJhbSBjdGltZSB0aGUgY3JlYXRpb24gdGltZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldENyZWF0aW9uVGltZShmaW5hbCBEYXRlIGN0aW1lKSB7CisgICAgICAgIHRoaXMuY3RpbWUgPSBjdGltZS5nZXRUaW1lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBnZW5lcmF0aW9uIG9mIHRoZSBmaWxlLgorICAgICAqIEByZXR1cm4gdGhlIGdlbmVyYXRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldEdlbmVyYXRpb24oKSB7CisgICAgICAgIHJldHVybiBnZW5lcmF0aW9uOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgZ2VuZXJhdGlvbiBvZiB0aGUgZmlsZS4KKyAgICAgKiBAcGFyYW0gZ2VuZXJhdGlvbiB0aGUgZ2VuZXJhdGlvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEdlbmVyYXRpb24oZmluYWwgaW50IGdlbmVyYXRpb24pIHsKKyAgICAgICAgdGhpcy5nZW5lcmF0aW9uID0gZ2VuZXJhdGlvbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBIYXMgdGhpcyBmaWxlIGJlZW4gZGVsZXRlZD8gKE9uIHZhbGlkIG9uIGluY3JlbWVudGFsIGR1bXBzLikKKyAgICAgKiBAcmV0dXJuIHdoZXRoZXIgdGhlIGZpbGUgaGFzIGJlZW4gZGVsZXRlZAorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzRGVsZXRlZCgpIHsKKyAgICAgICAgcmV0dXJuIGlzRGVsZXRlZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgd2hldGhlciB0aGlzIGZpbGUgaGFzIGJlZW4gZGVsZXRlZC4KKyAgICAgKiBAcGFyYW0gaXNEZWxldGVkIHdoZXRoZXIgdGhlIGZpbGUgaGFzIGJlZW4gZGVsZXRlZAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldERlbGV0ZWQoZmluYWwgYm9vbGVhbiBpc0RlbGV0ZWQpIHsKKyAgICAgICAgdGhpcy5pc0RlbGV0ZWQgPSBpc0RlbGV0ZWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBvZmZzZXQgd2l0aGluIHRoZSBhcmNoaXZlCisgICAgICogQHJldHVybiB0aGUgb2Zmc2V0CisgICAgICovCisgICAgcHVibGljIGxvbmcgZ2V0T2Zmc2V0KCkgeworICAgICAgICByZXR1cm4gb2Zmc2V0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgb2Zmc2V0IHdpdGhpbiB0aGUgYXJjaGl2ZS4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0IHRoZSBvZmZzZXQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRPZmZzZXQoZmluYWwgbG9uZyBvZmZzZXQpIHsKKyAgICAgICAgdGhpcy5vZmZzZXQgPSBvZmZzZXQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSB0YXBlIHZvbHVtZSB3aGVyZSB0aGlzIGZpbGUgaXMgbG9jYXRlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSB2b2x1bWUKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFZvbHVtZSgpIHsKKyAgICAgICAgcmV0dXJuIHZvbHVtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHRhcGUgdm9sdW1lLgorICAgICAqIEBwYXJhbSB2b2x1bWUgdGhlIHZvbHVtZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFZvbHVtZShmaW5hbCBpbnQgdm9sdW1lKSB7CisgICAgICAgIHRoaXMudm9sdW1lID0gdm9sdW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgdHlwZSBvZiB0aGUgdGFwZSBzZWdtZW50IGhlYWRlci4KKyAgICAgKiBAcmV0dXJuIHRoZSBzZWdtZW50IGhlYWRlcgorICAgICAqLworICAgIHB1YmxpYyBEdW1wQXJjaGl2ZUNvbnN0YW50cy5TRUdNRU5UX1RZUEUgZ2V0SGVhZGVyVHlwZSgpIHsKKyAgICAgICAgcmV0dXJuIGhlYWRlci5nZXRUeXBlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBudW1iZXIgb2YgcmVjb3JkcyBpbiB0aGlzIHNlZ21lbnQuCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIHJlY29yZHMKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldEhlYWRlckNvdW50KCkgeworICAgICAgICByZXR1cm4gaGVhZGVyLmdldENvdW50KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBudW1iZXIgb2Ygc3BhcnNlIHJlY29yZHMgaW4gdGhpcyBzZWdtZW50LgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBzcGFyc2UgcmVjb3JkcworICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0SGVhZGVySG9sZXMoKSB7CisgICAgICAgIHJldHVybiBoZWFkZXIuZ2V0SG9sZXMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJcyB0aGlzIGEgc3BhcnNlIHJlY29yZD8KKyAgICAgKiBAcGFyYW0gaWR4IGluZGV4IG9mIHRoZSByZWNvcmQgdG8gY2hlY2sKKyAgICAgKiBAcmV0dXJuIHdoZXRoZXIgdGhpcyBpcyBhIHNwYXJzZSByZWNvcmQKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NwYXJzZVJlY29yZChmaW5hbCBpbnQgaWR4KSB7CisgICAgICAgIHJldHVybiAoaGVhZGVyLmdldENkYXRhKGlkeCkgJiAweDAxKSA9PSAwOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIHJldHVybiBpbm87CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIE9iamVjdCBvKSB7CisgICAgICAgIGlmIChvID09IHRoaXMpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9IGVsc2UgaWYgKG8gPT0gbnVsbCB8fCAhby5nZXRDbGFzcygpLmVxdWFscyhnZXRDbGFzcygpKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgZmluYWwgRHVtcEFyY2hpdmVFbnRyeSByaHMgPSAoRHVtcEFyY2hpdmVFbnRyeSkgbzsKKworICAgICAgICBpZiAocmhzLmhlYWRlciA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBpZiAoaW5vICE9IHJocy5pbm8pIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHN1bW1hcnkgaXMgYWx3YXlzIG51bGwgcmlnaHQgbm93LCBidXQgdGhpcyBtYXkgY2hhbmdlIHNvbWUgZGF5CisgICAgICAgIGlmICgoc3VtbWFyeSA9PSBudWxsICYmIHJocy5zdW1tYXJ5ICE9IG51bGwpIC8vIE5PU09OQVIKKyAgICAgICAgICAgICAgICB8fCAoc3VtbWFyeSAhPSBudWxsICYmICFzdW1tYXJ5LmVxdWFscyhyaHMuc3VtbWFyeSkpKSB7IC8vIE5PU09OQVIKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIHJldHVybiBnZXROYW1lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUG9wdWxhdGUgdGhlIGR1bXAgYXJjaGl2ZSBlbnRyeSBhbmQgdGFwZSBzZWdtZW50IGhlYWRlciB3aXRoCisgICAgICogdGhlIGNvbnRlbnRzIG9mIHRoZSBidWZmZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYnVmZmVyIGJ1ZmZlciB0byByZWFkIGNvbnRlbnQgZnJvbQorICAgICAqLworICAgIHN0YXRpYyBEdW1wQXJjaGl2ZUVudHJ5IHBhcnNlKGZpbmFsIGJ5dGVbXSBidWZmZXIpIHsKKyAgICAgICAgZmluYWwgRHVtcEFyY2hpdmVFbnRyeSBlbnRyeSA9IG5ldyBEdW1wQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgIGZpbmFsIFRhcGVTZWdtZW50SGVhZGVyIGhlYWRlciA9IGVudHJ5LmhlYWRlcjsKKworICAgICAgICBoZWFkZXIudHlwZSA9IER1bXBBcmNoaXZlQ29uc3RhbnRzLlNFR01FTlRfVFlQRS5maW5kKER1bXBBcmNoaXZlVXRpbC5jb252ZXJ0MzIoCisgICAgICAgICAgICAgICAgICAgIGJ1ZmZlciwgMCkpOworCisgICAgICAgIC8vaGVhZGVyLmR1bXBEYXRlID0gbmV3IERhdGUoMTAwMEwgKiBEdW1wQXJjaGl2ZVV0aWwuY29udmVydDMyKGJ1ZmZlciwgNCkpOworICAgICAgICAvL2hlYWRlci5wcmV2aW91c0R1bXBEYXRlID0gbmV3IERhdGUoMTAwMEwgKiBEdW1wQXJjaGl2ZVV0aWwuY29udmVydDMyKAorICAgICAgICAvLyAgICAgICAgICAgIGJ1ZmZlciwgOCkpOworICAgICAgICBoZWFkZXIudm9sdW1lID0gRHVtcEFyY2hpdmVVdGlsLmNvbnZlcnQzMihidWZmZXIsIDEyKTsKKyAgICAgICAgLy9oZWFkZXIudGFwZWEgPSBEdW1wQXJjaGl2ZVV0aWwuY29udmVydDMyKGJ1ZmZlciwgMTYpOworICAgICAgICBlbnRyeS5pbm8gPSBoZWFkZXIuaW5vID0gRHVtcEFyY2hpdmVVdGlsLmNvbnZlcnQzMihidWZmZXIsIDIwKTsKKworICAgICAgICAvL2hlYWRlci5tYWdpYyA9IER1bXBBcmNoaXZlVXRpbC5jb252ZXJ0MzIoYnVmZmVyLCAyNCk7CisgICAgICAgIC8vaGVhZGVyLmNoZWNrc3VtID0gRHVtcEFyY2hpdmVVdGlsLmNvbnZlcnQzMihidWZmZXIsIDI4KTsKKyAgICAgICAgZmluYWwgaW50IG0gPSBEdW1wQXJjaGl2ZVV0aWwuY29udmVydDE2KGJ1ZmZlciwgMzIpOworCisgICAgICAgIC8vIGRldGVybWluZSB0aGUgdHlwZSBvZiB0aGUgZmlsZS4KKyAgICAgICAgZW50cnkuc2V0VHlwZShUWVBFLmZpbmQoKG0gPj4gMTIpICYgMHgwRikpOworCisgICAgICAgIC8vIGRldGVybWluZSB0aGUgc3RhbmRhcmQgcGVybWlzc2lvbnMKKyAgICAgICAgZW50cnkuc2V0TW9kZShtKTsKKworICAgICAgICBlbnRyeS5ubGluayA9IER1bXBBcmNoaXZlVXRpbC5jb252ZXJ0MTYoYnVmZmVyLCAzNCk7CisgICAgICAgIC8vIGludW1iZXIsIG9sZGlkcz8KKyAgICAgICAgZW50cnkuc2V0U2l6ZShEdW1wQXJjaGl2ZVV0aWwuY29udmVydDY0KGJ1ZmZlciwgNDApKTsKKworICAgICAgICBsb25nIHQgPSAoMTAwMEwgKiBEdW1wQXJjaGl2ZVV0aWwuY29udmVydDMyKGJ1ZmZlciwgNDgpKSArCisgICAgICAgICAgICAoRHVtcEFyY2hpdmVVdGlsLmNvbnZlcnQzMihidWZmZXIsIDUyKSAvIDEwMDApOworICAgICAgICBlbnRyeS5zZXRBY2Nlc3NUaW1lKG5ldyBEYXRlKHQpKTsKKyAgICAgICAgdCA9ICgxMDAwTCAqIER1bXBBcmNoaXZlVXRpbC5jb252ZXJ0MzIoYnVmZmVyLCA1NikpICsKKyAgICAgICAgICAgIChEdW1wQXJjaGl2ZVV0aWwuY29udmVydDMyKGJ1ZmZlciwgNjApIC8gMTAwMCk7CisgICAgICAgIGVudHJ5LnNldExhc3RNb2RpZmllZERhdGUobmV3IERhdGUodCkpOworICAgICAgICB0ID0gKDEwMDBMICogRHVtcEFyY2hpdmVVdGlsLmNvbnZlcnQzMihidWZmZXIsIDY0KSkgKworICAgICAgICAgICAgKER1bXBBcmNoaXZlVXRpbC5jb252ZXJ0MzIoYnVmZmVyLCA2OCkgLyAxMDAwKTsKKyAgICAgICAgZW50cnkuY3RpbWUgPSB0OworCisgICAgICAgIC8vIGRiOiA3Mi0xMTkgLSBkaXJlY3QgYmxvY2tzCisgICAgICAgIC8vIGlkOiAxMjAtMTMxIC0gaW5kaXJlY3QgYmxvY2tzCisgICAgICAgIC8vZW50cnkuZmxhZ3MgPSBEdW1wQXJjaGl2ZVV0aWwuY29udmVydDMyKGJ1ZmZlciwgMTMyKTsKKyAgICAgICAgLy9lbnRyeS5ibG9ja3MgPSBEdW1wQXJjaGl2ZVV0aWwuY29udmVydDMyKGJ1ZmZlciwgMTM2KTsKKyAgICAgICAgZW50cnkuZ2VuZXJhdGlvbiA9IER1bXBBcmNoaXZlVXRpbC5jb252ZXJ0MzIoYnVmZmVyLCAxNDApOworICAgICAgICBlbnRyeS5zZXRVc2VySWQoRHVtcEFyY2hpdmVVdGlsLmNvbnZlcnQzMihidWZmZXIsIDE0NCkpOworICAgICAgICBlbnRyeS5zZXRHcm91cElkKER1bXBBcmNoaXZlVXRpbC5jb252ZXJ0MzIoYnVmZmVyLCAxNDgpKTsKKyAgICAgICAgLy8gdHdvIDMyLWJpdCBzcGFyZSB2YWx1ZXMuCisgICAgICAgIGhlYWRlci5jb3VudCA9IER1bXBBcmNoaXZlVXRpbC5jb252ZXJ0MzIoYnVmZmVyLCAxNjApOworCisgICAgICAgIGhlYWRlci5ob2xlcyA9IDA7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IChpIDwgNTEyKSAmJiAoaSA8IGhlYWRlci5jb3VudCk7IGkrKykgeworICAgICAgICAgICAgaWYgKGJ1ZmZlclsxNjQgKyBpXSA9PSAwKSB7CisgICAgICAgICAgICAgICAgaGVhZGVyLmhvbGVzKys7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGJ1ZmZlciwgMTY0LCBoZWFkZXIuY2RhdGEsIDAsIDUxMik7CisKKyAgICAgICAgZW50cnkudm9sdW1lID0gaGVhZGVyLmdldFZvbHVtZSgpOworCisgICAgICAgIC8vZW50cnkuaXNTdW1tYXJ5T25seSA9IGZhbHNlOworICAgICAgICByZXR1cm4gZW50cnk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVXBkYXRlIGVudHJ5IHdpdGggaW5mb3JtYXRpb24gZnJvbSBuZXh0IHRhcGUgc2VnbWVudCBoZWFkZXIuCisgICAgICovCisgICAgdm9pZCB1cGRhdGUoZmluYWwgYnl0ZVtdIGJ1ZmZlcikgeworICAgICAgICBoZWFkZXIudm9sdW1lID0gRHVtcEFyY2hpdmVVdGlsLmNvbnZlcnQzMihidWZmZXIsIDE2KTsKKyAgICAgICAgaGVhZGVyLmNvdW50ID0gRHVtcEFyY2hpdmVVdGlsLmNvbnZlcnQzMihidWZmZXIsIDE2MCk7CisKKyAgICAgICAgaGVhZGVyLmhvbGVzID0gMDsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgKGkgPCA1MTIpICYmIChpIDwgaGVhZGVyLmNvdW50KTsgaSsrKSB7CisgICAgICAgICAgICBpZiAoYnVmZmVyWzE2NCArIGldID09IDApIHsKKyAgICAgICAgICAgICAgICBoZWFkZXIuaG9sZXMrKzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYnVmZmVyLCAxNjQsIGhlYWRlci5jZGF0YSwgMCwgNTEyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBcmNoaXZlIGVudHJ5IGFzIHN0b3JlZCBvbiB0YXBlLiBUaGVyZSBpcyBvbmUgVFNIIGZvciAoYXQgbW9zdCkKKyAgICAgKiBldmVyeSA1MTJrIGluIHRoZSBmaWxlLgorICAgICAqLworICAgIHN0YXRpYyBjbGFzcyBUYXBlU2VnbWVudEhlYWRlciB7CisgICAgICAgIHByaXZhdGUgRHVtcEFyY2hpdmVDb25zdGFudHMuU0VHTUVOVF9UWVBFIHR5cGU7CisgICAgICAgIHByaXZhdGUgaW50IHZvbHVtZTsKKyAgICAgICAgcHJpdmF0ZSBpbnQgaW5vOworICAgICAgICBwcml2YXRlIGludCBjb3VudDsKKyAgICAgICAgcHJpdmF0ZSBpbnQgaG9sZXM7CisgICAgICAgIHByaXZhdGUgZmluYWwgYnl0ZVtdIGNkYXRhID0gbmV3IGJ5dGVbNTEyXTsgLy8gbWFwIG9mIGFueSAnaG9sZXMnCisKKyAgICAgICAgcHVibGljIER1bXBBcmNoaXZlQ29uc3RhbnRzLlNFR01FTlRfVFlQRSBnZXRUeXBlKCkgeworICAgICAgICAgICAgcmV0dXJuIHR5cGU7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IGdldFZvbHVtZSgpIHsKKyAgICAgICAgICAgIHJldHVybiB2b2x1bWU7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IGdldElubygpIHsKKyAgICAgICAgICAgIHJldHVybiBpbm87CisgICAgICAgIH0KKworICAgICAgICB2b2lkIHNldElubyhmaW5hbCBpbnQgaW5vKSB7CisgICAgICAgICAgICB0aGlzLmlubyA9IGlubzsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgZ2V0Q291bnQoKSB7CisgICAgICAgICAgICByZXR1cm4gY291bnQ7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IGdldEhvbGVzKCkgeworICAgICAgICAgICAgcmV0dXJuIGhvbGVzOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCBnZXRDZGF0YShmaW5hbCBpbnQgaWR4KSB7CisgICAgICAgICAgICByZXR1cm4gY2RhdGFbaWR4XTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIGVudHJ5LgorICAgICAqCisgICAgICogPHA+VGhpcyBtZXRob2QgcmV0dXJucyB0aGUgcmF3IG5hbWUgYXMgaXQgaXMgc3RvcmVkIGluc2lkZSBvZiB0aGUgYXJjaGl2ZS48L3A+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuYW1lIG9mIHRoZSBlbnRyeS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7CisgICAgICAgIHJldHVybiBuYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHVubW9kaWZpZWQgbmFtZSBvZiB0aGUgZW50cnkuCisgICAgICogQHJldHVybiB0aGUgbmFtZSBvZiB0aGUgZW50cnkuCisgICAgICovCisgICAgU3RyaW5nIGdldE9yaWdpbmFsTmFtZSgpIHsKKyAgICAgICAgcmV0dXJuIG9yaWdpbmFsTmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBuYW1lIG9mIHRoZSBlbnRyeS4KKyAgICAgKiBAcGFyYW0gbmFtZSB0aGUgbmFtZQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHNldE5hbWUoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgdGhpcy5vcmlnaW5hbE5hbWUgPSBuYW1lOworICAgICAgICBpZiAobmFtZSAhPSBudWxsKSB7CisgICAgICAgICAgICBpZiAoaXNEaXJlY3RvcnkoKSAmJiAhbmFtZS5lbmRzV2l0aCgiLyIpKSB7CisgICAgICAgICAgICAgICAgbmFtZSArPSAiLyI7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAobmFtZS5zdGFydHNXaXRoKCIuLyIpKSB7CisgICAgICAgICAgICAgICAgbmFtZSA9IG5hbWUuc3Vic3RyaW5nKDIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIGxhc3QgbW9kaWZpZWQgZGF0ZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBsYXN0IG1vZGlmaWVkIGRhdGUKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRGF0ZSBnZXRMYXN0TW9kaWZpZWREYXRlKCkgeworICAgICAgICByZXR1cm4gbmV3IERhdGUobXRpbWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIElzIHRoaXMgYSBkaXJlY3Rvcnk/CisgICAgICogQHJldHVybiB3aGV0aGVyIHRoaXMgaXMgYSBkaXJlY3RvcnkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0RpcmVjdG9yeSgpIHsKKyAgICAgICAgcmV0dXJuIHR5cGUgPT0gVFlQRS5ESVJFQ1RPUlk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSXMgdGhpcyBhIHJlZ3VsYXIgZmlsZT8KKyAgICAgKiBAcmV0dXJuIHdoZXRoZXIgdGhpcyBpcyBhIHJlZ3VsYXIgZmlsZQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzRmlsZSgpIHsKKyAgICAgICAgcmV0dXJuIHR5cGUgPT0gVFlQRS5GSUxFOworICAgIH0KKworICAgIC8qKgorICAgICAqIElzIHRoaXMgYSBuZXR3b3JrIGRldmljZT8KKyAgICAgKiBAcmV0dXJuIHdoZXRoZXIgdGhpcyBpcyBhIHNvY2tldAorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzU29ja2V0KCkgeworICAgICAgICByZXR1cm4gdHlwZSA9PSBUWVBFLlNPQ0tFVDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJcyB0aGlzIGEgY2hhcmFjdGVyIGRldmljZT8KKyAgICAgKiBAcmV0dXJuIHdoZXRoZXIgdGhpcyBpcyBhIGNoYXJhY3RlciBkZXZpY2UKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0NockRldigpIHsKKyAgICAgICAgcmV0dXJuIHR5cGUgPT0gVFlQRS5DSFJERVY7CisgICAgfQorCisgICAgLyoqCisgICAgICogSXMgdGhpcyBhIGJsb2NrIGRldmljZT8KKyAgICAgKiBAcmV0dXJuIHdoZXRoZXIgdGhpcyBpcyBhIGJsb2NrIGRldmljZQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzQmxrRGV2KCkgeworICAgICAgICByZXR1cm4gdHlwZSA9PSBUWVBFLkJMS0RFVjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJcyB0aGlzIGEgZmlmby9waXBlPworICAgICAqIEByZXR1cm4gd2hldGhlciB0aGlzIGlzIGEgZmlmbworICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzRmlmbygpIHsKKyAgICAgICAgcmV0dXJuIHR5cGUgPT0gVFlQRS5GSUZPOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgdHlwZSBvZiB0aGUgZW50cnkuCisgICAgICogQHJldHVybiB0aGUgdHlwZQorICAgICAqLworICAgIHB1YmxpYyBUWVBFIGdldFR5cGUoKSB7CisgICAgICAgIHJldHVybiB0eXBlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgdHlwZSBvZiB0aGUgZW50cnkuCisgICAgICogQHBhcmFtIHR5cGUgdGhlIHR5cGUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRUeXBlKGZpbmFsIFRZUEUgdHlwZSkgeworICAgICAgICB0aGlzLnR5cGUgPSB0eXBlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgYWNjZXNzIHBlcm1pc3Npb25zIG9uIHRoZSBlbnRyeS4KKyAgICAgKiBAcmV0dXJuIHRoZSBhY2Nlc3MgcGVybWlzc2lvbnMKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldE1vZGUoKSB7CisgICAgICAgIHJldHVybiBtb2RlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgYWNjZXNzIHBlcm1pc3Npb25zIG9uIHRoZSBlbnRyeS4KKyAgICAgKiBAcGFyYW0gbW9kZSB0aGUgYWNjZXNzIHBlcm1pc3Npb25zCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TW9kZShmaW5hbCBpbnQgbW9kZSkgeworICAgICAgICB0aGlzLm1vZGUgPSBtb2RlICYgMDc3Nzc7CisgICAgICAgIHRoaXMucGVybWlzc2lvbnMgPSBQRVJNSVNTSU9OLmZpbmQobW9kZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcGVybWlzc2lvbnMgb24gdGhlIGVudHJ5LgorICAgICAqIEByZXR1cm4gdGhlIHBlcm1pc3Npb25zCisgICAgICovCisgICAgcHVibGljIFNldDxQRVJNSVNTSU9OPiBnZXRQZXJtaXNzaW9ucygpIHsKKyAgICAgICAgcmV0dXJuIHBlcm1pc3Npb25zOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHNpemUgb2YgdGhlIGVudHJ5LgorICAgICAqIEByZXR1cm4gdGhlIHNpemUKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgbG9uZyBnZXRTaXplKCkgeworICAgICAgICByZXR1cm4gaXNEaXJlY3RvcnkoKSA/IFNJWkVfVU5LTk9XTiA6IHNpemU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc2l6ZSBvZiB0aGUgZW50cnkgYXMgcmVhZCBmcm9tIHRoZSBhcmNoaXZlLgorICAgICAqLworICAgIGxvbmcgZ2V0RW50cnlTaXplKCkgeworICAgICAgICByZXR1cm4gc2l6ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHNpemUgb2YgdGhlIGVudHJ5LgorICAgICAqIEBwYXJhbSBzaXplIHRoZSBzaXplCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0U2l6ZShmaW5hbCBsb25nIHNpemUpIHsKKyAgICAgICAgdGhpcy5zaXplID0gc2l6ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHRpbWUgdGhlIGZpbGUgd2FzIGxhc3QgbW9kaWZpZWQuCisgICAgICogQHBhcmFtIG10aW1lIHRoZSBsYXN0IG1vZGlmaWVkIHRpbWUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRMYXN0TW9kaWZpZWREYXRlKGZpbmFsIERhdGUgbXRpbWUpIHsKKyAgICAgICAgdGhpcy5tdGltZSA9IG10aW1lLmdldFRpbWUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB0aW1lIHRoZSBmaWxlIHdhcyBsYXN0IGFjY2Vzc2VkLgorICAgICAqIEByZXR1cm4gdGhlIGFjY2VzcyB0aW1lCisgICAgICovCisgICAgcHVibGljIERhdGUgZ2V0QWNjZXNzVGltZSgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBEYXRlKGF0aW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHRpbWUgdGhlIGZpbGUgd2FzIGxhc3QgYWNjZXNzZWQuCisgICAgICogQHBhcmFtIGF0aW1lIHRoZSBhY2Nlc3MgdGltZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEFjY2Vzc1RpbWUoZmluYWwgRGF0ZSBhdGltZSkgeworICAgICAgICB0aGlzLmF0aW1lID0gYXRpbWUuZ2V0VGltZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgdXNlciBpZC4KKyAgICAgKiBAcmV0dXJuIHRoZSB1c2VyIGlkCisgICAgICovCisgICAgcHVibGljIGludCBnZXRVc2VySWQoKSB7CisgICAgICAgIHJldHVybiB1aWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSB1c2VyIGlkLgorICAgICAqIEBwYXJhbSB1aWQgdGhlIHVzZXIgaWQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRVc2VySWQoZmluYWwgaW50IHVpZCkgeworICAgICAgICB0aGlzLnVpZCA9IHVpZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIGdyb3VwIGlkCisgICAgICogQHJldHVybiB0aGUgZ3JvdXAgaWQKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldEdyb3VwSWQoKSB7CisgICAgICAgIHJldHVybiBnaWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBncm91cCBpZC4KKyAgICAgKiBAcGFyYW0gZ2lkIHRoZSBncm91cCBpZAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEdyb3VwSWQoZmluYWwgaW50IGdpZCkgeworICAgICAgICB0aGlzLmdpZCA9IGdpZDsKKyAgICB9CisKKyAgICBwdWJsaWMgZW51bSBUWVBFIHsKKyAgICAgICAgV0hJVEVPVVQoMTQpLAorICAgICAgICBTT0NLRVQoMTIpLAorICAgICAgICBMSU5LKDEwKSwKKyAgICAgICAgRklMRSg4KSwKKyAgICAgICAgQkxLREVWKDYpLAorICAgICAgICBESVJFQ1RPUlkoNCksCisgICAgICAgIENIUkRFVigyKSwKKyAgICAgICAgRklGTygxKSwKKyAgICAgICAgVU5LTk9XTigxNSk7CisKKyAgICAgICAgcHJpdmF0ZSBpbnQgY29kZTsKKworICAgICAgICBUWVBFKGZpbmFsIGludCBjb2RlKSB7CisgICAgICAgICAgICB0aGlzLmNvZGUgPSBjb2RlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHN0YXRpYyBUWVBFIGZpbmQoZmluYWwgaW50IGNvZGUpIHsKKyAgICAgICAgICAgIFRZUEUgdHlwZSA9IFVOS05PV047CisKKyAgICAgICAgICAgIGZvciAoZmluYWwgVFlQRSB0IDogVFlQRS52YWx1ZXMoKSkgeworICAgICAgICAgICAgICAgIGlmIChjb2RlID09IHQuY29kZSkgeworICAgICAgICAgICAgICAgICAgICB0eXBlID0gdDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHJldHVybiB0eXBlOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGVudW0gUEVSTUlTU0lPTiB7CisgICAgICAgIFNFVFVJRCgwNDAwMCksCisgICAgICAgIFNFVEdVSSgwMjAwMCksCisgICAgICAgIFNUSUNLWSgwMTAwMCksCisgICAgICAgIFVTRVJfUkVBRCgwMDQwMCksCisgICAgICAgIFVTRVJfV1JJVEUoMDAyMDApLAorICAgICAgICBVU0VSX0VYRUMoMDAxMDApLAorICAgICAgICBHUk9VUF9SRUFEKDAwMDQwKSwKKyAgICAgICAgR1JPVVBfV1JJVEUoMDAwMjApLAorICAgICAgICBHUk9VUF9FWEVDKDAwMDEwKSwKKyAgICAgICAgV09STERfUkVBRCgwMDAwNCksCisgICAgICAgIFdPUkxEX1dSSVRFKDAwMDAyKSwKKyAgICAgICAgV09STERfRVhFQygwMDAwMSk7CisKKyAgICAgICAgcHJpdmF0ZSBpbnQgY29kZTsKKworICAgICAgICBQRVJNSVNTSU9OKGZpbmFsIGludCBjb2RlKSB7CisgICAgICAgICAgICB0aGlzLmNvZGUgPSBjb2RlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHN0YXRpYyBTZXQ8UEVSTUlTU0lPTj4gZmluZChmaW5hbCBpbnQgY29kZSkgeworICAgICAgICAgICAgZmluYWwgU2V0PFBFUk1JU1NJT04+IHNldCA9IG5ldyBIYXNoU2V0PD4oKTsKKworICAgICAgICAgICAgZm9yIChmaW5hbCBQRVJNSVNTSU9OIHAgOiBQRVJNSVNTSU9OLnZhbHVlcygpKSB7CisgICAgICAgICAgICAgICAgaWYgKChjb2RlICYgcC5jb2RlKSA9PSBwLmNvZGUpIHsKKyAgICAgICAgICAgICAgICAgICAgc2V0LmFkZChwKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChzZXQuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLmVtcHR5U2V0KCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHJldHVybiBFbnVtU2V0LmNvcHlPZihzZXQpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2R1bXAvRHVtcEFyY2hpdmVFeGNlcHRpb24uamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9kdW1wL0R1bXBBcmNoaXZlRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjM1YjFkOQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9kdW1wL0R1bXBBcmNoaXZlRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw0NSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuZHVtcDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKKworLyoqCisgKiBEdW1wIEFyY2hpdmUgRXhjZXB0aW9uCisgKi8KK3B1YmxpYyBjbGFzcyBEdW1wQXJjaGl2ZUV4Y2VwdGlvbiBleHRlbmRzIElPRXhjZXB0aW9uIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxTDsKKworICAgIHB1YmxpYyBEdW1wQXJjaGl2ZUV4Y2VwdGlvbigpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgRHVtcEFyY2hpdmVFeGNlcHRpb24oZmluYWwgU3RyaW5nIG1zZykgeworICAgICAgICBzdXBlcihtc2cpOworICAgIH0KKworICAgIHB1YmxpYyBEdW1wQXJjaGl2ZUV4Y2VwdGlvbihmaW5hbCBUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgaW5pdENhdXNlKGNhdXNlKTsKKyAgICB9CisKKyAgICBwdWJsaWMgRHVtcEFyY2hpdmVFeGNlcHRpb24oZmluYWwgU3RyaW5nIG1zZywgZmluYWwgVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKG1zZyk7CisgICAgICAgIGluaXRDYXVzZShjYXVzZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2R1bXAvRHVtcEFyY2hpdmVJbnB1dFN0cmVhbS5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2R1bXAvRHVtcEFyY2hpdmVJbnB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVkNGYwMmYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvZHVtcC9EdW1wQXJjaGl2ZUlucHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSw1NjEgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLmR1bXA7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLkFyY2hpdmVFeGNlcHRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5BcmNoaXZlSW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXAuWmlwRW5jb2Rpbmc7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXAuWmlwRW5jb2RpbmdIZWxwZXI7CisKK2ltcG9ydCBqYXZhLmlvLkVPRkV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5Db21wYXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLlByaW9yaXR5UXVldWU7CitpbXBvcnQgamF2YS51dGlsLlF1ZXVlOworaW1wb3J0IGphdmEudXRpbC5TdGFjazsKKworLyoqCisgKiBUaGUgRHVtcEFyY2hpdmVJbnB1dFN0cmVhbSByZWFkcyBhIFVOSVggZHVtcCBhcmNoaXZlIGFzIGFuIElucHV0U3RyZWFtLgorICogTWV0aG9kcyBhcmUgcHJvdmlkZWQgdG8gcG9zaXRpb24gYXQgZWFjaCBzdWNjZXNzaXZlIGVudHJ5IGluCisgKiB0aGUgYXJjaGl2ZSwgYW5kIHRoZSByZWFkIGVhY2ggZW50cnkgYXMgYSBub3JtYWwgaW5wdXQgc3RyZWFtCisgKiB1c2luZyByZWFkKCkuCisgKgorICogVGhlcmUgZG9lc24ndCBzZWVtIHRvIGV4aXN0IGEgaGludCBvbiB0aGUgZW5jb2Rpbmcgb2Ygc3RyaW5nIHZhbHVlcworICogaW4gYW55IHBpZWNlIGRvY3VtZW50YXRpb24uICBHaXZlbiB0aGUgbWFpbiBwdXJwb3NlIG9mIGR1bXAvcmVzdG9yZQorICogaXMgYmFja2luZyB1cCBhIHN5c3RlbSBpdCBzZWVtcyB2ZXJ5IGxpa2VseSB0aGUgZm9ybWF0IHVzZXMgdGhlCisgKiBjdXJyZW50IGRlZmF1bHQgZW5jb2Rpbmcgb2YgdGhlIHN5c3RlbS4KKyAqCisgKiBATm90VGhyZWFkU2FmZQorICovCitwdWJsaWMgY2xhc3MgRHVtcEFyY2hpdmVJbnB1dFN0cmVhbSBleHRlbmRzIEFyY2hpdmVJbnB1dFN0cmVhbSB7CisgICAgcHJpdmF0ZSBEdW1wQXJjaGl2ZVN1bW1hcnkgc3VtbWFyeTsKKyAgICBwcml2YXRlIER1bXBBcmNoaXZlRW50cnkgYWN0aXZlOworICAgIHByaXZhdGUgYm9vbGVhbiBpc0Nsb3NlZDsKKyAgICBwcml2YXRlIGJvb2xlYW4gaGFzSGl0RU9GOworICAgIHByaXZhdGUgbG9uZyBlbnRyeVNpemU7CisgICAgcHJpdmF0ZSBsb25nIGVudHJ5T2Zmc2V0OworICAgIHByaXZhdGUgaW50IHJlYWRJZHg7CisgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10gcmVhZEJ1ZiA9IG5ldyBieXRlW0R1bXBBcmNoaXZlQ29uc3RhbnRzLlRQX1NJWkVdOworICAgIHByaXZhdGUgYnl0ZVtdIGJsb2NrQnVmZmVyOworICAgIHByaXZhdGUgaW50IHJlY29yZE9mZnNldDsKKyAgICBwcml2YXRlIGxvbmcgZmlsZXBvczsKKyAgICBwcm90ZWN0ZWQgVGFwZUlucHV0U3RyZWFtIHJhdzsKKworICAgIC8vIG1hcCBvZiBpbm8gLT4gZGlyZW50IGVudHJ5LiBXZSBjYW4gdXNlIHRoaXMgdG8gcmVjb25zdHJ1Y3QgZnVsbCBwYXRocy4KKyAgICBwcml2YXRlIGZpbmFsIE1hcDxJbnRlZ2VyLCBEaXJlbnQ+IG5hbWVzID0gbmV3IEhhc2hNYXA8PigpOworCisgICAgLy8gbWFwIG9mIGlubyAtPiAoZGlyZWN0b3J5KSBlbnRyeSB3aGVuIHdlJ3JlIG1pc3Npbmcgb25lIG9yIG1vcmUgZWxlbWVudHMgaW4gdGhlIHBhdGguCisgICAgcHJpdmF0ZSBmaW5hbCBNYXA8SW50ZWdlciwgRHVtcEFyY2hpdmVFbnRyeT4gcGVuZGluZyA9IG5ldyBIYXNoTWFwPD4oKTsKKworICAgIC8vIHF1ZXVlIG9mIChkaXJlY3RvcnkpIGVudHJpZXMgd2hlcmUgd2Ugbm93IGhhdmUgdGhlIGZ1bGwgcGF0aC4KKyAgICBwcml2YXRlIFF1ZXVlPER1bXBBcmNoaXZlRW50cnk+IHF1ZXVlOworCisgICAgLyoqCisgICAgICogVGhlIGVuY29kaW5nIHRvIHVzZSBmb3IgZmlsZW5hbWVzIGFuZCBsYWJlbHMuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBaaXBFbmNvZGluZyB6aXBFbmNvZGluZzsKKworICAgIC8vIHRoZSBwcm92aWRlZCBlbmNvZGluZyAoZm9yIHVuaXQgdGVzdHMpCisgICAgZmluYWwgU3RyaW5nIGVuY29kaW5nOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IgdXNpbmcgdGhlIHBsYXRmb3JtJ3MgZGVmYXVsdCBlbmNvZGluZyBmb3IgZmlsZQorICAgICAqIG5hbWVzLgorICAgICAqCisgICAgICogQHBhcmFtIGlzIHN0cmVhbSB0byByZWFkIGZyb20KKyAgICAgKiBAdGhyb3dzIEFyY2hpdmVFeGNlcHRpb24gb24gZXJyb3IKKyAgICAgKi8KKyAgICBwdWJsaWMgRHVtcEFyY2hpdmVJbnB1dFN0cmVhbShmaW5hbCBJbnB1dFN0cmVhbSBpcykgdGhyb3dzIEFyY2hpdmVFeGNlcHRpb24geworICAgICAgICB0aGlzKGlzLCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpcyBzdHJlYW0gdG8gcmVhZCBmcm9tCisgICAgICogQHBhcmFtIGVuY29kaW5nIHRoZSBlbmNvZGluZyB0byB1c2UgZm9yIGZpbGUgbmFtZXMsIHVzZSBudWxsCisgICAgICogZm9yIHRoZSBwbGF0Zm9ybSdzIGRlZmF1bHQgZW5jb2RpbmcKKyAgICAgKiBAc2luY2UgMS42CisgICAgICogQHRocm93cyBBcmNoaXZlRXhjZXB0aW9uIG9uIGVycm9yCisgICAgICovCisgICAgcHVibGljIER1bXBBcmNoaXZlSW5wdXRTdHJlYW0oZmluYWwgSW5wdXRTdHJlYW0gaXMsIGZpbmFsIFN0cmluZyBlbmNvZGluZykKKyAgICAgICAgdGhyb3dzIEFyY2hpdmVFeGNlcHRpb24geworICAgICAgICB0aGlzLnJhdyA9IG5ldyBUYXBlSW5wdXRTdHJlYW0oaXMpOworICAgICAgICB0aGlzLmhhc0hpdEVPRiA9IGZhbHNlOworICAgICAgICB0aGlzLmVuY29kaW5nID0gZW5jb2Rpbmc7CisgICAgICAgIHRoaXMuemlwRW5jb2RpbmcgPSBaaXBFbmNvZGluZ0hlbHBlci5nZXRaaXBFbmNvZGluZyhlbmNvZGluZyk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIHJlYWQgaGVhZGVyLCB2ZXJpZnkgaXQncyBhIGR1bXAgYXJjaGl2ZS4KKyAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBoZWFkZXJCeXRlcyA9IHJhdy5yZWFkUmVjb3JkKCk7CisKKyAgICAgICAgICAgIGlmICghRHVtcEFyY2hpdmVVdGlsLnZlcmlmeShoZWFkZXJCeXRlcykpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVW5yZWNvZ25pemVkRm9ybWF0RXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIGdldCBzdW1tYXJ5IGluZm9ybWF0aW9uCisgICAgICAgICAgICBzdW1tYXJ5ID0gbmV3IER1bXBBcmNoaXZlU3VtbWFyeShoZWFkZXJCeXRlcywgdGhpcy56aXBFbmNvZGluZyk7CisKKyAgICAgICAgICAgIC8vIHJlc2V0IGJ1ZmZlciB3aXRoIGFjdHVhbCBibG9jayBzaXplLgorICAgICAgICAgICAgcmF3LnJlc2V0QmxvY2tTaXplKHN1bW1hcnkuZ2V0TlRSZWMoKSwgc3VtbWFyeS5pc0NvbXByZXNzZWQoKSk7CisKKyAgICAgICAgICAgIC8vIGFsbG9jYXRlIG91ciByZWFkIGJ1ZmZlci4KKyAgICAgICAgICAgIGJsb2NrQnVmZmVyID0gbmV3IGJ5dGVbNCAqIER1bXBBcmNoaXZlQ29uc3RhbnRzLlRQX1NJWkVdOworCisgICAgICAgICAgICAvLyBza2lwIHBhc3QgQ0xSSSBhbmQgQklUUyBzZWdtZW50cyBzaW5jZSB3ZSBkb24ndCBoYW5kbGUgdGhlbSB5ZXQuCisgICAgICAgICAgICByZWFkQ0xSSSgpOworICAgICAgICAgICAgcmVhZEJJVFMoKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgSU9FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBcmNoaXZlRXhjZXB0aW9uKGV4LmdldE1lc3NhZ2UoKSwgZXgpOworICAgICAgICB9CisKKyAgICAgICAgLy8gcHV0IGluIGEgZHVtbXkgcmVjb3JkIGZvciB0aGUgcm9vdCBub2RlLgorICAgICAgICBmaW5hbCBEaXJlbnQgcm9vdCA9IG5ldyBEaXJlbnQoMiwgMiwgNCwgIi4iKTsKKyAgICAgICAgbmFtZXMucHV0KDIsIHJvb3QpOworCisgICAgICAgIC8vIHVzZSBwcmlvcml0eSBiYXNlZCBvbiBxdWV1ZSB0byBlbnN1cmUgcGFyZW50IGRpcmVjdG9yaWVzIGFyZQorICAgICAgICAvLyByZWxlYXNlZCBmaXJzdC4KKyAgICAgICAgcXVldWUgPSBuZXcgUHJpb3JpdHlRdWV1ZTw+KDEwLAorICAgICAgICAgICAgICAgIG5ldyBDb21wYXJhdG9yPER1bXBBcmNoaXZlRW50cnk+KCkgeworICAgICAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICAgICAgcHVibGljIGludCBjb21wYXJlKGZpbmFsIER1bXBBcmNoaXZlRW50cnkgcCwgZmluYWwgRHVtcEFyY2hpdmVFbnRyeSBxKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAocC5nZXRPcmlnaW5hbE5hbWUoKSA9PSBudWxsIHx8IHEuZ2V0T3JpZ2luYWxOYW1lKCkgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBJbnRlZ2VyLk1BWF9WQUxVRTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHAuZ2V0T3JpZ2luYWxOYW1lKCkuY29tcGFyZVRvKHEuZ2V0T3JpZ2luYWxOYW1lKCkpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSk7CisgICAgfQorCisgICAgQERlcHJlY2F0ZWQKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldENvdW50KCkgeworICAgICAgICByZXR1cm4gKGludCkgZ2V0Qnl0ZXNSZWFkKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGxvbmcgZ2V0Qnl0ZXNSZWFkKCkgeworICAgICAgICByZXR1cm4gcmF3LmdldEJ5dGVzUmVhZCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgYXJjaGl2ZSBzdW1tYXJ5IGluZm9ybWF0aW9uLgorICAgICAqIEByZXR1cm4gdGhlIHN1bW1hcnkKKyAgICAgKi8KKyAgICBwdWJsaWMgRHVtcEFyY2hpdmVTdW1tYXJ5IGdldFN1bW1hcnkoKSB7CisgICAgICAgIHJldHVybiBzdW1tYXJ5OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWQgQ0xSSSAoZGVsZXRlZCBpbm9kZSkgc2VnbWVudC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcmVhZENMUkkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBieXRlW10gYnVmZmVyID0gcmF3LnJlYWRSZWNvcmQoKTsKKworICAgICAgICBpZiAoIUR1bXBBcmNoaXZlVXRpbC52ZXJpZnkoYnVmZmVyKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRGb3JtYXRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIGFjdGl2ZSA9IER1bXBBcmNoaXZlRW50cnkucGFyc2UoYnVmZmVyKTsKKworICAgICAgICBpZiAoRHVtcEFyY2hpdmVDb25zdGFudHMuU0VHTUVOVF9UWVBFLkNMUkkgIT0gYWN0aXZlLmdldEhlYWRlclR5cGUoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRGb3JtYXRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHdlIGRvbid0IGRvIGFueXRoaW5nIHdpdGggdGhpcyB5ZXQuCisgICAgICAgIGlmIChyYXcuc2tpcCgobG9uZykgRHVtcEFyY2hpdmVDb25zdGFudHMuVFBfU0laRSAqIGFjdGl2ZS5nZXRIZWFkZXJDb3VudCgpKQorICAgICAgICAgICAgPT0gLTEpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBFT0ZFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICByZWFkSWR4ID0gYWN0aXZlLmdldEhlYWRlckNvdW50KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZCBCSVRTIHNlZ21lbnQuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHJlYWRCSVRTKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGJ1ZmZlciA9IHJhdy5yZWFkUmVjb3JkKCk7CisKKyAgICAgICAgaWYgKCFEdW1wQXJjaGl2ZVV0aWwudmVyaWZ5KGJ1ZmZlcikpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkRm9ybWF0RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBhY3RpdmUgPSBEdW1wQXJjaGl2ZUVudHJ5LnBhcnNlKGJ1ZmZlcik7CisKKyAgICAgICAgaWYgKER1bXBBcmNoaXZlQ29uc3RhbnRzLlNFR01FTlRfVFlQRS5CSVRTICE9IGFjdGl2ZS5nZXRIZWFkZXJUeXBlKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkRm9ybWF0RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICAvLyB3ZSBkb24ndCBkbyBhbnl0aGluZyB3aXRoIHRoaXMgeWV0LgorICAgICAgICBpZiAocmF3LnNraXAoKGxvbmcpIER1bXBBcmNoaXZlQ29uc3RhbnRzLlRQX1NJWkUgKiBhY3RpdmUuZ2V0SGVhZGVyQ291bnQoKSkKKyAgICAgICAgICAgID09IC0xKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRU9GRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmVhZElkeCA9IGFjdGl2ZS5nZXRIZWFkZXJDb3VudCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWQgdGhlIG5leHQgZW50cnkuCisgICAgICogQHJldHVybiB0aGUgbmV4dCBlbnRyeQorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gb24gZXJyb3IKKyAgICAgKi8KKyAgICBwdWJsaWMgRHVtcEFyY2hpdmVFbnRyeSBnZXROZXh0RHVtcEVudHJ5KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGdldE5leHRFbnRyeSgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBEdW1wQXJjaGl2ZUVudHJ5IGdldE5leHRFbnRyeSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIER1bXBBcmNoaXZlRW50cnkgZW50cnkgPSBudWxsOworICAgICAgICBTdHJpbmcgcGF0aCA9IG51bGw7CisKKyAgICAgICAgLy8gaXMgdGhlcmUgYW55dGhpbmcgaW4gdGhlIHF1ZXVlPworICAgICAgICBpZiAoIXF1ZXVlLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgcmV0dXJuIHF1ZXVlLnJlbW92ZSgpOworICAgICAgICB9CisKKyAgICAgICAgd2hpbGUgKGVudHJ5ID09IG51bGwpIHsKKyAgICAgICAgICAgIGlmIChoYXNIaXRFT0YpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gc2tpcCBhbnkgcmVtYWluaW5nIHJlY29yZHMgaW4gdGhpcyBzZWdtZW50IGZvciBwcmlvciBmaWxlLgorICAgICAgICAgICAgLy8gd2UgbWlnaHQgc3RpbGwgaGF2ZSBob2xlcy4uLiBlYXNpZXN0IHRvIGRvIGl0CisgICAgICAgICAgICAvLyBibG9jayBieSBibG9jay4gV2UgbWF5IHdhbnQgdG8gcmV2aXNpdCB0aGlzIGlmCisgICAgICAgICAgICAvLyB0aGUgdW5uZWNlc3NhcnkgZGVjb21wcmVzc2lvbiB0aW1lIGFkZHMgdXAuCisgICAgICAgICAgICB3aGlsZSAocmVhZElkeCA8IGFjdGl2ZS5nZXRIZWFkZXJDb3VudCgpKSB7CisgICAgICAgICAgICAgICAgaWYgKCFhY3RpdmUuaXNTcGFyc2VSZWNvcmQocmVhZElkeCsrKQorICAgICAgICAgICAgICAgICAgICAmJiByYXcuc2tpcChEdW1wQXJjaGl2ZUNvbnN0YW50cy5UUF9TSVpFKSA9PSAtMSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRU9GRXhjZXB0aW9uKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICByZWFkSWR4ID0gMDsKKyAgICAgICAgICAgIGZpbGVwb3MgPSByYXcuZ2V0Qnl0ZXNSZWFkKCk7CisKKyAgICAgICAgICAgIGJ5dGVbXSBoZWFkZXJCeXRlcyA9IHJhdy5yZWFkUmVjb3JkKCk7CisKKyAgICAgICAgICAgIGlmICghRHVtcEFyY2hpdmVVdGlsLnZlcmlmeShoZWFkZXJCeXRlcykpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEZvcm1hdEV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBhY3RpdmUgPSBEdW1wQXJjaGl2ZUVudHJ5LnBhcnNlKGhlYWRlckJ5dGVzKTsKKworICAgICAgICAgICAgLy8gc2tpcCBhbnkgcmVtYWluaW5nIHNlZ21lbnRzIGZvciBwcmlvciBmaWxlLgorICAgICAgICAgICAgd2hpbGUgKER1bXBBcmNoaXZlQ29uc3RhbnRzLlNFR01FTlRfVFlQRS5BRERSID09IGFjdGl2ZS5nZXRIZWFkZXJUeXBlKCkpIHsKKyAgICAgICAgICAgICAgICBpZiAocmF3LnNraXAoKGxvbmcpIER1bXBBcmNoaXZlQ29uc3RhbnRzLlRQX1NJWkUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiAoYWN0aXZlLmdldEhlYWRlckNvdW50KCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLSBhY3RpdmUuZ2V0SGVhZGVySG9sZXMoKSkpID09IC0xKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFT0ZFeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBmaWxlcG9zID0gcmF3LmdldEJ5dGVzUmVhZCgpOworICAgICAgICAgICAgICAgIGhlYWRlckJ5dGVzID0gcmF3LnJlYWRSZWNvcmQoKTsKKworICAgICAgICAgICAgICAgIGlmICghRHVtcEFyY2hpdmVVdGlsLnZlcmlmeShoZWFkZXJCeXRlcykpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRGb3JtYXRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBhY3RpdmUgPSBEdW1wQXJjaGl2ZUVudHJ5LnBhcnNlKGhlYWRlckJ5dGVzKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gY2hlY2sgaWYgdGhpcyBpcyBhbiBlbmQtb2Ytdm9sdW1lIG1hcmtlci4KKyAgICAgICAgICAgIGlmIChEdW1wQXJjaGl2ZUNvbnN0YW50cy5TRUdNRU5UX1RZUEUuRU5EID09IGFjdGl2ZS5nZXRIZWFkZXJUeXBlKCkpIHsKKyAgICAgICAgICAgICAgICBoYXNIaXRFT0YgPSB0cnVlOworCisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGVudHJ5ID0gYWN0aXZlOworCisgICAgICAgICAgICBpZiAoZW50cnkuaXNEaXJlY3RvcnkoKSkgeworICAgICAgICAgICAgICAgIHJlYWREaXJlY3RvcnlFbnRyeShhY3RpdmUpOworCisgICAgICAgICAgICAgICAgLy8gbm93IHdlIGNyZWF0ZSBhbiBlbXB0eSBJbnB1dFN0cmVhbS4KKyAgICAgICAgICAgICAgICBlbnRyeU9mZnNldCA9IDA7CisgICAgICAgICAgICAgICAgZW50cnlTaXplID0gMDsKKyAgICAgICAgICAgICAgICByZWFkSWR4ID0gYWN0aXZlLmdldEhlYWRlckNvdW50KCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGVudHJ5T2Zmc2V0ID0gMDsKKyAgICAgICAgICAgICAgICBlbnRyeVNpemUgPSBhY3RpdmUuZ2V0RW50cnlTaXplKCk7CisgICAgICAgICAgICAgICAgcmVhZElkeCA9IDA7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHJlY29yZE9mZnNldCA9IHJlYWRCdWYubGVuZ3RoOworCisgICAgICAgICAgICBwYXRoID0gZ2V0UGF0aChlbnRyeSk7CisKKyAgICAgICAgICAgIGlmIChwYXRoID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBlbnRyeSA9IG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBlbnRyeS5zZXROYW1lKHBhdGgpOworICAgICAgICBlbnRyeS5zZXRTaW1wbGVOYW1lKG5hbWVzLmdldChlbnRyeS5nZXRJbm8oKSkuZ2V0TmFtZSgpKTsKKyAgICAgICAgZW50cnkuc2V0T2Zmc2V0KGZpbGVwb3MpOworCisgICAgICAgIHJldHVybiBlbnRyeTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkIGRpcmVjdG9yeSBlbnRyeS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcmVhZERpcmVjdG9yeUVudHJ5KER1bXBBcmNoaXZlRW50cnkgZW50cnkpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGxvbmcgc2l6ZSA9IGVudHJ5LmdldEVudHJ5U2l6ZSgpOworICAgICAgICBib29sZWFuIGZpcnN0ID0gdHJ1ZTsKKworICAgICAgICB3aGlsZSAoZmlyc3QgfHwKKyAgICAgICAgICAgICAgICBEdW1wQXJjaGl2ZUNvbnN0YW50cy5TRUdNRU5UX1RZUEUuQUREUiA9PSBlbnRyeS5nZXRIZWFkZXJUeXBlKCkpIHsKKyAgICAgICAgICAgIC8vIHJlYWQgdGhlIGhlYWRlciB0aGF0IHdlIGp1c3QgcGVla2VkIGF0LgorICAgICAgICAgICAgaWYgKCFmaXJzdCkgeworICAgICAgICAgICAgICAgIHJhdy5yZWFkUmVjb3JkKCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmICghbmFtZXMuY29udGFpbnNLZXkoZW50cnkuZ2V0SW5vKCkpICYmCisgICAgICAgICAgICAgICAgICAgIER1bXBBcmNoaXZlQ29uc3RhbnRzLlNFR01FTlRfVFlQRS5JTk9ERSA9PSBlbnRyeS5nZXRIZWFkZXJUeXBlKCkpIHsKKyAgICAgICAgICAgICAgICBwZW5kaW5nLnB1dChlbnRyeS5nZXRJbm8oKSwgZW50cnkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBmaW5hbCBpbnQgZGF0YWxlbiA9IER1bXBBcmNoaXZlQ29uc3RhbnRzLlRQX1NJWkUgKiBlbnRyeS5nZXRIZWFkZXJDb3VudCgpOworCisgICAgICAgICAgICBpZiAoYmxvY2tCdWZmZXIubGVuZ3RoIDwgZGF0YWxlbikgeworICAgICAgICAgICAgICAgIGJsb2NrQnVmZmVyID0gbmV3IGJ5dGVbZGF0YWxlbl07CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChyYXcucmVhZChibG9ja0J1ZmZlciwgMCwgZGF0YWxlbikgIT0gZGF0YWxlbikgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBFT0ZFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaW50IHJlY2xlbiA9IDA7CisKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGF0YWxlbiAtIDggJiYgaSA8IHNpemUgLSA4OworICAgICAgICAgICAgICAgICAgICBpICs9IHJlY2xlbikgeworICAgICAgICAgICAgICAgIGZpbmFsIGludCBpbm8gPSBEdW1wQXJjaGl2ZVV0aWwuY29udmVydDMyKGJsb2NrQnVmZmVyLCBpKTsKKyAgICAgICAgICAgICAgICByZWNsZW4gPSBEdW1wQXJjaGl2ZVV0aWwuY29udmVydDE2KGJsb2NrQnVmZmVyLCBpICsgNCk7CisKKyAgICAgICAgICAgICAgICBmaW5hbCBieXRlIHR5cGUgPSBibG9ja0J1ZmZlcltpICsgNl07CisKKyAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgbmFtZSA9IER1bXBBcmNoaXZlVXRpbC5kZWNvZGUoemlwRW5jb2RpbmcsIGJsb2NrQnVmZmVyLCBpICsgOCwgYmxvY2tCdWZmZXJbaSArIDddKTsKKworICAgICAgICAgICAgICAgIGlmICgiLiIuZXF1YWxzKG5hbWUpIHx8ICIuLiIuZXF1YWxzKG5hbWUpKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIGRvIG5vdGhpbmcuLi4KKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgZmluYWwgRGlyZW50IGQgPSBuZXcgRGlyZW50KGlubywgZW50cnkuZ2V0SW5vKCksIHR5cGUsIG5hbWUpOworCisgICAgICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAgICBpZiAoKHR5cGUgPT0gNCkgJiYgbmFtZXMuY29udGFpbnNLZXkoaW5vKSkgeworICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIndlIGFscmVhZHkgaGF2ZSBpbm86ICIgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXMuZ2V0KGlubykpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAqLworCisgICAgICAgICAgICAgICAgbmFtZXMucHV0KGlubywgZCk7CisKKyAgICAgICAgICAgICAgICAvLyBjaGVjayB3aGV0aGVyIHRoaXMgYWxsb3dzIHVzIHRvIGZpbGwgYW55dGhpbmcgaW4gdGhlIHBlbmRpbmcgbGlzdC4KKyAgICAgICAgICAgICAgICBmb3IgKGZpbmFsIE1hcC5FbnRyeTxJbnRlZ2VyLCBEdW1wQXJjaGl2ZUVudHJ5PiBlIDogcGVuZGluZy5lbnRyeVNldCgpKSB7CisgICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBwYXRoID0gZ2V0UGF0aChlLmdldFZhbHVlKCkpOworCisgICAgICAgICAgICAgICAgICAgIGlmIChwYXRoICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGUuZ2V0VmFsdWUoKS5zZXROYW1lKHBhdGgpOworICAgICAgICAgICAgICAgICAgICAgICAgZS5nZXRWYWx1ZSgpCisgICAgICAgICAgICAgICAgICAgICAgICAgLnNldFNpbXBsZU5hbWUobmFtZXMuZ2V0KGUuZ2V0S2V5KCkpLmdldE5hbWUoKSk7CisgICAgICAgICAgICAgICAgICAgICAgICBxdWV1ZS5hZGQoZS5nZXRWYWx1ZSgpKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIC8vIHJlbW92ZSBhbnl0aGluZyB0aGF0IHdlIGZvdW5kLiAoV2UgY2FuJ3QgZG8gaXQgZWFybGllcgorICAgICAgICAgICAgICAgIC8vIGJlY2F1c2Ugb2YgY29uY3VycmVudCBtb2RpZmljYXRpb24gZXhjZXB0aW9ucy4pCisgICAgICAgICAgICAgICAgZm9yIChmaW5hbCBEdW1wQXJjaGl2ZUVudHJ5IGUgOiBxdWV1ZSkgeworICAgICAgICAgICAgICAgICAgICBwZW5kaW5nLnJlbW92ZShlLmdldElubygpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBwZWVrQnl0ZXMgPSByYXcucGVlaygpOworCisgICAgICAgICAgICBpZiAoIUR1bXBBcmNoaXZlVXRpbC52ZXJpZnkocGVla0J5dGVzKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkRm9ybWF0RXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGVudHJ5ID0gRHVtcEFyY2hpdmVFbnRyeS5wYXJzZShwZWVrQnl0ZXMpOworICAgICAgICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgICAgICAgIHNpemUgLT0gRHVtcEFyY2hpdmVDb25zdGFudHMuVFBfU0laRTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCBmdWxsIHBhdGggZm9yIHNwZWNpZmllZCBhcmNoaXZlIGVudHJ5LCBvciBudWxsIGlmIHRoZXJlJ3MgYSBnYXAuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZW50cnkKKyAgICAgKiBAcmV0dXJuICBmdWxsIHBhdGggZm9yIHNwZWNpZmllZCBhcmNoaXZlIGVudHJ5LCBvciBudWxsIGlmIHRoZXJlJ3MgYSBnYXAuCisgICAgICovCisgICAgcHJpdmF0ZSBTdHJpbmcgZ2V0UGF0aChmaW5hbCBEdW1wQXJjaGl2ZUVudHJ5IGVudHJ5KSB7CisgICAgICAgIC8vIGJ1aWxkIHRoZSBzdGFjayBvZiBlbGVtZW50cy4gSXQncyBwb3NzaWJsZSB0aGF0IHdlJ3JlCisgICAgICAgIC8vIHN0aWxsIG1pc3NpbmcgYW4gaW50ZXJtZWRpYXRlIHZhbHVlIGFuZCBpZiBzbyB3ZQorICAgICAgICBmaW5hbCBTdGFjazxTdHJpbmc+IGVsZW1lbnRzID0gbmV3IFN0YWNrPD4oKTsKKyAgICAgICAgRGlyZW50IGRpcmVudCA9IG51bGw7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IGVudHJ5LmdldElubygpOzsgaSA9IGRpcmVudC5nZXRQYXJlbnRJbm8oKSkgeworICAgICAgICAgICAgaWYgKCFuYW1lcy5jb250YWluc0tleShpKSkgeworICAgICAgICAgICAgICAgIGVsZW1lbnRzLmNsZWFyKCk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGRpcmVudCA9IG5hbWVzLmdldChpKTsKKyAgICAgICAgICAgIGVsZW1lbnRzLnB1c2goZGlyZW50LmdldE5hbWUoKSk7CisKKyAgICAgICAgICAgIGlmIChkaXJlbnQuZ2V0SW5vKCkgPT0gZGlyZW50LmdldFBhcmVudElubygpKSB7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyBpZiBhbiBlbGVtZW50IGlzIG1pc3NpbmcgZGVmZXIgdGhlIHdvcmsgYW5kIHJlYWQgbmV4dCBlbnRyeS4KKyAgICAgICAgaWYgKGVsZW1lbnRzLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgcGVuZGluZy5wdXQoZW50cnkuZ2V0SW5vKCksIGVudHJ5KTsKKworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICAvLyBnZW5lcmF0ZSBmdWxsIHBhdGggZnJvbSBzdGFjayBvZiBlbGVtZW50cy4KKyAgICAgICAgZmluYWwgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKGVsZW1lbnRzLnBvcCgpKTsKKworICAgICAgICB3aGlsZSAoIWVsZW1lbnRzLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgc2IuYXBwZW5kKCcvJyk7CisgICAgICAgICAgICBzYi5hcHBlbmQoZWxlbWVudHMucG9wKCkpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgYnl0ZXMgZnJvbSB0aGUgY3VycmVudCBkdW1wIGFyY2hpdmUgZW50cnkuCisgICAgICoKKyAgICAgKiBUaGlzIG1ldGhvZCBpcyBhd2FyZSBvZiB0aGUgYm91bmRhcmllcyBvZiB0aGUgY3VycmVudAorICAgICAqIGVudHJ5IGluIHRoZSBhcmNoaXZlIGFuZCB3aWxsIGRlYWwgd2l0aCB0aGVtIGFzIGlmIHRoZXkKKyAgICAgKiB3ZXJlIHRoaXMgc3RyZWFtJ3Mgc3RhcnQgYW5kIEVPRi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBidWYgVGhlIGJ1ZmZlciBpbnRvIHdoaWNoIHRvIHBsYWNlIGJ5dGVzIHJlYWQuCisgICAgICogQHBhcmFtIG9mZiBUaGUgb2Zmc2V0IGF0IHdoaWNoIHRvIHBsYWNlIGJ5dGVzIHJlYWQuCisgICAgICogQHBhcmFtIGxlbiBUaGUgbnVtYmVyIG9mIGJ5dGVzIHRvIHJlYWQuCisgICAgICogQHJldHVybiBUaGUgbnVtYmVyIG9mIGJ5dGVzIHJlYWQsIG9yIC0xIGF0IEVPRi4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIG9uIGVycm9yCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCByZWFkKGZpbmFsIGJ5dGVbXSBidWYsIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCB0b3RhbFJlYWQgPSAwOworCisgICAgICAgIGlmIChoYXNIaXRFT0YgfHwgaXNDbG9zZWQgfHwgZW50cnlPZmZzZXQgPj0gZW50cnlTaXplKSB7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKworICAgICAgICBpZiAoYWN0aXZlID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIk5vIGN1cnJlbnQgZHVtcCBlbnRyeSIpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGxlbiArIGVudHJ5T2Zmc2V0ID4gZW50cnlTaXplKSB7CisgICAgICAgICAgICBsZW4gPSAoaW50KSAoZW50cnlTaXplIC0gZW50cnlPZmZzZXQpOworICAgICAgICB9CisKKyAgICAgICAgd2hpbGUgKGxlbiA+IDApIHsKKyAgICAgICAgICAgIGZpbmFsIGludCBzeiA9IGxlbiA+IHJlYWRCdWYubGVuZ3RoIC0gcmVjb3JkT2Zmc2V0CisgICAgICAgICAgICAgICAgPyByZWFkQnVmLmxlbmd0aCAtIHJlY29yZE9mZnNldCA6IGxlbjsKKworICAgICAgICAgICAgLy8gY29weSBhbnkgZGF0YSB3ZSBoYXZlCisgICAgICAgICAgICBpZiAocmVjb3JkT2Zmc2V0ICsgc3ogPD0gcmVhZEJ1Zi5sZW5ndGgpIHsKKyAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHJlYWRCdWYsIHJlY29yZE9mZnNldCwgYnVmLCBvZmYsIHN6KTsKKyAgICAgICAgICAgICAgICB0b3RhbFJlYWQgKz0gc3o7CisgICAgICAgICAgICAgICAgcmVjb3JkT2Zmc2V0ICs9IHN6OworICAgICAgICAgICAgICAgIGxlbiAtPSBzejsKKyAgICAgICAgICAgICAgICBvZmYgKz0gc3o7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIGxvYWQgbmV4dCBibG9jayBpZiBuZWNlc3NhcnkuCisgICAgICAgICAgICBpZiAobGVuID4gMCkgeworICAgICAgICAgICAgICAgIGlmIChyZWFkSWR4ID49IDUxMikgeworICAgICAgICAgICAgICAgICAgICBmaW5hbCBieXRlW10gaGVhZGVyQnl0ZXMgPSByYXcucmVhZFJlY29yZCgpOworCisgICAgICAgICAgICAgICAgICAgIGlmICghRHVtcEFyY2hpdmVVdGlsLnZlcmlmeShoZWFkZXJCeXRlcykpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkRm9ybWF0RXhjZXB0aW9uKCk7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBhY3RpdmUgPSBEdW1wQXJjaGl2ZUVudHJ5LnBhcnNlKGhlYWRlckJ5dGVzKTsKKyAgICAgICAgICAgICAgICAgICAgcmVhZElkeCA9IDA7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgaWYgKCFhY3RpdmUuaXNTcGFyc2VSZWNvcmQocmVhZElkeCsrKSkgeworICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgciA9IHJhdy5yZWFkKHJlYWRCdWYsIDAsIHJlYWRCdWYubGVuZ3RoKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHIgIT0gcmVhZEJ1Zi5sZW5ndGgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFT0ZFeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIEFycmF5cy5maWxsKHJlYWRCdWYsIChieXRlKSAwKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICByZWNvcmRPZmZzZXQgPSAwOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgZW50cnlPZmZzZXQgKz0gdG90YWxSZWFkOworCisgICAgICAgIHJldHVybiB0b3RhbFJlYWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvc2VzIHRoZSBzdHJlYW0gZm9yIHRoaXMgZW50cnkuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoIWlzQ2xvc2VkKSB7CisgICAgICAgICAgICBpc0Nsb3NlZCA9IHRydWU7CisgICAgICAgICAgICByYXcuY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIExvb2sgYXQgdGhlIGZpcnN0IGZldyBieXRlcyBvZiB0aGUgZmlsZSB0byBkZWNpZGUgaWYgaXQncyBhIGR1bXAKKyAgICAgKiBhcmNoaXZlLiBXaXRoIDMyIGJ5dGVzIHdlIGNhbiBsb29rIGF0IHRoZSBtYWdpYyB2YWx1ZSwgd2l0aCBhIGZ1bGwKKyAgICAgKiAxayB3ZSBjYW4gdmVyaWZ5IHRoZSBjaGVja3N1bS4KKyAgICAgKiBAcGFyYW0gYnVmZmVyIGRhdGEgdG8gbWF0Y2gKKyAgICAgKiBAcGFyYW0gbGVuZ3RoIGxlbmd0aCBvZiBkYXRhCisgICAgICogQHJldHVybiB3aGV0aGVyIHRoZSBidWZmZXIgc2VlbXMgdG8gY29udGFpbiBkdW1wIGRhdGEKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gbWF0Y2hlcyhmaW5hbCBieXRlW10gYnVmZmVyLCBmaW5hbCBpbnQgbGVuZ3RoKSB7CisgICAgICAgIC8vIGRvIHdlIGhhdmUgZW5vdWdoIG9mIHRoZSBoZWFkZXI/CisgICAgICAgIGlmIChsZW5ndGggPCAzMikgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgLy8gdGhpcyBpcyB0aGUgYmVzdCB0ZXN0CisgICAgICAgIGlmIChsZW5ndGggPj0gRHVtcEFyY2hpdmVDb25zdGFudHMuVFBfU0laRSkgeworICAgICAgICAgICAgcmV0dXJuIER1bXBBcmNoaXZlVXRpbC52ZXJpZnkoYnVmZmVyKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHRoaXMgd2lsbCB3b3JrIGluIGEgcGluY2guCisgICAgICAgIHJldHVybiBEdW1wQXJjaGl2ZUNvbnN0YW50cy5ORlNfTUFHSUMgPT0gRHVtcEFyY2hpdmVVdGlsLmNvbnZlcnQzMihidWZmZXIsCisgICAgICAgICAgICAyNCk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvZHVtcC9EdW1wQXJjaGl2ZVN1bW1hcnkuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9kdW1wL0R1bXBBcmNoaXZlU3VtbWFyeS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYxN2U3MGYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvZHVtcC9EdW1wQXJjaGl2ZVN1bW1hcnkuamF2YQpAQCAtMCwwICsxLDMzNiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuZHVtcDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkRhdGU7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcC5aaXBFbmNvZGluZzsKKworLyoqCisgKiBUaGlzIGNsYXNzIHJlcHJlc2VudHMgaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24gYWJvdXQgYSBEdW1wIGFyY2hpdmUgdm9sdW1lLgorICogSXQgY29uc2lzdHMgdGhlIGFyY2hpdmUncyBkdW1wIGRhdGUsIGxhYmVsLCBob3N0bmFtZSwgZGV2aWNlIG5hbWUgYW5kIHBvc3NpYmx5CisgKiBsYXN0IG1vdW50IHBvaW50IHBsdXMgdGhlIHZvbHVtZSdzIHZvbHVtZSBpZCBhbmRmaXJzdCByZWNvcmQgbnVtYmVyLgorICoKKyAqIEZvciB0aGUgY29ycmVzcG9uZGluZyBDIHN0cnVjdHVyZSBzZWUgdGhlIGhlYWRlciBvZiB7QGxpbmsgRHVtcEFyY2hpdmVFbnRyeX0uCisgKi8KK3B1YmxpYyBjbGFzcyBEdW1wQXJjaGl2ZVN1bW1hcnkgeworICAgIHByaXZhdGUgbG9uZyBkdW1wRGF0ZTsKKyAgICBwcml2YXRlIGxvbmcgcHJldmlvdXNEdW1wRGF0ZTsKKyAgICBwcml2YXRlIGludCB2b2x1bWU7CisgICAgcHJpdmF0ZSBTdHJpbmcgbGFiZWw7CisgICAgcHJpdmF0ZSBpbnQgbGV2ZWw7CisgICAgcHJpdmF0ZSBTdHJpbmcgZmlsZXN5czsKKyAgICBwcml2YXRlIFN0cmluZyBkZXZuYW1lOworICAgIHByaXZhdGUgU3RyaW5nIGhvc3RuYW1lOworICAgIHByaXZhdGUgaW50IGZsYWdzOworICAgIHByaXZhdGUgaW50IGZpcnN0cmVjOworICAgIHByaXZhdGUgaW50IG50cmVjOworCisgICAgRHVtcEFyY2hpdmVTdW1tYXJ5KGZpbmFsIGJ5dGVbXSBidWZmZXIsIGZpbmFsIFppcEVuY29kaW5nIGVuY29kaW5nKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBkdW1wRGF0ZSA9IDEwMDBMICogRHVtcEFyY2hpdmVVdGlsLmNvbnZlcnQzMihidWZmZXIsIDQpOworICAgICAgICBwcmV2aW91c0R1bXBEYXRlID0gMTAwMEwgKiBEdW1wQXJjaGl2ZVV0aWwuY29udmVydDMyKGJ1ZmZlciwgOCk7CisgICAgICAgIHZvbHVtZSA9IER1bXBBcmNoaXZlVXRpbC5jb252ZXJ0MzIoYnVmZmVyLCAxMik7CisgICAgICAgIGxhYmVsID0gRHVtcEFyY2hpdmVVdGlsLmRlY29kZShlbmNvZGluZywgYnVmZmVyLCA2NzYsIER1bXBBcmNoaXZlQ29uc3RhbnRzLkxCTFNJWkUpLnRyaW0oKTsKKyAgICAgICAgbGV2ZWwgPSBEdW1wQXJjaGl2ZVV0aWwuY29udmVydDMyKGJ1ZmZlciwgNjkyKTsKKyAgICAgICAgZmlsZXN5cyA9IER1bXBBcmNoaXZlVXRpbC5kZWNvZGUoZW5jb2RpbmcsIGJ1ZmZlciwgNjk2LCBEdW1wQXJjaGl2ZUNvbnN0YW50cy5OQU1FTEVOKS50cmltKCk7CisgICAgICAgIGRldm5hbWUgPSBEdW1wQXJjaGl2ZVV0aWwuZGVjb2RlKGVuY29kaW5nLCBidWZmZXIsIDc2MCwgRHVtcEFyY2hpdmVDb25zdGFudHMuTkFNRUxFTikudHJpbSgpOworICAgICAgICBob3N0bmFtZSA9IER1bXBBcmNoaXZlVXRpbC5kZWNvZGUoZW5jb2RpbmcsIGJ1ZmZlciwgODI0LCBEdW1wQXJjaGl2ZUNvbnN0YW50cy5OQU1FTEVOKS50cmltKCk7CisgICAgICAgIGZsYWdzID0gRHVtcEFyY2hpdmVVdGlsLmNvbnZlcnQzMihidWZmZXIsIDg4OCk7CisgICAgICAgIGZpcnN0cmVjID0gRHVtcEFyY2hpdmVVdGlsLmNvbnZlcnQzMihidWZmZXIsIDg5Mik7CisgICAgICAgIG50cmVjID0gRHVtcEFyY2hpdmVVdGlsLmNvbnZlcnQzMihidWZmZXIsIDg5Nik7CisKKyAgICAgICAgLy9leHRBdHRyaWJ1dGVzID0gRHVtcEFyY2hpdmVVdGlsLmNvbnZlcnQzMihidWZmZXIsIDkwMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBkYXRlIG9mIHRoaXMgZHVtcC4KKyAgICAgKiBAcmV0dXJuIHRoZSBkYXRlIG9mIHRoaXMgZHVtcC4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGF0ZSBnZXREdW1wRGF0ZSgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBEYXRlKGR1bXBEYXRlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgZHVtcCBkYXRlLgorICAgICAqIEBwYXJhbSBkdW1wRGF0ZSB0aGUgZHVtcCBkYXRlCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RHVtcERhdGUoZmluYWwgRGF0ZSBkdW1wRGF0ZSkgeworICAgICAgICB0aGlzLmR1bXBEYXRlID0gZHVtcERhdGUuZ2V0VGltZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgZGF0ZSBvZiB0aGUgcHJldmlvdXMgZHVtcCBhdCB0aGlzIGxldmVsIGhpZ2hlci4KKyAgICAgKiBAcmV0dXJuIGR1bXBkYXRlIG1heSBiZSBudWxsCisgICAgICovCisgICAgcHVibGljIERhdGUgZ2V0UHJldmlvdXNEdW1wRGF0ZSgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBEYXRlKHByZXZpb3VzRHVtcERhdGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCBwcmV2aW91cyBkdW1wIGRhdGUuCisgICAgICogQHBhcmFtIHByZXZpb3VzRHVtcERhdGUgdGhlIHByZXZpb3VzIGR1bXAgZGF0CisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UHJldmlvdXNEdW1wRGF0ZShmaW5hbCBEYXRlIHByZXZpb3VzRHVtcERhdGUpIHsKKyAgICAgICAgdGhpcy5wcmV2aW91c0R1bXBEYXRlID0gcHJldmlvdXNEdW1wRGF0ZS5nZXRUaW1lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHZvbHVtZSAodGFwZSkgbnVtYmVyLgorICAgICAqIEByZXR1cm4gdm9sdW1lICh0YXBlKSBudW1iZXIuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRWb2x1bWUoKSB7CisgICAgICAgIHJldHVybiB2b2x1bWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHZvbHVtZSAodGFwZSkgbnVtYmVyLgorICAgICAqIEBwYXJhbSB2b2x1bWUgdGhlIHZvbHVtZSBudW1iZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRWb2x1bWUoZmluYWwgaW50IHZvbHVtZSkgeworICAgICAgICB0aGlzLnZvbHVtZSA9IHZvbHVtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIGxldmVsIG9mIHRoaXMgZHVtcC4gVGhpcyBpcyBhIG51bWJlciBiZXR3ZWVuIDAgYW5kIDksIGluY2x1c2l2ZSwKKyAgICAgKiBhbmQgYSBsZXZlbCAwIGR1bXAgaXMgYSBjb21wbGV0ZSBkdW1wIG9mIHRoZSBwYXJ0aXRpb24uIEZvciBhbnkgb3RoZXIgZHVtcAorICAgICAqICduJyB0aGlzIGR1bXAgY29udGFpbnMgYWxsIGZpbGVzIHRoYXQgaGF2ZSBjaGFuZ2VkIHNpbmNlIHRoZSBsYXN0IGR1bXAKKyAgICAgKiBhdCB0aGlzIGxldmVsIG9yIGxvd2VyLiBUaGlzIGlzIHVzZWQgdG8gc3VwcG9ydCBkaWZmZXJlbnQgbGV2ZWxzIG9mCisgICAgICogaW5jcmVtZW50YWwgYmFja3Vwcy4KKyAgICAgKiBAcmV0dXJuIGR1bXAgbGV2ZWwKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldExldmVsKCkgeworICAgICAgICByZXR1cm4gbGV2ZWw7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IGxldmVsLgorICAgICAqIEBwYXJhbSBsZXZlbCB0aGUgbGV2ZWwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRMZXZlbChmaW5hbCBpbnQgbGV2ZWwpIHsKKyAgICAgICAgdGhpcy5sZXZlbCA9IGxldmVsOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCBkdW1wIGxhYmVsLiBUaGlzIG1heSBiZSBhdXRvZ2VuZXJhdGVkIG9yIGl0IG1heSBiZSBzcGVjaWZpZWQKKyAgICAgKiBidSB0aGUgdXNlci4KKyAgICAgKiBAcmV0dXJuIGR1bXAgbGFiZWwKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldExhYmVsKCkgeworICAgICAgICByZXR1cm4gbGFiZWw7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IGR1bXAgbGFiZWwuCisgICAgICogQHBhcmFtIGxhYmVsIHRoZSBsYWJlbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldExhYmVsKGZpbmFsIFN0cmluZyBsYWJlbCkgeworICAgICAgICB0aGlzLmxhYmVsID0gbGFiZWw7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBsYXN0IG1vdW50cG9pbnQsIGUuZy4sIC9ob21lLgorICAgICAqIEByZXR1cm4gbGFzdCBtb3VudHBvaW50CisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRGaWxlc3lzdGVtKCkgeworICAgICAgICByZXR1cm4gZmlsZXN5czsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIGxhc3QgbW91bnRwb2ludC4KKyAgICAgKiBAcGFyYW0gZmlsZXN5c3RlbSB0aGUgbGFzdCBtb3VudHBvaW50CisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RmlsZXN5c3RlbShmaW5hbCBTdHJpbmcgZmlsZXN5c3RlbSkgeworICAgICAgICB0aGlzLmZpbGVzeXMgPSBmaWxlc3lzdGVtOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgZGV2aWNlIG5hbWUsIGUuZy4sIC9kZXYvc2RhMyBvciAvZGV2L21hcHBlci92ZzAtaG9tZS4KKyAgICAgKiBAcmV0dXJuIGRldmljZSBuYW1lCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXREZXZuYW1lKCkgeworICAgICAgICByZXR1cm4gZGV2bmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIGRldmljZSBuYW1lLgorICAgICAqIEBwYXJhbSBkZXZuYW1lIHRoZSBkZXZpY2UgbmFtZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldERldm5hbWUoZmluYWwgU3RyaW5nIGRldm5hbWUpIHsKKyAgICAgICAgdGhpcy5kZXZuYW1lID0gZGV2bmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIGhvc3RuYW1lIG9mIHRoZSBzeXN0ZW0gd2hlcmUgdGhlIGR1bXAgd2FzIHBlcmZvcm1lZC4KKyAgICAgKiBAcmV0dXJuIGhvc3RuYW1lIHRoZSBob3N0IG5hbWUKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEhvc3RuYW1lKCkgeworICAgICAgICByZXR1cm4gaG9zdG5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBob3N0bmFtZS4KKyAgICAgKiBAcGFyYW0gaG9zdG5hbWUgdGhlIGhvc3QgbmFtZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEhvc3RuYW1lKGZpbmFsIFN0cmluZyBob3N0bmFtZSkgeworICAgICAgICB0aGlzLmhvc3RuYW1lID0gaG9zdG5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBtaXNjZWxsYW5lb3VzIGZsYWdzLiBTZWUgYmVsb3cuCisgICAgICogQHJldHVybiBmbGFncworICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0RmxhZ3MoKSB7CisgICAgICAgIHJldHVybiBmbGFnczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIG1pc2NlbGxhbmVvdXMgZmxhZ3MuCisgICAgICogQHBhcmFtIGZsYWdzIGZsYWdzCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RmxhZ3MoZmluYWwgaW50IGZsYWdzKSB7CisgICAgICAgIHRoaXMuZmxhZ3MgPSBmbGFnczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIGlub2RlIG9mIHRoZSBmaXJzdCByZWNvcmQgb24gdGhpcyB2b2x1bWUuCisgICAgICogQHJldHVybiBpbm9kZSBvZiB0aGUgZmlyc3QgcmVjb3JkIG9uIHRoaXMgdm9sdW1lLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0Rmlyc3RSZWNvcmQoKSB7CisgICAgICAgIHJldHVybiBmaXJzdHJlYzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIGlub2RlIG9mIHRoZSBmaXJzdCByZWNvcmQuCisgICAgICogQHBhcmFtIGZpcnN0cmVjIHRoZSBmaXJzdCByZWNvcmQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRGaXJzdFJlY29yZChmaW5hbCBpbnQgZmlyc3RyZWMpIHsKKyAgICAgICAgdGhpcy5maXJzdHJlYyA9IGZpcnN0cmVjOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgbnVtYmVyIG9mIHJlY29yZHMgcGVyIHRhcGUgYmxvY2suIFRoaXMgaXMgdHlwaWNhbGx5CisgICAgICogYmV0d2VlbiAxMCBhbmQgMzIuCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIHJlY29yZHMgcGVyIHRhcGUgYmxvY2sKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldE5UUmVjKCkgeworICAgICAgICByZXR1cm4gbnRyZWM7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBudW1iZXIgb2YgcmVjb3JkcyBwZXIgdGFwZSBibG9jay4KKyAgICAgKiBAcGFyYW0gbnRyZWMgdGhlIG51bWJlciBvZiByZWNvcmRzIHBlciB0YXBlIGJsb2NrCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TlRSZWMoZmluYWwgaW50IG50cmVjKSB7CisgICAgICAgIHRoaXMubnRyZWMgPSBudHJlYzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJcyB0aGlzIHRoZSBuZXcgaGVhZGVyIGZvcm1hdD8gKFdlIGRvIG5vdCBjdXJyZW50bHkgc3VwcG9ydCB0aGUKKyAgICAgKiBvbGQgZm9ybWF0LikKKyAgICAgKgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB1c2luZyBuZXcgaGVhZGVyIGZvcm1hdAorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzTmV3SGVhZGVyKCkgeworICAgICAgICByZXR1cm4gKGZsYWdzICYgMHgwMDAxKSA9PSAweDAwMDE7CisgICAgfQorCisgICAgLyoqCisgICAgICogSXMgdGhpcyB0aGUgbmV3IGlub2RlIGZvcm1hdD8gKFdlIGRvIG5vdCBjdXJyZW50bHkgc3VwcG9ydCB0aGUKKyAgICAgKiBvbGQgZm9ybWF0LikKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdXNpbmcgbmV3IGlub2RlIGZvcm1hdAorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzTmV3SW5vZGUoKSB7CisgICAgICAgIHJldHVybiAoZmxhZ3MgJiAweDAwMDIpID09IDB4MDAwMjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJcyB0aGlzIHZvbHVtZSBjb21wcmVzc2VkPyBOLkIuLCBpbmRpdmlkdWFsIGJsb2NrcyBtYXkgb3IgbWF5IG5vdCBiZSBjb21wcmVzc2VkLgorICAgICAqIFRoZSBmaXJzdCBibG9jayBpcyBuZXZlciBjb21wcmVzc2VkLgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB2b2x1bWUgaXMgY29tcHJlc3NlZAorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzQ29tcHJlc3NlZCgpIHsKKyAgICAgICAgcmV0dXJuIChmbGFncyAmIDB4MDA4MCkgPT0gMHgwMDgwOworICAgIH0KKworICAgIC8qKgorICAgICAqIERvZXMgdGhpcyB2b2x1bWUgb25seSBjb250YWluIG1ldGFkYXRhPworICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB2b2x1bWUgb25seSBjb250YWlucyBtZXRhLWRhdGEKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc01ldGFEYXRhT25seSgpIHsKKyAgICAgICAgcmV0dXJuIChmbGFncyAmIDB4MDEwMCkgPT0gMHgwMTAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIERvZXMgdGhpcyB2b2x1bWUgY290YWluIGV4dGVuZGVkIGF0dHJpYnV0ZXMuCisgICAgICogQHJldHVybiB0cnVlIGlmIHZvbHVtZSBjb3RhaW5zIGV4dGVuZGVkIGF0dHJpYnV0ZXMuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNFeHRlbmRlZEF0dHJpYnV0ZXMoKSB7CisgICAgICAgIHJldHVybiAoZmxhZ3MgJiAweDgwMDApID09IDB4ODAwMDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICBpbnQgaGFzaCA9IDE3OworCisgICAgICAgIGlmIChsYWJlbCAhPSBudWxsKSB7CisgICAgICAgICAgICBoYXNoID0gbGFiZWwuaGFzaENvZGUoKTsKKyAgICAgICAgfQorCisgICAgICAgIGhhc2ggKz0gMzEgKiBkdW1wRGF0ZTsKKworICAgICAgICBpZiAoaG9zdG5hbWUgIT0gbnVsbCkgeworICAgICAgICAgICAgaGFzaCA9ICgzMSAqIGhvc3RuYW1lLmhhc2hDb2RlKCkpICsgMTc7CisgICAgICAgIH0KKworICAgICAgICBpZiAoZGV2bmFtZSAhPSBudWxsKSB7CisgICAgICAgICAgICBoYXNoID0gKDMxICogZGV2bmFtZS5oYXNoQ29kZSgpKSArIDE3OworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGhhc2g7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIE9iamVjdCBvKSB7CisgICAgICAgIGlmICh0aGlzID09IG8pIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisKKyAgICAgICAgaWYgKG8gPT0gbnVsbCB8fCAhby5nZXRDbGFzcygpLmVxdWFscyhnZXRDbGFzcygpKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgZmluYWwgRHVtcEFyY2hpdmVTdW1tYXJ5IHJocyA9IChEdW1wQXJjaGl2ZVN1bW1hcnkpIG87CisKKyAgICAgICAgaWYgKGR1bXBEYXRlICE9IHJocy5kdW1wRGF0ZSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgaWYgKChnZXRIb3N0bmFtZSgpID09IG51bGwpIHx8CisgICAgICAgICAgICAgICAgIWdldEhvc3RuYW1lKCkuZXF1YWxzKHJocy5nZXRIb3N0bmFtZSgpKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgaWYgKChnZXREZXZuYW1lKCkgPT0gbnVsbCkgfHwgIWdldERldm5hbWUoKS5lcXVhbHMocmhzLmdldERldm5hbWUoKSkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9kdW1wL0R1bXBBcmNoaXZlVXRpbC5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2R1bXAvRHVtcEFyY2hpdmVVdGlsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjBlMWViMwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9kdW1wL0R1bXBBcmNoaXZlVXRpbC5qYXZhCkBAIC0wLDAgKzEsMTIxIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5kdW1wOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwLlppcEVuY29kaW5nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5CeXRlVXRpbHM7CisKKy8qKgorICogVmFyaW91cyB1dGlsaXRpZXMgZm9yIGR1bXAgYXJjaGl2ZXMuCisgKi8KK2NsYXNzIER1bXBBcmNoaXZlVXRpbCB7CisgICAgLyoqCisgICAgICogUHJpdmF0ZSBjb25zdHJ1Y3RvciB0byBwcmV2ZW50IGluc3RhbnRpYXRpb24uCisgICAgICovCisgICAgcHJpdmF0ZSBEdW1wQXJjaGl2ZVV0aWwoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2FsY3VsYXRlIGNoZWNrc3VtIGZvciBidWZmZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYnVmZmVyIGJ1ZmZlciBjb250YWluaW5nIHRhcGUgc2VnbWVudCBoZWFkZXIKKyAgICAgKiBAcmV0dXJucyBjaGVja3N1bQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IGNhbGN1bGF0ZUNoZWNrc3VtKGZpbmFsIGJ5dGVbXSBidWZmZXIpIHsKKyAgICAgICAgaW50IGNhbGMgPSAwOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMjU2OyBpKyspIHsKKyAgICAgICAgICAgIGNhbGMgKz0gRHVtcEFyY2hpdmVVdGlsLmNvbnZlcnQzMihidWZmZXIsIDQgKiBpKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBEdW1wQXJjaGl2ZUNvbnN0YW50cy5DSEVDS1NVTSAtCisgICAgICAgIChjYWxjIC0gRHVtcEFyY2hpdmVVdGlsLmNvbnZlcnQzMihidWZmZXIsIDI4KSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVmVyaWZ5IHRoYXQgdGhlIGJ1ZmZlciBjb250YWlucyBhIHRhcGUgc2VnbWVudCBoZWFkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYnVmZmVyCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBib29sZWFuIHZlcmlmeShmaW5hbCBieXRlW10gYnVmZmVyKSB7CisgICAgICAgIC8vIHZlcmlmeSBtYWdpYy4gZm9yIG5vdyBvbmx5IGFjY2VwdCBORlNfTUFHSUMuCisgICAgICAgIGZpbmFsIGludCBtYWdpYyA9IGNvbnZlcnQzMihidWZmZXIsIDI0KTsKKworICAgICAgICBpZiAobWFnaWMgIT0gRHVtcEFyY2hpdmVDb25zdGFudHMuTkZTX01BR0lDKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICAvL3ZlcmlmeSBjaGVja3N1bS4uLgorICAgICAgICBmaW5hbCBpbnQgY2hlY2tzdW0gPSBjb252ZXJ0MzIoYnVmZmVyLCAyOCk7CisKKyAgICAgICAgcmV0dXJuIGNoZWNrc3VtID09IGNhbGN1bGF0ZUNoZWNrc3VtKGJ1ZmZlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBpbm8gYXNzb2NpYXRlZCB3aXRoIHRoaXMgYnVmZmVyLgorICAgICAqCisgICAgICogQHBhcmFtIGJ1ZmZlcgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGdldElubyhmaW5hbCBieXRlW10gYnVmZmVyKSB7CisgICAgICAgIHJldHVybiBjb252ZXJ0MzIoYnVmZmVyLCAyMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZCA4LWJ5dGUgaW50ZWdlciBmcm9tIGJ1ZmZlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBidWZmZXIKKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogQHJldHVybiB0aGUgOC1ieXRlIGVudHJ5IGFzIGEgbG9uZworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgbG9uZyBjb252ZXJ0NjQoZmluYWwgYnl0ZVtdIGJ1ZmZlciwgZmluYWwgaW50IG9mZnNldCkgeworICAgICAgICByZXR1cm4gQnl0ZVV0aWxzLmZyb21MaXR0bGVFbmRpYW4oYnVmZmVyLCBvZmZzZXQsIDgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWQgNC1ieXRlIGludGVnZXIgZnJvbSBidWZmZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYnVmZmVyCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqIEByZXR1cm4gdGhlIDQtYnl0ZSBlbnRyeSBhcyBhbiBpbnQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBjb252ZXJ0MzIoZmluYWwgYnl0ZVtdIGJ1ZmZlciwgZmluYWwgaW50IG9mZnNldCkgeworICAgICAgICByZXR1cm4gKGludCkgQnl0ZVV0aWxzLmZyb21MaXR0bGVFbmRpYW4oYnVmZmVyLCBvZmZzZXQsIDQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWQgMi1ieXRlIGludGVnZXIgZnJvbSBidWZmZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYnVmZmVyCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqIEByZXR1cm4gdGhlIDItYnl0ZSBlbnRyeSBhcyBhbiBpbnQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBjb252ZXJ0MTYoZmluYWwgYnl0ZVtdIGJ1ZmZlciwgZmluYWwgaW50IG9mZnNldCkgeworICAgICAgICByZXR1cm4gKGludCkgQnl0ZVV0aWxzLmZyb21MaXR0bGVFbmRpYW4oYnVmZmVyLCBvZmZzZXQsIDIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIERlY29kZXMgYSBieXRlIGFycmF5IHRvIGEgc3RyaW5nLgorICAgICAqLworICAgIHN0YXRpYyBTdHJpbmcgZGVjb2RlKGZpbmFsIFppcEVuY29kaW5nIGVuY29kaW5nLCBmaW5hbCBieXRlW10gYiwgZmluYWwgaW50IG9mZnNldCwgZmluYWwgaW50IGxlbikKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGVuY29kaW5nLmRlY29kZShBcnJheXMuY29weU9mUmFuZ2UoYiwgb2Zmc2V0LCBvZmZzZXQgKyBsZW4pKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvZHVtcC9JbnZhbGlkRm9ybWF0RXhjZXB0aW9uLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvZHVtcC9JbnZhbGlkRm9ybWF0RXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjE2OWRmZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9kdW1wL0ludmFsaWRGb3JtYXRFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDQzIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5kdW1wOworCisKKy8qKgorICogSW52YWxpZCBGb3JtYXQgRXhjZXB0aW9uLiBUaGVyZSB3YXMgYW4gZXJyb3IgZGVjb2RpbmcgYQorICogdGFwZSBzZWdtZW50IGhlYWRlci4KKyAqLworcHVibGljIGNsYXNzIEludmFsaWRGb3JtYXRFeGNlcHRpb24gZXh0ZW5kcyBEdW1wQXJjaGl2ZUV4Y2VwdGlvbiB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7CisgICAgcHJvdGVjdGVkIGxvbmcgb2Zmc2V0OworCisgICAgcHVibGljIEludmFsaWRGb3JtYXRFeGNlcHRpb24oKSB7CisgICAgICAgIHN1cGVyKCJ0aGVyZSB3YXMgYW4gZXJyb3IgZGVjb2RpbmcgYSB0YXBlIHNlZ21lbnQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgSW52YWxpZEZvcm1hdEV4Y2VwdGlvbihmaW5hbCBsb25nIG9mZnNldCkgeworICAgICAgICBzdXBlcigidGhlcmUgd2FzIGFuIGVycm9yIGRlY29kaW5nIGEgdGFwZSBzZWdtZW50IGhlYWRlciBhdCBvZmZzZXQgIiArCisgICAgICAgICAgICBvZmZzZXQgKyAiLiIpOworICAgICAgICB0aGlzLm9mZnNldCA9IG9mZnNldDsKKyAgICB9CisKKyAgICBwdWJsaWMgbG9uZyBnZXRPZmZzZXQoKSB7CisgICAgICAgIHJldHVybiBvZmZzZXQ7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2R1bXAvU2hvcnRGaWxlRXhjZXB0aW9uLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvZHVtcC9TaG9ydEZpbGVFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMDZjOTdjCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2R1bXAvU2hvcnRGaWxlRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSwzMiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuZHVtcDsKKworCisvKioKKyAqIFNob3J0IEZpbGUgRXhjZXB0aW9uLiBUaGVyZSB3YXMgYW4gdW5leHBlY3RlZCBFT0Ygd2hlbiByZWFkaW5nCisgKiB0aGUgaW5wdXQgc3RyZWFtLgorICovCitwdWJsaWMgY2xhc3MgU2hvcnRGaWxlRXhjZXB0aW9uIGV4dGVuZHMgRHVtcEFyY2hpdmVFeGNlcHRpb24geworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOworCisgICAgcHVibGljIFNob3J0RmlsZUV4Y2VwdGlvbigpIHsKKyAgICAgICAgc3VwZXIoInVuZXhwZWN0ZWQgRU9GIik7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2R1bXAvVGFwZUlucHV0U3RyZWFtLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvZHVtcC9UYXBlSW5wdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NjQzZGVjCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2R1bXAvVGFwZUlucHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwzNTUgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLmR1bXA7CisKK2ltcG9ydCBqYXZhLmlvLkZpbHRlcklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLnppcC5EYXRhRm9ybWF0RXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC56aXAuSW5mbGF0ZXI7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuSU9VdGlsczsKKworLyoqCisgKiBGaWx0ZXIgc3RyZWFtIHRoYXQgbWltaWNzIGEgcGh5c2ljYWwgdGFwZSBkcml2ZSBjYXBhYmxlIG9mIGNvbXByZXNzaW5nCisgKiB0aGUgZGF0YSBzdHJlYW0uCisgKgorICogQE5vdFRocmVhZFNhZmUKKyAqLworY2xhc3MgVGFwZUlucHV0U3RyZWFtIGV4dGVuZHMgRmlsdGVySW5wdXRTdHJlYW0geworICAgIHByaXZhdGUgYnl0ZVtdIGJsb2NrQnVmZmVyID0gbmV3IGJ5dGVbRHVtcEFyY2hpdmVDb25zdGFudHMuVFBfU0laRV07CisgICAgcHJpdmF0ZSBpbnQgY3VyckJsa0lkeCA9IC0xOworICAgIHByaXZhdGUgaW50IGJsb2NrU2l6ZSA9IER1bXBBcmNoaXZlQ29uc3RhbnRzLlRQX1NJWkU7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFJFQ09SRF9TSVpFID0gRHVtcEFyY2hpdmVDb25zdGFudHMuVFBfU0laRTsKKyAgICBwcml2YXRlIGludCByZWFkT2Zmc2V0ID0gRHVtcEFyY2hpdmVDb25zdGFudHMuVFBfU0laRTsKKyAgICBwcml2YXRlIGJvb2xlYW4gaXNDb21wcmVzc2VkID0gZmFsc2U7CisgICAgcHJpdmF0ZSBsb25nIGJ5dGVzUmVhZCA9IDA7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvcgorICAgICAqLworICAgIHB1YmxpYyBUYXBlSW5wdXRTdHJlYW0oZmluYWwgSW5wdXRTdHJlYW0gaW4pIHsKKyAgICAgICAgc3VwZXIoaW4pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgRHVtcEFyY2hpdmUgQnVmZmVyJ3MgYmxvY2sgc2l6ZS4gV2UgbmVlZCB0byBzeW5jIHRoZSBibG9jayBzaXplIHdpdGggdGhlCisgICAgICogZHVtcCBhcmNoaXZlJ3MgYWN0dWFsIGJsb2NrIHNpemUgc2luY2UgY29tcHJlc3Npb24gaXMgaGFuZGxlZCBhdCB0aGUKKyAgICAgKiBibG9jayBsZXZlbC4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZWNzUGVyQmxvY2sKKyAgICAgKiAgICAgICAgICAgIHJlY29yZHMgcGVyIGJsb2NrCisgICAgICogQHBhcmFtIGlzQ29tcHJlc3NlZAorICAgICAqICAgICAgICAgICAgdHJ1ZSBpZiB0aGUgYXJjaGl2ZSBpcyBjb21wcmVzc2VkCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIG1vcmUgdGhhbiBvbmUgYmxvY2sgaGFzIGJlZW4gcmVhZAorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB0aGVyZSB3YXMgYW4gZXJyb3IgcmVhZGluZyBhZGRpdGlvbmFsIGJsb2Nrcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZXNldEJsb2NrU2l6ZShmaW5hbCBpbnQgcmVjc1BlckJsb2NrLCBmaW5hbCBib29sZWFuIGlzQ29tcHJlc3NlZCkKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcy5pc0NvbXByZXNzZWQgPSBpc0NvbXByZXNzZWQ7CisKKyAgICAgICAgYmxvY2tTaXplID0gUkVDT1JEX1NJWkUgKiByZWNzUGVyQmxvY2s7CisKKyAgICAgICAgLy8gc2F2ZSBmaXJzdCBibG9jayBpbiBjYXNlIHdlIG5lZWQgaXQgYWdhaW4KKyAgICAgICAgZmluYWwgYnl0ZVtdIG9sZEJ1ZmZlciA9IGJsb2NrQnVmZmVyOworCisgICAgICAgIC8vIHJlYWQgcmVzdCBvZiBuZXcgYmxvY2sKKyAgICAgICAgYmxvY2tCdWZmZXIgPSBuZXcgYnl0ZVtibG9ja1NpemVdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG9sZEJ1ZmZlciwgMCwgYmxvY2tCdWZmZXIsIDAsIFJFQ09SRF9TSVpFKTsKKyAgICAgICAgcmVhZEZ1bGx5KGJsb2NrQnVmZmVyLCBSRUNPUkRfU0laRSwgYmxvY2tTaXplIC0gUkVDT1JEX1NJWkUpOworCisgICAgICAgIHRoaXMuY3VyckJsa0lkeCA9IDA7CisgICAgICAgIHRoaXMucmVhZE9mZnNldCA9IFJFQ09SRF9TSVpFOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgamF2YS5pby5JbnB1dFN0cmVhbSNhdmFpbGFibGUKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGF2YWlsYWJsZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChyZWFkT2Zmc2V0IDwgYmxvY2tTaXplKSB7CisgICAgICAgICAgICByZXR1cm4gYmxvY2tTaXplIC0gcmVhZE9mZnNldDsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBpbi5hdmFpbGFibGUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIGphdmEuaW8uSW5wdXRTdHJlYW0jcmVhZCgpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCByZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKyAgICAgICAgICAgICJhbGwgcmVhZHMgbXVzdCBiZSBtdWx0aXBsZSBvZiByZWNvcmQgc2l6ZSAoIiArIFJFQ09SRF9TSVpFICsKKyAgICAgICAgICAgICIgYnl0ZXMuIik7CisgICAgfQorCisgICAgLyoqCisgICAgICoge0Bpbmhlcml0RG9jfQorICAgICAqCisgICAgICogPHA+cmVhZHMgdGhlIGZ1bGwgZ2l2ZW4gbGVuZ3RoIHVubGVzcyBFT0YgaXMgcmVhY2hlZC48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gbGVuIGxlbmd0aCB0byByZWFkLCBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgdGhlIHN0cmVhbSdzCisgICAgICogcmVjb3JkIHNpemUKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHJlYWQoZmluYWwgYnl0ZVtdIGIsIGludCBvZmYsIGZpbmFsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICgobGVuICUgUkVDT1JEX1NJWkUpICE9IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgImFsbCByZWFkcyBtdXN0IGJlIG11bHRpcGxlIG9mIHJlY29yZCBzaXplICgiICsgUkVDT1JEX1NJWkUgKworICAgICAgICAgICAgICAgICIgYnl0ZXMuIik7CisgICAgICAgIH0KKworICAgICAgICBpbnQgYnl0ZXMgPSAwOworCisgICAgICAgIHdoaWxlIChieXRlcyA8IGxlbikgeworICAgICAgICAgICAgLy8gd2UgbmVlZCB0byByZWFkIGZyb20gdGhlIHVuZGVybHlpbmcgc3RyZWFtLgorICAgICAgICAgICAgLy8gdGhpcyB3aWxsIHJlc2V0IHJlYWRPZmZzZXQgdmFsdWUuCisgICAgICAgICAgICAvLyByZXR1cm4gLTEgaWYgdGhlcmUncyBhIHByb2JsZW0uCisgICAgICAgICAgICBpZiAocmVhZE9mZnNldCA9PSBibG9ja1NpemUpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICByZWFkQmxvY2sodHJ1ZSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoU2hvcnRGaWxlRXhjZXB0aW9uIHNmZSkgeyAvLyBOT1NPTkFSCisgICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGludCBuID0gMDsKKworICAgICAgICAgICAgaWYgKChyZWFkT2Zmc2V0ICsgKGxlbiAtIGJ5dGVzKSkgPD0gYmxvY2tTaXplKSB7CisgICAgICAgICAgICAgICAgLy8gd2UgY2FuIHJlYWQgZW50aXJlbHkgZnJvbSB0aGUgYnVmZmVyLgorICAgICAgICAgICAgICAgIG4gPSBsZW4gLSBieXRlczsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgLy8gY29weSB3aGF0IHdlIGNhbiBmcm9tIHRoZSBidWZmZXIuCisgICAgICAgICAgICAgICAgbiA9IGJsb2NrU2l6ZSAtIHJlYWRPZmZzZXQ7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIGNvcHkgZGF0YSwgaW5jcmVtZW50IGNvdW50ZXJzLgorICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShibG9ja0J1ZmZlciwgcmVhZE9mZnNldCwgYiwgb2ZmLCBuKTsKKyAgICAgICAgICAgIHJlYWRPZmZzZXQgKz0gbjsKKyAgICAgICAgICAgIGJ5dGVzICs9IG47CisgICAgICAgICAgICBvZmYgKz0gbjsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBieXRlczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTa2lwIGJ5dGVzLiBTYW1lIGFzIHJlYWQgYnV0IHdpdGhvdXQgdGhlIGFycmF5Y29weS4KKyAgICAgKgorICAgICAqIDxwPnNraXBzIHRoZSBmdWxsIGdpdmVuIGxlbmd0aCB1bmxlc3MgRU9GIGlzIHJlYWNoZWQuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGxlbiBsZW5ndGggdG8gcmVhZCwgbXVzdCBiZSBhIG11bHRpcGxlIG9mIHRoZSBzdHJlYW0ncworICAgICAqIHJlY29yZCBzaXplCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGxvbmcgc2tpcChmaW5hbCBsb25nIGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKChsZW4gJSBSRUNPUkRfU0laRSkgIT0gMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAiYWxsIHJlYWRzIG11c3QgYmUgbXVsdGlwbGUgb2YgcmVjb3JkIHNpemUgKCIgKyBSRUNPUkRfU0laRSArCisgICAgICAgICAgICAgICAgIiBieXRlcy4iKTsKKyAgICAgICAgfQorCisgICAgICAgIGxvbmcgYnl0ZXMgPSAwOworCisgICAgICAgIHdoaWxlIChieXRlcyA8IGxlbikgeworICAgICAgICAgICAgLy8gd2UgbmVlZCB0byByZWFkIGZyb20gdGhlIHVuZGVybHlpbmcgc3RyZWFtLgorICAgICAgICAgICAgLy8gdGhpcyB3aWxsIHJlc2V0IHJlYWRPZmZzZXQgdmFsdWUuIFdlIGRvIG5vdCBwZXJmb3JtCisgICAgICAgICAgICAvLyBhbnkgZGVjb21wcmVzc2lvbiBpZiB3ZSB3b24ndCBldmVudHVhbGx5IHJlYWQgdGhlIGRhdGEuCisgICAgICAgICAgICAvLyByZXR1cm4gLTEgaWYgdGhlcmUncyBhIHByb2JsZW0uCisgICAgICAgICAgICBpZiAocmVhZE9mZnNldCA9PSBibG9ja1NpemUpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICByZWFkQmxvY2soKGxlbiAtIGJ5dGVzKSA8IGJsb2NrU2l6ZSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoU2hvcnRGaWxlRXhjZXB0aW9uIHNmZSkgeyAvLyBOT1NPTkFSCisgICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGxvbmcgbiA9IDA7CisKKyAgICAgICAgICAgIGlmICgocmVhZE9mZnNldCArIChsZW4gLSBieXRlcykpIDw9IGJsb2NrU2l6ZSkgeworICAgICAgICAgICAgICAgIC8vIHdlIGNhbiByZWFkIGVudGlyZWx5IGZyb20gdGhlIGJ1ZmZlci4KKyAgICAgICAgICAgICAgICBuID0gbGVuIC0gYnl0ZXM7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIC8vIGNvcHkgd2hhdCB3ZSBjYW4gZnJvbSB0aGUgYnVmZmVyLgorICAgICAgICAgICAgICAgIG4gPSAobG9uZykgYmxvY2tTaXplIC0gcmVhZE9mZnNldDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gZG8gbm90IGNvcHkgZGF0YSBidXQgc3RpbGwgaW5jcmVtZW50IGNvdW50ZXJzLgorICAgICAgICAgICAgcmVhZE9mZnNldCArPSBuOworICAgICAgICAgICAgYnl0ZXMgKz0gbjsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBieXRlczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbG9zZSB0aGUgaW5wdXQgc3RyZWFtLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBvbiBlcnJvcgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGluICE9IG51bGwgJiYgaW4gIT0gU3lzdGVtLmluKSB7CisgICAgICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUGVlayBhdCB0aGUgbmV4dCByZWNvcmQgZnJvbSB0aGUgaW5wdXQgc3RyZWFtIGFuZCByZXR1cm4gdGhlIGRhdGEuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoZSByZWNvcmQgZGF0YS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIG9uIGVycm9yCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBwZWVrKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gd2UgbmVlZCB0byByZWFkIGZyb20gdGhlIHVuZGVybHlpbmcgc3RyZWFtLiBUaGlzCisgICAgICAgIC8vIGlzbid0IGEgcHJvYmxlbSBzaW5jZSBpdCB3b3VsZCBiZSB0aGUgZmlyc3Qgc3RlcCBpbgorICAgICAgICAvLyBhbnkgc3Vic2VxdWVudCByZWFkKCkgYW55d2F5LgorICAgICAgICBpZiAocmVhZE9mZnNldCA9PSBibG9ja1NpemUpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcmVhZEJsb2NrKHRydWUpOworICAgICAgICAgICAgfSBjYXRjaCAoU2hvcnRGaWxlRXhjZXB0aW9uIHNmZSkgeyAvLyBOT1NPTkFSCisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyBjb3B5IGRhdGEsIGluY3JlbWVudCBjb3VudGVycy4KKyAgICAgICAgZmluYWwgYnl0ZVtdIGIgPSBuZXcgYnl0ZVtSRUNPUkRfU0laRV07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYmxvY2tCdWZmZXIsIHJlYWRPZmZzZXQsIGIsIDAsIGIubGVuZ3RoKTsKKworICAgICAgICByZXR1cm4gYjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkIGEgcmVjb3JkIGZyb20gdGhlIGlucHV0IHN0cmVhbSBhbmQgcmV0dXJuIHRoZSBkYXRhLgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgcmVjb3JkIGRhdGEuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBvbiBlcnJvcgorICAgICAqLworICAgIHB1YmxpYyBieXRlW10gcmVhZFJlY29yZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIGJ5dGVbXSByZXN1bHQgPSBuZXcgYnl0ZVtSRUNPUkRfU0laRV07CisKKyAgICAgICAgLy8gdGhlIHJlYWQgaW1wbGVtZW50YXRpb24gd2lsbCBsb29wIGludGVybmFsbHkgYXMgbG9uZyBhcworICAgICAgICAvLyBpbnB1dCBpcyBhdmFpbGFibGUKKyAgICAgICAgaWYgKC0xID09IHJlYWQocmVzdWx0LCAwLCByZXN1bHQubGVuZ3RoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFNob3J0RmlsZUV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkIG5leHQgYmxvY2suIEFsbCBkZWNvbXByZXNzaW9uIGlzIGhhbmRsZWQgaGVyZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZWNvbXByZXNzIGlmIGZhbHNlIHRoZSBidWZmZXIgd2lsbCBub3QgYmUgZGVjb21wcmVzc2VkLgorICAgICAqICAgICAgICBUaGlzIGlzIGFuIG9wdGltaXphdGlvbiBmb3IgbG9uZ2VyIHNlZWtzLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCByZWFkQmxvY2soZmluYWwgYm9vbGVhbiBkZWNvbXByZXNzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoaW4gPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJpbnB1dCBidWZmZXIgaXMgY2xvc2VkIik7CisgICAgICAgIH0KKworICAgICAgICBpZiAoIWlzQ29tcHJlc3NlZCB8fCAoY3VyckJsa0lkeCA9PSAtMSkpIHsKKyAgICAgICAgICAgIC8vIGZpbGUgaXMgbm90IGNvbXByZXNzZWQKKyAgICAgICAgICAgIHJlYWRGdWxseShibG9ja0J1ZmZlciwgMCwgYmxvY2tTaXplKTsKKyAgICAgICAgICAgIGJ5dGVzUmVhZCArPSBibG9ja1NpemU7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZWFkRnVsbHkoYmxvY2tCdWZmZXIsIDAsIDQpOworICAgICAgICAgICAgYnl0ZXNSZWFkICs9IDQ7CisKKyAgICAgICAgICAgIGZpbmFsIGludCBoID0gRHVtcEFyY2hpdmVVdGlsLmNvbnZlcnQzMihibG9ja0J1ZmZlciwgMCk7CisgICAgICAgICAgICBmaW5hbCBib29sZWFuIGNvbXByZXNzZWQgPSAoaCAmIDB4MDEpID09IDB4MDE7CisKKyAgICAgICAgICAgIGlmICghY29tcHJlc3NlZCkgeworICAgICAgICAgICAgICAgIC8vIGZpbGUgaXMgY29tcHJlc3NlZCBidXQgdGhpcyBibG9jayBpcyBub3QuCisgICAgICAgICAgICAgICAgcmVhZEZ1bGx5KGJsb2NrQnVmZmVyLCAwLCBibG9ja1NpemUpOworICAgICAgICAgICAgICAgIGJ5dGVzUmVhZCArPSBibG9ja1NpemU7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIC8vIHRoaXMgYmxvY2sgaXMgY29tcHJlc3NlZC4KKyAgICAgICAgICAgICAgICBmaW5hbCBpbnQgZmxhZ3MgPSAoaCA+PiAxKSAmIDB4MDc7CisgICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IChoID4+IDQpICYgMHgwRkZGRkZGRjsKKyAgICAgICAgICAgICAgICBmaW5hbCBieXRlW10gY29tcEJ1ZmZlciA9IG5ldyBieXRlW2xlbmd0aF07CisgICAgICAgICAgICAgICAgcmVhZEZ1bGx5KGNvbXBCdWZmZXIsIDAsIGxlbmd0aCk7CisgICAgICAgICAgICAgICAgYnl0ZXNSZWFkICs9IGxlbmd0aDsKKworICAgICAgICAgICAgICAgIGlmICghZGVjb21wcmVzcykgeworICAgICAgICAgICAgICAgICAgICAvLyBqdXN0IGluIGNhc2Ugc29tZW9uZSByZWFkcyB0aGUgZGF0YS4KKyAgICAgICAgICAgICAgICAgICAgQXJyYXlzLmZpbGwoYmxvY2tCdWZmZXIsIChieXRlKSAwKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKER1bXBBcmNoaXZlQ29uc3RhbnRzLkNPTVBSRVNTSU9OX1RZUEUuZmluZChmbGFncyAmCisgICAgICAgICAgICAgICAgICAgICAgICAweDAzKSkgeworICAgICAgICAgICAgICAgICAgICBjYXNlIFpMSUI6CisKKyAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEluZmxhdGVyIGluZmxhdG9yID0gbmV3IEluZmxhdGVyKCk7CisgICAgICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZmxhdG9yLnNldElucHV0KGNvbXBCdWZmZXIsIDAsIGNvbXBCdWZmZXIubGVuZ3RoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZW5ndGggPSBpbmZsYXRvci5pbmZsYXRlKGJsb2NrQnVmZmVyKTsKKworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsZW5ndGggIT0gYmxvY2tTaXplKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBTaG9ydEZpbGVFeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChmaW5hbCBEYXRhRm9ybWF0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRHVtcEFyY2hpdmVFeGNlcHRpb24oImJhZCBkYXRhIiwgZSk7CisgICAgICAgICAgICAgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZmxhdG9yLmVuZCgpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgICAgICAgICBjYXNlIEJaTElCOgorICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkQ29tcHJlc3Npb25BbGdvcml0aG1FeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkJaTElCMiIpOworCisgICAgICAgICAgICAgICAgICAgIGNhc2UgTFpPOgorICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkQ29tcHJlc3Npb25BbGdvcml0aG1FeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkxaTyIpOworCisgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRDb21wcmVzc2lvbkFsZ29yaXRobUV4Y2VwdGlvbigpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgY3VyckJsa0lkeCsrOworICAgICAgICByZWFkT2Zmc2V0ID0gMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkIGJ1ZmZlcgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCByZWFkRnVsbHkoZmluYWwgYnl0ZVtdIGIsIGZpbmFsIGludCBvZmYsIGZpbmFsIGludCBsZW4pCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIGludCBjb3VudCA9IElPVXRpbHMucmVhZEZ1bGx5KGluLCBiLCBvZmYsIGxlbik7CisgICAgICAgIGlmIChjb3VudCA8IGxlbikgeworICAgICAgICAgICAgdGhyb3cgbmV3IFNob3J0RmlsZUV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IG51bWJlciBvZiBieXRlcyByZWFkLgorICAgICAqLworICAgIHB1YmxpYyBsb25nIGdldEJ5dGVzUmVhZCgpIHsKKyAgICAgICAgcmV0dXJuIGJ5dGVzUmVhZDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvZHVtcC9VbnJlY29nbml6ZWRGb3JtYXRFeGNlcHRpb24uamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9kdW1wL1VucmVjb2duaXplZEZvcm1hdEV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMzM2FlYWMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvZHVtcC9VbnJlY29nbml6ZWRGb3JtYXRFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDMyIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5kdW1wOworCisKKy8qKgorICogVW5yZWNvZ25pemVkIEZvcm1hdCBFeGNlcHRpb24uIFRoaXMgaXMgZWl0aGVyIG5vdCBhIHJlY29nbml6ZWQgZHVtcCBhcmNoaXZlIG9yIHRoZXJlJ3MKKyAqIGEgYmFkIHRhcGUgc2VnbWVudCBoZWFkZXIuCisgKi8KK3B1YmxpYyBjbGFzcyBVbnJlY29nbml6ZWRGb3JtYXRFeGNlcHRpb24gZXh0ZW5kcyBEdW1wQXJjaGl2ZUV4Y2VwdGlvbiB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7CisKKyAgICBwdWJsaWMgVW5yZWNvZ25pemVkRm9ybWF0RXhjZXB0aW9uKCkgeworICAgICAgICBzdXBlcigidGhpcyBpcyBub3QgYSByZWNvZ25pemVkIGZvcm1hdC4iKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvZHVtcC9VbnN1cHBvcnRlZENvbXByZXNzaW9uQWxnb3JpdGhtRXhjZXB0aW9uLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvZHVtcC9VbnN1cHBvcnRlZENvbXByZXNzaW9uQWxnb3JpdGhtRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGM2MDQwMwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9kdW1wL1Vuc3VwcG9ydGVkQ29tcHJlc3Npb25BbGdvcml0aG1FeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDM4IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5kdW1wOworCisKKy8qKgorICogVW5zdXBwb3J0ZWQgY29tcHJlc3Npb24gYWxnb3JpdGhtLiBUaGUgZHVtcCBhcmNoaXZlIHVzZXMgYW4gdW5zdXBwb3J0ZWQKKyAqIGNvbXByZXNzaW9uIGFsZ29yaXRobSAoQlpMSUIyIG9yIExaTykuCisgKi8KK3B1YmxpYyBjbGFzcyBVbnN1cHBvcnRlZENvbXByZXNzaW9uQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgZXh0ZW5kcyBEdW1wQXJjaGl2ZUV4Y2VwdGlvbiB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7CisKKyAgICBwdWJsaWMgVW5zdXBwb3J0ZWRDb21wcmVzc2lvbkFsZ29yaXRobUV4Y2VwdGlvbigpIHsKKyAgICAgICAgc3VwZXIoInRoaXMgZmlsZSB1c2VzIGFuIHVuc3VwcG9ydGVkIGNvbXByZXNzaW9uIGFsZ29yaXRobS4iKTsKKyAgICB9CisKKyAgICBwdWJsaWMgVW5zdXBwb3J0ZWRDb21wcmVzc2lvbkFsZ29yaXRobUV4Y2VwdGlvbihmaW5hbCBTdHJpbmcgYWxnKSB7CisgICAgICAgIHN1cGVyKCJ0aGlzIGZpbGUgdXNlcyBhbiB1bnN1cHBvcnRlZCBjb21wcmVzc2lvbiBhbGdvcml0aG06ICIgKyBhbGcgKworICAgICAgICAgICAgIi4iKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvZHVtcC9wYWNrYWdlLmh0bWwgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvZHVtcC9wYWNrYWdlLmh0bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzJmM2M2OAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9kdW1wL3BhY2thZ2UuaHRtbApAQCAtMCwwICsxLDU2IEBACis8aHRtbD4KKzwhLS0KKworICAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAgIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAgIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKworICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorCisgICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKworLS0+CisgIDxib2R5PgorICAgIDxwPlRoaXMgcGFja2FnZSBwcm92aWRlcyBzdHJlYW0gY2xhc3NlcyBmb3IgcmVhZGluZyBhcmNoaXZlcworICAgICAgdXNpbmcgdGhlIFVuaXggRFVNUCBmb3JtYXQuIFRoaXMgZm9ybWF0IGlzIHNpbWlsYXIgdG8gKGFuZCAKKyAgICAgIGNvbnRlbXBvcmFyeSB3aXRoKSBUQVIgYnV0IHJlYWRzIHRoZSByYXcgZmlsZXN5c3RlbSBkaXJlY3RseS4KKyAgICAgIFRoaXMgbWVhbnMgdGhhdCB3cml0ZXJzIGFyZSBmaWxlc3lzdGVtLXNwZWNpZmljIGV2ZW4gdGhvdWdoIHRoZQorICAgICAgY3JlYXRlZCBhcmNoaXZlcyBhcmUgZmlsZXN5c3RlbS1hZ25vc3RpYy4KKyAgICAgIDwvcD4KKyAgICAgCisgICAgPHA+VW5saWtlIG90aGVyIGZvcm1hdHMgRFVNUCBvZmZlcnMgY2xlYW4gc3VwcG9ydCBmb3Igc3BhcnNlIGZpbGVzLAorICAgICAgZXh0ZW5kZWQgYXR0cmlidXRlcywgYW5kIG90aGVyIGZpbGUgbWV0YWRhdGEuIEluIGFkZGl0aW9uIERVTVAgCisgICAgICBzdXBwb3J0cyBpbmNyZW1lbnRhbCBkdW1wIGZpbGVzIGNhbiBjYXB0dXJlIChtb3N0KSBmaWxlIGRlbGV0aW9uLgorICAgICAgSXQgYWxzbyBwcm92aWRlcyBhIG5hdGl2ZSBmb3JtIG9mIGNvbXByZXNzaW9uIGFuZCB3aWxsIHNvb24gc3VwcG9ydAorICAgICAgbmF0aXZlIGVuY3J5cHRpb24gYXMgd2VsbC4KKyAgICAgIDwvcD4KKworICAgIDxwPkluIHByYWN0aWNlIFRBUiBhcmNoaXZlcyBhcmUgdXNlZCBmb3IgYm90aCBkaXN0cmlidXRpb24KKyAgICAgIGFuZCBiYWNrdXBzLiBEVU1QIGFyY2hpdmVzIGFyZSB1c2VkIGV4Y2x1c2l2ZWx5IGZvciBiYWNrdXBzLgorICAgICAgPC9wPgorCisgICAgPHA+TGlrZSBhbnkgMzArLXllYXItb2xkIGFwcGxpY2F0aW9uIHRoZXJlIGFyZSBhIG51bWJlciBvZiB2YXJpYW50cy4KKyAgICAgIEZvciBwcmFnbWF0aWMgcmVhc29ucyB3ZSB3aWxsIG9ubHkgc3VwcG9ydCBhcmNoaXZlcyB3aXRoIHRoZQorICAgICAgJ25ldycgdGFwZSBoZWFkZXIgYW5kIGlub2RlIGZvcm1hdHMuIE90aGVyIHJlc3RyaWN0aW9uczoKKworICAgICAgPHVsPgorICAgICAgPGxpPldlIG9ubHkgc3VwcG9ydCBaTElCIGNvbXByZXNzaW9uLiBUaGUgZm9ybWF0CisgICAgICAgIGFsc28gcGVybWl0cyBMWk8gYW5kIEJaTElCIGNvbXByZXNzaW9uLjwvbGk+CisgICAgICA8bGk+U3BhcnNlIGZpbGVzIHdpbGwgaGF2ZSB0aGUgaG9sZXMgZmlsbGVkLjwvbGk+CisgICAgICA8bGk+TWFjT1MgZmluZGVyIGFuZCByZXNvdXJjZSBzdHJlYW1zIGFyZSBpZ25vcmVkLjwvbGk+CisgICAgICA8bGk+RXh0ZW5kZWQgYXR0cmlidXRlcyBhcmUgbm90IGN1cnJlbnRseSBwcm92aWRlZC48L2xpPgorICAgICAgPGxpPlNFTGludXggbGFiZWxzIGFyZSBub3QgY3VycmVudGx5IHByb3ZpZGVkLjwvbGk+CisgICAgICA8L3VsPgorICAgIDwvcD4KKworICAgIDxwPkFzIG9mIEFwYWNoZSBDb21tb25zIENvbXByZXNzIDEuMyBzdXBwb3J0IGZvciB0aGUgZHVtcCBmb3JtYXQgaXMKKyAgICAgIHJlYWQtb25seS48L3A+CisgIDwvYm9keT4KKzwvaHRtbD4KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9leGFtcGxlcy9BcmNoaXZlci5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2V4YW1wbGVzL0FyY2hpdmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjM0ZDE2YgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9leGFtcGxlcy9BcmNoaXZlci5qYXZhCkBAIC0wLDAgKzEsMjE3IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5leGFtcGxlczsKKworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLkNoYW5uZWxzOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLkZpbGVDaGFubmVsOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLlNlZWthYmxlQnl0ZUNoYW5uZWw7CitpbXBvcnQgamF2YS5uaW8uZmlsZS5GaWxlczsKK2ltcG9ydCBqYXZhLm5pby5maWxlLlN0YW5kYXJkT3Blbk9wdGlvbjsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZUVudHJ5OworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZUV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLkFyY2hpdmVPdXRwdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5BcmNoaXZlU3RyZWFtRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnNldmVuei5TZXZlblpPdXRwdXRGaWxlOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwLlppcEFyY2hpdmVPdXRwdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLklPVXRpbHM7CisKKy8qKgorICogUHJvdmlkZXMgYSBoaWdoIGxldmVsIEFQSSBmb3IgY3JlYXRpbmcgYXJjaGl2ZXMuCisgKiBAc2luY2UgMS4xNworICovCitwdWJsaWMgY2xhc3MgQXJjaGl2ZXIgeworCisgICAgcHJpdmF0ZSBpbnRlcmZhY2UgQXJjaGl2ZUVudHJ5Q3JlYXRvciB7CisgICAgICAgIEFyY2hpdmVFbnRyeSBjcmVhdGUoRmlsZSBmLCBTdHJpbmcgZW50cnlOYW1lKSB0aHJvd3MgSU9FeGNlcHRpb247CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnRlcmZhY2UgQXJjaGl2ZUVudHJ5Q29uc3VtZXIgeworICAgICAgICB2b2lkIGFjY2VwdChGaWxlIHNvdXJjZSwgQXJjaGl2ZUVudHJ5IGVudHJ5KSB0aHJvd3MgSU9FeGNlcHRpb247CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnRlcmZhY2UgRmluaXNoZXIgeworICAgICAgICB2b2lkIGZpbmlzaCgpIHRocm93cyBJT0V4Y2VwdGlvbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIGFyY2hpdmUge0Bjb2RlIHRhcmdldH0gdXNpbmcgdGhlIGZvcm1hdCB7QGNvZGUKKyAgICAgKiBmb3JtYXR9IGJ5IHJlY3Vyc2l2ZWx5IGluY2x1ZGluZyBhbGwgZmlsZXMgYW5kIGRpcmVjdG9yaWVzIGluCisgICAgICoge0Bjb2RlIGRpcmVjdG9yeX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZm9ybWF0IHRoZSBhcmNoaXZlIGZvcm1hdC4gVGhpcyB1c2VzIHRoZSBzYW1lIGZvcm1hdCBhcworICAgICAqIGFjY2VwdGVkIGJ5IHtAbGluayBBcmNoaXZlU3RyZWFtRmFjdG9yeX0uCisgICAgICogQHBhcmFtIHRhcmdldCB0aGUgZmlsZSB0byB3cml0ZSB0aGUgbmV3IGFyY2hpdmUgdG8uCisgICAgICogQHBhcmFtIGRpcmVjdG9yeSB0aGUgZGlyZWN0b3J5IHRoYXQgY29udGFpbnMgdGhlIGZpbGVzIHRvIGFyY2hpdmUuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiBhbiBJL08gZXJyb3Igb2NjdXJzCisgICAgICogQHRocm93cyBBcmNoaXZlRXhjZXB0aW9uIGlmIHRoZSBhcmNoaXZlIGNhbm5vdCBiZSBjcmVhdGVkIGZvciBvdGhlciByZWFzb25zCisgICAgICovCisgICAgcHVibGljIHZvaWQgY3JlYXRlKFN0cmluZyBmb3JtYXQsIEZpbGUgdGFyZ2V0LCBGaWxlIGRpcmVjdG9yeSkgdGhyb3dzIElPRXhjZXB0aW9uLCBBcmNoaXZlRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHByZWZlcnNTZWVrYWJsZUJ5dGVDaGFubmVsKGZvcm1hdCkpIHsKKyAgICAgICAgICAgIHRyeSAoU2Vla2FibGVCeXRlQ2hhbm5lbCBjID0gRmlsZUNoYW5uZWwub3Blbih0YXJnZXQudG9QYXRoKCksIFN0YW5kYXJkT3Blbk9wdGlvbi5XUklURSwKKyAgICAgICAgICAgICAgICBTdGFuZGFyZE9wZW5PcHRpb24uQ1JFQVRFLCBTdGFuZGFyZE9wZW5PcHRpb24uVFJVTkNBVEVfRVhJU1RJTkcpKSB7CisgICAgICAgICAgICAgICAgY3JlYXRlKGZvcm1hdCwgYywgZGlyZWN0b3J5KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICB0cnkgKE91dHB1dFN0cmVhbSBvID0gRmlsZXMubmV3T3V0cHV0U3RyZWFtKHRhcmdldC50b1BhdGgoKSkpIHsKKyAgICAgICAgICAgIGNyZWF0ZShmb3JtYXQsIG8sIGRpcmVjdG9yeSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIGFyY2hpdmUge0Bjb2RlIHRhcmdldH0gdXNpbmcgdGhlIGZvcm1hdCB7QGNvZGUKKyAgICAgKiBmb3JtYXR9IGJ5IHJlY3Vyc2l2ZWx5IGluY2x1ZGluZyBhbGwgZmlsZXMgYW5kIGRpcmVjdG9yaWVzIGluCisgICAgICoge0Bjb2RlIGRpcmVjdG9yeX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZm9ybWF0IHRoZSBhcmNoaXZlIGZvcm1hdC4gVGhpcyB1c2VzIHRoZSBzYW1lIGZvcm1hdCBhcworICAgICAqIGFjY2VwdGVkIGJ5IHtAbGluayBBcmNoaXZlU3RyZWFtRmFjdG9yeX0uCisgICAgICogQHBhcmFtIHRhcmdldCB0aGUgc3RyZWFtIHRvIHdyaXRlIHRoZSBuZXcgYXJjaGl2ZSB0by4KKyAgICAgKiBAcGFyYW0gZGlyZWN0b3J5IHRoZSBkaXJlY3RvcnkgdGhhdCBjb250YWlucyB0aGUgZmlsZXMgdG8gYXJjaGl2ZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMKKyAgICAgKiBAdGhyb3dzIEFyY2hpdmVFeGNlcHRpb24gaWYgdGhlIGFyY2hpdmUgY2Fubm90IGJlIGNyZWF0ZWQgZm9yIG90aGVyIHJlYXNvbnMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBjcmVhdGUoU3RyaW5nIGZvcm1hdCwgT3V0cHV0U3RyZWFtIHRhcmdldCwgRmlsZSBkaXJlY3RvcnkpIHRocm93cyBJT0V4Y2VwdGlvbiwgQXJjaGl2ZUV4Y2VwdGlvbiB7CisgICAgICAgIGNyZWF0ZShuZXcgQXJjaGl2ZVN0cmVhbUZhY3RvcnkoKS5jcmVhdGVBcmNoaXZlT3V0cHV0U3RyZWFtKGZvcm1hdCwgdGFyZ2V0KSwgZGlyZWN0b3J5KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIGFyY2hpdmUge0Bjb2RlIHRhcmdldH0gdXNpbmcgdGhlIGZvcm1hdCB7QGNvZGUKKyAgICAgKiBmb3JtYXR9IGJ5IHJlY3Vyc2l2ZWx5IGluY2x1ZGluZyBhbGwgZmlsZXMgYW5kIGRpcmVjdG9yaWVzIGluCisgICAgICoge0Bjb2RlIGRpcmVjdG9yeX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZm9ybWF0IHRoZSBhcmNoaXZlIGZvcm1hdC4gVGhpcyB1c2VzIHRoZSBzYW1lIGZvcm1hdCBhcworICAgICAqIGFjY2VwdGVkIGJ5IHtAbGluayBBcmNoaXZlU3RyZWFtRmFjdG9yeX0uCisgICAgICogQHBhcmFtIHRhcmdldCB0aGUgY2hhbm5lbCB0byB3cml0ZSB0aGUgbmV3IGFyY2hpdmUgdG8uCisgICAgICogQHBhcmFtIGRpcmVjdG9yeSB0aGUgZGlyZWN0b3J5IHRoYXQgY29udGFpbnMgdGhlIGZpbGVzIHRvIGFyY2hpdmUuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiBhbiBJL08gZXJyb3Igb2NjdXJzCisgICAgICogQHRocm93cyBBcmNoaXZlRXhjZXB0aW9uIGlmIHRoZSBhcmNoaXZlIGNhbm5vdCBiZSBjcmVhdGVkIGZvciBvdGhlciByZWFzb25zCisgICAgICovCisgICAgcHVibGljIHZvaWQgY3JlYXRlKFN0cmluZyBmb3JtYXQsIFNlZWthYmxlQnl0ZUNoYW5uZWwgdGFyZ2V0LCBGaWxlIGRpcmVjdG9yeSkKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBBcmNoaXZlRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFwcmVmZXJzU2Vla2FibGVCeXRlQ2hhbm5lbChmb3JtYXQpKSB7CisgICAgICAgICAgICBjcmVhdGUoZm9ybWF0LCBDaGFubmVscy5uZXdPdXRwdXRTdHJlYW0odGFyZ2V0KSwgZGlyZWN0b3J5KTsKKyAgICAgICAgfSBlbHNlIGlmIChBcmNoaXZlU3RyZWFtRmFjdG9yeS5aSVAuZXF1YWxzSWdub3JlQ2FzZShmb3JtYXQpKSB7CisgICAgICAgICAgICBjcmVhdGUobmV3IFppcEFyY2hpdmVPdXRwdXRTdHJlYW0odGFyZ2V0KSwgZGlyZWN0b3J5KTsKKyAgICAgICAgfSBlbHNlIGlmIChBcmNoaXZlU3RyZWFtRmFjdG9yeS5TRVZFTl9aLmVxdWFsc0lnbm9yZUNhc2UoZm9ybWF0KSkgeworICAgICAgICAgICAgY3JlYXRlKG5ldyBTZXZlblpPdXRwdXRGaWxlKHRhcmdldCksIGRpcmVjdG9yeSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvLyBuZXZlciByZWFjaGVkIGFzIHByZWZlcnNTZWVrYWJsZUJ5dGVDaGFubmVsIG9ubHkgcmV0dXJucyB0cnVlIGZvciBaSVAgYW5kIDd6CisgICAgICAgICAgICB0aHJvdyBuZXcgQXJjaGl2ZUV4Y2VwdGlvbigiZG9uJ3Qga25vdyBob3cgdG8gaGFuZGxlIGZvcm1hdCAiICsgZm9ybWF0KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gYXJjaGl2ZSB7QGNvZGUgdGFyZ2V0fSBieSByZWN1cnNpdmVseSBpbmNsdWRpbmcgYWxsCisgICAgICogZmlsZXMgYW5kIGRpcmVjdG9yaWVzIGluIHtAY29kZSBkaXJlY3Rvcnl9LgorICAgICAqCisgICAgICogQHBhcmFtIHRhcmdldCB0aGUgc3RyZWFtIHRvIHdyaXRlIHRoZSBuZXcgYXJjaGl2ZSB0by4KKyAgICAgKiBAcGFyYW0gZGlyZWN0b3J5IHRoZSBkaXJlY3RvcnkgdGhhdCBjb250YWlucyB0aGUgZmlsZXMgdG8gYXJjaGl2ZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMKKyAgICAgKiBAdGhyb3dzIEFyY2hpdmVFeGNlcHRpb24gaWYgdGhlIGFyY2hpdmUgY2Fubm90IGJlIGNyZWF0ZWQgZm9yIG90aGVyIHJlYXNvbnMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBjcmVhdGUoZmluYWwgQXJjaGl2ZU91dHB1dFN0cmVhbSB0YXJnZXQsIEZpbGUgZGlyZWN0b3J5KQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIEFyY2hpdmVFeGNlcHRpb24geworICAgICAgICBjcmVhdGUoZGlyZWN0b3J5LCBuZXcgQXJjaGl2ZUVudHJ5Q3JlYXRvcigpIHsKKyAgICAgICAgICAgIHB1YmxpYyBBcmNoaXZlRW50cnkgY3JlYXRlKEZpbGUgZiwgU3RyaW5nIGVudHJ5TmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gdGFyZ2V0LmNyZWF0ZUFyY2hpdmVFbnRyeShmLCBlbnRyeU5hbWUpOworICAgICAgICAgICAgfQorICAgICAgICB9LCBuZXcgQXJjaGl2ZUVudHJ5Q29uc3VtZXIoKSB7CisgICAgICAgICAgICBwdWJsaWMgdm9pZCBhY2NlcHQoRmlsZSBzb3VyY2UsIEFyY2hpdmVFbnRyeSBlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgICAgIHRhcmdldC5wdXRBcmNoaXZlRW50cnkoZSk7CisgICAgICAgICAgICAgICAgaWYgKCFlLmlzRGlyZWN0b3J5KCkpIHsKKyAgICAgICAgICAgICAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBpbiA9IG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKEZpbGVzLm5ld0lucHV0U3RyZWFtKHNvdXJjZS50b1BhdGgoKSkpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBJT1V0aWxzLmNvcHkoaW4sIHRhcmdldCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgdGFyZ2V0LmNsb3NlQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0sIG5ldyBGaW5pc2hlcigpIHsKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIGZpbmlzaCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgdGFyZ2V0LmZpbmlzaCgpOworICAgICAgICAgICAgfQorICAgICAgICB9KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIGFyY2hpdmUge0Bjb2RlIHRhcmdldH0gYnkgcmVjdXJzaXZlbHkgaW5jbHVkaW5nIGFsbAorICAgICAqIGZpbGVzIGFuZCBkaXJlY3RvcmllcyBpbiB7QGNvZGUgZGlyZWN0b3J5fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0YXJnZXQgdGhlIGZpbGUgdG8gd3JpdGUgdGhlIG5ldyBhcmNoaXZlIHRvLgorICAgICAqIEBwYXJhbSBkaXJlY3RvcnkgdGhlIGRpcmVjdG9yeSB0aGF0IGNvbnRhaW5zIHRoZSBmaWxlcyB0byBhcmNoaXZlLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgYW4gSS9PIGVycm9yIG9jY3VycworICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNyZWF0ZShmaW5hbCBTZXZlblpPdXRwdXRGaWxlIHRhcmdldCwgRmlsZSBkaXJlY3RvcnkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNyZWF0ZShkaXJlY3RvcnksIG5ldyBBcmNoaXZlRW50cnlDcmVhdG9yKCkgeworICAgICAgICAgICAgcHVibGljIEFyY2hpdmVFbnRyeSBjcmVhdGUoRmlsZSBmLCBTdHJpbmcgZW50cnlOYW1lKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgICAgIHJldHVybiB0YXJnZXQuY3JlYXRlQXJjaGl2ZUVudHJ5KGYsIGVudHJ5TmFtZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0sIG5ldyBBcmNoaXZlRW50cnlDb25zdW1lcigpIHsKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIGFjY2VwdChGaWxlIHNvdXJjZSwgQXJjaGl2ZUVudHJ5IGUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgdGFyZ2V0LnB1dEFyY2hpdmVFbnRyeShlKTsKKyAgICAgICAgICAgICAgICBpZiAoIWUuaXNEaXJlY3RvcnkoKSkgeworICAgICAgICAgICAgICAgICAgICBmaW5hbCBieXRlW10gYnVmZmVyID0gbmV3IGJ5dGVbODAyNF07CisgICAgICAgICAgICAgICAgICAgIGludCBuID0gMDsKKyAgICAgICAgICAgICAgICAgICAgbG9uZyBjb3VudCA9IDA7CisgICAgICAgICAgICAgICAgICAgIHRyeSAoSW5wdXRTdHJlYW0gaW4gPSBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShGaWxlcy5uZXdJbnB1dFN0cmVhbShzb3VyY2UudG9QYXRoKCkpKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKC0xICE9IChuID0gaW4ucmVhZChidWZmZXIpKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldC53cml0ZShidWZmZXIsIDAsIG4pOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IG47CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgdGFyZ2V0LmNsb3NlQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0sIG5ldyBGaW5pc2hlcigpIHsKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIGZpbmlzaCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgdGFyZ2V0LmZpbmlzaCgpOworICAgICAgICAgICAgfQorICAgICAgICB9KTsKKyAgICB9CisKKyAgICBwcml2YXRlIGJvb2xlYW4gcHJlZmVyc1NlZWthYmxlQnl0ZUNoYW5uZWwoU3RyaW5nIGZvcm1hdCkgeworICAgICAgICByZXR1cm4gQXJjaGl2ZVN0cmVhbUZhY3RvcnkuWklQLmVxdWFsc0lnbm9yZUNhc2UoZm9ybWF0KSB8fCBBcmNoaXZlU3RyZWFtRmFjdG9yeS5TRVZFTl9aLmVxdWFsc0lnbm9yZUNhc2UoZm9ybWF0KTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY3JlYXRlKEZpbGUgZGlyZWN0b3J5LCBBcmNoaXZlRW50cnlDcmVhdG9yIGNyZWF0b3IsIEFyY2hpdmVFbnRyeUNvbnN1bWVyIGNvbnN1bWVyLAorICAgICAgICBGaW5pc2hlciBmaW5pc2hlcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY3JlYXRlKCIiLCBkaXJlY3RvcnksIGNyZWF0b3IsIGNvbnN1bWVyKTsKKyAgICAgICAgZmluaXNoZXIuZmluaXNoKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNyZWF0ZShTdHJpbmcgcHJlZml4LCBGaWxlIGRpcmVjdG9yeSwgQXJjaGl2ZUVudHJ5Q3JlYXRvciBjcmVhdG9yLCBBcmNoaXZlRW50cnlDb25zdW1lciBjb25zdW1lcikKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgRmlsZVtdIGNoaWxkcmVuID0gZGlyZWN0b3J5Lmxpc3RGaWxlcygpOworICAgICAgICBpZiAoY2hpbGRyZW4gPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGZvciAoRmlsZSBmIDogY2hpbGRyZW4pIHsKKyAgICAgICAgICAgIFN0cmluZyBlbnRyeU5hbWUgPSBwcmVmaXggKyBmLmdldE5hbWUoKSArIChmLmlzRGlyZWN0b3J5KCkgPyAiLyIgOiAiIik7CisgICAgICAgICAgICBjb25zdW1lci5hY2NlcHQoZiwgY3JlYXRvci5jcmVhdGUoZiwgZW50cnlOYW1lKSk7CisgICAgICAgICAgICBpZiAoZi5pc0RpcmVjdG9yeSgpKSB7CisgICAgICAgICAgICAgICAgY3JlYXRlKGVudHJ5TmFtZSwgZiwgY3JlYXRvciwgY29uc3VtZXIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2V4YW1wbGVzL0V4cGFuZGVyLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvZXhhbXBsZXMvRXhwYW5kZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40OTIyNTI3Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2V4YW1wbGVzL0V4cGFuZGVyLmphdmEKQEAgLTAsMCArMSwyNjcgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLmV4YW1wbGVzOworCitpbXBvcnQgamF2YS5pby5CdWZmZXJlZElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuQ2hhbm5lbHM7CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuRmlsZUNoYW5uZWw7CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuU2Vla2FibGVCeXRlQ2hhbm5lbDsKK2ltcG9ydCBqYXZhLm5pby5maWxlLkZpbGVzOworaW1wb3J0IGphdmEubmlvLmZpbGUuU3RhbmRhcmRPcGVuT3B0aW9uOworaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZUVudHJ5OworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZUV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLkFyY2hpdmVJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLkFyY2hpdmVTdHJlYW1GYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuc2V2ZW56LlNldmVuWkZpbGU7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXAuWmlwQXJjaGl2ZUVudHJ5OworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwLlppcEZpbGU7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLklPVXRpbHM7CisKKy8qKgorICogUHJvdmlkZXMgYSBoaWdoIGxldmVsIEFQSSBmb3IgZXhwYW5kaW5nIGFyY2hpdmVzLgorICogQHNpbmNlIDEuMTcKKyAqLworcHVibGljIGNsYXNzIEV4cGFuZGVyIHsKKworICAgIHByaXZhdGUgaW50ZXJmYWNlIEFyY2hpdmVFbnRyeVN1cHBsaWVyIHsKKyAgICAgICAgQXJjaGl2ZUVudHJ5IGdldE5leHRSZWFkYWJsZUVudHJ5KCkgdGhyb3dzIElPRXhjZXB0aW9uOworICAgIH0KKworICAgIHByaXZhdGUgaW50ZXJmYWNlIEVudHJ5V3JpdGVyIHsKKyAgICAgICAgdm9pZCB3cml0ZUVudHJ5RGF0YVRvKEFyY2hpdmVFbnRyeSBlbnRyeSwgT3V0cHV0U3RyZWFtIG91dCkgdGhyb3dzIElPRXhjZXB0aW9uOworICAgIH0KKworICAgIC8qKgorICAgICAqIEV4cGFuZHMge0Bjb2RlIGFyY2hpdmV9IGludG8ge0Bjb2RlIHRhcmdldERpcmVjdG9yeX0uCisgICAgICoKKyAgICAgKiA8cD5UcmllcyB0byBhdXRvLWRldGVjdCB0aGUgYXJjaGl2ZSdzIGZvcm1hdC48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJjaGl2ZSB0aGUgZmlsZSB0byBleHBhbmQKKyAgICAgKiBAcGFyYW0gdGFyZ2V0RGlyZWN0b3J5IHRoZSBkaXJlY3RvcnkgdG8gd3JpdGUgdG8KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMKKyAgICAgKiBAdGhyb3dzIEFyY2hpdmVFeGNlcHRpb24gaWYgdGhlIGFyY2hpdmUgY2Fubm90IGJlIHJlYWQgZm9yIG90aGVyIHJlYXNvbnMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBleHBhbmQoRmlsZSBhcmNoaXZlLCBGaWxlIHRhcmdldERpcmVjdG9yeSkgdGhyb3dzIElPRXhjZXB0aW9uLCBBcmNoaXZlRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIGZvcm1hdCA9IG51bGw7CisgICAgICAgIHRyeSAoSW5wdXRTdHJlYW0gaSA9IG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKEZpbGVzLm5ld0lucHV0U3RyZWFtKGFyY2hpdmUudG9QYXRoKCkpKSkgeworICAgICAgICAgICAgZm9ybWF0ID0gbmV3IEFyY2hpdmVTdHJlYW1GYWN0b3J5KCkuZGV0ZWN0KGkpOworICAgICAgICB9CisgICAgICAgIGV4cGFuZChmb3JtYXQsIGFyY2hpdmUsIHRhcmdldERpcmVjdG9yeSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRXhwYW5kcyB7QGNvZGUgYXJjaGl2ZX0gaW50byB7QGNvZGUgdGFyZ2V0RGlyZWN0b3J5fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcmNoaXZlIHRoZSBmaWxlIHRvIGV4cGFuZAorICAgICAqIEBwYXJhbSB0YXJnZXREaXJlY3RvcnkgdGhlIGRpcmVjdG9yeSB0byB3cml0ZSB0bworICAgICAqIEBwYXJhbSBmb3JtYXQgdGhlIGFyY2hpdmUgZm9ybWF0LiBUaGlzIHVzZXMgdGhlIHNhbWUgZm9ybWF0IGFzCisgICAgICogYWNjZXB0ZWQgYnkge0BsaW5rIEFyY2hpdmVTdHJlYW1GYWN0b3J5fS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMKKyAgICAgKiBAdGhyb3dzIEFyY2hpdmVFeGNlcHRpb24gaWYgdGhlIGFyY2hpdmUgY2Fubm90IGJlIHJlYWQgZm9yIG90aGVyIHJlYXNvbnMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBleHBhbmQoU3RyaW5nIGZvcm1hdCwgRmlsZSBhcmNoaXZlLCBGaWxlIHRhcmdldERpcmVjdG9yeSkgdGhyb3dzIElPRXhjZXB0aW9uLCBBcmNoaXZlRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHByZWZlcnNTZWVrYWJsZUJ5dGVDaGFubmVsKGZvcm1hdCkpIHsKKyAgICAgICAgICAgIHRyeSAoU2Vla2FibGVCeXRlQ2hhbm5lbCBjID0gRmlsZUNoYW5uZWwub3BlbihhcmNoaXZlLnRvUGF0aCgpLCBTdGFuZGFyZE9wZW5PcHRpb24uUkVBRCkpIHsKKyAgICAgICAgICAgICAgICBleHBhbmQoZm9ybWF0LCBjLCB0YXJnZXREaXJlY3RvcnkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIHRyeSAoSW5wdXRTdHJlYW0gaSA9IG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKEZpbGVzLm5ld0lucHV0U3RyZWFtKGFyY2hpdmUudG9QYXRoKCkpKSkgeworICAgICAgICAgICAgZXhwYW5kKGZvcm1hdCwgaSwgdGFyZ2V0RGlyZWN0b3J5KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEV4cGFuZHMge0Bjb2RlIGFyY2hpdmV9IGludG8ge0Bjb2RlIHRhcmdldERpcmVjdG9yeX0uCisgICAgICoKKyAgICAgKiA8cD5UcmllcyB0byBhdXRvLWRldGVjdCB0aGUgYXJjaGl2ZSdzIGZvcm1hdC48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJjaGl2ZSB0aGUgZmlsZSB0byBleHBhbmQKKyAgICAgKiBAcGFyYW0gdGFyZ2V0RGlyZWN0b3J5IHRoZSBkaXJlY3RvcnkgdG8gd3JpdGUgdG8KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMKKyAgICAgKiBAdGhyb3dzIEFyY2hpdmVFeGNlcHRpb24gaWYgdGhlIGFyY2hpdmUgY2Fubm90IGJlIHJlYWQgZm9yIG90aGVyIHJlYXNvbnMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBleHBhbmQoSW5wdXRTdHJlYW0gYXJjaGl2ZSwgRmlsZSB0YXJnZXREaXJlY3RvcnkpIHRocm93cyBJT0V4Y2VwdGlvbiwgQXJjaGl2ZUV4Y2VwdGlvbiB7CisgICAgICAgIGV4cGFuZChuZXcgQXJjaGl2ZVN0cmVhbUZhY3RvcnkoKS5jcmVhdGVBcmNoaXZlSW5wdXRTdHJlYW0oYXJjaGl2ZSksIHRhcmdldERpcmVjdG9yeSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRXhwYW5kcyB7QGNvZGUgYXJjaGl2ZX0gaW50byB7QGNvZGUgdGFyZ2V0RGlyZWN0b3J5fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcmNoaXZlIHRoZSBmaWxlIHRvIGV4cGFuZAorICAgICAqIEBwYXJhbSB0YXJnZXREaXJlY3RvcnkgdGhlIGRpcmVjdG9yeSB0byB3cml0ZSB0bworICAgICAqIEBwYXJhbSBmb3JtYXQgdGhlIGFyY2hpdmUgZm9ybWF0LiBUaGlzIHVzZXMgdGhlIHNhbWUgZm9ybWF0IGFzCisgICAgICogYWNjZXB0ZWQgYnkge0BsaW5rIEFyY2hpdmVTdHJlYW1GYWN0b3J5fS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMKKyAgICAgKiBAdGhyb3dzIEFyY2hpdmVFeGNlcHRpb24gaWYgdGhlIGFyY2hpdmUgY2Fubm90IGJlIHJlYWQgZm9yIG90aGVyIHJlYXNvbnMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBleHBhbmQoU3RyaW5nIGZvcm1hdCwgSW5wdXRTdHJlYW0gYXJjaGl2ZSwgRmlsZSB0YXJnZXREaXJlY3RvcnkpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgQXJjaGl2ZUV4Y2VwdGlvbiB7CisgICAgICAgIGV4cGFuZChuZXcgQXJjaGl2ZVN0cmVhbUZhY3RvcnkoKS5jcmVhdGVBcmNoaXZlSW5wdXRTdHJlYW0oZm9ybWF0LCBhcmNoaXZlKSwgdGFyZ2V0RGlyZWN0b3J5KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFeHBhbmRzIHtAY29kZSBhcmNoaXZlfSBpbnRvIHtAY29kZSB0YXJnZXREaXJlY3Rvcnl9LgorICAgICAqCisgICAgICogQHBhcmFtIGFyY2hpdmUgdGhlIGZpbGUgdG8gZXhwYW5kCisgICAgICogQHBhcmFtIHRhcmdldERpcmVjdG9yeSB0aGUgZGlyZWN0b3J5IHRvIHdyaXRlIHRvCisgICAgICogQHBhcmFtIGZvcm1hdCB0aGUgYXJjaGl2ZSBmb3JtYXQuIFRoaXMgdXNlcyB0aGUgc2FtZSBmb3JtYXQgYXMKKyAgICAgKiBhY2NlcHRlZCBieSB7QGxpbmsgQXJjaGl2ZVN0cmVhbUZhY3Rvcnl9LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgYW4gSS9PIGVycm9yIG9jY3VycworICAgICAqIEB0aHJvd3MgQXJjaGl2ZUV4Y2VwdGlvbiBpZiB0aGUgYXJjaGl2ZSBjYW5ub3QgYmUgcmVhZCBmb3Igb3RoZXIgcmVhc29ucworICAgICAqLworICAgIHB1YmxpYyB2b2lkIGV4cGFuZChTdHJpbmcgZm9ybWF0LCBTZWVrYWJsZUJ5dGVDaGFubmVsIGFyY2hpdmUsIEZpbGUgdGFyZ2V0RGlyZWN0b3J5KQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIEFyY2hpdmVFeGNlcHRpb24geworICAgICAgICBpZiAoIXByZWZlcnNTZWVrYWJsZUJ5dGVDaGFubmVsKGZvcm1hdCkpIHsKKyAgICAgICAgICAgIGV4cGFuZChmb3JtYXQsIENoYW5uZWxzLm5ld0lucHV0U3RyZWFtKGFyY2hpdmUpLCB0YXJnZXREaXJlY3RvcnkpOworICAgICAgICB9IGVsc2UgaWYgKEFyY2hpdmVTdHJlYW1GYWN0b3J5LlpJUC5lcXVhbHNJZ25vcmVDYXNlKGZvcm1hdCkpIHsKKyAgICAgICAgICAgIGV4cGFuZChuZXcgWmlwRmlsZShhcmNoaXZlKSwgdGFyZ2V0RGlyZWN0b3J5KTsKKyAgICAgICAgfSBlbHNlIGlmIChBcmNoaXZlU3RyZWFtRmFjdG9yeS5TRVZFTl9aLmVxdWFsc0lnbm9yZUNhc2UoZm9ybWF0KSkgeworICAgICAgICAgICAgZXhwYW5kKG5ldyBTZXZlblpGaWxlKGFyY2hpdmUpLCB0YXJnZXREaXJlY3RvcnkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gbmV2ZXIgcmVhY2hlZCBhcyBwcmVmZXJzU2Vla2FibGVCeXRlQ2hhbm5lbCBvbmx5IHJldHVybnMgdHJ1ZSBmb3IgWklQIGFuZCA3egorICAgICAgICAgICAgdGhyb3cgbmV3IEFyY2hpdmVFeGNlcHRpb24oImRvbid0IGtub3cgaG93IHRvIGhhbmRsZSBmb3JtYXQgIiArIGZvcm1hdCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFeHBhbmRzIHtAY29kZSBhcmNoaXZlfSBpbnRvIHtAY29kZSB0YXJnZXREaXJlY3Rvcnl9LgorICAgICAqCisgICAgICogQHBhcmFtIGFyY2hpdmUgdGhlIGZpbGUgdG8gZXhwYW5kCisgICAgICogQHBhcmFtIHRhcmdldERpcmVjdG9yeSB0aGUgZGlyZWN0b3J5IHRvIHdyaXRlIHRvCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiBhbiBJL08gZXJyb3Igb2NjdXJzCisgICAgICogQHRocm93cyBBcmNoaXZlRXhjZXB0aW9uIGlmIHRoZSBhcmNoaXZlIGNhbm5vdCBiZSByZWFkIGZvciBvdGhlciByZWFzb25zCisgICAgICovCisgICAgcHVibGljIHZvaWQgZXhwYW5kKGZpbmFsIEFyY2hpdmVJbnB1dFN0cmVhbSBhcmNoaXZlLCBGaWxlIHRhcmdldERpcmVjdG9yeSkKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBBcmNoaXZlRXhjZXB0aW9uIHsKKyAgICAgICAgZXhwYW5kKG5ldyBBcmNoaXZlRW50cnlTdXBwbGllcigpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIEFyY2hpdmVFbnRyeSBnZXROZXh0UmVhZGFibGVFbnRyeSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgQXJjaGl2ZUVudHJ5IG5leHQgPSBhcmNoaXZlLmdldE5leHRFbnRyeSgpOworICAgICAgICAgICAgICAgIHdoaWxlIChuZXh0ICE9IG51bGwgJiYgIWFyY2hpdmUuY2FuUmVhZEVudHJ5RGF0YShuZXh0KSkgeworICAgICAgICAgICAgICAgICAgICBuZXh0ID0gYXJjaGl2ZS5nZXROZXh0RW50cnkoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIG5leHQ7CisgICAgICAgICAgICB9CisgICAgICAgIH0sIG5ldyBFbnRyeVdyaXRlcigpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIHZvaWQgd3JpdGVFbnRyeURhdGFUbyhBcmNoaXZlRW50cnkgZW50cnksIE91dHB1dFN0cmVhbSBvdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgSU9VdGlscy5jb3B5KGFyY2hpdmUsIG91dCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0sIHRhcmdldERpcmVjdG9yeSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRXhwYW5kcyB7QGNvZGUgYXJjaGl2ZX0gaW50byB7QGNvZGUgdGFyZ2V0RGlyZWN0b3J5fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcmNoaXZlIHRoZSBmaWxlIHRvIGV4cGFuZAorICAgICAqIEBwYXJhbSB0YXJnZXREaXJlY3RvcnkgdGhlIGRpcmVjdG9yeSB0byB3cml0ZSB0bworICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgYW4gSS9PIGVycm9yIG9jY3VycworICAgICAqIEB0aHJvd3MgQXJjaGl2ZUV4Y2VwdGlvbiBpZiB0aGUgYXJjaGl2ZSBjYW5ub3QgYmUgcmVhZCBmb3Igb3RoZXIgcmVhc29ucworICAgICAqLworICAgIHB1YmxpYyB2b2lkIGV4cGFuZChmaW5hbCBaaXBGaWxlIGFyY2hpdmUsIEZpbGUgdGFyZ2V0RGlyZWN0b3J5KQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIEFyY2hpdmVFeGNlcHRpb24geworICAgICAgICBmaW5hbCBFbnVtZXJhdGlvbjxaaXBBcmNoaXZlRW50cnk+IGVudHJpZXMgPSBhcmNoaXZlLmdldEVudHJpZXMoKTsKKyAgICAgICAgZXhwYW5kKG5ldyBBcmNoaXZlRW50cnlTdXBwbGllcigpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIEFyY2hpdmVFbnRyeSBnZXROZXh0UmVhZGFibGVFbnRyeSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgWmlwQXJjaGl2ZUVudHJ5IG5leHQgPSBlbnRyaWVzLmhhc01vcmVFbGVtZW50cygpID8gZW50cmllcy5uZXh0RWxlbWVudCgpIDogbnVsbDsKKyAgICAgICAgICAgICAgICB3aGlsZSAobmV4dCAhPSBudWxsICYmICFhcmNoaXZlLmNhblJlYWRFbnRyeURhdGEobmV4dCkpIHsKKyAgICAgICAgICAgICAgICAgICAgbmV4dCA9IGVudHJpZXMuaGFzTW9yZUVsZW1lbnRzKCkgPyBlbnRyaWVzLm5leHRFbGVtZW50KCkgOiBudWxsOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gbmV4dDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSwgbmV3IEVudHJ5V3JpdGVyKCkgeworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgdm9pZCB3cml0ZUVudHJ5RGF0YVRvKEFyY2hpdmVFbnRyeSBlbnRyeSwgT3V0cHV0U3RyZWFtIG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICB0cnkgKElucHV0U3RyZWFtIGluID0gYXJjaGl2ZS5nZXRJbnB1dFN0cmVhbSgoWmlwQXJjaGl2ZUVudHJ5KSBlbnRyeSkpIHsKKyAgICAgICAgICAgICAgICAgICAgSU9VdGlscy5jb3B5KGluLCBvdXQpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSwgdGFyZ2V0RGlyZWN0b3J5KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFeHBhbmRzIHtAY29kZSBhcmNoaXZlfSBpbnRvIHtAY29kZSB0YXJnZXREaXJlY3Rvcnl9LgorICAgICAqCisgICAgICogQHBhcmFtIGFyY2hpdmUgdGhlIGZpbGUgdG8gZXhwYW5kCisgICAgICogQHBhcmFtIHRhcmdldERpcmVjdG9yeSB0aGUgZGlyZWN0b3J5IHRvIHdyaXRlIHRvCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiBhbiBJL08gZXJyb3Igb2NjdXJzCisgICAgICogQHRocm93cyBBcmNoaXZlRXhjZXB0aW9uIGlmIHRoZSBhcmNoaXZlIGNhbm5vdCBiZSByZWFkIGZvciBvdGhlciByZWFzb25zCisgICAgICovCisgICAgcHVibGljIHZvaWQgZXhwYW5kKGZpbmFsIFNldmVuWkZpbGUgYXJjaGl2ZSwgRmlsZSB0YXJnZXREaXJlY3RvcnkpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgQXJjaGl2ZUV4Y2VwdGlvbiB7CisgICAgICAgIGV4cGFuZChuZXcgQXJjaGl2ZUVudHJ5U3VwcGxpZXIoKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBBcmNoaXZlRW50cnkgZ2V0TmV4dFJlYWRhYmxlRW50cnkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgICAgIHJldHVybiBhcmNoaXZlLmdldE5leHRFbnRyeSgpOworICAgICAgICAgICAgfQorICAgICAgICB9LCBuZXcgRW50cnlXcml0ZXIoKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHdyaXRlRW50cnlEYXRhVG8oQXJjaGl2ZUVudHJ5IGVudHJ5LCBPdXRwdXRTdHJlYW0gb3V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBidWZmZXIgPSBuZXcgYnl0ZVs4MDI0XTsKKyAgICAgICAgICAgICAgICBpbnQgbjsKKyAgICAgICAgICAgICAgICB3aGlsZSAoLTEgIT0gKG4gPSBhcmNoaXZlLnJlYWQoYnVmZmVyKSkpIHsKKyAgICAgICAgICAgICAgICAgICAgb3V0LndyaXRlKGJ1ZmZlciwgMCwgbik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9LCB0YXJnZXREaXJlY3RvcnkpOworICAgIH0KKworICAgIHByaXZhdGUgYm9vbGVhbiBwcmVmZXJzU2Vla2FibGVCeXRlQ2hhbm5lbChTdHJpbmcgZm9ybWF0KSB7CisgICAgICAgIHJldHVybiBBcmNoaXZlU3RyZWFtRmFjdG9yeS5aSVAuZXF1YWxzSWdub3JlQ2FzZShmb3JtYXQpIHx8IEFyY2hpdmVTdHJlYW1GYWN0b3J5LlNFVkVOX1ouZXF1YWxzSWdub3JlQ2FzZShmb3JtYXQpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBleHBhbmQoQXJjaGl2ZUVudHJ5U3VwcGxpZXIgc3VwcGxpZXIsIEVudHJ5V3JpdGVyIHdyaXRlciwgRmlsZSB0YXJnZXREaXJlY3RvcnkpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyB0YXJnZXREaXJQYXRoID0gdGFyZ2V0RGlyZWN0b3J5LmdldENhbm9uaWNhbFBhdGgoKTsKKyAgICAgICAgaWYgKCF0YXJnZXREaXJQYXRoLmVuZHNXaXRoKEZpbGUuc2VwYXJhdG9yKSkgeworICAgICAgICAgICAgdGFyZ2V0RGlyUGF0aCArPSBGaWxlLnNlcGFyYXRvcjsKKyAgICAgICAgfQorICAgICAgICBBcmNoaXZlRW50cnkgbmV4dEVudHJ5ID0gc3VwcGxpZXIuZ2V0TmV4dFJlYWRhYmxlRW50cnkoKTsKKyAgICAgICAgd2hpbGUgKG5leHRFbnRyeSAhPSBudWxsKSB7CisgICAgICAgICAgICBGaWxlIGYgPSBuZXcgRmlsZSh0YXJnZXREaXJlY3RvcnksIG5leHRFbnRyeS5nZXROYW1lKCkpOworICAgICAgICAgICAgaWYgKCFmLmdldENhbm9uaWNhbFBhdGgoKS5zdGFydHNXaXRoKHRhcmdldERpclBhdGgpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJleHBhbmRpbmcgIiArIG5leHRFbnRyeS5nZXROYW1lKCkKKyAgICAgICAgICAgICAgICAgICAgKyAiIHdvdWxkIGNyZWF0ZSBmaWxlIG91dHNpZGUgb2YgIiArIHRhcmdldERpcmVjdG9yeSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAobmV4dEVudHJ5LmlzRGlyZWN0b3J5KCkpIHsKKyAgICAgICAgICAgICAgICBpZiAoIWYuaXNEaXJlY3RvcnkoKSAmJiAhZi5ta2RpcnMoKSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oImZhaWxlZCB0byBjcmVhdGUgZGlyZWN0b3J5ICIgKyBmKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIEZpbGUgcGFyZW50ID0gZi5nZXRQYXJlbnRGaWxlKCk7CisgICAgICAgICAgICAgICAgaWYgKCFwYXJlbnQuaXNEaXJlY3RvcnkoKSAmJiAhcGFyZW50Lm1rZGlycygpKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiZmFpbGVkIHRvIGNyZWF0ZSBkaXJlY3RvcnkgIiArIHBhcmVudCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHRyeSAoT3V0cHV0U3RyZWFtIG8gPSBGaWxlcy5uZXdPdXRwdXRTdHJlYW0oZi50b1BhdGgoKSkpIHsKKyAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlRW50cnlEYXRhVG8obmV4dEVudHJ5LCBvKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBuZXh0RW50cnkgPSBzdXBwbGllci5nZXROZXh0UmVhZGFibGVFbnRyeSgpOworICAgICAgICB9CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvZXhhbXBsZXMvcGFja2FnZS5odG1sIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2V4YW1wbGVzL3BhY2thZ2UuaHRtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40NDNkNWZjCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2V4YW1wbGVzL3BhY2thZ2UuaHRtbApAQCAtMCwwICsxLDI1IEBACis8aHRtbD4KKzwhLS0KKworICAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAgIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAgIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKworICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorCisgICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKworLS0+CisgIDxib2R5PgorICAgIDxwPkNvbnRhaW5zIGV4YW1wbGUgY29kZSB0aGF0IGlzIG5vdCBndWFyYW50ZWVkIHRvIHByb3ZpZGUgYQorICAgICAgc3RhYmxlIEFQSSBhY3Jvc3MgcmVsZWFzZXMgb2YgQ29tbW9ucyBDb21wcmVzcy48L3A+CisKKyAgPC9ib2R5PgorPC9odG1sPgpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2phci9KYXJBcmNoaXZlRW50cnkuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9qYXIvSmFyQXJjaGl2ZUVudHJ5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjBjMDVmMAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9qYXIvSmFyQXJjaGl2ZUVudHJ5LmphdmEKQEAgLTAsMCArMSw5MCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuamFyOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlOworaW1wb3J0IGphdmEudXRpbC5qYXIuQXR0cmlidXRlczsKK2ltcG9ydCBqYXZhLnV0aWwuamFyLkphckVudHJ5OworaW1wb3J0IGphdmEudXRpbC56aXAuWmlwRW50cnk7CitpbXBvcnQgamF2YS51dGlsLnppcC5aaXBFeGNlcHRpb247CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcC5aaXBBcmNoaXZlRW50cnk7CisKKy8qKgorICoKKyAqIEBOb3RUaHJlYWRTYWZlIChwYXJlbnQgaXMgbm90IHRocmVhZC1zYWZlKQorICovCitwdWJsaWMgY2xhc3MgSmFyQXJjaGl2ZUVudHJ5IGV4dGVuZHMgWmlwQXJjaGl2ZUVudHJ5IHsKKworICAgIC8vIFRoZXNlIGFyZSBhbHdheXMgbnVsbCAtIHNlZSBodHRwczovL2lzc3Vlcy5hcGFjaGUub3JnL2ppcmEvYnJvd3NlL0NPTVBSRVNTLTE4IGZvciBkaXNjdXNzaW9uCisgICAgcHJpdmF0ZSBmaW5hbCBBdHRyaWJ1dGVzIG1hbmlmZXN0QXR0cmlidXRlcyA9IG51bGw7CisgICAgcHJpdmF0ZSBmaW5hbCBDZXJ0aWZpY2F0ZVtdIGNlcnRpZmljYXRlcyA9IG51bGw7CisKKyAgICBwdWJsaWMgSmFyQXJjaGl2ZUVudHJ5KGZpbmFsIFppcEVudHJ5IGVudHJ5KSB0aHJvd3MgWmlwRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIoZW50cnkpOworICAgIH0KKworICAgIHB1YmxpYyBKYXJBcmNoaXZlRW50cnkoZmluYWwgU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgc3VwZXIobmFtZSk7CisgICAgfQorCisgICAgcHVibGljIEphckFyY2hpdmVFbnRyeShmaW5hbCBaaXBBcmNoaXZlRW50cnkgZW50cnkpIHRocm93cyBaaXBFeGNlcHRpb24geworICAgICAgICBzdXBlcihlbnRyeSk7CisgICAgfQorCisgICAgcHVibGljIEphckFyY2hpdmVFbnRyeShmaW5hbCBKYXJFbnRyeSBlbnRyeSkgdGhyb3dzIFppcEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyKGVudHJ5KTsKKworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgbWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZCBhbmQgd29uJ3QgZXZlciBiZS4KKyAgICAgKiBUaGUgSlZNIGVxdWl2YWxlbnQgaGFzIGEgZGlmZmVyZW50IG5hbWUge0BsaW5rIGphdmEudXRpbC5qYXIuSmFyRW50cnkjZ2V0QXR0cmlidXRlcygpfQorICAgICAqCisgICAgICogQGRlcHJlY2F0ZWQgc2luY2UgMS41LCBkbyBub3QgdXNlOyBhbHdheXMgcmV0dXJucyBudWxsCisgICAgICogQHJldHVybiBBbHdheXMgcmV0dXJucyBudWxsLgorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIEF0dHJpYnV0ZXMgZ2V0TWFuaWZlc3RBdHRyaWJ1dGVzKCkgeworICAgICAgICByZXR1cm4gbWFuaWZlc3RBdHRyaWJ1dGVzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiBhIGNvcHkgb2YgdGhlIGxpc3Qgb2YgY2VydGlmaWNhdGVzIG9yIG51bGwgaWYgdGhlcmUgYXJlIG5vbmUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIEFsd2F5cyByZXR1cm5zIG51bGwgaW4gdGhlIGN1cnJlbnQgaW1wbGVtZW50YXRpb24KKyAgICAgKgorICAgICAqIEBkZXByZWNhdGVkIHNpbmNlIDEuNSwgbm90IGN1cnJlbnRseSBpbXBsZW1lbnRlZAorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIENlcnRpZmljYXRlW10gZ2V0Q2VydGlmaWNhdGVzKCkgeworICAgICAgICBpZiAoY2VydGlmaWNhdGVzICE9IG51bGwpIHsgLy8gbmV2ZXIgdHJ1ZSBjdXJyZW50bHkgLy8gTk9TT05BUgorICAgICAgICAgICAgZmluYWwgQ2VydGlmaWNhdGVbXSBjZXJ0cyA9IG5ldyBDZXJ0aWZpY2F0ZVtjZXJ0aWZpY2F0ZXMubGVuZ3RoXTsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoY2VydGlmaWNhdGVzLCAwLCBjZXJ0cywgMCwgY2VydHMubGVuZ3RoKTsKKyAgICAgICAgICAgIHJldHVybiBjZXJ0czsKKyAgICAgICAgfQorICAgICAgICAvKgorICAgICAgICAgKiBOb3RlLCB0aGUgbWV0aG9kCisgICAgICAgICAqIENlcnRpZmljYXRlW10gamF2YS51dGlsLmphci5KYXJFbnRyeS5nZXRDZXJ0aWZpY2F0ZXMoKQorICAgICAgICAgKiBhbHNvIHJldHVybnMgbnVsbCBvciB0aGUgbGlzdCBvZiBjZXJ0aWZpY2F0ZXMgKGJ1dCBub3QgY29waWVkKQorICAgICAgICAgKi8KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvamFyL0phckFyY2hpdmVJbnB1dFN0cmVhbS5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2phci9KYXJBcmNoaXZlSW5wdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40N2IxNTgzCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2phci9KYXJBcmNoaXZlSW5wdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDc4IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5qYXI7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLkFyY2hpdmVFbnRyeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcC5aaXBBcmNoaXZlRW50cnk7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXAuWmlwQXJjaGl2ZUlucHV0U3RyZWFtOworCisvKioKKyAqIEltcGxlbWVudHMgYW4gaW5wdXQgc3RyZWFtIHRoYXQgY2FuIHJlYWQgZW50cmllcyBmcm9tIGphciBmaWxlcy4KKyAqCisgKiBATm90VGhyZWFkU2FmZQorICovCitwdWJsaWMgY2xhc3MgSmFyQXJjaGl2ZUlucHV0U3RyZWFtIGV4dGVuZHMgWmlwQXJjaGl2ZUlucHV0U3RyZWFtIHsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gaW5zdGFuY2UgZnJvbSB0aGUgaW5wdXQgc3RyZWFtIHVzaW5nIHRoZSBkZWZhdWx0IGVuY29kaW5nLgorICAgICAqCisgICAgICogQHBhcmFtIGlucHV0U3RyZWFtIHRoZSBpbnB1dCBzdHJlYW0gdG8gd3JhcAorICAgICAqLworICAgIHB1YmxpYyBKYXJBcmNoaXZlSW5wdXRTdHJlYW0oIGZpbmFsIElucHV0U3RyZWFtIGlucHV0U3RyZWFtICkgeworICAgICAgICBzdXBlcihpbnB1dFN0cmVhbSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBmcm9tIHRoZSBpbnB1dCBzdHJlYW0gdXNpbmcgdGhlIHNwZWNpZmllZCBlbmNvZGluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbnB1dFN0cmVhbSB0aGUgaW5wdXQgc3RyZWFtIHRvIHdyYXAKKyAgICAgKiBAcGFyYW0gZW5jb2RpbmcgdGhlIGVuY29kaW5nIHRvIHVzZQorICAgICAqIEBzaW5jZSAxLjEwCisgICAgICovCisgICAgcHVibGljIEphckFyY2hpdmVJbnB1dFN0cmVhbSggZmluYWwgSW5wdXRTdHJlYW0gaW5wdXRTdHJlYW0sIGZpbmFsIFN0cmluZyBlbmNvZGluZyApIHsKKyAgICAgICAgc3VwZXIoaW5wdXRTdHJlYW0sIGVuY29kaW5nKTsKKyAgICB9CisKKyAgICBwdWJsaWMgSmFyQXJjaGl2ZUVudHJ5IGdldE5leHRKYXJFbnRyeSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFppcEFyY2hpdmVFbnRyeSBlbnRyeSA9IGdldE5leHRaaXBFbnRyeSgpOworICAgICAgICByZXR1cm4gZW50cnkgPT0gbnVsbCA/IG51bGwgOiBuZXcgSmFyQXJjaGl2ZUVudHJ5KGVudHJ5KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQXJjaGl2ZUVudHJ5IGdldE5leHRFbnRyeSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBnZXROZXh0SmFyRW50cnkoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgaWYgdGhlIHNpZ25hdHVyZSBtYXRjaGVzIHdoYXQgaXMgZXhwZWN0ZWQgZm9yIGEgamFyIGZpbGUKKyAgICAgKiAoaW4gdGhpcyBjYXNlIGl0IGlzIHRoZSBzYW1lIGFzIGZvciBhIHppcCBmaWxlKS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzaWduYXR1cmUKKyAgICAgKiAgICAgICAgICAgIHRoZSBieXRlcyB0byBjaGVjaworICAgICAqIEBwYXJhbSBsZW5ndGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gY2hlY2sKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoaXMgc3RyZWFtIGlzIGEgamFyIGFyY2hpdmUgc3RyZWFtLCBmYWxzZSBvdGhlcndpc2UKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gbWF0Y2hlcyhmaW5hbCBieXRlW10gc2lnbmF0dXJlLCBmaW5hbCBpbnQgbGVuZ3RoICkgeworICAgICAgICByZXR1cm4gWmlwQXJjaGl2ZUlucHV0U3RyZWFtLm1hdGNoZXMoc2lnbmF0dXJlLCBsZW5ndGgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9qYXIvSmFyQXJjaGl2ZU91dHB1dFN0cmVhbS5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2phci9KYXJBcmNoaXZlT3V0cHV0U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWUyYzdhOAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9qYXIvSmFyQXJjaGl2ZU91dHB1dFN0cmVhbS5qYXZhCkBAIC0wLDAgKzEsNjUgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLmphcjsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLkFyY2hpdmVFbnRyeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcC5KYXJNYXJrZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXAuWmlwQXJjaGl2ZUVudHJ5OworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwLlppcEFyY2hpdmVPdXRwdXRTdHJlYW07CisKKy8qKgorICogU3ViY2xhc3MgdGhhdCBhZGRzIGEgc3BlY2lhbCBleHRyYSBmaWVsZCB0byB0aGUgdmVyeSBmaXJzdCBlbnRyeQorICogd2hpY2ggYWxsb3dzIHRoZSBjcmVhdGVkIGFyY2hpdmUgdG8gYmUgdXNlZCBhcyBhbiBleGVjdXRhYmxlIGphciBvbgorICogU29sYXJpcy4KKyAqCisgKiBATm90VGhyZWFkU2FmZQorICovCitwdWJsaWMgY2xhc3MgSmFyQXJjaGl2ZU91dHB1dFN0cmVhbSBleHRlbmRzIFppcEFyY2hpdmVPdXRwdXRTdHJlYW0geworCisgICAgcHJpdmF0ZSBib29sZWFuIGphck1hcmtlckFkZGVkID0gZmFsc2U7CisKKyAgICBwdWJsaWMgSmFyQXJjaGl2ZU91dHB1dFN0cmVhbShmaW5hbCBPdXRwdXRTdHJlYW0gb3V0KSB7CisgICAgICAgIHN1cGVyKG91dCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlIGFuZCBpbnN0YW5jZSB0aGF0IHdyYXBzIHRoZSBvdXRwdXQgc3RyZWFtIHVzaW5nIHRoZSBwcm92aWRlZCBlbmNvZGluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvdXQgdGhlIG91dHB1dCBzdHJlYW0gdG8gd3JhcAorICAgICAqIEBwYXJhbSBlbmNvZGluZyB0aGUgZW5jb2RpbmcgdG8gdXNlLiBVc2UgbnVsbCBmb3IgdGhlIHBsYXRmb3JtIGRlZmF1bHQuCisgICAgICogQHNpbmNlIDEuMTAKKyAgICAgKi8KKyAgICBwdWJsaWMgSmFyQXJjaGl2ZU91dHB1dFN0cmVhbShmaW5hbCBPdXRwdXRTdHJlYW0gb3V0LCBmaW5hbCBTdHJpbmcgZW5jb2RpbmcpIHsKKyAgICAgICAgc3VwZXIob3V0KTsKKyAgICAgICAgc2V0RW5jb2RpbmcoZW5jb2RpbmcpOworICAgIH0KKworICAgIC8vIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIGlmIGVudHJ5IGlzIG5vdCBhbiBpbnN0YW5jZSBvZiBaaXBBcmNoaXZlRW50cnkKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBwdXRBcmNoaXZlRW50cnkoZmluYWwgQXJjaGl2ZUVudHJ5IHplKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoIWphck1hcmtlckFkZGVkKSB7CisgICAgICAgICAgICAoKFppcEFyY2hpdmVFbnRyeSl6ZSkuYWRkQXNGaXJzdEV4dHJhRmllbGQoSmFyTWFya2VyLmdldEluc3RhbmNlKCkpOworICAgICAgICAgICAgamFyTWFya2VyQWRkZWQgPSB0cnVlOworICAgICAgICB9CisgICAgICAgIHN1cGVyLnB1dEFyY2hpdmVFbnRyeSh6ZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2phci9wYWNrYWdlLmh0bWwgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvamFyL3BhY2thZ2UuaHRtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wOTgyOWFlCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2phci9wYWNrYWdlLmh0bWwKQEAgLTAsMCArMSwyNSBAQAorPGh0bWw+Cis8IS0tCisKKyAgIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAgIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisKKyAgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKworICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAgIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisKKy0tPgorICA8Ym9keT4KKyAgICA8cD5Qcm92aWRlcyBzdHJlYW0gY2xhc3NlcyBmb3IgcmVhZGluZyBhbmQgd3JpdGluZyBhcmNoaXZlcyB1c2luZworICAgICAgdGhlIFpJUCBmb3JtYXQgd2l0aCBzb21lIGV4dGVuc2lvbnMgZm9yIHRoZSBzcGVjaWFsIGNhc2Ugb2YgSkFSCisgICAgICBhcmNoaXZlcy48L3A+CisgIDwvYm9keT4KKzwvaHRtbD4KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9wYWNrYWdlLmh0bWwgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvcGFja2FnZS5odG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRmMTkyMmIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvcGFja2FnZS5odG1sCkBAIC0wLDAgKzEsMjQgQEAKKzxodG1sPgorPCEtLQorCisgICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAgIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAgICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorCisgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisKKyAgIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAgIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAgIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAgIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorCistLT4KKyAgPGJvZHk+CisgICAgPHA+UHJvdmlkZXMgYSB1bmlmaWVkIEFQSSBhbmQgZmFjdG9yaWVzIGZvciBkZWFsaW5nIHdpdGggYXJjaGl2ZXMKKyAgICAgIGluIGRpZmZlcmVudCBmb3JtYXRzLjwvcD4KKyAgPC9ib2R5PgorPC9odG1sPgpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3NldmVuei9BRVMyNTZTSEEyNTZEZWNvZGVyLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvc2V2ZW56L0FFUzI1NlNIQTI1NkRlY29kZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hY2E5Nzc3Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3NldmVuei9BRVMyNTZTSEEyNTZEZWNvZGVyLmphdmEKQEAgLTAsMCArMSwxMTggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5zZXZlbno7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5zZWN1cml0eS5HZW5lcmFsU2VjdXJpdHlFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5NZXNzYWdlRGlnZXN0OworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmF4LmNyeXB0by5DaXBoZXI7CitpbXBvcnQgamF2YXguY3J5cHRvLkNpcGhlcklucHV0U3RyZWFtOworaW1wb3J0IGphdmF4LmNyeXB0by5TZWNyZXRLZXk7CitpbXBvcnQgamF2YXguY3J5cHRvLnNwZWMuSXZQYXJhbWV0ZXJTcGVjOworaW1wb3J0IGphdmF4LmNyeXB0by5zcGVjLlNlY3JldEtleVNwZWM7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLlBhc3N3b3JkUmVxdWlyZWRFeGNlcHRpb247CisKK2NsYXNzIEFFUzI1NlNIQTI1NkRlY29kZXIgZXh0ZW5kcyBDb2RlckJhc2UgeworICAgIEBPdmVycmlkZQorICAgIElucHV0U3RyZWFtIGRlY29kZShmaW5hbCBTdHJpbmcgYXJjaGl2ZU5hbWUsIGZpbmFsIElucHV0U3RyZWFtIGluLCBmaW5hbCBsb25nIHVuY29tcHJlc3NlZExlbmd0aCwKKyAgICAgICAgICAgIGZpbmFsIENvZGVyIGNvZGVyLCBmaW5hbCBieXRlW10gcGFzc3dvcmRCeXRlcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIG5ldyBJbnB1dFN0cmVhbSgpIHsKKyAgICAgICAgICAgIHByaXZhdGUgYm9vbGVhbiBpc0luaXRpYWxpemVkID0gZmFsc2U7CisgICAgICAgICAgICBwcml2YXRlIENpcGhlcklucHV0U3RyZWFtIGNpcGhlcklucHV0U3RyZWFtID0gbnVsbDsKKworICAgICAgICAgICAgcHJpdmF0ZSBDaXBoZXJJbnB1dFN0cmVhbSBpbml0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICBpZiAoaXNJbml0aWFsaXplZCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gY2lwaGVySW5wdXRTdHJlYW07CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGZpbmFsIGludCBieXRlMCA9IDB4ZmYgJiBjb2Rlci5wcm9wZXJ0aWVzWzBdOworICAgICAgICAgICAgICAgIGZpbmFsIGludCBudW1DeWNsZXNQb3dlciA9IGJ5dGUwICYgMHgzZjsKKyAgICAgICAgICAgICAgICBmaW5hbCBpbnQgYnl0ZTEgPSAweGZmICYgY29kZXIucHJvcGVydGllc1sxXTsKKyAgICAgICAgICAgICAgICBmaW5hbCBpbnQgaXZTaXplID0gKChieXRlMCA+PiA2KSAmIDEpICsgKGJ5dGUxICYgMHgwZik7CisgICAgICAgICAgICAgICAgZmluYWwgaW50IHNhbHRTaXplID0gKChieXRlMCA+PiA3KSAmIDEpICsgKGJ5dGUxID4+IDQpOworICAgICAgICAgICAgICAgIGlmICgyICsgc2FsdFNpemUgKyBpdlNpemUgPiBjb2Rlci5wcm9wZXJ0aWVzLmxlbmd0aCkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlNhbHQgc2l6ZSArIElWIHNpemUgdG9vIGxvbmcgaW4gIiArIGFyY2hpdmVOYW1lKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZmluYWwgYnl0ZVtdIHNhbHQgPSBuZXcgYnl0ZVtzYWx0U2l6ZV07CisgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShjb2Rlci5wcm9wZXJ0aWVzLCAyLCBzYWx0LCAwLCBzYWx0U2l6ZSk7CisgICAgICAgICAgICAgICAgZmluYWwgYnl0ZVtdIGl2ID0gbmV3IGJ5dGVbMTZdOworICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoY29kZXIucHJvcGVydGllcywgMiArIHNhbHRTaXplLCBpdiwgMCwgaXZTaXplKTsKKworICAgICAgICAgICAgICAgIGlmIChwYXNzd29yZEJ5dGVzID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFBhc3N3b3JkUmVxdWlyZWRFeGNlcHRpb24oYXJjaGl2ZU5hbWUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBmaW5hbCBieXRlW10gYWVzS2V5Qnl0ZXM7CisgICAgICAgICAgICAgICAgaWYgKG51bUN5Y2xlc1Bvd2VyID09IDB4M2YpIHsKKyAgICAgICAgICAgICAgICAgICAgYWVzS2V5Qnl0ZXMgPSBuZXcgYnl0ZVszMl07CisgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoc2FsdCwgMCwgYWVzS2V5Qnl0ZXMsIDAsIHNhbHRTaXplKTsKKyAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShwYXNzd29yZEJ5dGVzLCAwLCBhZXNLZXlCeXRlcywgc2FsdFNpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWF0aC5taW4ocGFzc3dvcmRCeXRlcy5sZW5ndGgsIGFlc0tleUJ5dGVzLmxlbmd0aCAtIHNhbHRTaXplKSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgTWVzc2FnZURpZ2VzdCBkaWdlc3Q7CisgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICBkaWdlc3QgPSBNZXNzYWdlRGlnZXN0LmdldEluc3RhbmNlKCJTSEEtMjU2Iik7CisgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGZpbmFsIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBub1N1Y2hBbGdvcml0aG1FeGNlcHRpb24pIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiU0hBLTI1NiBpcyB1bnN1cHBvcnRlZCBieSB5b3VyIEphdmEgaW1wbGVtZW50YXRpb24iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbik7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgZmluYWwgYnl0ZVtdIGV4dHJhID0gbmV3IGJ5dGVbOF07CisgICAgICAgICAgICAgICAgICAgIGZvciAobG9uZyBqID0gMDsgaiA8ICgxTCA8PCBudW1DeWNsZXNQb3dlcik7IGorKykgeworICAgICAgICAgICAgICAgICAgICAgICAgZGlnZXN0LnVwZGF0ZShzYWx0KTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGRpZ2VzdC51cGRhdGUocGFzc3dvcmRCeXRlcyk7CisgICAgICAgICAgICAgICAgICAgICAgICBkaWdlc3QudXBkYXRlKGV4dHJhKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGsgPSAwOyBrIDwgZXh0cmEubGVuZ3RoOyBrKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICArK2V4dHJhW2tdOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChleHRyYVtrXSAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBhZXNLZXlCeXRlcyA9IGRpZ2VzdC5kaWdlc3QoKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBmaW5hbCBTZWNyZXRLZXkgYWVzS2V5ID0gbmV3IFNlY3JldEtleVNwZWMoYWVzS2V5Qnl0ZXMsICJBRVMiKTsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBmaW5hbCBDaXBoZXIgY2lwaGVyID0gQ2lwaGVyLmdldEluc3RhbmNlKCJBRVMvQ0JDL05vUGFkZGluZyIpOworICAgICAgICAgICAgICAgICAgICBjaXBoZXIuaW5pdChDaXBoZXIuREVDUllQVF9NT0RFLCBhZXNLZXksIG5ldyBJdlBhcmFtZXRlclNwZWMoaXYpKTsKKyAgICAgICAgICAgICAgICAgICAgY2lwaGVySW5wdXRTdHJlYW0gPSBuZXcgQ2lwaGVySW5wdXRTdHJlYW0oaW4sIGNpcGhlcik7CisgICAgICAgICAgICAgICAgICAgIGlzSW5pdGlhbGl6ZWQgPSB0cnVlOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gY2lwaGVySW5wdXRTdHJlYW07CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoZmluYWwgR2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9uIGdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbikgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkRlY3J5cHRpb24gZXJyb3IgIiArCisgICAgICAgICAgICAgICAgICAgICAgICAiKGRvIHlvdSBoYXZlIHRoZSBKQ0UgVW5saW1pdGVkIFN0cmVuZ3RoIEp1cmlzZGljdGlvbiBQb2xpY3kgRmlsZXMgaW5zdGFsbGVkPykiLAorICAgICAgICAgICAgICAgICAgICAgICAgZ2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9uKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGluaXQoKS5yZWFkKCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIGludCByZWFkKGZpbmFsIGJ5dGVbXSBiLCBmaW5hbCBpbnQgb2ZmLCBmaW5hbCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgICAgIHJldHVybiBpbml0KCkucmVhZChiLCBvZmYsIGxlbik7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIHZvaWQgY2xvc2UoKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH07CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3NldmVuei9BcmNoaXZlLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvc2V2ZW56L0FyY2hpdmUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kZDFjNzVhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3NldmVuei9BcmNoaXZlLmphdmEKQEAgLTAsMCArMSw1NSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICoKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnNldmVuejsKKworaW1wb3J0IGphdmEudXRpbC5CaXRTZXQ7CisKK2NsYXNzIEFyY2hpdmUgeworICAgIC8vLyBPZmZzZXQgZnJvbSBiZWdpbm5pbmcgb2YgZmlsZSArIFNJR05BVFVSRV9IRUFERVJfU0laRSB0byBwYWNrZWQgc3RyZWFtcy4KKyAgICBsb25nIHBhY2tQb3M7CisgICAgLy8vIFNpemUgb2YgZWFjaCBwYWNrZWQgc3RyZWFtLgorICAgIGxvbmdbXSBwYWNrU2l6ZXM7CisgICAgLy8vIFdoZXRoZXIgZWFjaCBwYXJ0aWN1bGFyIHBhY2tlZCBzdHJlYW1zIGhhcyBhIENSQy4KKyAgICBCaXRTZXQgcGFja0NyY3NEZWZpbmVkOworICAgIC8vLyBDUkNzIGZvciBlYWNoIHBhY2tlZCBzdHJlYW0sIHZhbGlkIG9ubHkgaWYgdGhhdCBwYWNrZWQgc3RyZWFtIGhhcyBvbmUuCisgICAgbG9uZ1tdIHBhY2tDcmNzOworICAgIC8vLyBQcm9wZXJ0aWVzIG9mIHNvbGlkIGNvbXByZXNzaW9uIGJsb2Nrcy4KKyAgICBGb2xkZXJbXSBmb2xkZXJzOworICAgIC8vLyBUZW1wb3JhcnkgcHJvcGVydGllcyBmb3Igbm9uLWVtcHR5IGZpbGVzIChzdWJzdW1lZCBpbnRvIHRoZSBmaWxlcyBhcnJheSBsYXRlcikuCisgICAgU3ViU3RyZWFtc0luZm8gc3ViU3RyZWFtc0luZm87CisgICAgLy8vIFRoZSBmaWxlcyBhbmQgZGlyZWN0b3JpZXMgaW4gdGhlIGFyY2hpdmUuCisgICAgU2V2ZW5aQXJjaGl2ZUVudHJ5W10gZmlsZXM7CisgICAgLy8vIE1hcHBpbmcgYmV0d2VlbiBmb2xkZXJzLCBmaWxlcyBhbmQgc3RyZWFtcy4KKyAgICBTdHJlYW1NYXAgc3RyZWFtTWFwOworCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuICJBcmNoaXZlIHdpdGggcGFja2VkIHN0cmVhbXMgc3RhcnRpbmcgYXQgb2Zmc2V0ICIgKyBwYWNrUG9zCisgICAgICAgICAgICArICIsICIgKyBsZW5ndGhPZihwYWNrU2l6ZXMpICsgIiBwYWNrIHNpemVzLCAiICsgbGVuZ3RoT2YocGFja0NyY3MpCisgICAgICAgICAgICArICIgQ1JDcywgIiArIGxlbmd0aE9mKGZvbGRlcnMpICsgIiBmb2xkZXJzLCAiICsgbGVuZ3RoT2YoZmlsZXMpCisgICAgICAgICAgICArICIgZmlsZXMgYW5kICIgKyBzdHJlYW1NYXA7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGxlbmd0aE9mKGZpbmFsIGxvbmdbXSBhKSB7CisgICAgICAgIHJldHVybiBhID09IG51bGwgPyAiKG51bGwpIiA6IFN0cmluZy52YWx1ZU9mKGEubGVuZ3RoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgbGVuZ3RoT2YoZmluYWwgT2JqZWN0W10gYSkgeworICAgICAgICByZXR1cm4gYSA9PSBudWxsID8gIihudWxsKSIgOiBTdHJpbmcudmFsdWVPZihhLmxlbmd0aCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3NldmVuei9CaW5kUGFpci5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3NldmVuei9CaW5kUGFpci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI3MTBiNzIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvc2V2ZW56L0JpbmRQYWlyLmphdmEKQEAgLTAsMCArMSwyOCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICoKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnNldmVuejsKKworY2xhc3MgQmluZFBhaXIgeworICAgIGxvbmcgaW5JbmRleDsKKyAgICBsb25nIG91dEluZGV4OworCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuICJCaW5kUGFpciBiaW5kaW5nIGlucHV0ICIgKyBpbkluZGV4ICsgIiB0byBvdXRwdXQgIiArIG91dEluZGV4OworICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9zZXZlbnovQm91bmRlZFNlZWthYmxlQnl0ZUNoYW5uZWxJbnB1dFN0cmVhbS5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3NldmVuei9Cb3VuZGVkU2Vla2FibGVCeXRlQ2hhbm5lbElucHV0U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzJiM2JkYQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9zZXZlbnovQm91bmRlZFNlZWthYmxlQnl0ZUNoYW5uZWxJbnB1dFN0cmVhbS5qYXZhCkBAIC0wLDAgKzEsOTIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5zZXZlbno7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5TZWVrYWJsZUJ5dGVDaGFubmVsOworCitjbGFzcyBCb3VuZGVkU2Vla2FibGVCeXRlQ2hhbm5lbElucHV0U3RyZWFtIGV4dGVuZHMgSW5wdXRTdHJlYW0geworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNQVhfQlVGX0xFTiA9IDgxOTI7CisgICAgcHJpdmF0ZSBmaW5hbCBCeXRlQnVmZmVyIGJ1ZmZlcjsKKyAgICBwcml2YXRlIGZpbmFsIFNlZWthYmxlQnl0ZUNoYW5uZWwgY2hhbm5lbDsKKyAgICBwcml2YXRlIGxvbmcgYnl0ZXNSZW1haW5pbmc7CisKKyAgICBwdWJsaWMgQm91bmRlZFNlZWthYmxlQnl0ZUNoYW5uZWxJbnB1dFN0cmVhbShmaW5hbCBTZWVrYWJsZUJ5dGVDaGFubmVsIGNoYW5uZWwsCisgICAgICAgICAgICBmaW5hbCBsb25nIHNpemUpIHsKKyAgICAgICAgdGhpcy5jaGFubmVsID0gY2hhbm5lbDsKKyAgICAgICAgdGhpcy5ieXRlc1JlbWFpbmluZyA9IHNpemU7CisgICAgICAgIGlmIChzaXplIDwgTUFYX0JVRl9MRU4gJiYgc2l6ZSA+IDApIHsKKyAgICAgICAgICAgIGJ1ZmZlciA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUoKGludCkgc2l6ZSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBidWZmZXIgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKE1BWF9CVUZfTEVOKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChieXRlc1JlbWFpbmluZyA+IDApIHsKKyAgICAgICAgICAgIC0tYnl0ZXNSZW1haW5pbmc7CisgICAgICAgICAgICBpbnQgcmVhZCA9IHJlYWQoMSk7CisgICAgICAgICAgICBpZiAocmVhZCA8IDApIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gcmVhZDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBidWZmZXIuZ2V0KCkgJiAweGZmOworICAgICAgICB9CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHJlYWQoZmluYWwgYnl0ZVtdIGIsIGZpbmFsIGludCBvZmYsIGZpbmFsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChieXRlc1JlbWFpbmluZyA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICAgICAgaW50IGJ5dGVzVG9SZWFkID0gbGVuOworICAgICAgICBpZiAoYnl0ZXNUb1JlYWQgPiBieXRlc1JlbWFpbmluZykgeworICAgICAgICAgICAgYnl0ZXNUb1JlYWQgPSAoaW50KSBieXRlc1JlbWFpbmluZzsKKyAgICAgICAgfQorICAgICAgICBpbnQgYnl0ZXNSZWFkOworICAgICAgICBCeXRlQnVmZmVyIGJ1ZjsKKyAgICAgICAgaWYgKGJ5dGVzVG9SZWFkIDw9IGJ1ZmZlci5jYXBhY2l0eSgpKSB7CisgICAgICAgICAgICBidWYgPSBidWZmZXI7CisgICAgICAgICAgICBieXRlc1JlYWQgPSByZWFkKGJ5dGVzVG9SZWFkKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGJ1ZiA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUoYnl0ZXNUb1JlYWQpOworICAgICAgICAgICAgYnl0ZXNSZWFkID0gY2hhbm5lbC5yZWFkKGJ1Zik7CisgICAgICAgICAgICBidWYuZmxpcCgpOworICAgICAgICB9CisgICAgICAgIGlmIChieXRlc1JlYWQgPj0gMCkgeworICAgICAgICAgICAgYnVmLmdldChiLCBvZmYsIGJ5dGVzUmVhZCk7CisgICAgICAgICAgICBieXRlc1JlbWFpbmluZyAtPSBieXRlc1JlYWQ7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGJ5dGVzUmVhZDsKKyAgICB9CisKKyAgICBwcml2YXRlIGludCByZWFkKGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJ1ZmZlci5yZXdpbmQoKS5saW1pdChsZW4pOworICAgICAgICBpbnQgcmVhZCA9IGNoYW5uZWwucmVhZChidWZmZXIpOworICAgICAgICBidWZmZXIuZmxpcCgpOworICAgICAgICByZXR1cm4gcmVhZDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHsKKyAgICAgICAgLy8gdGhlIG5lc3RlZCBjaGFubmVsIGlzIGNvbnRyb2xsZWQgZXh0ZXJuYWxseQorICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9zZXZlbnovQ0xJLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvc2V2ZW56L0NMSS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE0MGYyYjMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvc2V2ZW56L0NMSS5qYXZhCkBAIC0wLDAgKzEsMTQ2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuc2V2ZW56OworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCitwdWJsaWMgY2xhc3MgQ0xJIHsKKworCisgICAgcHJpdmF0ZSBlbnVtIE1vZGUgeworICAgICAgICBMSVNUKCJBbmFseXNpbmciKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHRha2VBY3Rpb24oZmluYWwgU2V2ZW5aRmlsZSBhcmNoaXZlLCBmaW5hbCBTZXZlblpBcmNoaXZlRW50cnkgZW50cnkpIHsKKyAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KGVudHJ5LmdldE5hbWUoKSk7CisgICAgICAgICAgICAgICAgaWYgKGVudHJ5LmlzRGlyZWN0b3J5KCkpIHsKKyAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiIGRpciIpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIiAiICsgZW50cnkuZ2V0Q29tcHJlc3NlZFNpemUoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIi8iICsgZW50cnkuZ2V0U2l6ZSgpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKGVudHJ5LmdldEhhc0xhc3RNb2RpZmllZERhdGUoKSkgeworICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIgIiArIGVudHJ5LmdldExhc3RNb2RpZmllZERhdGUoKSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiIG5vIGxhc3QgbW9kaWZpZWQgZGF0ZSIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoIWVudHJ5LmlzRGlyZWN0b3J5KCkpIHsKKyAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCIgIiArIGdldENvbnRlbnRNZXRob2RzKGVudHJ5KSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCIiKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHByaXZhdGUgU3RyaW5nIGdldENvbnRlbnRNZXRob2RzKGZpbmFsIFNldmVuWkFyY2hpdmVFbnRyeSBlbnRyeSkgeworICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICAgICAgICAgIGJvb2xlYW4gZmlyc3QgPSB0cnVlOworICAgICAgICAgICAgICAgIGZvciAoZmluYWwgU2V2ZW5aTWV0aG9kQ29uZmlndXJhdGlvbiBtIDogZW50cnkuZ2V0Q29udGVudE1ldGhvZHMoKSkgeworICAgICAgICAgICAgICAgICAgICBpZiAoIWZpcnN0KSB7CisgICAgICAgICAgICAgICAgICAgICAgICBzYi5hcHBlbmQoIiwgIik7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgc2IuYXBwZW5kKG0uZ2V0TWV0aG9kKCkpOworICAgICAgICAgICAgICAgICAgICBpZiAobS5nZXRPcHRpb25zKCkgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgc2IuYXBwZW5kKCIoIikuYXBwZW5kKG0uZ2V0T3B0aW9ucygpKS5hcHBlbmQoIikiKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSwKKyAgICAgICAgRVhUUkFDVCgiRXh0cmFjdGluZyIpIHsKKyAgICAgICAgICAgIHByaXZhdGUgZmluYWwgYnl0ZVtdIGJ1ZiA9IG5ldyBieXRlWzgxOTJdOworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgdm9pZCB0YWtlQWN0aW9uKGZpbmFsIFNldmVuWkZpbGUgYXJjaGl2ZSwgZmluYWwgU2V2ZW5aQXJjaGl2ZUVudHJ5IGVudHJ5KQorICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgZmluYWwgRmlsZSBvdXRGaWxlID0gbmV3IEZpbGUoZW50cnkuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgICAgICBpZiAoZW50cnkuaXNEaXJlY3RvcnkoKSkgeworICAgICAgICAgICAgICAgICAgICBpZiAoIW91dEZpbGUuaXNEaXJlY3RvcnkoKSAmJiAhb3V0RmlsZS5ta2RpcnMoKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJDYW5ub3QgY3JlYXRlIGRpcmVjdG9yeSAiICsgb3V0RmlsZSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJjcmVhdGVkIGRpcmVjdG9yeSAiICsgb3V0RmlsZSk7CisgICAgICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oImV4dHJhY3RpbmcgdG8gIiArIG91dEZpbGUpOworICAgICAgICAgICAgICAgIGZpbmFsIEZpbGUgcGFyZW50ID0gb3V0RmlsZS5nZXRQYXJlbnRGaWxlKCk7CisgICAgICAgICAgICAgICAgaWYgKHBhcmVudCAhPSBudWxsICYmICFwYXJlbnQuZXhpc3RzKCkgJiYgIXBhcmVudC5ta2RpcnMoKSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkNhbm5vdCBjcmVhdGUgIiArIHBhcmVudCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHRyeSAoZmluYWwgRmlsZU91dHB1dFN0cmVhbSBmb3MgPSBuZXcgRmlsZU91dHB1dFN0cmVhbShvdXRGaWxlKSkgeworICAgICAgICAgICAgICAgICAgICBmaW5hbCBsb25nIHRvdGFsID0gZW50cnkuZ2V0U2l6ZSgpOworICAgICAgICAgICAgICAgICAgICBsb25nIG9mZiA9IDA7CisgICAgICAgICAgICAgICAgICAgIHdoaWxlIChvZmYgPCB0b3RhbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IHRvUmVhZCA9IChpbnQpIE1hdGgubWluKHRvdGFsIC0gb2ZmLCBidWYubGVuZ3RoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBieXRlc1JlYWQgPSBhcmNoaXZlLnJlYWQoYnVmLCAwLCB0b1JlYWQpOworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJ5dGVzUmVhZCA8IDEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oInJlYWNoZWQgZW5kIG9mIGVudHJ5ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBlbnRyeS5nZXROYW1lKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIGFmdGVyICIgKyBvZmYKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIGJ5dGVzLCBleHBlY3RlZCAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgdG90YWwpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgb2ZmICs9IGJ5dGVzUmVhZDsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZvcy53cml0ZShidWYsIDAsIGJ5dGVzUmVhZCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH07CisKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgbWVzc2FnZTsKKyAgICAgICAgTW9kZShmaW5hbCBTdHJpbmcgbWVzc2FnZSkgeworICAgICAgICAgICAgdGhpcy5tZXNzYWdlID0gbWVzc2FnZTsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgU3RyaW5nIGdldE1lc3NhZ2UoKSB7CisgICAgICAgICAgICByZXR1cm4gbWVzc2FnZTsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCB0YWtlQWN0aW9uKFNldmVuWkZpbGUgYXJjaGl2ZSwgU2V2ZW5aQXJjaGl2ZUVudHJ5IGVudHJ5KQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBpZiAoYXJncy5sZW5ndGggPT0gMCkgeworICAgICAgICAgICAgdXNhZ2UoKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBmaW5hbCBNb2RlIG1vZGUgPSBncmFiTW9kZShhcmdzKTsKKyAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKG1vZGUuZ2V0TWVzc2FnZSgpICsgIiAiICsgYXJnc1swXSk7CisgICAgICAgIGZpbmFsIEZpbGUgZiA9IG5ldyBGaWxlKGFyZ3NbMF0pOworICAgICAgICBpZiAoIWYuaXNGaWxlKCkpIHsKKyAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbihmICsgIiBkb2Vzbid0IGV4aXN0IG9yIGlzIGEgZGlyZWN0b3J5Iik7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IChmaW5hbCBTZXZlblpGaWxlIGFyY2hpdmUgPSBuZXcgU2V2ZW5aRmlsZShmKSkgeworICAgICAgICAgICAgU2V2ZW5aQXJjaGl2ZUVudHJ5IGFlOworICAgICAgICAgICAgd2hpbGUoKGFlPWFyY2hpdmUuZ2V0TmV4dEVudHJ5KCkpICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBtb2RlLnRha2VBY3Rpb24oYXJjaGl2ZSwgYWUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCB1c2FnZSgpIHsKKyAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJQYXJhbWV0ZXJzOiBhcmNoaXZlLW5hbWUgW2xpc3R8ZXh0cmFjdF0iKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBNb2RlIGdyYWJNb2RlKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgaWYgKGFyZ3MubGVuZ3RoIDwgMikgeworICAgICAgICAgICAgcmV0dXJuIE1vZGUuTElTVDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gRW51bS52YWx1ZU9mKE1vZGUuY2xhc3MsIGFyZ3NbMV0udG9VcHBlckNhc2UoKSk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvc2V2ZW56L0NvZGVyLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvc2V2ZW56L0NvZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2JkMjcxZAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9zZXZlbnovQ29kZXIuamF2YQpAQCAtMCwwICsxLDI1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuc2V2ZW56OworCitjbGFzcyBDb2RlciB7CisgICAgYnl0ZVtdIGRlY29tcHJlc3Npb25NZXRob2RJZDsKKyAgICBsb25nIG51bUluU3RyZWFtczsKKyAgICBsb25nIG51bU91dFN0cmVhbXM7CisgICAgYnl0ZVtdIHByb3BlcnRpZXMgPSBudWxsOworfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3NldmVuei9Db2RlckJhc2UuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9zZXZlbnovQ29kZXJCYXNlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzg0MjUxMwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9zZXZlbnovQ29kZXJCYXNlLmphdmEKQEAgLTAsMCArMSw4NSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICoKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnNldmVuejsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKKworLyoqCisgKiBCYXNlIENvZGVjIGNsYXNzLgorICovCithYnN0cmFjdCBjbGFzcyBDb2RlckJhc2UgeworICAgIHByaXZhdGUgZmluYWwgQ2xhc3M8Pz5bXSBhY2NlcHRhYmxlT3B0aW9uczsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gTk9ORSA9IG5ldyBieXRlWzBdOworCisgICAgLyoqCisgICAgICogQHBhcmFtIGFjY2VwdGFibGVPcHRpb25zIHR5cGVzIHRoYXQgY2FuIGJlIHVzZWQgYXMgb3B0aW9ucyBmb3IgdGhpcyBjb2RlYy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgQ29kZXJCYXNlKGZpbmFsIENsYXNzPD8+Li4uIGFjY2VwdGFibGVPcHRpb25zKSB7CisgICAgICAgIHRoaXMuYWNjZXB0YWJsZU9wdGlvbnMgPSBhY2NlcHRhYmxlT3B0aW9uczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcmV0dXJuIHdoZXRoZXIgdGhpcyBtZXRob2QgY2FuIGV4dHJhY3Qgb3B0aW9ucyBmcm9tIHRoZSBnaXZlbiBvYmplY3QuCisgICAgICovCisgICAgYm9vbGVhbiBjYW5BY2NlcHRPcHRpb25zKGZpbmFsIE9iamVjdCBvcHRzKSB7CisgICAgICAgIGZvciAoZmluYWwgQ2xhc3M8Pz4gYyA6IGFjY2VwdGFibGVPcHRpb25zKSB7CisgICAgICAgICAgICBpZiAoYy5pc0luc3RhbmNlKG9wdHMpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEByZXR1cm4gcHJvcGVydHktYnl0ZXMgdG8gd3JpdGUgaW4gYSBGb2xkZXIgYmxvY2sKKyAgICAgKi8KKyAgICBieXRlW10gZ2V0T3B0aW9uc0FzUHJvcGVydGllcyhmaW5hbCBPYmplY3Qgb3B0aW9ucykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIE5PTkU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHJldHVybiBjb25maWd1cmF0aW9uIG9wdGlvbnMgdGhhdCBoYXZlIGJlZW4gdXNlZCB0byBjcmVhdGUgdGhlIGdpdmVuIElucHV0U3RyZWFtIGZyb20gdGhlIGdpdmVuIENvZGVyCisgICAgICovCisgICAgT2JqZWN0IGdldE9wdGlvbnNGcm9tQ29kZXIoZmluYWwgQ29kZXIgY29kZXIsIGZpbmFsIElucHV0U3RyZWFtIGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcmV0dXJuIGEgc3RyZWFtIHRoYXQgcmVhZHMgZnJvbSBpbiB1c2luZyB0aGUgY29uZmlndXJlZCBjb2RlciBhbmQgcGFzc3dvcmQuCisgICAgICovCisgICAgYWJzdHJhY3QgSW5wdXRTdHJlYW0gZGVjb2RlKGZpbmFsIFN0cmluZyBhcmNoaXZlTmFtZSwKKyAgICAgICAgZmluYWwgSW5wdXRTdHJlYW0gaW4sIGxvbmcgdW5jb21yZXNzZWRMZW5ndGgsCisgICAgICAgIGZpbmFsIENvZGVyIGNvZGVyLCBieXRlW10gcGFzc3dvcmQpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEByZXR1cm4gYSBzdHJlYW0gdGhhdCB3cml0ZXMgdG8gb3V0IHVzaW5nIHRoZSBnaXZlbiBjb25maWd1cmF0aW9uLgorICAgICAqLworICAgIE91dHB1dFN0cmVhbSBlbmNvZGUoZmluYWwgT3V0cHV0U3RyZWFtIG91dCwgZmluYWwgT2JqZWN0IG9wdGlvbnMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigibWV0aG9kIGRvZXNuJ3Qgc3VwcG9ydCB3cml0aW5nIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogSWYgdGhlIG9wdGlvbiByZXByZXNlbnRzIGEgbnVtYmVyLCByZXR1cm4gaXRzIGludGVnZXIKKyAgICAgKiB2YWx1ZSwgb3RoZXJ3aXNlIHJldHVybiB0aGUgZ2l2ZW4gZGVmYXVsdCB2YWx1ZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgc3RhdGljIGludCBudW1iZXJPcHRpb25PckRlZmF1bHQoZmluYWwgT2JqZWN0IG9wdGlvbnMsIGZpbmFsIGludCBkZWZhdWx0VmFsdWUpIHsKKyAgICAgICAgcmV0dXJuIG9wdGlvbnMgaW5zdGFuY2VvZiBOdW1iZXIgPyAoKE51bWJlcikgb3B0aW9ucykuaW50VmFsdWUoKSA6IGRlZmF1bHRWYWx1ZTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvc2V2ZW56L0NvZGVycy5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3NldmVuei9Db2RlcnMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43MjlhMWEzCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3NldmVuei9Db2RlcnMuamF2YQpAQCAtMCwwICsxLDI2NCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICoKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnNldmVuejsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uU2VxdWVuY2VJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLnppcC5EZWZsYXRlcjsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLkRlZmxhdGVyT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC56aXAuSW5mbGF0ZXI7CitpbXBvcnQgamF2YS51dGlsLnppcC5JbmZsYXRlcklucHV0U3RyZWFtOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLmJ6aXAyLkJaaXAyQ29tcHJlc3NvcklucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5iemlwMi5CWmlwMkNvbXByZXNzb3JPdXRwdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLmRlZmxhdGU2NC5EZWZsYXRlNjRDb21wcmVzc29ySW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLkZsdXNoU2hpZWxkRmlsdGVyT3V0cHV0U3RyZWFtOworaW1wb3J0IG9yZy50dWthYW5pLnh6LkFSTU9wdGlvbnM7CitpbXBvcnQgb3JnLnR1a2FhbmkueHouQVJNVGh1bWJPcHRpb25zOworaW1wb3J0IG9yZy50dWthYW5pLnh6LkZpbHRlck9wdGlvbnM7CitpbXBvcnQgb3JnLnR1a2FhbmkueHouRmluaXNoYWJsZVdyYXBwZXJPdXRwdXRTdHJlYW07CitpbXBvcnQgb3JnLnR1a2FhbmkueHouSUE2NE9wdGlvbnM7CitpbXBvcnQgb3JnLnR1a2FhbmkueHouUG93ZXJQQ09wdGlvbnM7CitpbXBvcnQgb3JnLnR1a2FhbmkueHouU1BBUkNPcHRpb25zOworaW1wb3J0IG9yZy50dWthYW5pLnh6Llg4Nk9wdGlvbnM7CisKK2NsYXNzIENvZGVycyB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTWFwPFNldmVuWk1ldGhvZCwgQ29kZXJCYXNlPiBDT0RFUl9NQVAgPSBuZXcgSGFzaE1hcDxTZXZlblpNZXRob2QsIENvZGVyQmFzZT4oKSB7CisKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMTY2NDgyOTEzMTgwNjUyMDg2N0w7CisgICAgeworICAgICAgICAgICAgcHV0KFNldmVuWk1ldGhvZC5DT1BZLCBuZXcgQ29weURlY29kZXIoKSk7CisgICAgICAgICAgICBwdXQoU2V2ZW5aTWV0aG9kLkxaTUEsIG5ldyBMWk1BRGVjb2RlcigpKTsKKyAgICAgICAgICAgIHB1dChTZXZlblpNZXRob2QuTFpNQTIsIG5ldyBMWk1BMkRlY29kZXIoKSk7CisgICAgICAgICAgICBwdXQoU2V2ZW5aTWV0aG9kLkRFRkxBVEUsIG5ldyBEZWZsYXRlRGVjb2RlcigpKTsKKyAgICAgICAgICAgIHB1dChTZXZlblpNZXRob2QuREVGTEFURTY0LCBuZXcgRGVmbGF0ZTY0RGVjb2RlcigpKTsKKyAgICAgICAgICAgIHB1dChTZXZlblpNZXRob2QuQlpJUDIsIG5ldyBCWklQMkRlY29kZXIoKSk7CisgICAgICAgICAgICBwdXQoU2V2ZW5aTWV0aG9kLkFFUzI1NlNIQTI1NiwgbmV3IEFFUzI1NlNIQTI1NkRlY29kZXIoKSk7CisgICAgICAgICAgICBwdXQoU2V2ZW5aTWV0aG9kLkJDSl9YODZfRklMVEVSLCBuZXcgQkNKRGVjb2RlcihuZXcgWDg2T3B0aW9ucygpKSk7CisgICAgICAgICAgICBwdXQoU2V2ZW5aTWV0aG9kLkJDSl9QUENfRklMVEVSLCBuZXcgQkNKRGVjb2RlcihuZXcgUG93ZXJQQ09wdGlvbnMoKSkpOworICAgICAgICAgICAgcHV0KFNldmVuWk1ldGhvZC5CQ0pfSUE2NF9GSUxURVIsIG5ldyBCQ0pEZWNvZGVyKG5ldyBJQTY0T3B0aW9ucygpKSk7CisgICAgICAgICAgICBwdXQoU2V2ZW5aTWV0aG9kLkJDSl9BUk1fRklMVEVSLCBuZXcgQkNKRGVjb2RlcihuZXcgQVJNT3B0aW9ucygpKSk7CisgICAgICAgICAgICBwdXQoU2V2ZW5aTWV0aG9kLkJDSl9BUk1fVEhVTUJfRklMVEVSLCBuZXcgQkNKRGVjb2RlcihuZXcgQVJNVGh1bWJPcHRpb25zKCkpKTsKKyAgICAgICAgICAgIHB1dChTZXZlblpNZXRob2QuQkNKX1NQQVJDX0ZJTFRFUiwgbmV3IEJDSkRlY29kZXIobmV3IFNQQVJDT3B0aW9ucygpKSk7CisgICAgICAgICAgICBwdXQoU2V2ZW5aTWV0aG9kLkRFTFRBX0ZJTFRFUiwgbmV3IERlbHRhRGVjb2RlcigpKTsKKyAgICAgICAgfX07CisKKyAgICBzdGF0aWMgQ29kZXJCYXNlIGZpbmRCeU1ldGhvZChmaW5hbCBTZXZlblpNZXRob2QgbWV0aG9kKSB7CisgICAgICAgIHJldHVybiBDT0RFUl9NQVAuZ2V0KG1ldGhvZCk7CisgICAgfQorCisgICAgc3RhdGljIElucHV0U3RyZWFtIGFkZERlY29kZXIoZmluYWwgU3RyaW5nIGFyY2hpdmVOYW1lLCBmaW5hbCBJbnB1dFN0cmVhbSBpcywgZmluYWwgbG9uZyB1bmNvbXByZXNzZWRMZW5ndGgsCisgICAgICAgICAgICBmaW5hbCBDb2RlciBjb2RlciwgZmluYWwgYnl0ZVtdIHBhc3N3b3JkKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBDb2RlckJhc2UgY2IgPSBmaW5kQnlNZXRob2QoU2V2ZW5aTWV0aG9kLmJ5SWQoY29kZXIuZGVjb21wcmVzc2lvbk1ldGhvZElkKSk7CisgICAgICAgIGlmIChjYiA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlVuc3VwcG9ydGVkIGNvbXByZXNzaW9uIG1ldGhvZCAiICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBcnJheXMudG9TdHJpbmcoY29kZXIuZGVjb21wcmVzc2lvbk1ldGhvZElkKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiB1c2VkIGluICIgKyBhcmNoaXZlTmFtZSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGNiLmRlY29kZShhcmNoaXZlTmFtZSwgaXMsIHVuY29tcHJlc3NlZExlbmd0aCwgY29kZXIsIHBhc3N3b3JkKTsKKyAgICB9CisKKyAgICBzdGF0aWMgT3V0cHV0U3RyZWFtIGFkZEVuY29kZXIoZmluYWwgT3V0cHV0U3RyZWFtIG91dCwgZmluYWwgU2V2ZW5aTWV0aG9kIG1ldGhvZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgT2JqZWN0IG9wdGlvbnMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIENvZGVyQmFzZSBjYiA9IGZpbmRCeU1ldGhvZChtZXRob2QpOworICAgICAgICBpZiAoY2IgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJVbnN1cHBvcnRlZCBjb21wcmVzc2lvbiBtZXRob2QgIiArIG1ldGhvZCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGNiLmVuY29kZShvdXQsIG9wdGlvbnMpOworICAgIH0KKworICAgIHN0YXRpYyBjbGFzcyBDb3B5RGVjb2RlciBleHRlbmRzIENvZGVyQmFzZSB7CisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBJbnB1dFN0cmVhbSBkZWNvZGUoZmluYWwgU3RyaW5nIGFyY2hpdmVOYW1lLCBmaW5hbCBJbnB1dFN0cmVhbSBpbiwgZmluYWwgbG9uZyB1bmNvbXByZXNzZWRMZW5ndGgsCisgICAgICAgICAgICAgICAgZmluYWwgQ29kZXIgY29kZXIsIGZpbmFsIGJ5dGVbXSBwYXNzd29yZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBpbjsKKyAgICAgICAgfQorICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgT3V0cHV0U3RyZWFtIGVuY29kZShmaW5hbCBPdXRwdXRTdHJlYW0gb3V0LCBmaW5hbCBPYmplY3Qgb3B0aW9ucykgeworICAgICAgICAgICAgcmV0dXJuIG91dDsKKyAgICAgICAgfQorICAgIH0KKworICAgIHN0YXRpYyBjbGFzcyBCQ0pEZWNvZGVyIGV4dGVuZHMgQ29kZXJCYXNlIHsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBGaWx0ZXJPcHRpb25zIG9wdHM7CisgICAgICAgIEJDSkRlY29kZXIoZmluYWwgRmlsdGVyT3B0aW9ucyBvcHRzKSB7CisgICAgICAgICAgICB0aGlzLm9wdHMgPSBvcHRzOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIElucHV0U3RyZWFtIGRlY29kZShmaW5hbCBTdHJpbmcgYXJjaGl2ZU5hbWUsIGZpbmFsIElucHV0U3RyZWFtIGluLCBmaW5hbCBsb25nIHVuY29tcHJlc3NlZExlbmd0aCwKKyAgICAgICAgICAgICAgICBmaW5hbCBDb2RlciBjb2RlciwgZmluYWwgYnl0ZVtdIHBhc3N3b3JkKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICByZXR1cm4gb3B0cy5nZXRJbnB1dFN0cmVhbShpbik7CisgICAgICAgICAgICB9IGNhdGNoIChmaW5hbCBBc3NlcnRpb25FcnJvciBlKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJCQ0ogZmlsdGVyIHVzZWQgaW4gIiArIGFyY2hpdmVOYW1lCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiBuZWVkcyBYWiBmb3IgSmF2YSA+IDEuNCAtIHNlZSAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgImh0dHBzOi8vY29tbW9ucy5hcGFjaGUub3JnL3Byb3Blci9jb21tb25zLWNvbXByZXNzL2xpbWl0YXRpb25zLmh0bWwjN1oiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJyZXNvdXJjZSIpCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBPdXRwdXRTdHJlYW0gZW5jb2RlKGZpbmFsIE91dHB1dFN0cmVhbSBvdXQsIGZpbmFsIE9iamVjdCBvcHRpb25zKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IEZsdXNoU2hpZWxkRmlsdGVyT3V0cHV0U3RyZWFtKG9wdHMuZ2V0T3V0cHV0U3RyZWFtKG5ldyBGaW5pc2hhYmxlV3JhcHBlck91dHB1dFN0cmVhbShvdXQpKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBzdGF0aWMgY2xhc3MgRGVmbGF0ZURlY29kZXIgZXh0ZW5kcyBDb2RlckJhc2UgeworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gT05FX1pFUk9fQllURSA9IG5ldyBieXRlWzFdOworICAgICAgICBEZWZsYXRlRGVjb2RlcigpIHsKKyAgICAgICAgICAgIHN1cGVyKE51bWJlci5jbGFzcyk7CisgICAgICAgIH0KKworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygicmVzb3VyY2UiKSAvLyBjYWxsZXIgbXVzdCBjbG9zZSB0aGUgSW5wdXRTdHJlYW0KKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIElucHV0U3RyZWFtIGRlY29kZShmaW5hbCBTdHJpbmcgYXJjaGl2ZU5hbWUsIGZpbmFsIElucHV0U3RyZWFtIGluLCBmaW5hbCBsb25nIHVuY29tcHJlc3NlZExlbmd0aCwKKyAgICAgICAgICAgICAgICBmaW5hbCBDb2RlciBjb2RlciwgZmluYWwgYnl0ZVtdIHBhc3N3b3JkKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGZpbmFsIEluZmxhdGVyIGluZmxhdGVyID0gbmV3IEluZmxhdGVyKHRydWUpOworICAgICAgICAgICAgLy8gSW5mbGF0ZXIgd2l0aCBub3dyYXA9dHJ1ZSBoYXMgdGhpcyBvZGQgY29udHJhY3QgZm9yIGEgemVybyBwYWRkaW5nCisgICAgICAgICAgICAvLyBieXRlIGZvbGxvd2luZyB0aGUgZGF0YSBzdHJlYW07IHRoaXMgdXNlZCB0byBiZSB6bGliJ3MgcmVxdWlyZW1lbnQKKyAgICAgICAgICAgIC8vIGFuZCBoYXMgYmVlbiBmaXhlZCBhIGxvbmcgdGltZSBhZ28sIGJ1dCB0aGUgY29udHJhY3QgcGVyc2lzdHMgc28KKyAgICAgICAgICAgIC8vIHdlIGNvbXBseS4KKyAgICAgICAgICAgIC8vIGh0dHBzOi8vZG9jcy5vcmFjbGUuY29tL2phdmFzZS83L2RvY3MvYXBpL2phdmEvdXRpbC96aXAvSW5mbGF0ZXIuaHRtbCNJbmZsYXRlcihib29sZWFuKQorICAgICAgICAgICAgZmluYWwgSW5mbGF0ZXJJbnB1dFN0cmVhbSBpbmZsYXRlcklucHV0U3RyZWFtID0gbmV3IEluZmxhdGVySW5wdXRTdHJlYW0obmV3IFNlcXVlbmNlSW5wdXRTdHJlYW0oaW4sCisgICAgICAgICAgICAgICAgbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKE9ORV9aRVJPX0JZVEUpKSwgaW5mbGF0ZXIpOworICAgICAgICAgICAgcmV0dXJuIG5ldyBEZWZsYXRlRGVjb2RlcklucHV0U3RyZWFtKGluZmxhdGVySW5wdXRTdHJlYW0sIGluZmxhdGVyKTsKKyAgICAgICAgfQorICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgT3V0cHV0U3RyZWFtIGVuY29kZShmaW5hbCBPdXRwdXRTdHJlYW0gb3V0LCBmaW5hbCBPYmplY3Qgb3B0aW9ucykgeworICAgICAgICAgICAgZmluYWwgaW50IGxldmVsID0gbnVtYmVyT3B0aW9uT3JEZWZhdWx0KG9wdGlvbnMsIDkpOworICAgICAgICAgICAgZmluYWwgRGVmbGF0ZXIgZGVmbGF0ZXIgPSBuZXcgRGVmbGF0ZXIobGV2ZWwsIHRydWUpOworICAgICAgICAgICAgZmluYWwgRGVmbGF0ZXJPdXRwdXRTdHJlYW0gZGVmbGF0ZXJPdXRwdXRTdHJlYW0gPSBuZXcgRGVmbGF0ZXJPdXRwdXRTdHJlYW0ob3V0LCBkZWZsYXRlcik7CisgICAgICAgICAgICByZXR1cm4gbmV3IERlZmxhdGVEZWNvZGVyT3V0cHV0U3RyZWFtKGRlZmxhdGVyT3V0cHV0U3RyZWFtLCBkZWZsYXRlcik7CisgICAgICAgIH0KKworICAgICAgICAgc3RhdGljIGNsYXNzIERlZmxhdGVEZWNvZGVySW5wdXRTdHJlYW0gZXh0ZW5kcyBJbnB1dFN0cmVhbSB7CisKKyAgICAgICAgICAgICAgSW5mbGF0ZXJJbnB1dFN0cmVhbSBpbmZsYXRlcklucHV0U3RyZWFtOworICAgICAgICAgICAgICBJbmZsYXRlciBpbmZsYXRlcjsKKworICAgICAgICAgICAgcHVibGljIERlZmxhdGVEZWNvZGVySW5wdXRTdHJlYW0oSW5mbGF0ZXJJbnB1dFN0cmVhbSBpbmZsYXRlcklucHV0U3RyZWFtLAorICAgICAgICAgICAgICAgIEluZmxhdGVyIGluZmxhdGVyKSB7CisgICAgICAgICAgICAgICAgdGhpcy5pbmZsYXRlcklucHV0U3RyZWFtID0gaW5mbGF0ZXJJbnB1dFN0cmVhbTsKKyAgICAgICAgICAgICAgICB0aGlzLmluZmxhdGVyID0gaW5mbGF0ZXI7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIGludCByZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gaW5mbGF0ZXJJbnB1dFN0cmVhbS5yZWFkKCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIGludCByZWFkKGZpbmFsIGJ5dGVbXSBiLCBmaW5hbCBpbnQgb2ZmLCBmaW5hbCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgICAgIHJldHVybiBpbmZsYXRlcklucHV0U3RyZWFtLnJlYWQoYiwgb2ZmLCBsZW4pOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBpbnQgcmVhZChmaW5hbCBieXRlW10gYikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gaW5mbGF0ZXJJbnB1dFN0cmVhbS5yZWFkKGIpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBpbmZsYXRlcklucHV0U3RyZWFtLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICAgICAgaW5mbGF0ZXIuZW5kKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgIHN0YXRpYyBjbGFzcyBEZWZsYXRlRGVjb2Rlck91dHB1dFN0cmVhbSBleHRlbmRzIE91dHB1dFN0cmVhbSB7CisKKyAgICAgICAgICAgICAgRGVmbGF0ZXJPdXRwdXRTdHJlYW0gZGVmbGF0ZXJPdXRwdXRTdHJlYW07CisgICAgICAgICAgICAgIERlZmxhdGVyIGRlZmxhdGVyOworCisgICAgICAgICAgICBwdWJsaWMgRGVmbGF0ZURlY29kZXJPdXRwdXRTdHJlYW0oRGVmbGF0ZXJPdXRwdXRTdHJlYW0gZGVmbGF0ZXJPdXRwdXRTdHJlYW0sCisgICAgICAgICAgICAgICAgRGVmbGF0ZXIgZGVmbGF0ZXIpIHsKKyAgICAgICAgICAgICAgICB0aGlzLmRlZmxhdGVyT3V0cHV0U3RyZWFtID0gZGVmbGF0ZXJPdXRwdXRTdHJlYW07CisgICAgICAgICAgICAgICAgdGhpcy5kZWZsYXRlciA9IGRlZmxhdGVyOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHdyaXRlKGZpbmFsIGludCBiKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgICAgIGRlZmxhdGVyT3V0cHV0U3RyZWFtLndyaXRlKGIpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHdyaXRlKGZpbmFsIGJ5dGVbXSBiKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgICAgIGRlZmxhdGVyT3V0cHV0U3RyZWFtLndyaXRlKGIpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHdyaXRlKGZpbmFsIGJ5dGVbXSBiLCBmaW5hbCBpbnQgb2ZmLCBmaW5hbCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgICAgIGRlZmxhdGVyT3V0cHV0U3RyZWFtLndyaXRlKGIsIG9mZiwgbGVuKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgZGVmbGF0ZXJPdXRwdXRTdHJlYW0uY2xvc2UoKTsKKyAgICAgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgICAgICBkZWZsYXRlci5lbmQoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBzdGF0aWMgY2xhc3MgRGVmbGF0ZTY0RGVjb2RlciBleHRlbmRzIENvZGVyQmFzZSB7CisgICAgICAgIERlZmxhdGU2NERlY29kZXIoKSB7CisgICAgICAgICAgICBzdXBlcihOdW1iZXIuY2xhc3MpOworICAgICAgICB9CisKKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInJlc291cmNlIikgLy8gY2FsbGVyIG11c3QgY2xvc2UgdGhlIElucHV0U3RyZWFtCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBJbnB1dFN0cmVhbSBkZWNvZGUoZmluYWwgU3RyaW5nIGFyY2hpdmVOYW1lLCBmaW5hbCBJbnB1dFN0cmVhbSBpbiwgZmluYWwgbG9uZyB1bmNvbXByZXNzZWRMZW5ndGgsCisgICAgICAgICAgICAgICAgZmluYWwgQ29kZXIgY29kZXIsIGZpbmFsIGJ5dGVbXSBwYXNzd29yZCkKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gbmV3IERlZmxhdGU2NENvbXByZXNzb3JJbnB1dFN0cmVhbShpbik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBzdGF0aWMgY2xhc3MgQlpJUDJEZWNvZGVyIGV4dGVuZHMgQ29kZXJCYXNlIHsKKyAgICAgICAgQlpJUDJEZWNvZGVyKCkgeworICAgICAgICAgICAgc3VwZXIoTnVtYmVyLmNsYXNzKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBJbnB1dFN0cmVhbSBkZWNvZGUoZmluYWwgU3RyaW5nIGFyY2hpdmVOYW1lLCBmaW5hbCBJbnB1dFN0cmVhbSBpbiwgZmluYWwgbG9uZyB1bmNvbXByZXNzZWRMZW5ndGgsCisgICAgICAgICAgICAgICAgZmluYWwgQ29kZXIgY29kZXIsIGZpbmFsIGJ5dGVbXSBwYXNzd29yZCkKKyAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIG5ldyBCWmlwMkNvbXByZXNzb3JJbnB1dFN0cmVhbShpbik7CisgICAgICAgIH0KKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIE91dHB1dFN0cmVhbSBlbmNvZGUoZmluYWwgT3V0cHV0U3RyZWFtIG91dCwgZmluYWwgT2JqZWN0IG9wdGlvbnMpCisgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGZpbmFsIGludCBibG9ja1NpemUgPSBudW1iZXJPcHRpb25PckRlZmF1bHQob3B0aW9ucywgQlppcDJDb21wcmVzc29yT3V0cHV0U3RyZWFtLk1BWF9CTE9DS1NJWkUpOworICAgICAgICAgICAgcmV0dXJuIG5ldyBCWmlwMkNvbXByZXNzb3JPdXRwdXRTdHJlYW0ob3V0LCBibG9ja1NpemUpOworICAgICAgICB9CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvc2V2ZW56L0RlbHRhRGVjb2Rlci5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3NldmVuei9EZWx0YURlY29kZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iYzU4YzYzCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3NldmVuei9EZWx0YURlY29kZXIuamF2YQpAQCAtMCwwICsxLDY3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuc2V2ZW56OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IG9yZy50dWthYW5pLnh6LkRlbHRhT3B0aW9uczsKK2ltcG9ydCBvcmcudHVrYWFuaS54ei5GaW5pc2hhYmxlV3JhcHBlck91dHB1dFN0cmVhbTsKK2ltcG9ydCBvcmcudHVrYWFuaS54ei5VbnN1cHBvcnRlZE9wdGlvbnNFeGNlcHRpb247CisKK2NsYXNzIERlbHRhRGVjb2RlciBleHRlbmRzIENvZGVyQmFzZSB7CisgICAgRGVsdGFEZWNvZGVyKCkgeworICAgICAgICBzdXBlcihOdW1iZXIuY2xhc3MpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIElucHV0U3RyZWFtIGRlY29kZShmaW5hbCBTdHJpbmcgYXJjaGl2ZU5hbWUsIGZpbmFsIElucHV0U3RyZWFtIGluLCBmaW5hbCBsb25nIHVuY29tcHJlc3NlZExlbmd0aCwKKyAgICAgICAgICAgIGZpbmFsIENvZGVyIGNvZGVyLCBmaW5hbCBieXRlW10gcGFzc3dvcmQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBuZXcgRGVsdGFPcHRpb25zKGdldE9wdGlvbnNGcm9tQ29kZXIoY29kZXIpKS5nZXRJbnB1dFN0cmVhbShpbik7CisgICAgfQorCisgICAgQFN1cHByZXNzV2FybmluZ3MoInJlc291cmNlIikKKyAgICBAT3ZlcnJpZGUKKyAgICBPdXRwdXRTdHJlYW0gZW5jb2RlKGZpbmFsIE91dHB1dFN0cmVhbSBvdXQsIGZpbmFsIE9iamVjdCBvcHRpb25zKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBpbnQgZGlzdGFuY2UgPSBudW1iZXJPcHRpb25PckRlZmF1bHQob3B0aW9ucywgMSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IERlbHRhT3B0aW9ucyhkaXN0YW5jZSkuZ2V0T3V0cHV0U3RyZWFtKG5ldyBGaW5pc2hhYmxlV3JhcHBlck91dHB1dFN0cmVhbShvdXQpKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgVW5zdXBwb3J0ZWRPcHRpb25zRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oZXguZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIGJ5dGVbXSBnZXRPcHRpb25zQXNQcm9wZXJ0aWVzKGZpbmFsIE9iamVjdCBvcHRpb25zKSB7CisgICAgICAgIHJldHVybiBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgIChieXRlKSAobnVtYmVyT3B0aW9uT3JEZWZhdWx0KG9wdGlvbnMsIDEpIC0gMSkKKyAgICAgICAgfTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBPYmplY3QgZ2V0T3B0aW9uc0Zyb21Db2RlcihmaW5hbCBDb2RlciBjb2RlciwgZmluYWwgSW5wdXRTdHJlYW0gaW4pIHsKKyAgICAgICAgcmV0dXJuIGdldE9wdGlvbnNGcm9tQ29kZXIoY29kZXIpOworICAgIH0KKworICAgIHByaXZhdGUgaW50IGdldE9wdGlvbnNGcm9tQ29kZXIoZmluYWwgQ29kZXIgY29kZXIpIHsKKyAgICAgICAgaWYgKGNvZGVyLnByb3BlcnRpZXMgPT0gbnVsbCB8fCBjb2Rlci5wcm9wZXJ0aWVzLmxlbmd0aCA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gMTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gKDB4ZmYgJiBjb2Rlci5wcm9wZXJ0aWVzWzBdKSArIDE7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3NldmVuei9Gb2xkZXIuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9zZXZlbnovRm9sZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTI4Y2JhOQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9zZXZlbnovRm9sZGVyLmphdmEKQEAgLTAsMCArMSwxMTYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5zZXZlbno7CisKK2ltcG9ydCBqYXZhLnV0aWwuTGlua2VkTGlzdDsKKworLyoqCisgKiBUaGUgdW5pdCBvZiBzb2xpZCBjb21wcmVzc2lvbi4KKyAqLworY2xhc3MgRm9sZGVyIHsKKyAgICAvLy8gTGlzdCBvZiBjb2RlcnMgdXNlZCBpbiB0aGlzIGZvbGRlciwgZWcuIG9uZSBmb3IgY29tcHJlc3Npb24sIG9uZSBmb3IgZW5jcnlwdGlvbi4KKyAgICBDb2RlcltdIGNvZGVyczsKKyAgICAvLy8gVG90YWwgbnVtYmVyIG9mIGlucHV0IHN0cmVhbXMgYWNyb3NzIGFsbCBjb2RlcnMuCisgICAgLy8vIHRoaXMgZmllbGQgaXMgY3VycmVudGx5IHVudXNlZCBidXQgdGVjaG5pY2FsbHkgcGFydCBvZiB0aGUgN3ogQVBJCisgICAgbG9uZyB0b3RhbElucHV0U3RyZWFtczsKKyAgICAvLy8gVG90YWwgbnVtYmVyIG9mIG91dHB1dCBzdHJlYW1zIGFjcm9zcyBhbGwgY29kZXJzLgorICAgIGxvbmcgdG90YWxPdXRwdXRTdHJlYW1zOworICAgIC8vLyBNYXBwaW5nIGJldHdlZW4gaW5wdXQgYW5kIG91dHB1dCBzdHJlYW1zLgorICAgIEJpbmRQYWlyW10gYmluZFBhaXJzOworICAgIC8vLyBJbmRlY2VzIG9mIGlucHV0IHN0cmVhbXMsIG9uZSBwZXIgaW5wdXQgc3RyZWFtIG5vdCBsaXN0ZWQgaW4gYmluZFBhaXJzLgorICAgIGxvbmdbXSBwYWNrZWRTdHJlYW1zOworICAgIC8vLyBVbnBhY2sgc2l6ZXMsIHBlciBlYWNoIG91dHB1dCBzdHJlYW0uCisgICAgbG9uZ1tdIHVucGFja1NpemVzOworICAgIC8vLyBXaGV0aGVyIHRoZSBmb2xkZXIgaGFzIGEgQ1JDLgorICAgIGJvb2xlYW4gaGFzQ3JjOworICAgIC8vLyBUaGUgQ1JDLCBpZiBwcmVzZW50LgorICAgIGxvbmcgY3JjOworICAgIC8vLyBUaGUgbnVtYmVyIG9mIHVucGFjayBzdWJzdHJlYW1zLCBwcm9kdWN0IG9mIHRoZSBudW1iZXIgb2YKKyAgICAvLy8gb3V0cHV0IHN0cmVhbXMgYW5kIHRoZSBudWJlciBvZiBub24tZW1wdHkgZmlsZXMgaW4gdGhpcworICAgIC8vLyBmb2xkZXIuCisgICAgaW50IG51bVVucGFja1N1YlN0cmVhbXM7CisKKyAgICAvKioKKyAgICAgKiBTb3J0cyBDb2RlcnMgdXNpbmcgYmluZCBwYWlycy4KKyAgICAgKiA8cD5UaGUgZmlyc3QgY29kZXIgcmVhZHMgZnJvbSB0aGUgcGFja2VkIHN0cmVhbSAod2UgY3VycmVudGx5CisgICAgICogb25seSBzdXBwb3J0IHNpbmdsZSBpbnB1dCBzdHJlYW0gZGVjb2RlcnMpLCB0aGUgc2Vjb25kIHJlYWRzCisgICAgICogZnJvbSB0aGUgb3V0cHV0IG9mIHRoZSBmaXJzdCBhbmQgc28gb24uPC9wPgorICAgICAqLworICAgIEl0ZXJhYmxlPENvZGVyPiBnZXRPcmRlcmVkQ29kZXJzKCkgeworICAgICAgICBmaW5hbCBMaW5rZWRMaXN0PENvZGVyPiBsID0gbmV3IExpbmtlZExpc3Q8PigpOworICAgICAgICBpbnQgY3VycmVudCA9IChpbnQpIHBhY2tlZFN0cmVhbXNbMF07IC8vIG1vcmUgdGhhdCAyXjMxIGNvZGVycz8KKyAgICAgICAgd2hpbGUgKGN1cnJlbnQgIT0gLTEpIHsKKyAgICAgICAgICAgIGwuYWRkTGFzdChjb2RlcnNbY3VycmVudF0pOworICAgICAgICAgICAgZmluYWwgaW50IHBhaXIgPSBmaW5kQmluZFBhaXJGb3JPdXRTdHJlYW0oY3VycmVudCk7CisgICAgICAgICAgICBjdXJyZW50ID0gcGFpciAhPSAtMSA/IChpbnQpIGJpbmRQYWlyc1twYWlyXS5pbkluZGV4IDogLTE7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGw7CisgICAgfQorCisgICAgaW50IGZpbmRCaW5kUGFpckZvckluU3RyZWFtKGZpbmFsIGludCBpbmRleCkgeworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGJpbmRQYWlycy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgaWYgKGJpbmRQYWlyc1tpXS5pbkluZGV4ID09IGluZGV4KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIGludCBmaW5kQmluZFBhaXJGb3JPdXRTdHJlYW0oZmluYWwgaW50IGluZGV4KSB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYmluZFBhaXJzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBpZiAoYmluZFBhaXJzW2ldLm91dEluZGV4ID09IGluZGV4KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIGxvbmcgZ2V0VW5wYWNrU2l6ZSgpIHsKKyAgICAgICAgaWYgKHRvdGFsT3V0cHV0U3RyZWFtcyA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gKChpbnQpdG90YWxPdXRwdXRTdHJlYW1zKSAtIDE7IGkgPj0gMDsgaS0tKSB7CisgICAgICAgICAgICBpZiAoZmluZEJpbmRQYWlyRm9yT3V0U3RyZWFtKGkpIDwgMCkgeworICAgICAgICAgICAgICAgIHJldHVybiB1bnBhY2tTaXplc1tpXTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBsb25nIGdldFVucGFja1NpemVGb3JDb2RlcihmaW5hbCBDb2RlciBjb2RlcikgeworICAgICAgICBpZiAoY29kZXJzICE9IG51bGwpIHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY29kZXJzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgaWYgKGNvZGVyc1tpXSA9PSBjb2RlcikgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gdW5wYWNrU2l6ZXNbaV07CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIHJldHVybiAiRm9sZGVyIHdpdGggIiArIGNvZGVycy5sZW5ndGggKyAiIGNvZGVycywgIiArIHRvdGFsSW5wdXRTdHJlYW1zCisgICAgICAgICAgICArICIgaW5wdXQgc3RyZWFtcywgIiArIHRvdGFsT3V0cHV0U3RyZWFtcyArICIgb3V0cHV0IHN0cmVhbXMsICIKKyAgICAgICAgICAgICsgYmluZFBhaXJzLmxlbmd0aCArICIgYmluZCBwYWlycywgIiArIHBhY2tlZFN0cmVhbXMubGVuZ3RoCisgICAgICAgICAgICArICIgcGFja2VkIHN0cmVhbXMsICIgKyB1bnBhY2tTaXplcy5sZW5ndGggKyAiIHVucGFjayBzaXplcywgIgorICAgICAgICAgICAgKyAoaGFzQ3JjID8gIndpdGggQ1JDICIgKyBjcmMgOiAid2l0aG91dCBDUkMiKQorICAgICAgICAgICAgKyAiIGFuZCAiICsgbnVtVW5wYWNrU3ViU3RyZWFtcyArICIgdW5wYWNrIHN0cmVhbXMiOworICAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3NldmVuei9MWk1BMkRlY29kZXIuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9zZXZlbnovTFpNQTJEZWNvZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGYxM2NhOQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9zZXZlbnovTFpNQTJEZWNvZGVyLmphdmEKQEAgLTAsMCArMSwxMDEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5zZXZlbno7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CisKK2ltcG9ydCBvcmcudHVrYWFuaS54ei5GaW5pc2hhYmxlV3JhcHBlck91dHB1dFN0cmVhbTsKK2ltcG9ydCBvcmcudHVrYWFuaS54ei5GaW5pc2hhYmxlT3V0cHV0U3RyZWFtOworaW1wb3J0IG9yZy50dWthYW5pLnh6LkxaTUEySW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLnR1a2FhbmkueHouTFpNQTJPcHRpb25zOworCitjbGFzcyBMWk1BMkRlY29kZXIgZXh0ZW5kcyBDb2RlckJhc2UgeworICAgIExaTUEyRGVjb2RlcigpIHsKKyAgICAgICAgc3VwZXIoTFpNQTJPcHRpb25zLmNsYXNzLCBOdW1iZXIuY2xhc3MpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIElucHV0U3RyZWFtIGRlY29kZShmaW5hbCBTdHJpbmcgYXJjaGl2ZU5hbWUsIGZpbmFsIElucHV0U3RyZWFtIGluLCBmaW5hbCBsb25nIHVuY29tcHJlc3NlZExlbmd0aCwKKyAgICAgICAgICAgIGZpbmFsIENvZGVyIGNvZGVyLCBmaW5hbCBieXRlW10gcGFzc3dvcmQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmaW5hbCBpbnQgZGljdGlvbmFyeVNpemUgPSBnZXREaWN0aW9uYXJ5U2l6ZShjb2Rlcik7CisgICAgICAgICAgICByZXR1cm4gbmV3IExaTUEySW5wdXRTdHJlYW0oaW4sIGRpY3Rpb25hcnlTaXplKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oZXguZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIE91dHB1dFN0cmVhbSBlbmNvZGUoZmluYWwgT3V0cHV0U3RyZWFtIG91dCwgZmluYWwgT2JqZWN0IG9wdHMpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIExaTUEyT3B0aW9ucyBvcHRpb25zID0gZ2V0T3B0aW9ucyhvcHRzKTsKKyAgICAgICAgZmluYWwgRmluaXNoYWJsZU91dHB1dFN0cmVhbSB3cmFwcGVkID0gbmV3IEZpbmlzaGFibGVXcmFwcGVyT3V0cHV0U3RyZWFtKG91dCk7CisgICAgICAgIHJldHVybiBvcHRpb25zLmdldE91dHB1dFN0cmVhbSh3cmFwcGVkKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBieXRlW10gZ2V0T3B0aW9uc0FzUHJvcGVydGllcyhmaW5hbCBPYmplY3Qgb3B0cykgeworICAgICAgICBmaW5hbCBpbnQgZGljdFNpemUgPSBnZXREaWN0U2l6ZShvcHRzKTsKKyAgICAgICAgZmluYWwgaW50IGxlYWQgPSBJbnRlZ2VyLm51bWJlck9mTGVhZGluZ1plcm9zKGRpY3RTaXplKTsKKyAgICAgICAgZmluYWwgaW50IHNlY29uZEJpdCA9IChkaWN0U2l6ZSA+Pj4gKDMwIC0gbGVhZCkpIC0gMjsKKyAgICAgICAgcmV0dXJuIG5ldyBieXRlW10geworICAgICAgICAgICAgKGJ5dGUpICgoMTkgLSBsZWFkKSAqIDIgKyBzZWNvbmRCaXQpCisgICAgICAgIH07CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgT2JqZWN0IGdldE9wdGlvbnNGcm9tQ29kZXIoZmluYWwgQ29kZXIgY29kZXIsIGZpbmFsIElucHV0U3RyZWFtIGluKSB7CisgICAgICAgIHJldHVybiBnZXREaWN0aW9uYXJ5U2l6ZShjb2Rlcik7CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnQgZ2V0RGljdFNpemUoZmluYWwgT2JqZWN0IG9wdHMpIHsKKyAgICAgICAgaWYgKG9wdHMgaW5zdGFuY2VvZiBMWk1BMk9wdGlvbnMpIHsKKyAgICAgICAgICAgIHJldHVybiAoKExaTUEyT3B0aW9ucykgb3B0cykuZ2V0RGljdFNpemUoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVtYmVyT3B0aW9uT3JEZWZhdWx0KG9wdHMpOworICAgIH0KKworICAgIHByaXZhdGUgaW50IGdldERpY3Rpb25hcnlTaXplKGZpbmFsIENvZGVyIGNvZGVyKSB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgaW50IGRpY3Rpb25hcnlTaXplQml0cyA9IDB4ZmYgJiBjb2Rlci5wcm9wZXJ0aWVzWzBdOworICAgICAgICBpZiAoKGRpY3Rpb25hcnlTaXplQml0cyAmICh+MHgzZikpICE9IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlVuc3VwcG9ydGVkIExaTUEyIHByb3BlcnR5IGJpdHMiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZGljdGlvbmFyeVNpemVCaXRzID4gNDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkRpY3Rpb25hcnkgbGFyZ2VyIHRoYW4gNEdpQiBtYXhpbXVtIHNpemUiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZGljdGlvbmFyeVNpemVCaXRzID09IDQwKSB7CisgICAgICAgICAgICByZXR1cm4gMHhGRkZGZmZmZjsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gKDIgfCAoZGljdGlvbmFyeVNpemVCaXRzICYgMHgxKSkgPDwgKGRpY3Rpb25hcnlTaXplQml0cyAvIDIgKyAxMSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBMWk1BMk9wdGlvbnMgZ2V0T3B0aW9ucyhmaW5hbCBPYmplY3Qgb3B0cykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKG9wdHMgaW5zdGFuY2VvZiBMWk1BMk9wdGlvbnMpIHsKKyAgICAgICAgICAgIHJldHVybiAoTFpNQTJPcHRpb25zKSBvcHRzOworICAgICAgICB9CisgICAgICAgIGZpbmFsIExaTUEyT3B0aW9ucyBvcHRpb25zID0gbmV3IExaTUEyT3B0aW9ucygpOworICAgICAgICBvcHRpb25zLnNldERpY3RTaXplKG51bWJlck9wdGlvbk9yRGVmYXVsdChvcHRzKSk7CisgICAgICAgIHJldHVybiBvcHRpb25zOworICAgIH0KKworICAgIHByaXZhdGUgaW50IG51bWJlck9wdGlvbk9yRGVmYXVsdChmaW5hbCBPYmplY3Qgb3B0cykgeworICAgICAgICByZXR1cm4gbnVtYmVyT3B0aW9uT3JEZWZhdWx0KG9wdHMsIExaTUEyT3B0aW9ucy5ESUNUX1NJWkVfREVGQVVMVCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3NldmVuei9MWk1BRGVjb2Rlci5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3NldmVuei9MWk1BRGVjb2Rlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZlM2Q0NmMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvc2V2ZW56L0xaTUFEZWNvZGVyLmphdmEKQEAgLTAsMCArMSw5NiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICoKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnNldmVuejsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5CeXRlVXRpbHM7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLkZsdXNoU2hpZWxkRmlsdGVyT3V0cHV0U3RyZWFtOworaW1wb3J0IG9yZy50dWthYW5pLnh6LkxaTUEyT3B0aW9uczsKK2ltcG9ydCBvcmcudHVrYWFuaS54ei5MWk1BSW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLnR1a2FhbmkueHouTFpNQU91dHB1dFN0cmVhbTsKKworY2xhc3MgTFpNQURlY29kZXIgZXh0ZW5kcyBDb2RlckJhc2UgeworICAgIExaTUFEZWNvZGVyKCkgeworICAgICAgICBzdXBlcihMWk1BMk9wdGlvbnMuY2xhc3MsIE51bWJlci5jbGFzcyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgSW5wdXRTdHJlYW0gZGVjb2RlKGZpbmFsIFN0cmluZyBhcmNoaXZlTmFtZSwgZmluYWwgSW5wdXRTdHJlYW0gaW4sIGZpbmFsIGxvbmcgdW5jb21wcmVzc2VkTGVuZ3RoLAorICAgICAgICAgICAgZmluYWwgQ29kZXIgY29kZXIsIGZpbmFsIGJ5dGVbXSBwYXNzd29yZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgYnl0ZSBwcm9wc0J5dGUgPSBjb2Rlci5wcm9wZXJ0aWVzWzBdOworICAgICAgICBmaW5hbCBpbnQgZGljdFNpemUgPSBnZXREaWN0aW9uYXJ5U2l6ZShjb2Rlcik7CisgICAgICAgIGlmIChkaWN0U2l6ZSA+IExaTUFJbnB1dFN0cmVhbS5ESUNUX1NJWkVfTUFYKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkRpY3Rpb25hcnkgbGFyZ2VyIHRoYW4gNEdpQiBtYXhpbXVtIHNpemUgdXNlZCBpbiAiICsgYXJjaGl2ZU5hbWUpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgTFpNQUlucHV0U3RyZWFtKGluLCB1bmNvbXByZXNzZWRMZW5ndGgsIHByb3BzQnl0ZSwgZGljdFNpemUpOworICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJyZXNvdXJjZSIpCisgICAgQE92ZXJyaWRlCisgICAgT3V0cHV0U3RyZWFtIGVuY29kZShmaW5hbCBPdXRwdXRTdHJlYW0gb3V0LCBmaW5hbCBPYmplY3Qgb3B0cykKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gTk9PUCBhcyBMWk1BT3V0cHV0U3RyZWFtIHRocm93cyBhbiBleGNlcHRpb24gaW4gZmx1c2gKKyAgICAgICAgcmV0dXJuIG5ldyBGbHVzaFNoaWVsZEZpbHRlck91dHB1dFN0cmVhbShuZXcgTFpNQU91dHB1dFN0cmVhbShvdXQsIGdldE9wdGlvbnMob3B0cyksIGZhbHNlKSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgYnl0ZVtdIGdldE9wdGlvbnNBc1Byb3BlcnRpZXMoZmluYWwgT2JqZWN0IG9wdHMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIExaTUEyT3B0aW9ucyBvcHRpb25zID0gZ2V0T3B0aW9ucyhvcHRzKTsKKyAgICAgICAgZmluYWwgYnl0ZSBwcm9wcyA9IChieXRlKSAoKG9wdGlvbnMuZ2V0UGIoKSAqIDUgKyBvcHRpb25zLmdldExwKCkpICogOSArIG9wdGlvbnMuZ2V0TGMoKSk7CisgICAgICAgIGludCBkaWN0U2l6ZSA9IG9wdGlvbnMuZ2V0RGljdFNpemUoKTsKKyAgICAgICAgYnl0ZVtdIG8gPSBuZXcgYnl0ZVs1XTsKKyAgICAgICAgb1swXSA9IHByb3BzOworICAgICAgICBCeXRlVXRpbHMudG9MaXR0bGVFbmRpYW4obywgZGljdFNpemUsIDEsIDQpOworICAgICAgICByZXR1cm4gbzsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBPYmplY3QgZ2V0T3B0aW9uc0Zyb21Db2RlcihmaW5hbCBDb2RlciBjb2RlciwgZmluYWwgSW5wdXRTdHJlYW0gaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIGJ5dGUgcHJvcHNCeXRlID0gY29kZXIucHJvcGVydGllc1swXTsKKyAgICAgICAgaW50IHByb3BzID0gcHJvcHNCeXRlICYgMHhGRjsKKyAgICAgICAgaW50IHBiID0gcHJvcHMgLyAoOSAqIDUpOworICAgICAgICBwcm9wcyAtPSBwYiAqIDkgKiA1OworICAgICAgICBpbnQgbHAgPSBwcm9wcyAvIDk7CisgICAgICAgIGludCBsYyA9IHByb3BzIC0gbHAgKiA5OworICAgICAgICBMWk1BMk9wdGlvbnMgb3B0cyA9IG5ldyBMWk1BMk9wdGlvbnMoKTsKKyAgICAgICAgb3B0cy5zZXRQYihwYik7CisgICAgICAgIG9wdHMuc2V0TGNMcChsYywgbHApOworICAgICAgICBvcHRzLnNldERpY3RTaXplKGdldERpY3Rpb25hcnlTaXplKGNvZGVyKSk7CisgICAgICAgIHJldHVybiBvcHRzOworICAgIH0KKworICAgIHByaXZhdGUgaW50IGdldERpY3Rpb25hcnlTaXplKGZpbmFsIENvZGVyIGNvZGVyKSB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIChpbnQpIEJ5dGVVdGlscy5mcm9tTGl0dGxlRW5kaWFuKGNvZGVyLnByb3BlcnRpZXMsIDEsIDQpOworICAgIH0KKworICAgIHByaXZhdGUgTFpNQTJPcHRpb25zIGdldE9wdGlvbnMoZmluYWwgT2JqZWN0IG9wdHMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChvcHRzIGluc3RhbmNlb2YgTFpNQTJPcHRpb25zKSB7CisgICAgICAgICAgICByZXR1cm4gKExaTUEyT3B0aW9ucykgb3B0czsKKyAgICAgICAgfQorICAgICAgICBmaW5hbCBMWk1BMk9wdGlvbnMgb3B0aW9ucyA9IG5ldyBMWk1BMk9wdGlvbnMoKTsKKyAgICAgICAgb3B0aW9ucy5zZXREaWN0U2l6ZShudW1iZXJPcHRpb25PckRlZmF1bHQob3B0cykpOworICAgICAgICByZXR1cm4gb3B0aW9uczsKKyAgICB9CisKKyAgICBwcml2YXRlIGludCBudW1iZXJPcHRpb25PckRlZmF1bHQoZmluYWwgT2JqZWN0IG9wdHMpIHsKKyAgICAgICAgcmV0dXJuIG51bWJlck9wdGlvbk9yRGVmYXVsdChvcHRzLCBMWk1BMk9wdGlvbnMuRElDVF9TSVpFX0RFRkFVTFQpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9zZXZlbnovTklELmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvc2V2ZW56L05JRC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg5YTgxM2EKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvc2V2ZW56L05JRC5qYXZhCkBAIC0wLDAgKzEsNDcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5zZXZlbno7CisKK2ZpbmFsIGNsYXNzIE5JRCB7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0VuZCA9IDB4MDA7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0hlYWRlciA9IDB4MDE7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0FyY2hpdmVQcm9wZXJ0aWVzID0gMHgwMjsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQWRkaXRpb25hbFN0cmVhbXNJbmZvID0gMHgwMzsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrTWFpblN0cmVhbXNJbmZvID0gMHgwNDsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRmlsZXNJbmZvID0gMHgwNTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrUGFja0luZm8gPSAweDA2OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtVbnBhY2tJbmZvID0gMHgwNzsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrU3ViU3RyZWFtc0luZm8gPSAweDA4OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtTaXplID0gMHgwOTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ1JDID0gMHgwQTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRm9sZGVyID0gMHgwQjsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29kZXJzVW5wYWNrU2l6ZSA9IDB4MEM7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga051bVVucGFja1N0cmVhbSA9IDB4MEQ7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0VtcHR5U3RyZWFtID0gMHgwRTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRW1wdHlGaWxlID0gMHgwRjsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQW50aSA9IDB4MTA7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga05hbWUgPSAweDExOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtDVGltZSA9IDB4MTI7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0FUaW1lID0gMHgxMzsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrTVRpbWUgPSAweDE0OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtXaW5BdHRyaWJ1dGVzID0gMHgxNTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29tbWVudCA9IDB4MTY7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0VuY29kZWRIZWFkZXIgPSAweDE3OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtTdGFydFBvcyA9IDB4MTg7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0R1bW15ID0gMHgxOTsKK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9zZXZlbnovU2V2ZW5aQXJjaGl2ZUVudHJ5LmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvc2V2ZW56L1NldmVuWkFyY2hpdmVFbnRyeS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY5NTQyNmIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvc2V2ZW56L1NldmVuWkFyY2hpdmVFbnRyeS5qYXZhCkBAIC0wLDAgKzEsNTE1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuc2V2ZW56OworCitpbXBvcnQgamF2YS51dGlsLkNhbGVuZGFyOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKK2ltcG9ydCBqYXZhLnV0aWwuRGF0ZTsKK2ltcG9ydCBqYXZhLnV0aWwuTGlua2VkTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuVGltZVpvbmU7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLkFyY2hpdmVFbnRyeTsKKworLyoqCisgKiBBbiBlbnRyeSBpbiBhIDd6IGFyY2hpdmUuCisgKgorICogQE5vdFRocmVhZFNhZmUKKyAqIEBzaW5jZSAxLjYKKyAqLworcHVibGljIGNsYXNzIFNldmVuWkFyY2hpdmVFbnRyeSBpbXBsZW1lbnRzIEFyY2hpdmVFbnRyeSB7CisgICAgcHJpdmF0ZSBTdHJpbmcgbmFtZTsKKyAgICBwcml2YXRlIGJvb2xlYW4gaGFzU3RyZWFtOworICAgIHByaXZhdGUgYm9vbGVhbiBpc0RpcmVjdG9yeTsKKyAgICBwcml2YXRlIGJvb2xlYW4gaXNBbnRpSXRlbTsKKyAgICBwcml2YXRlIGJvb2xlYW4gaGFzQ3JlYXRpb25EYXRlOworICAgIHByaXZhdGUgYm9vbGVhbiBoYXNMYXN0TW9kaWZpZWREYXRlOworICAgIHByaXZhdGUgYm9vbGVhbiBoYXNBY2Nlc3NEYXRlOworICAgIHByaXZhdGUgbG9uZyBjcmVhdGlvbkRhdGU7CisgICAgcHJpdmF0ZSBsb25nIGxhc3RNb2RpZmllZERhdGU7CisgICAgcHJpdmF0ZSBsb25nIGFjY2Vzc0RhdGU7CisgICAgcHJpdmF0ZSBib29sZWFuIGhhc1dpbmRvd3NBdHRyaWJ1dGVzOworICAgIHByaXZhdGUgaW50IHdpbmRvd3NBdHRyaWJ1dGVzOworICAgIHByaXZhdGUgYm9vbGVhbiBoYXNDcmM7CisgICAgcHJpdmF0ZSBsb25nIGNyYywgY29tcHJlc3NlZENyYzsKKyAgICBwcml2YXRlIGxvbmcgc2l6ZSwgY29tcHJlc3NlZFNpemU7CisgICAgcHJpdmF0ZSBJdGVyYWJsZTw/IGV4dGVuZHMgU2V2ZW5aTWV0aG9kQ29uZmlndXJhdGlvbj4gY29udGVudE1ldGhvZHM7CisKKyAgICBwdWJsaWMgU2V2ZW5aQXJjaGl2ZUVudHJ5KCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGlzIGVudHJ5J3MgbmFtZS4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIHJldHVybnMgdGhlIHJhdyBuYW1lIGFzIGl0IGlzIHN0b3JlZCBpbnNpZGUgb2YgdGhlIGFyY2hpdmUuPC9wPgorICAgICAqCisgICAgICogQHJldHVybiBUaGlzIGVudHJ5J3MgbmFtZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7CisgICAgICAgIHJldHVybiBuYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGlzIGVudHJ5J3MgbmFtZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lIFRoaXMgZW50cnkncyBuZXcgbmFtZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXROYW1lKGZpbmFsIFN0cmluZyBuYW1lKSB7CisgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogV2hldGhlciB0aGVyZSBpcyBhbnkgY29udGVudCBhc3NvY2lhdGVkIHdpdGggdGhpcyBlbnRyeS4KKyAgICAgKiBAcmV0dXJuIHdoZXRoZXIgdGhlcmUgaXMgYW55IGNvbnRlbnQgYXNzb2NpYXRlZCB3aXRoIHRoaXMgZW50cnkuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaGFzU3RyZWFtKCkgeworICAgICAgICByZXR1cm4gaGFzU3RyZWFtOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgd2hldGhlciB0aGVyZSBpcyBhbnkgY29udGVudCBhc3NvY2lhdGVkIHdpdGggdGhpcyBlbnRyeS4KKyAgICAgKiBAcGFyYW0gaGFzU3RyZWFtIHdoZXRoZXIgdGhlcmUgaXMgYW55IGNvbnRlbnQgYXNzb2NpYXRlZCB3aXRoIHRoaXMgZW50cnkuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0SGFzU3RyZWFtKGZpbmFsIGJvb2xlYW4gaGFzU3RyZWFtKSB7CisgICAgICAgIHRoaXMuaGFzU3RyZWFtID0gaGFzU3RyZWFtOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB3aGV0aGVyIG9yIG5vdCB0aGlzIGVudHJ5IHJlcHJlc2VudHMgYSBkaXJlY3RvcnkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRydWUgaWYgdGhpcyBlbnRyeSBpcyBhIGRpcmVjdG9yeS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0RpcmVjdG9yeSgpIHsKKyAgICAgICAgcmV0dXJuIGlzRGlyZWN0b3J5OworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgd2hldGhlciBvciBub3QgdGhpcyBlbnRyeSByZXByZXNlbnRzIGEgZGlyZWN0b3J5LgorICAgICAqCisgICAgICogQHBhcmFtIGlzRGlyZWN0b3J5IFRydWUgaWYgdGhpcyBlbnRyeSBpcyBhIGRpcmVjdG9yeS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXREaXJlY3RvcnkoZmluYWwgYm9vbGVhbiBpc0RpcmVjdG9yeSkgeworICAgICAgICB0aGlzLmlzRGlyZWN0b3J5ID0gaXNEaXJlY3Rvcnk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhpcyBpcyBhbiAiYW50aS1pdGVtIiB1c2VkIGluIGRpZmZlcmVudGlhbCBiYWNrdXBzLAorICAgICAqIG1lYW5pbmcgaXQgc2hvdWxkIGRlbGV0ZSB0aGUgc2FtZSBmaWxlIGZyb20gYSBwcmV2aW91cyBiYWNrdXAuCisgICAgICogQHJldHVybiB0cnVlIGlmIGl0IGlzIGFuIGFudGktaXRlbSwgZmFsc2Ugb3RoZXJ3aXNlCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNBbnRpSXRlbSgpIHsKKyAgICAgICAgcmV0dXJuIGlzQW50aUl0ZW07CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB3aGV0aGVyIHRoaXMgaXMgYW4gImFudGktaXRlbSIgdXNlZCBpbiBkaWZmZXJlbnRpYWwgYmFja3VwcywKKyAgICAgKiBtZWFuaW5nIGl0IHNob3VsZCBkZWxldGUgdGhlIHNhbWUgZmlsZSBmcm9tIGEgcHJldmlvdXMgYmFja3VwLgorICAgICAqIEBwYXJhbSBpc0FudGlJdGVtIHRydWUgaWYgaXQgaXMgYW4gYW50aS1pdGVtLCBmYWxzZSBvdGhlcndpc2UKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRBbnRpSXRlbShmaW5hbCBib29sZWFuIGlzQW50aUl0ZW0pIHsKKyAgICAgICAgdGhpcy5pc0FudGlJdGVtID0gaXNBbnRpSXRlbTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhpcyBlbnRyeSBoYXMgZ290IGEgY3JlYXRpb24gZGF0ZSBhdCBhbGwuCisgICAgICogQHJldHVybiB3aGV0aGVyIHRoZSBlbnRyeSBoYXMgZ290IGEgY3JlYXRpb24gZGF0ZQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGdldEhhc0NyZWF0aW9uRGF0ZSgpIHsKKyAgICAgICAgcmV0dXJuIGhhc0NyZWF0aW9uRGF0ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHdoZXRoZXIgdGhpcyBlbnRyeSBoYXMgZ290IGEgY3JlYXRpb24gZGF0ZSBhdCBhbGwuCisgICAgICogQHBhcmFtIGhhc0NyZWF0aW9uRGF0ZSB3aGV0aGVyIHRoZSBlbnRyeSBoYXMgZ290IGEgY3JlYXRpb24gZGF0ZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEhhc0NyZWF0aW9uRGF0ZShmaW5hbCBib29sZWFuIGhhc0NyZWF0aW9uRGF0ZSkgeworICAgICAgICB0aGlzLmhhc0NyZWF0aW9uRGF0ZSA9IGhhc0NyZWF0aW9uRGF0ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBjcmVhdGlvbiBkYXRlLgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gaWYgdGhlIGVudHJ5IGhhc24ndCBnb3QgYQorICAgICAqIGNyZWF0aW9uIGRhdGUuCisgICAgICogQHJldHVybiB0aGUgY3JlYXRpb24gZGF0ZQorICAgICAqLworICAgIHB1YmxpYyBEYXRlIGdldENyZWF0aW9uRGF0ZSgpIHsKKyAgICAgICAgaWYgKGhhc0NyZWF0aW9uRGF0ZSkgeworICAgICAgICAgICAgcmV0dXJuIG50ZnNUaW1lVG9KYXZhVGltZShjcmVhdGlvbkRhdGUpOworICAgICAgICB9CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAiVGhlIGVudHJ5IGRvZXNuJ3QgaGF2ZSB0aGlzIHRpbWVzdGFtcCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGNyZWF0aW9uIGRhdGUgdXNpbmcgTlRGUyB0aW1lICgxMDAgbmFub3NlY29uZCB1bml0cworICAgICAqIHNpbmNlIDEgSmFudWFyeSAxNjAxKQorICAgICAqIEBwYXJhbSBudGZzQ3JlYXRpb25EYXRlIHRoZSBjcmVhdGlvbiBkYXRlCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Q3JlYXRpb25EYXRlKGZpbmFsIGxvbmcgbnRmc0NyZWF0aW9uRGF0ZSkgeworICAgICAgICB0aGlzLmNyZWF0aW9uRGF0ZSA9IG50ZnNDcmVhdGlvbkRhdGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgY3JlYXRpb24gZGF0ZSwKKyAgICAgKiBAcGFyYW0gY3JlYXRpb25EYXRlIHRoZSBjcmVhdGlvbiBkYXRlCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Q3JlYXRpb25EYXRlKGZpbmFsIERhdGUgY3JlYXRpb25EYXRlKSB7CisgICAgICAgIGhhc0NyZWF0aW9uRGF0ZSA9IGNyZWF0aW9uRGF0ZSAhPSBudWxsOworICAgICAgICBpZiAoaGFzQ3JlYXRpb25EYXRlKSB7CisgICAgICAgICAgICB0aGlzLmNyZWF0aW9uRGF0ZSA9IGphdmFUaW1lVG9OdGZzVGltZShjcmVhdGlvbkRhdGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIHRoaXMgZW50cnkgaGFzIGdvdCBhIGxhc3QgbW9kaWZpZWQgZGF0ZSBhdCBhbGwuCisgICAgICogQHJldHVybiB3aGV0aGVyIHRoaXMgZW50cnkgaGFzIGdvdCBhIGxhc3QgbW9kaWZpZWQgZGF0ZSBhdCBhbGwKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBnZXRIYXNMYXN0TW9kaWZpZWREYXRlKCkgeworICAgICAgICByZXR1cm4gaGFzTGFzdE1vZGlmaWVkRGF0ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHdoZXRoZXIgdGhpcyBlbnRyeSBoYXMgZ290IGEgbGFzdCBtb2RpZmllZCBkYXRlIGF0IGFsbC4KKyAgICAgKiBAcGFyYW0gaGFzTGFzdE1vZGlmaWVkRGF0ZSB3aGV0aGVyIHRoaXMgZW50cnkgaGFzIGdvdCBhIGxhc3QKKyAgICAgKiBtb2RpZmllZCBkYXRlIGF0IGFsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEhhc0xhc3RNb2RpZmllZERhdGUoZmluYWwgYm9vbGVhbiBoYXNMYXN0TW9kaWZpZWREYXRlKSB7CisgICAgICAgIHRoaXMuaGFzTGFzdE1vZGlmaWVkRGF0ZSA9IGhhc0xhc3RNb2RpZmllZERhdGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbGFzdCBtb2RpZmllZCBkYXRlLgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gaWYgdGhlIGVudHJ5IGhhc24ndCBnb3QgYQorICAgICAqIGxhc3QgbW9kaWZpZWQgZGF0ZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBsYXN0IG1vZGlmaWVkIGRhdGUKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRGF0ZSBnZXRMYXN0TW9kaWZpZWREYXRlKCkgeworICAgICAgICBpZiAoaGFzTGFzdE1vZGlmaWVkRGF0ZSkgeworICAgICAgICAgICAgcmV0dXJuIG50ZnNUaW1lVG9KYXZhVGltZShsYXN0TW9kaWZpZWREYXRlKTsKKyAgICAgICAgfQorICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oCisgICAgICAgICAgICAgICAgIlRoZSBlbnRyeSBkb2Vzbid0IGhhdmUgdGhpcyB0aW1lc3RhbXAiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBsYXN0IG1vZGlmaWVkIGRhdGUgdXNpbmcgTlRGUyB0aW1lICgxMDAgbmFub3NlY29uZAorICAgICAqIHVuaXRzIHNpbmNlIDEgSmFudWFyeSAxNjAxKQorICAgICAqIEBwYXJhbSBudGZzTGFzdE1vZGlmaWVkRGF0ZSB0aGUgbGFzdCBtb2RpZmllZCBkYXRlCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TGFzdE1vZGlmaWVkRGF0ZShmaW5hbCBsb25nIG50ZnNMYXN0TW9kaWZpZWREYXRlKSB7CisgICAgICAgIHRoaXMubGFzdE1vZGlmaWVkRGF0ZSA9IG50ZnNMYXN0TW9kaWZpZWREYXRlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGxhc3QgbW9kaWZpZWQgZGF0ZSwKKyAgICAgKiBAcGFyYW0gbGFzdE1vZGlmaWVkRGF0ZSB0aGUgbGFzdCBtb2RpZmllZCBkYXRlCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TGFzdE1vZGlmaWVkRGF0ZShmaW5hbCBEYXRlIGxhc3RNb2RpZmllZERhdGUpIHsKKyAgICAgICAgaGFzTGFzdE1vZGlmaWVkRGF0ZSA9IGxhc3RNb2RpZmllZERhdGUgIT0gbnVsbDsKKyAgICAgICAgaWYgKGhhc0xhc3RNb2RpZmllZERhdGUpIHsKKyAgICAgICAgICAgIHRoaXMubGFzdE1vZGlmaWVkRGF0ZSA9IGphdmFUaW1lVG9OdGZzVGltZShsYXN0TW9kaWZpZWREYXRlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciB0aGlzIGVudHJ5IGhhcyBnb3QgYW4gYWNjZXNzIGRhdGUgYXQgYWxsLgorICAgICAqIEByZXR1cm4gd2hldGhlciB0aGlzIGVudHJ5IGhhcyBnb3QgYW4gYWNjZXNzIGRhdGUgYXQgYWxsLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGdldEhhc0FjY2Vzc0RhdGUoKSB7CisgICAgICAgIHJldHVybiBoYXNBY2Nlc3NEYXRlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgd2hldGhlciB0aGlzIGVudHJ5IGhhcyBnb3QgYW4gYWNjZXNzIGRhdGUgYXQgYWxsLgorICAgICAqIEBwYXJhbSBoYXNBY2Vzc0RhdGUgd2hldGhlciB0aGlzIGVudHJ5IGhhcyBnb3QgYW4gYWNjZXNzIGRhdGUgYXQgYWxsLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEhhc0FjY2Vzc0RhdGUoZmluYWwgYm9vbGVhbiBoYXNBY2Vzc0RhdGUpIHsKKyAgICAgICAgdGhpcy5oYXNBY2Nlc3NEYXRlID0gaGFzQWNlc3NEYXRlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGFjY2VzcyBkYXRlLgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gaWYgdGhlIGVudHJ5IGhhc24ndCBnb3QgYQorICAgICAqIGFjY2VzcyBkYXRlLgorICAgICAqIEByZXR1cm4gdGhlIGFjY2VzcyBkYXRlCisgICAgICovCisgICAgcHVibGljIERhdGUgZ2V0QWNjZXNzRGF0ZSgpIHsKKyAgICAgICAgaWYgKGhhc0FjY2Vzc0RhdGUpIHsKKyAgICAgICAgICAgIHJldHVybiBudGZzVGltZVRvSmF2YVRpbWUoYWNjZXNzRGF0ZSk7CisgICAgICAgIH0KKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICJUaGUgZW50cnkgZG9lc24ndCBoYXZlIHRoaXMgdGltZXN0YW1wIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgYWNjZXNzIGRhdGUgdXNpbmcgTlRGUyB0aW1lICgxMDAgbmFub3NlY29uZCB1bml0cworICAgICAqIHNpbmNlIDEgSmFudWFyeSAxNjAxKQorICAgICAqIEBwYXJhbSBudGZzQWNjZXNzRGF0ZSB0aGUgYWNjZXNzIGRhdGUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRBY2Nlc3NEYXRlKGZpbmFsIGxvbmcgbnRmc0FjY2Vzc0RhdGUpIHsKKyAgICAgICAgdGhpcy5hY2Nlc3NEYXRlID0gbnRmc0FjY2Vzc0RhdGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgYWNjZXNzIGRhdGUsCisgICAgICogQHBhcmFtIGFjY2Vzc0RhdGUgdGhlIGFjY2VzcyBkYXRlCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0QWNjZXNzRGF0ZShmaW5hbCBEYXRlIGFjY2Vzc0RhdGUpIHsKKyAgICAgICAgaGFzQWNjZXNzRGF0ZSA9IGFjY2Vzc0RhdGUgIT0gbnVsbDsKKyAgICAgICAgaWYgKGhhc0FjY2Vzc0RhdGUpIHsKKyAgICAgICAgICAgIHRoaXMuYWNjZXNzRGF0ZSA9IGphdmFUaW1lVG9OdGZzVGltZShhY2Nlc3NEYXRlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciB0aGlzIGVudHJ5IGhhcyB3aW5kb3dzIGF0dHJpYnV0ZXMuCisgICAgICogQHJldHVybiB3aGV0aGVyIHRoaXMgZW50cnkgaGFzIHdpbmRvd3MgYXR0cmlidXRlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBnZXRIYXNXaW5kb3dzQXR0cmlidXRlcygpIHsKKyAgICAgICAgcmV0dXJuIGhhc1dpbmRvd3NBdHRyaWJ1dGVzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgd2hldGhlciB0aGlzIGVudHJ5IGhhcyB3aW5kb3dzIGF0dHJpYnV0ZXMuCisgICAgICogQHBhcmFtIGhhc1dpbmRvd3NBdHRyaWJ1dGVzIHdoZXRoZXIgdGhpcyBlbnRyeSBoYXMgd2luZG93cyBhdHRyaWJ1dGVzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEhhc1dpbmRvd3NBdHRyaWJ1dGVzKGZpbmFsIGJvb2xlYW4gaGFzV2luZG93c0F0dHJpYnV0ZXMpIHsKKyAgICAgICAgdGhpcy5oYXNXaW5kb3dzQXR0cmlidXRlcyA9IGhhc1dpbmRvd3NBdHRyaWJ1dGVzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHdpbmRvd3MgYXR0cmlidXRlcy4KKyAgICAgKiBAcmV0dXJuIHRoZSB3aW5kb3dzIGF0dHJpYnV0ZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFdpbmRvd3NBdHRyaWJ1dGVzKCkgeworICAgICAgICByZXR1cm4gd2luZG93c0F0dHJpYnV0ZXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgd2luZG93cyBhdHRyaWJ1dGVzLgorICAgICAqIEBwYXJhbSB3aW5kb3dzQXR0cmlidXRlcyB0aGUgd2luZG93cyBhdHRyaWJ1dGVzCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0V2luZG93c0F0dHJpYnV0ZXMoZmluYWwgaW50IHdpbmRvd3NBdHRyaWJ1dGVzKSB7CisgICAgICAgIHRoaXMud2luZG93c0F0dHJpYnV0ZXMgPSB3aW5kb3dzQXR0cmlidXRlczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhpcyBlbnRyeSBoYXMgZ290IGEgY3JjLgorICAgICAqCisgICAgICogPHA+SW4gZ2VuZXJhbCBlbnRyaWVzIHdpdGhvdXQgc3RyZWFtcyBkb24ndCBoYXZlIGEgQ1JDIGVpdGhlci48L3A+CisgICAgICogQHJldHVybiB3aGV0aGVyIHRoaXMgZW50cnkgaGFzIGdvdCBhIGNyYy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBnZXRIYXNDcmMoKSB7CisgICAgICAgIHJldHVybiBoYXNDcmM7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB3aGV0aGVyIHRoaXMgZW50cnkgaGFzIGdvdCBhIGNyYy4KKyAgICAgKiBAcGFyYW0gaGFzQ3JjIHdoZXRoZXIgdGhpcyBlbnRyeSBoYXMgZ290IGEgY3JjLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEhhc0NyYyhmaW5hbCBib29sZWFuIGhhc0NyYykgeworICAgICAgICB0aGlzLmhhc0NyYyA9IGhhc0NyYzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBDUkMuCisgICAgICogQGRlcHJlY2F0ZWQgdXNlIGdldENyY1ZhbHVlIGluc3RlYWQuCisgICAgICogQHJldHVybiB0aGUgQ1JDCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgaW50IGdldENyYygpIHsKKyAgICAgICAgcmV0dXJuIChpbnQpIGNyYzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBDUkMuCisgICAgICogQGRlcHJlY2F0ZWQgdXNlIHNldENyY1ZhbHVlIGluc3RlYWQuCisgICAgICogQHBhcmFtIGNyYyB0aGUgQ1JDCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgdm9pZCBzZXRDcmMoZmluYWwgaW50IGNyYykgeworICAgICAgICB0aGlzLmNyYyA9IGNyYzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBDUkMuCisgICAgICogQHNpbmNlIENvbXByZXNzIDEuNworICAgICAqIEByZXR1cm4gdGhlIENSQworICAgICAqLworICAgIHB1YmxpYyBsb25nIGdldENyY1ZhbHVlKCkgeworICAgICAgICByZXR1cm4gY3JjOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIENSQy4KKyAgICAgKiBAc2luY2UgQ29tcHJlc3MgMS43CisgICAgICogQHBhcmFtIGNyYyB0aGUgQ1JDCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Q3JjVmFsdWUoZmluYWwgbG9uZyBjcmMpIHsKKyAgICAgICAgdGhpcy5jcmMgPSBjcmM7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgY29tcHJlc3NlZCBDUkMuCisgICAgICogQGRlcHJlY2F0ZWQgdXNlIGdldENvbXByZXNzZWRDcmNWYWx1ZSBpbnN0ZWFkLgorICAgICAqIEByZXR1cm4gdGhlIGNvbXByZXNzZWQgQ1JDCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBpbnQgZ2V0Q29tcHJlc3NlZENyYygpIHsKKyAgICAgICAgcmV0dXJuIChpbnQpIGNvbXByZXNzZWRDcmM7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgY29tcHJlc3NlZCBDUkMuCisgICAgICogQGRlcHJlY2F0ZWQgdXNlIHNldENvbXByZXNzZWRDcmNWYWx1ZSBpbnN0ZWFkLgorICAgICAqIEBwYXJhbSBjcmMgdGhlIENSQworICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgdm9pZCBzZXRDb21wcmVzc2VkQ3JjKGZpbmFsIGludCBjcmMpIHsKKyAgICAgICAgdGhpcy5jb21wcmVzc2VkQ3JjID0gY3JjOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGNvbXByZXNzZWQgQ1JDLgorICAgICAqIEBzaW5jZSBDb21wcmVzcyAxLjcKKyAgICAgKiBAcmV0dXJuIHRoZSBDUkMKKyAgICAgKi8KKyAgICBsb25nIGdldENvbXByZXNzZWRDcmNWYWx1ZSgpIHsKKyAgICAgICAgcmV0dXJuIGNvbXByZXNzZWRDcmM7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgY29tcHJlc3NlZCBDUkMuCisgICAgICogQHNpbmNlIENvbXByZXNzIDEuNworICAgICAqIEBwYXJhbSBjcmMgdGhlIENSQworICAgICAqLworICAgIHZvaWQgc2V0Q29tcHJlc3NlZENyY1ZhbHVlKGZpbmFsIGxvbmcgY3JjKSB7CisgICAgICAgIHRoaXMuY29tcHJlc3NlZENyYyA9IGNyYzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhpcyBlbnRyeSdzIGZpbGUgc2l6ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhpcyBlbnRyeSdzIGZpbGUgc2l6ZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgbG9uZyBnZXRTaXplKCkgeworICAgICAgICByZXR1cm4gc2l6ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhpcyBlbnRyeSdzIGZpbGUgc2l6ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzaXplIFRoaXMgZW50cnkncyBuZXcgZmlsZSBzaXplLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFNpemUoZmluYWwgbG9uZyBzaXplKSB7CisgICAgICAgIHRoaXMuc2l6ZSA9IHNpemU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoaXMgZW50cnkncyBjb21wcmVzc2VkIGZpbGUgc2l6ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhpcyBlbnRyeSdzIGNvbXByZXNzZWQgZmlsZSBzaXplLgorICAgICAqLworICAgIGxvbmcgZ2V0Q29tcHJlc3NlZFNpemUoKSB7CisgICAgICAgIHJldHVybiBjb21wcmVzc2VkU2l6ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhpcyBlbnRyeSdzIGNvbXByZXNzZWQgZmlsZSBzaXplLgorICAgICAqCisgICAgICogQHBhcmFtIHNpemUgVGhpcyBlbnRyeSdzIG5ldyBjb21wcmVzc2VkIGZpbGUgc2l6ZS4KKyAgICAgKi8KKyAgICB2b2lkIHNldENvbXByZXNzZWRTaXplKGZpbmFsIGxvbmcgc2l6ZSkgeworICAgICAgICB0aGlzLmNvbXByZXNzZWRTaXplID0gc2l6ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSAoY29tcHJlc3Npb24pIG1ldGhvZHMgdG8gdXNlIGZvciBlbnRyeSdzIGNvbnRlbnQgLSB0aGUKKyAgICAgKiBkZWZhdWx0IGlzIExaTUEyLgorICAgICAqCisgICAgICogPHA+Q3VycmVudGx5IG9ubHkge0BsaW5rIFNldmVuWk1ldGhvZCNDT1BZfSwge0BsaW5rCisgICAgICogU2V2ZW5aTWV0aG9kI0xaTUEyfSwge0BsaW5rIFNldmVuWk1ldGhvZCNCWklQMn0gYW5kIHtAbGluaworICAgICAqIFNldmVuWk1ldGhvZCNERUZMQVRFfSBhcmUgc3VwcG9ydGVkIHdoZW4gd3JpdGluZyBhcmNoaXZlcy48L3A+CisgICAgICoKKyAgICAgKiA8cD5UaGUgbWV0aG9kcyB3aWxsIGJlIGNvbnN1bHRlZCBpbiBpdGVyYXRpb24gb3JkZXIgdG8gY3JlYXRlCisgICAgICogdGhlIGZpbmFsIG91dHB1dC48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gbWV0aG9kcyB0aGUgbWV0aG9kcyB0byB1c2UgZm9yIHRoZSBjb250ZW50CisgICAgICogQHNpbmNlIDEuOAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldENvbnRlbnRNZXRob2RzKGZpbmFsIEl0ZXJhYmxlPD8gZXh0ZW5kcyBTZXZlblpNZXRob2RDb25maWd1cmF0aW9uPiBtZXRob2RzKSB7CisgICAgICAgIGlmIChtZXRob2RzICE9IG51bGwpIHsKKyAgICAgICAgICAgIGZpbmFsIExpbmtlZExpc3Q8U2V2ZW5aTWV0aG9kQ29uZmlndXJhdGlvbj4gbCA9IG5ldyBMaW5rZWRMaXN0PD4oKTsKKyAgICAgICAgICAgIGZvciAoZmluYWwgU2V2ZW5aTWV0aG9kQ29uZmlndXJhdGlvbiBtIDogbWV0aG9kcykgeworICAgICAgICAgICAgICAgIGwuYWRkTGFzdChtKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNvbnRlbnRNZXRob2RzID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChsKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGNvbnRlbnRNZXRob2RzID0gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIChjb21wcmVzc2lvbikgbWV0aG9kcyB0byB1c2UgZm9yIGVudHJ5J3MgY29udGVudCAtIHRoZQorICAgICAqIGRlZmF1bHQgaXMgTFpNQTIuCisgICAgICoKKyAgICAgKiA8cD5DdXJyZW50bHkgb25seSB7QGxpbmsgU2V2ZW5aTWV0aG9kI0NPUFl9LCB7QGxpbmsKKyAgICAgKiBTZXZlblpNZXRob2QjTFpNQTJ9LCB7QGxpbmsgU2V2ZW5aTWV0aG9kI0JaSVAyfSBhbmQge0BsaW5rCisgICAgICogU2V2ZW5aTWV0aG9kI0RFRkxBVEV9IGFyZSBzdXBwb3J0ZWQgd2hlbiB3cml0aW5nIGFyY2hpdmVzLjwvcD4KKyAgICAgKgorICAgICAqIDxwPlRoZSBtZXRob2RzIHdpbGwgYmUgY29uc3VsdGVkIGluIGl0ZXJhdGlvbiBvcmRlciB0byBjcmVhdGUKKyAgICAgKiB0aGUgZmluYWwgb3V0cHV0LjwvcD4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjgKKyAgICAgKiBAcmV0dXJuIHRoZSBtZXRob2RzIHRvIHVzZSBmb3IgdGhlIGNvbnRlbnQKKyAgICAgKi8KKyAgICBwdWJsaWMgSXRlcmFibGU8PyBleHRlbmRzIFNldmVuWk1ldGhvZENvbmZpZ3VyYXRpb24+IGdldENvbnRlbnRNZXRob2RzKCkgeworICAgICAgICByZXR1cm4gY29udGVudE1ldGhvZHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydHMgTlRGUyB0aW1lICgxMDAgbmFub3NlY29uZCB1bml0cyBzaW5jZSAxIEphbnVhcnkgMTYwMSkKKyAgICAgKiB0byBKYXZhIHRpbWUuCisgICAgICogQHBhcmFtIG50ZnNUaW1lIHRoZSBOVEZTIHRpbWUgaW4gMTAwIG5hbm9zZWNvbmQgdW5pdHMKKyAgICAgKiBAcmV0dXJuIHRoZSBKYXZhIHRpbWUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIERhdGUgbnRmc1RpbWVUb0phdmFUaW1lKGZpbmFsIGxvbmcgbnRmc1RpbWUpIHsKKyAgICAgICAgZmluYWwgQ2FsZW5kYXIgbnRmc0Vwb2NoID0gQ2FsZW5kYXIuZ2V0SW5zdGFuY2UoKTsKKyAgICAgICAgbnRmc0Vwb2NoLnNldFRpbWVab25lKFRpbWVab25lLmdldFRpbWVab25lKCJHTVQrMCIpKTsKKyAgICAgICAgbnRmc0Vwb2NoLnNldCgxNjAxLCAwLCAxLCAwLCAwLCAwKTsKKyAgICAgICAgbnRmc0Vwb2NoLnNldChDYWxlbmRhci5NSUxMSVNFQ09ORCwgMCk7CisgICAgICAgIGZpbmFsIGxvbmcgcmVhbFRpbWUgPSBudGZzRXBvY2guZ2V0VGltZUluTWlsbGlzKCkgKyAobnRmc1RpbWUgLyAoMTAqMTAwMCkpOworICAgICAgICByZXR1cm4gbmV3IERhdGUocmVhbFRpbWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlcnRzIEphdmEgdGltZSB0byBOVEZTIHRpbWUuCisgICAgICogQHBhcmFtIGRhdGUgdGhlIEphdmEgdGltZQorICAgICAqIEByZXR1cm4gdGhlIE5URlMgdGltZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbG9uZyBqYXZhVGltZVRvTnRmc1RpbWUoZmluYWwgRGF0ZSBkYXRlKSB7CisgICAgICAgIGZpbmFsIENhbGVuZGFyIG50ZnNFcG9jaCA9IENhbGVuZGFyLmdldEluc3RhbmNlKCk7CisgICAgICAgIG50ZnNFcG9jaC5zZXRUaW1lWm9uZShUaW1lWm9uZS5nZXRUaW1lWm9uZSgiR01UKzAiKSk7CisgICAgICAgIG50ZnNFcG9jaC5zZXQoMTYwMSwgMCwgMSwgMCwgMCwgMCk7CisgICAgICAgIG50ZnNFcG9jaC5zZXQoQ2FsZW5kYXIuTUlMTElTRUNPTkQsIDApOworICAgICAgICByZXR1cm4gKChkYXRlLmdldFRpbWUoKSAtIG50ZnNFcG9jaC5nZXRUaW1lSW5NaWxsaXMoKSkqIDEwMDAgKiAxMCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3NldmVuei9TZXZlblpGaWxlLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvc2V2ZW56L1NldmVuWkZpbGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40MjFjMzRhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3NldmVuei9TZXZlblpGaWxlLmphdmEKQEAgLTAsMCArMSwxMjExIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuc2V2ZW56OworCitpbXBvcnQgamF2YS5pby5CdWZmZXJlZElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5DbG9zZWFibGU7CitpbXBvcnQgamF2YS5pby5EYXRhSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsdGVySW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEubmlvLkJ5dGVCdWZmZXI7CitpbXBvcnQgamF2YS5uaW8uQnl0ZU9yZGVyOworaW1wb3J0IGphdmEubmlvLkNoYXJCdWZmZXI7CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuU2Vla2FibGVCeXRlQ2hhbm5lbDsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LlN0YW5kYXJkQ2hhcnNldHM7CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0RW5jb2RlcjsKK2ltcG9ydCBqYXZhLm5pby5maWxlLkZpbGVzOworaW1wb3J0IGphdmEubmlvLmZpbGUuU3RhbmRhcmRPcGVuT3B0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuQml0U2V0OworaW1wb3J0IGphdmEudXRpbC5FbnVtU2V0OworaW1wb3J0IGphdmEudXRpbC5MaW5rZWRMaXN0OworaW1wb3J0IGphdmEudXRpbC56aXAuQ1JDMzI7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuQm91bmRlZElucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5DUkMzMlZlcmlmeWluZ0lucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5DaGFyc2V0TmFtZXM7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLklPVXRpbHM7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLklucHV0U3RyZWFtU3RhdGlzdGljczsKKworLyoqCisgKiBSZWFkcyBhIDd6IGZpbGUsIHVzaW5nIFNlZWthYmxlQnl0ZUNoYW5uZWwgdW5kZXIKKyAqIHRoZSBjb3ZlcnMuCisgKiA8cD4KKyAqIFRoZSA3eiBmaWxlIGZvcm1hdCBpcyBhIGZsZXhpYmxlIGNvbnRhaW5lcgorICogdGhhdCBjYW4gY29udGFpbiBtYW55IGNvbXByZXNzaW9uIGFuZAorICogZW5jcnlwdGlvbiB0eXBlcywgYnV0IGF0IHRoZSBtb21lbnQgb25seQorICogb25seSBDb3B5LCBMWk1BLCBMWk1BMiwgQlpJUDIsIERlZmxhdGUgYW5kIEFFUy0yNTYgKyBTSEEtMjU2CisgKiBhcmUgc3VwcG9ydGVkLgorICogPHA+CisgKiBUaGUgZm9ybWF0IGlzIHZlcnkgV2luZG93cy9JbnRlbCBzcGVjaWZpYywKKyAqIHNvIGl0IHVzZXMgbGl0dGxlLWVuZGlhbiBieXRlIG9yZGVyLAorICogZG9lc24ndCBzdG9yZSB1c2VyL2dyb3VwIG9yIHBlcm1pc3Npb24gYml0cywKKyAqIGFuZCByZXByZXNlbnRzIHRpbWVzIHVzaW5nIE5URlMgdGltZXN0YW1wcworICogKDEwMCBuYW5vc2Vjb25kIHVuaXRzIHNpbmNlIDEgSmFudWFyeSAxNjAxKS4KKyAqIEhlbmNlIHRoZSBvZmZpY2lhbCB0b29scyByZWNvbW1lbmQgYWdhaW5zdAorICogdXNpbmcgaXQgZm9yIGJhY2t1cCBwdXJwb3NlcyBvbiAqbml4LCBhbmQKKyAqIHJlY29tbWVuZCAudGFyLjd6IG9yIC50YXIubHptYSBvciAudGFyLnh6CisgKiBpbnN0ZWFkLgorICogPHA+CisgKiBCb3RoIHRoZSBoZWFkZXIgYW5kIGZpbGUgY29udGVudHMgbWF5IGJlCisgKiBjb21wcmVzc2VkIGFuZC9vciBlbmNyeXB0ZWQuIFdpdGggYm90aAorICogZW5jcnlwdGVkLCBuZWl0aGVyIGZpbGUgbmFtZXMgbm9yIGZpbGUKKyAqIGNvbnRlbnRzIGNhbiBiZSByZWFkLCBidXQgdGhlIHVzZSBvZgorICogZW5jcnlwdGlvbiBpc24ndCBwbGF1c2libHkgZGVuaWFibGUuCisgKgorICogQE5vdFRocmVhZFNhZmUKKyAqIEBzaW5jZSAxLjYKKyAqLworcHVibGljIGNsYXNzIFNldmVuWkZpbGUgaW1wbGVtZW50cyBDbG9zZWFibGUgeworICAgIHN0YXRpYyBmaW5hbCBpbnQgU0lHTkFUVVJFX0hFQURFUl9TSVpFID0gMzI7CisKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBmaWxlTmFtZTsKKyAgICBwcml2YXRlIFNlZWthYmxlQnl0ZUNoYW5uZWwgY2hhbm5lbDsKKyAgICBwcml2YXRlIGZpbmFsIEFyY2hpdmUgYXJjaGl2ZTsKKyAgICBwcml2YXRlIGludCBjdXJyZW50RW50cnlJbmRleCA9IC0xOworICAgIHByaXZhdGUgaW50IGN1cnJlbnRGb2xkZXJJbmRleCA9IC0xOworICAgIHByaXZhdGUgSW5wdXRTdHJlYW0gY3VycmVudEZvbGRlcklucHV0U3RyZWFtID0gbnVsbDsKKyAgICBwcml2YXRlIGJ5dGVbXSBwYXNzd29yZDsKKworICAgIHByaXZhdGUgbG9uZyBjb21wcmVzc2VkQnl0ZXNSZWFkRnJvbUN1cnJlbnRFbnRyeTsKKyAgICBwcml2YXRlIGxvbmcgdW5jb21wcmVzc2VkQnl0ZXNSZWFkRnJvbUN1cnJlbnRFbnRyeTsKKworICAgIHByaXZhdGUgZmluYWwgQXJyYXlMaXN0PElucHV0U3RyZWFtPiBkZWZlcnJlZEJsb2NrU3RyZWFtcyA9IG5ldyBBcnJheUxpc3Q8PigpOworCisgICAgLy8gc2hhcmVkIHdpdGggU2V2ZW5aT3V0cHV0RmlsZSBhbmQgdGVzdHMsIG5laXRoZXIgbXV0YXRlcyBpdAorICAgIHN0YXRpYyBmaW5hbCBieXRlW10gc2V2ZW5aU2lnbmF0dXJlID0geyAvL05PU09OQVIKKyAgICAgICAgKGJ5dGUpJzcnLCAoYnl0ZSkneicsIChieXRlKTB4QkMsIChieXRlKTB4QUYsIChieXRlKTB4MjcsIChieXRlKTB4MUMKKyAgICB9OworCisgICAgLyoqCisgICAgICogUmVhZHMgYSBmaWxlIGFzIDd6IGFyY2hpdmUKKyAgICAgKgorICAgICAqIEBwYXJhbSBmaWxlbmFtZSB0aGUgZmlsZSB0byByZWFkCisgICAgICogQHBhcmFtIHBhc3N3b3JkIG9wdGlvbmFsIHBhc3N3b3JkIGlmIHRoZSBhcmNoaXZlIGlzIGVuY3J5cHRlZAorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgcmVhZGluZyB0aGUgYXJjaGl2ZSBmYWlscworICAgICAqIEBzaW5jZSAxLjE3CisgICAgICovCisgICAgcHVibGljIFNldmVuWkZpbGUoZmluYWwgRmlsZSBmaWxlbmFtZSwgZmluYWwgY2hhcltdIHBhc3N3b3JkKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzKEZpbGVzLm5ld0J5dGVDaGFubmVsKGZpbGVuYW1lLnRvUGF0aCgpLCBFbnVtU2V0Lm9mKFN0YW5kYXJkT3Blbk9wdGlvbi5SRUFEKSksCisgICAgICAgICAgICAgZmlsZW5hbWUuZ2V0QWJzb2x1dGVQYXRoKCksIHV0ZjE2RGVjb2RlKHBhc3N3b3JkKSwgdHJ1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgYSBmaWxlIGFzIDd6IGFyY2hpdmUKKyAgICAgKgorICAgICAqIEBwYXJhbSBmaWxlbmFtZSB0aGUgZmlsZSB0byByZWFkCisgICAgICogQHBhcmFtIHBhc3N3b3JkIG9wdGlvbmFsIHBhc3N3b3JkIGlmIHRoZSBhcmNoaXZlIGlzIGVuY3J5cHRlZCAtCisgICAgICogdGhlIGJ5dGUgYXJyYXkgaXMgc3VwcG9zZWQgdG8gYmUgdGhlIFVURjE2LUxFIGVuY29kZWQKKyAgICAgKiByZXByZXNlbnRhdGlvbiBvZiB0aGUgcGFzc3dvcmQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiByZWFkaW5nIHRoZSBhcmNoaXZlIGZhaWxzCisgICAgICogQGRlcHJlY2F0ZWQgdXNlIHRoZSBjaGFyW10tYXJnIHZlcnNpb24gZm9yIHRoZSBwYXNzd29yZCBpbnN0ZWFkCisgICAgICovCisgICAgcHVibGljIFNldmVuWkZpbGUoZmluYWwgRmlsZSBmaWxlbmFtZSwgZmluYWwgYnl0ZVtdIHBhc3N3b3JkKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzKEZpbGVzLm5ld0J5dGVDaGFubmVsKGZpbGVuYW1lLnRvUGF0aCgpLCBFbnVtU2V0Lm9mKFN0YW5kYXJkT3Blbk9wdGlvbi5SRUFEKSksCisgICAgICAgICAgICAgZmlsZW5hbWUuZ2V0QWJzb2x1dGVQYXRoKCksIHBhc3N3b3JkLCB0cnVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhIFNlZWthYmxlQnl0ZUNoYW5uZWwgYXMgN3ogYXJjaGl2ZQorICAgICAqCisgICAgICogPHA+e0BsaW5rCisgICAgICogb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLlNlZWthYmxlSW5NZW1vcnlCeXRlQ2hhbm5lbH0KKyAgICAgKiBhbGxvd3MgeW91IHRvIHJlYWQgZnJvbSBhbiBpbi1tZW1vcnkgYXJjaGl2ZS48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gY2hhbm5lbCB0aGUgY2hhbm5lbCB0byByZWFkCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiByZWFkaW5nIHRoZSBhcmNoaXZlIGZhaWxzCisgICAgICogQHNpbmNlIDEuMTMKKyAgICAgKi8KKyAgICBwdWJsaWMgU2V2ZW5aRmlsZShmaW5hbCBTZWVrYWJsZUJ5dGVDaGFubmVsIGNoYW5uZWwpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMoY2hhbm5lbCwgInVua25vd24gYXJjaGl2ZSIsIChjaGFyW10pIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGEgU2Vla2FibGVCeXRlQ2hhbm5lbCBhcyA3eiBhcmNoaXZlCisgICAgICoKKyAgICAgKiA8cD57QGxpbmsKKyAgICAgKiBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuU2Vla2FibGVJbk1lbW9yeUJ5dGVDaGFubmVsfQorICAgICAqIGFsbG93cyB5b3UgdG8gcmVhZCBmcm9tIGFuIGluLW1lbW9yeSBhcmNoaXZlLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjaGFubmVsIHRoZSBjaGFubmVsIHRvIHJlYWQKKyAgICAgKiBAcGFyYW0gcGFzc3dvcmQgb3B0aW9uYWwgcGFzc3dvcmQgaWYgdGhlIGFyY2hpdmUgaXMgZW5jcnlwdGVkCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiByZWFkaW5nIHRoZSBhcmNoaXZlIGZhaWxzCisgICAgICogQHNpbmNlIDEuMTcKKyAgICAgKi8KKyAgICBwdWJsaWMgU2V2ZW5aRmlsZShmaW5hbCBTZWVrYWJsZUJ5dGVDaGFubmVsIGNoYW5uZWwsCisgICAgICAgICAgICAgICAgICAgICAgZmluYWwgY2hhcltdIHBhc3N3b3JkKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzKGNoYW5uZWwsICJ1bmtub3duIGFyY2hpdmUiLCB1dGYxNkRlY29kZShwYXNzd29yZCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGEgU2Vla2FibGVCeXRlQ2hhbm5lbCBhcyA3eiBhcmNoaXZlCisgICAgICoKKyAgICAgKiA8cD57QGxpbmsKKyAgICAgKiBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuU2Vla2FibGVJbk1lbW9yeUJ5dGVDaGFubmVsfQorICAgICAqIGFsbG93cyB5b3UgdG8gcmVhZCBmcm9tIGFuIGluLW1lbW9yeSBhcmNoaXZlLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjaGFubmVsIHRoZSBjaGFubmVsIHRvIHJlYWQKKyAgICAgKiBAcGFyYW0gZmlsZW5hbWUgbmFtZSBvZiB0aGUgYXJjaGl2ZSAtIG9ubHkgdXNlZCBmb3IgZXJyb3IgcmVwb3J0aW5nCisgICAgICogQHBhcmFtIHBhc3N3b3JkIG9wdGlvbmFsIHBhc3N3b3JkIGlmIHRoZSBhcmNoaXZlIGlzIGVuY3J5cHRlZAorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgcmVhZGluZyB0aGUgYXJjaGl2ZSBmYWlscworICAgICAqIEBzaW5jZSAxLjE3CisgICAgICovCisgICAgcHVibGljIFNldmVuWkZpbGUoZmluYWwgU2Vla2FibGVCeXRlQ2hhbm5lbCBjaGFubmVsLCBTdHJpbmcgZmlsZW5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgZmluYWwgY2hhcltdIHBhc3N3b3JkKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzKGNoYW5uZWwsIGZpbGVuYW1lLCB1dGYxNkRlY29kZShwYXNzd29yZCksIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhIFNlZWthYmxlQnl0ZUNoYW5uZWwgYXMgN3ogYXJjaGl2ZQorICAgICAqCisgICAgICogPHA+e0BsaW5rCisgICAgICogb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLlNlZWthYmxlSW5NZW1vcnlCeXRlQ2hhbm5lbH0KKyAgICAgKiBhbGxvd3MgeW91IHRvIHJlYWQgZnJvbSBhbiBpbi1tZW1vcnkgYXJjaGl2ZS48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gY2hhbm5lbCB0aGUgY2hhbm5lbCB0byByZWFkCisgICAgICogQHBhcmFtIGZpbGVuYW1lIG5hbWUgb2YgdGhlIGFyY2hpdmUgLSBvbmx5IHVzZWQgZm9yIGVycm9yIHJlcG9ydGluZworICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgcmVhZGluZyB0aGUgYXJjaGl2ZSBmYWlscworICAgICAqIEBzaW5jZSAxLjE3CisgICAgICovCisgICAgcHVibGljIFNldmVuWkZpbGUoZmluYWwgU2Vla2FibGVCeXRlQ2hhbm5lbCBjaGFubmVsLCBTdHJpbmcgZmlsZW5hbWUpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMoY2hhbm5lbCwgZmlsZW5hbWUsIG51bGwsIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhIFNlZWthYmxlQnl0ZUNoYW5uZWwgYXMgN3ogYXJjaGl2ZQorICAgICAqCisgICAgICogPHA+e0BsaW5rCisgICAgICogb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLlNlZWthYmxlSW5NZW1vcnlCeXRlQ2hhbm5lbH0KKyAgICAgKiBhbGxvd3MgeW91IHRvIHJlYWQgZnJvbSBhbiBpbi1tZW1vcnkgYXJjaGl2ZS48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gY2hhbm5lbCB0aGUgY2hhbm5lbCB0byByZWFkCisgICAgICogQHBhcmFtIHBhc3N3b3JkIG9wdGlvbmFsIHBhc3N3b3JkIGlmIHRoZSBhcmNoaXZlIGlzIGVuY3J5cHRlZCAtCisgICAgICogdGhlIGJ5dGUgYXJyYXkgaXMgc3VwcG9zZWQgdG8gYmUgdGhlIFVURjE2LUxFIGVuY29kZWQKKyAgICAgKiByZXByZXNlbnRhdGlvbiBvZiB0aGUgcGFzc3dvcmQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiByZWFkaW5nIHRoZSBhcmNoaXZlIGZhaWxzCisgICAgICogQHNpbmNlIDEuMTMKKyAgICAgKiBAZGVwcmVjYXRlZCB1c2UgdGhlIGNoYXJbXS1hcmcgdmVyc2lvbiBmb3IgdGhlIHBhc3N3b3JkIGluc3RlYWQKKyAgICAgKi8KKyAgICBwdWJsaWMgU2V2ZW5aRmlsZShmaW5hbCBTZWVrYWJsZUJ5dGVDaGFubmVsIGNoYW5uZWwsCisgICAgICAgICAgICAgICAgICAgICAgZmluYWwgYnl0ZVtdIHBhc3N3b3JkKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzKGNoYW5uZWwsICJ1bmtub3duIGFyY2hpdmUiLCBwYXNzd29yZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgYSBTZWVrYWJsZUJ5dGVDaGFubmVsIGFzIDd6IGFyY2hpdmUKKyAgICAgKgorICAgICAqIDxwPntAbGluaworICAgICAqIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5TZWVrYWJsZUluTWVtb3J5Qnl0ZUNoYW5uZWx9CisgICAgICogYWxsb3dzIHlvdSB0byByZWFkIGZyb20gYW4gaW4tbWVtb3J5IGFyY2hpdmUuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGNoYW5uZWwgdGhlIGNoYW5uZWwgdG8gcmVhZAorICAgICAqIEBwYXJhbSBmaWxlbmFtZSBuYW1lIG9mIHRoZSBhcmNoaXZlIC0gb25seSB1c2VkIGZvciBlcnJvciByZXBvcnRpbmcKKyAgICAgKiBAcGFyYW0gcGFzc3dvcmQgb3B0aW9uYWwgcGFzc3dvcmQgaWYgdGhlIGFyY2hpdmUgaXMgZW5jcnlwdGVkIC0KKyAgICAgKiB0aGUgYnl0ZSBhcnJheSBpcyBzdXBwb3NlZCB0byBiZSB0aGUgVVRGMTYtTEUgZW5jb2RlZAorICAgICAqIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBwYXNzd29yZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHJlYWRpbmcgdGhlIGFyY2hpdmUgZmFpbHMKKyAgICAgKiBAc2luY2UgMS4xMworICAgICAqIEBkZXByZWNhdGVkIHVzZSB0aGUgY2hhcltdLWFyZyB2ZXJzaW9uIGZvciB0aGUgcGFzc3dvcmQgaW5zdGVhZAorICAgICAqLworICAgIHB1YmxpYyBTZXZlblpGaWxlKGZpbmFsIFNlZWthYmxlQnl0ZUNoYW5uZWwgY2hhbm5lbCwgU3RyaW5nIGZpbGVuYW1lLAorICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBwYXNzd29yZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcyhjaGFubmVsLCBmaWxlbmFtZSwgcGFzc3dvcmQsIGZhbHNlKTsKKyAgICB9CisKKyAgICBwcml2YXRlIFNldmVuWkZpbGUoZmluYWwgU2Vla2FibGVCeXRlQ2hhbm5lbCBjaGFubmVsLCBTdHJpbmcgZmlsZW5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBwYXNzd29yZCwgYm9vbGVhbiBjbG9zZU9uRXJyb3IpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJvb2xlYW4gc3VjY2VlZGVkID0gZmFsc2U7CisgICAgICAgIHRoaXMuY2hhbm5lbCA9IGNoYW5uZWw7CisgICAgICAgIHRoaXMuZmlsZU5hbWUgPSBmaWxlbmFtZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFyY2hpdmUgPSByZWFkSGVhZGVycyhwYXNzd29yZCk7CisgICAgICAgICAgICBpZiAocGFzc3dvcmQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRoaXMucGFzc3dvcmQgPSBBcnJheXMuY29weU9mKHBhc3N3b3JkLCBwYXNzd29yZC5sZW5ndGgpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB0aGlzLnBhc3N3b3JkID0gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHN1Y2NlZWRlZCA9IHRydWU7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAoIXN1Y2NlZWRlZCAmJiBjbG9zZU9uRXJyb3IpIHsKKyAgICAgICAgICAgICAgICB0aGlzLmNoYW5uZWwuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGEgZmlsZSBhcyB1bmVuY3J5cHRlZCA3eiBhcmNoaXZlCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmlsZW5hbWUgdGhlIGZpbGUgdG8gcmVhZAorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgcmVhZGluZyB0aGUgYXJjaGl2ZSBmYWlscworICAgICAqLworICAgIHB1YmxpYyBTZXZlblpGaWxlKGZpbmFsIEZpbGUgZmlsZW5hbWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMoZmlsZW5hbWUsIChjaGFyW10pIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENsb3NlcyB0aGUgYXJjaGl2ZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIGNsb3NpbmcgdGhlIGZpbGUgZmFpbHMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChjaGFubmVsICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgY2hhbm5lbC5jbG9zZSgpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBjaGFubmVsID0gbnVsbDsKKyAgICAgICAgICAgICAgICBpZiAocGFzc3dvcmQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBBcnJheXMuZmlsbChwYXNzd29yZCwgKGJ5dGUpIDApOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBwYXNzd29yZCA9IG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuZXh0IEFyY2hpdmUgRW50cnkgaW4gdGhpcyBhcmNoaXZlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmV4dCBlbnRyeSwKKyAgICAgKiAgICAgICAgIG9yIHtAY29kZSBudWxsfSBpZiB0aGVyZSBhcmUgbm8gbW9yZSBlbnRyaWVzCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiB0aGUgbmV4dCBlbnRyeSBjb3VsZCBub3QgYmUgcmVhZAorICAgICAqLworICAgIHB1YmxpYyBTZXZlblpBcmNoaXZlRW50cnkgZ2V0TmV4dEVudHJ5KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGN1cnJlbnRFbnRyeUluZGV4ID49IGFyY2hpdmUuZmlsZXMubGVuZ3RoIC0gMSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgKytjdXJyZW50RW50cnlJbmRleDsKKyAgICAgICAgZmluYWwgU2V2ZW5aQXJjaGl2ZUVudHJ5IGVudHJ5ID0gYXJjaGl2ZS5maWxlc1tjdXJyZW50RW50cnlJbmRleF07CisgICAgICAgIGJ1aWxkRGVjb2RpbmdTdHJlYW0oKTsKKyAgICAgICAgdW5jb21wcmVzc2VkQnl0ZXNSZWFkRnJvbUN1cnJlbnRFbnRyeSA9IGNvbXByZXNzZWRCeXRlc1JlYWRGcm9tQ3VycmVudEVudHJ5ID0gMDsKKyAgICAgICAgcmV0dXJuIGVudHJ5OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgbWV0YS1kYXRhIG9mIGFsbCBhcmNoaXZlIGVudHJpZXMuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBvbmx5IHByb3ZpZGVzIG1ldGEtZGF0YSwgdGhlIGVudHJpZXMgY2FuIG5vdCBiZQorICAgICAqIHVzZWQgdG8gcmVhZCB0aGUgY29udGVudHMsIHlvdSBzdGlsbCBuZWVkIHRvIHByb2Nlc3MgYWxsCisgICAgICogZW50cmllcyBpbiBvcmRlciB1c2luZyB7QGxpbmsgI2dldE5leHRFbnRyeX0gZm9yIHRoYXQuPC9wPgorICAgICAqCisgICAgICogPHA+VGhlIGNvbnRlbnQgbWV0aG9kcyBhcmUgb25seSBhdmFpbGFibGUgZm9yIGVudHJpZXMgdGhhdCBoYXZlCisgICAgICogYWxyZWFkeSBiZWVuIHJlYWNoZWQgdmlhIHtAbGluayAjZ2V0TmV4dEVudHJ5fS48L3A+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIG1ldGEtZGF0YSBvZiBhbGwgYXJjaGl2ZSBlbnRyaWVzLgorICAgICAqIEBzaW5jZSAxLjExCisgICAgICovCisgICAgcHVibGljIEl0ZXJhYmxlPFNldmVuWkFyY2hpdmVFbnRyeT4gZ2V0RW50cmllcygpIHsKKyAgICAgICAgcmV0dXJuIEFycmF5cy5hc0xpc3QoYXJjaGl2ZS5maWxlcyk7CisgICAgfQorCisgICAgcHJpdmF0ZSBBcmNoaXZlIHJlYWRIZWFkZXJzKGZpbmFsIGJ5dGVbXSBwYXNzd29yZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgQnl0ZUJ1ZmZlciBidWYgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKDEyIC8qIHNpZ25hdHVyZSArIDIgYnl0ZXMgdmVyc2lvbiArIDQgYnl0ZXMgQ1JDICovKQorICAgICAgICAgICAgLm9yZGVyKEJ5dGVPcmRlci5MSVRUTEVfRU5ESUFOKTsKKyAgICAgICAgcmVhZEZ1bGx5KGJ1Zik7CisgICAgICAgIGZpbmFsIGJ5dGVbXSBzaWduYXR1cmUgPSBuZXcgYnl0ZVs2XTsKKyAgICAgICAgYnVmLmdldChzaWduYXR1cmUpOworICAgICAgICBpZiAoIUFycmF5cy5lcXVhbHMoc2lnbmF0dXJlLCBzZXZlblpTaWduYXR1cmUpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkJhZCA3eiBzaWduYXR1cmUiKTsKKyAgICAgICAgfQorICAgICAgICAvLyA3ekZvcm1hdC50eHQgaGFzIGl0IHdyb25nIC0gaXQncyBmaXJzdCBtYWpvciB0aGVuIG1pbm9yCisgICAgICAgIGZpbmFsIGJ5dGUgYXJjaGl2ZVZlcnNpb25NYWpvciA9IGJ1Zi5nZXQoKTsKKyAgICAgICAgZmluYWwgYnl0ZSBhcmNoaXZlVmVyc2lvbk1pbm9yID0gYnVmLmdldCgpOworICAgICAgICBpZiAoYXJjaGl2ZVZlcnNpb25NYWpvciAhPSAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oU3RyaW5nLmZvcm1hdCgiVW5zdXBwb3J0ZWQgN3ogdmVyc2lvbiAoJWQsJWQpIiwKKyAgICAgICAgICAgICAgICAgICAgYXJjaGl2ZVZlcnNpb25NYWpvciwgYXJjaGl2ZVZlcnNpb25NaW5vcikpOworICAgICAgICB9CisKKyAgICAgICAgZmluYWwgbG9uZyBzdGFydEhlYWRlckNyYyA9IDB4ZmZmZkZGRkZMICYgYnVmLmdldEludCgpOworICAgICAgICBmaW5hbCBTdGFydEhlYWRlciBzdGFydEhlYWRlciA9IHJlYWRTdGFydEhlYWRlcihzdGFydEhlYWRlckNyYyk7CisKKyAgICAgICAgZmluYWwgaW50IG5leHRIZWFkZXJTaXplSW50ID0gKGludCkgc3RhcnRIZWFkZXIubmV4dEhlYWRlclNpemU7CisgICAgICAgIGlmIChuZXh0SGVhZGVyU2l6ZUludCAhPSBzdGFydEhlYWRlci5uZXh0SGVhZGVyU2l6ZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJjYW5ub3QgaGFuZGxlIG5leHRIZWFkZXJTaXplICIgKyBzdGFydEhlYWRlci5uZXh0SGVhZGVyU2l6ZSk7CisgICAgICAgIH0KKyAgICAgICAgY2hhbm5lbC5wb3NpdGlvbihTSUdOQVRVUkVfSEVBREVSX1NJWkUgKyBzdGFydEhlYWRlci5uZXh0SGVhZGVyT2Zmc2V0KTsKKyAgICAgICAgYnVmID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZShuZXh0SGVhZGVyU2l6ZUludCkub3JkZXIoQnl0ZU9yZGVyLkxJVFRMRV9FTkRJQU4pOworICAgICAgICByZWFkRnVsbHkoYnVmKTsKKyAgICAgICAgZmluYWwgQ1JDMzIgY3JjID0gbmV3IENSQzMyKCk7CisgICAgICAgIGNyYy51cGRhdGUoYnVmLmFycmF5KCkpOworICAgICAgICBpZiAoc3RhcnRIZWFkZXIubmV4dEhlYWRlckNyYyAhPSBjcmMuZ2V0VmFsdWUoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJOZXh0SGVhZGVyIENSQyBtaXNtYXRjaCIpOworICAgICAgICB9CisKKyAgICAgICAgQXJjaGl2ZSBhcmNoaXZlID0gbmV3IEFyY2hpdmUoKTsKKyAgICAgICAgaW50IG5pZCA9IGdldFVuc2lnbmVkQnl0ZShidWYpOworICAgICAgICBpZiAobmlkID09IE5JRC5rRW5jb2RlZEhlYWRlcikgeworICAgICAgICAgICAgYnVmID0gcmVhZEVuY29kZWRIZWFkZXIoYnVmLCBhcmNoaXZlLCBwYXNzd29yZCk7CisgICAgICAgICAgICAvLyBBcmNoaXZlIGdldHMgcmVidWlsdCB3aXRoIHRoZSBuZXcgaGVhZGVyCisgICAgICAgICAgICBhcmNoaXZlID0gbmV3IEFyY2hpdmUoKTsKKyAgICAgICAgICAgIG5pZCA9IGdldFVuc2lnbmVkQnl0ZShidWYpOworICAgICAgICB9CisgICAgICAgIGlmIChuaWQgPT0gTklELmtIZWFkZXIpIHsKKyAgICAgICAgICAgIHJlYWRIZWFkZXIoYnVmLCBhcmNoaXZlKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiQnJva2VuIG9yIHVuc3VwcG9ydGVkIGFyY2hpdmU6IG5vIEhlYWRlciIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBhcmNoaXZlOworICAgIH0KKworICAgIHByaXZhdGUgU3RhcnRIZWFkZXIgcmVhZFN0YXJ0SGVhZGVyKGZpbmFsIGxvbmcgc3RhcnRIZWFkZXJDcmMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFN0YXJ0SGVhZGVyIHN0YXJ0SGVhZGVyID0gbmV3IFN0YXJ0SGVhZGVyKCk7CisgICAgICAgIC8vIHVzaW5nIFN0cmVhbSByYXRoZXIgdGhhbiBCeXRlQnVmZmVyIGZvciB0aGUgYmVuZWZpdCBvZiB0aGUKKyAgICAgICAgLy8gYnVpbHQtaW4gQ1JDIGNoZWNrCisgICAgICAgIHRyeSAoRGF0YUlucHV0U3RyZWFtIGRhdGFJbnB1dFN0cmVhbSA9IG5ldyBEYXRhSW5wdXRTdHJlYW0obmV3IENSQzMyVmVyaWZ5aW5nSW5wdXRTdHJlYW0oCisgICAgICAgICAgICAgICAgbmV3IEJvdW5kZWRTZWVrYWJsZUJ5dGVDaGFubmVsSW5wdXRTdHJlYW0oY2hhbm5lbCwgMjApLCAyMCwgc3RhcnRIZWFkZXJDcmMpKSkgeworICAgICAgICAgICAgIHN0YXJ0SGVhZGVyLm5leHRIZWFkZXJPZmZzZXQgPSBMb25nLnJldmVyc2VCeXRlcyhkYXRhSW5wdXRTdHJlYW0ucmVhZExvbmcoKSk7CisgICAgICAgICAgICAgc3RhcnRIZWFkZXIubmV4dEhlYWRlclNpemUgPSBMb25nLnJldmVyc2VCeXRlcyhkYXRhSW5wdXRTdHJlYW0ucmVhZExvbmcoKSk7CisgICAgICAgICAgICAgc3RhcnRIZWFkZXIubmV4dEhlYWRlckNyYyA9IDB4ZmZmZkZGRkZMICYgSW50ZWdlci5yZXZlcnNlQnl0ZXMoZGF0YUlucHV0U3RyZWFtLnJlYWRJbnQoKSk7CisgICAgICAgICAgICAgcmV0dXJuIHN0YXJ0SGVhZGVyOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHJlYWRIZWFkZXIoZmluYWwgQnl0ZUJ1ZmZlciBoZWFkZXIsIGZpbmFsIEFyY2hpdmUgYXJjaGl2ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IG5pZCA9IGdldFVuc2lnbmVkQnl0ZShoZWFkZXIpOworCisgICAgICAgIGlmIChuaWQgPT0gTklELmtBcmNoaXZlUHJvcGVydGllcykgeworICAgICAgICAgICAgcmVhZEFyY2hpdmVQcm9wZXJ0aWVzKGhlYWRlcik7CisgICAgICAgICAgICBuaWQgPSBnZXRVbnNpZ25lZEJ5dGUoaGVhZGVyKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChuaWQgPT0gTklELmtBZGRpdGlvbmFsU3RyZWFtc0luZm8pIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiQWRkaXRpb25hbCBzdHJlYW1zIHVuc3VwcG9ydGVkIik7CisgICAgICAgICAgICAvL25pZCA9IGhlYWRlci5yZWFkVW5zaWduZWRCeXRlKCk7CisgICAgICAgIH0KKworICAgICAgICBpZiAobmlkID09IE5JRC5rTWFpblN0cmVhbXNJbmZvKSB7CisgICAgICAgICAgICByZWFkU3RyZWFtc0luZm8oaGVhZGVyLCBhcmNoaXZlKTsKKyAgICAgICAgICAgIG5pZCA9IGdldFVuc2lnbmVkQnl0ZShoZWFkZXIpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKG5pZCA9PSBOSUQua0ZpbGVzSW5mbykgeworICAgICAgICAgICAgcmVhZEZpbGVzSW5mbyhoZWFkZXIsIGFyY2hpdmUpOworICAgICAgICAgICAgbmlkID0gZ2V0VW5zaWduZWRCeXRlKGhlYWRlcik7CisgICAgICAgIH0KKworICAgICAgICBpZiAobmlkICE9IE5JRC5rRW5kKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkJhZGx5IHRlcm1pbmF0ZWQgaGVhZGVyLCBmb3VuZCAiICsgbmlkKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByZWFkQXJjaGl2ZVByb3BlcnRpZXMoZmluYWwgQnl0ZUJ1ZmZlciBpbnB1dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gRklYTUU6IHRoZSByZWZlcmVuY2UgaW1wbGVtZW50YXRpb24ganVzdCB0aHJvd3MgdGhlbSBhd2F5PworICAgICAgICBpbnQgbmlkID0gIGdldFVuc2lnbmVkQnl0ZShpbnB1dCk7CisgICAgICAgIHdoaWxlIChuaWQgIT0gTklELmtFbmQpIHsKKyAgICAgICAgICAgIGZpbmFsIGxvbmcgcHJvcGVydHlTaXplID0gcmVhZFVpbnQ2NChpbnB1dCk7CisgICAgICAgICAgICBmaW5hbCBieXRlW10gcHJvcGVydHkgPSBuZXcgYnl0ZVsoaW50KXByb3BlcnR5U2l6ZV07CisgICAgICAgICAgICBpbnB1dC5nZXQocHJvcGVydHkpOworICAgICAgICAgICAgbmlkID0gZ2V0VW5zaWduZWRCeXRlKGlucHV0KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgQnl0ZUJ1ZmZlciByZWFkRW5jb2RlZEhlYWRlcihmaW5hbCBCeXRlQnVmZmVyIGhlYWRlciwgZmluYWwgQXJjaGl2ZSBhcmNoaXZlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBieXRlW10gcGFzc3dvcmQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJlYWRTdHJlYW1zSW5mbyhoZWFkZXIsIGFyY2hpdmUpOworCisgICAgICAgIC8vIEZJWE1FOiBtZXJnZSB3aXRoIGJ1aWxkRGVjb2RpbmdTdHJlYW0oKS9idWlsZERlY29kZXJTdGFjaygpIGF0IHNvbWUgc3RhZ2U/CisgICAgICAgIGZpbmFsIEZvbGRlciBmb2xkZXIgPSBhcmNoaXZlLmZvbGRlcnNbMF07CisgICAgICAgIGZpbmFsIGludCBmaXJzdFBhY2tTdHJlYW1JbmRleCA9IDA7CisgICAgICAgIGZpbmFsIGxvbmcgZm9sZGVyT2Zmc2V0ID0gU0lHTkFUVVJFX0hFQURFUl9TSVpFICsgYXJjaGl2ZS5wYWNrUG9zICsKKyAgICAgICAgICAgICAgICAwOworCisgICAgICAgIGNoYW5uZWwucG9zaXRpb24oZm9sZGVyT2Zmc2V0KTsKKyAgICAgICAgSW5wdXRTdHJlYW0gaW5wdXRTdHJlYW1TdGFjayA9IG5ldyBCb3VuZGVkU2Vla2FibGVCeXRlQ2hhbm5lbElucHV0U3RyZWFtKGNoYW5uZWwsCisgICAgICAgICAgICAgICAgYXJjaGl2ZS5wYWNrU2l6ZXNbZmlyc3RQYWNrU3RyZWFtSW5kZXhdKTsKKyAgICAgICAgZm9yIChmaW5hbCBDb2RlciBjb2RlciA6IGZvbGRlci5nZXRPcmRlcmVkQ29kZXJzKCkpIHsKKyAgICAgICAgICAgIGlmIChjb2Rlci5udW1JblN0cmVhbXMgIT0gMSB8fCBjb2Rlci5udW1PdXRTdHJlYW1zICE9IDEpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIk11bHRpIGlucHV0L291dHB1dCBzdHJlYW0gY29kZXJzIGFyZSBub3QgeWV0IHN1cHBvcnRlZCIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaW5wdXRTdHJlYW1TdGFjayA9IENvZGVycy5hZGREZWNvZGVyKGZpbGVOYW1lLCBpbnB1dFN0cmVhbVN0YWNrLCAvL05PU09OQVIKKyAgICAgICAgICAgICAgICAgICAgZm9sZGVyLmdldFVucGFja1NpemVGb3JDb2Rlcihjb2RlciksIGNvZGVyLCBwYXNzd29yZCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGZvbGRlci5oYXNDcmMpIHsKKyAgICAgICAgICAgIGlucHV0U3RyZWFtU3RhY2sgPSBuZXcgQ1JDMzJWZXJpZnlpbmdJbnB1dFN0cmVhbShpbnB1dFN0cmVhbVN0YWNrLAorICAgICAgICAgICAgICAgICAgICBmb2xkZXIuZ2V0VW5wYWNrU2l6ZSgpLCBmb2xkZXIuY3JjKTsKKyAgICAgICAgfQorICAgICAgICBmaW5hbCBieXRlW10gbmV4dEhlYWRlciA9IG5ldyBieXRlWyhpbnQpZm9sZGVyLmdldFVucGFja1NpemUoKV07CisgICAgICAgIHRyeSAoRGF0YUlucHV0U3RyZWFtIG5leHRIZWFkZXJJbnB1dFN0cmVhbSA9IG5ldyBEYXRhSW5wdXRTdHJlYW0oaW5wdXRTdHJlYW1TdGFjaykpIHsKKyAgICAgICAgICAgIG5leHRIZWFkZXJJbnB1dFN0cmVhbS5yZWFkRnVsbHkobmV4dEhlYWRlcik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIEJ5dGVCdWZmZXIud3JhcChuZXh0SGVhZGVyKS5vcmRlcihCeXRlT3JkZXIuTElUVExFX0VORElBTik7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHJlYWRTdHJlYW1zSW5mbyhmaW5hbCBCeXRlQnVmZmVyIGhlYWRlciwgZmluYWwgQXJjaGl2ZSBhcmNoaXZlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgbmlkID0gZ2V0VW5zaWduZWRCeXRlKGhlYWRlcik7CisKKyAgICAgICAgaWYgKG5pZCA9PSBOSUQua1BhY2tJbmZvKSB7CisgICAgICAgICAgICByZWFkUGFja0luZm8oaGVhZGVyLCBhcmNoaXZlKTsKKyAgICAgICAgICAgIG5pZCA9IGdldFVuc2lnbmVkQnl0ZShoZWFkZXIpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKG5pZCA9PSBOSUQua1VucGFja0luZm8pIHsKKyAgICAgICAgICAgIHJlYWRVbnBhY2tJbmZvKGhlYWRlciwgYXJjaGl2ZSk7CisgICAgICAgICAgICBuaWQgPSBnZXRVbnNpZ25lZEJ5dGUoaGVhZGVyKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8vIGFyY2hpdmUgd2l0aG91dCB1bnBhY2svY29kZXJzIGluZm8KKyAgICAgICAgICAgIGFyY2hpdmUuZm9sZGVycyA9IG5ldyBGb2xkZXJbMF07CisgICAgICAgIH0KKworICAgICAgICBpZiAobmlkID09IE5JRC5rU3ViU3RyZWFtc0luZm8pIHsKKyAgICAgICAgICAgIHJlYWRTdWJTdHJlYW1zSW5mbyhoZWFkZXIsIGFyY2hpdmUpOworICAgICAgICAgICAgbmlkID0gZ2V0VW5zaWduZWRCeXRlKGhlYWRlcik7CisgICAgICAgIH0KKworICAgICAgICBpZiAobmlkICE9IE5JRC5rRW5kKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkJhZGx5IHRlcm1pbmF0ZWQgU3RyZWFtc0luZm8iKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByZWFkUGFja0luZm8oZmluYWwgQnl0ZUJ1ZmZlciBoZWFkZXIsIGZpbmFsIEFyY2hpdmUgYXJjaGl2ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYXJjaGl2ZS5wYWNrUG9zID0gcmVhZFVpbnQ2NChoZWFkZXIpOworICAgICAgICBmaW5hbCBsb25nIG51bVBhY2tTdHJlYW1zID0gcmVhZFVpbnQ2NChoZWFkZXIpOworICAgICAgICBpbnQgbmlkID0gZ2V0VW5zaWduZWRCeXRlKGhlYWRlcik7CisgICAgICAgIGlmIChuaWQgPT0gTklELmtTaXplKSB7CisgICAgICAgICAgICBhcmNoaXZlLnBhY2tTaXplcyA9IG5ldyBsb25nWyhpbnQpbnVtUGFja1N0cmVhbXNdOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcmNoaXZlLnBhY2tTaXplcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIGFyY2hpdmUucGFja1NpemVzW2ldID0gcmVhZFVpbnQ2NChoZWFkZXIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgbmlkID0gZ2V0VW5zaWduZWRCeXRlKGhlYWRlcik7CisgICAgICAgIH0KKworICAgICAgICBpZiAobmlkID09IE5JRC5rQ1JDKSB7CisgICAgICAgICAgICBhcmNoaXZlLnBhY2tDcmNzRGVmaW5lZCA9IHJlYWRBbGxPckJpdHMoaGVhZGVyLCAoaW50KW51bVBhY2tTdHJlYW1zKTsKKyAgICAgICAgICAgIGFyY2hpdmUucGFja0NyY3MgPSBuZXcgbG9uZ1soaW50KW51bVBhY2tTdHJlYW1zXTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgKGludCludW1QYWNrU3RyZWFtczsgaSsrKSB7CisgICAgICAgICAgICAgICAgaWYgKGFyY2hpdmUucGFja0NyY3NEZWZpbmVkLmdldChpKSkgeworICAgICAgICAgICAgICAgICAgICBhcmNoaXZlLnBhY2tDcmNzW2ldID0gMHhmZmZmRkZGRkwgJiBoZWFkZXIuZ2V0SW50KCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBuaWQgPSBnZXRVbnNpZ25lZEJ5dGUoaGVhZGVyKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChuaWQgIT0gTklELmtFbmQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiQmFkbHkgdGVybWluYXRlZCBQYWNrSW5mbyAoIiArIG5pZCArICIpIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcmVhZFVucGFja0luZm8oZmluYWwgQnl0ZUJ1ZmZlciBoZWFkZXIsIGZpbmFsIEFyY2hpdmUgYXJjaGl2ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IG5pZCA9IGdldFVuc2lnbmVkQnl0ZShoZWFkZXIpOworICAgICAgICBpZiAobmlkICE9IE5JRC5rRm9sZGVyKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkV4cGVjdGVkIGtGb2xkZXIsIGdvdCAiICsgbmlkKTsKKyAgICAgICAgfQorICAgICAgICBmaW5hbCBsb25nIG51bUZvbGRlcnMgPSByZWFkVWludDY0KGhlYWRlcik7CisgICAgICAgIGZpbmFsIEZvbGRlcltdIGZvbGRlcnMgPSBuZXcgRm9sZGVyWyhpbnQpbnVtRm9sZGVyc107CisgICAgICAgIGFyY2hpdmUuZm9sZGVycyA9IGZvbGRlcnM7CisgICAgICAgIGZpbmFsIGludCBleHRlcm5hbCA9IGdldFVuc2lnbmVkQnl0ZShoZWFkZXIpOworICAgICAgICBpZiAoZXh0ZXJuYWwgIT0gMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJFeHRlcm5hbCB1bnN1cHBvcnRlZCIpOworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgKGludCludW1Gb2xkZXJzOyBpKyspIHsKKyAgICAgICAgICAgIGZvbGRlcnNbaV0gPSByZWFkRm9sZGVyKGhlYWRlcik7CisgICAgICAgIH0KKworICAgICAgICBuaWQgPSBnZXRVbnNpZ25lZEJ5dGUoaGVhZGVyKTsKKyAgICAgICAgaWYgKG5pZCAhPSBOSUQua0NvZGVyc1VucGFja1NpemUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiRXhwZWN0ZWQga0NvZGVyc1VucGFja1NpemUsIGdvdCAiICsgbmlkKTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGZpbmFsIEZvbGRlciBmb2xkZXIgOiBmb2xkZXJzKSB7CisgICAgICAgICAgICBmb2xkZXIudW5wYWNrU2l6ZXMgPSBuZXcgbG9uZ1soaW50KWZvbGRlci50b3RhbE91dHB1dFN0cmVhbXNdOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmb2xkZXIudG90YWxPdXRwdXRTdHJlYW1zOyBpKyspIHsKKyAgICAgICAgICAgICAgICBmb2xkZXIudW5wYWNrU2l6ZXNbaV0gPSByZWFkVWludDY0KGhlYWRlcik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBuaWQgPSBnZXRVbnNpZ25lZEJ5dGUoaGVhZGVyKTsKKyAgICAgICAgaWYgKG5pZCA9PSBOSUQua0NSQykgeworICAgICAgICAgICAgZmluYWwgQml0U2V0IGNyY3NEZWZpbmVkID0gcmVhZEFsbE9yQml0cyhoZWFkZXIsIChpbnQpbnVtRm9sZGVycyk7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IChpbnQpbnVtRm9sZGVyczsgaSsrKSB7CisgICAgICAgICAgICAgICAgaWYgKGNyY3NEZWZpbmVkLmdldChpKSkgeworICAgICAgICAgICAgICAgICAgICBmb2xkZXJzW2ldLmhhc0NyYyA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgIGZvbGRlcnNbaV0uY3JjID0gMHhmZmZmRkZGRkwgJiBoZWFkZXIuZ2V0SW50KCk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgZm9sZGVyc1tpXS5oYXNDcmMgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIG5pZCA9IGdldFVuc2lnbmVkQnl0ZShoZWFkZXIpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKG5pZCAhPSBOSUQua0VuZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJCYWRseSB0ZXJtaW5hdGVkIFVucGFja0luZm8iKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByZWFkU3ViU3RyZWFtc0luZm8oZmluYWwgQnl0ZUJ1ZmZlciBoZWFkZXIsIGZpbmFsIEFyY2hpdmUgYXJjaGl2ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZm9yIChmaW5hbCBGb2xkZXIgZm9sZGVyIDogYXJjaGl2ZS5mb2xkZXJzKSB7CisgICAgICAgICAgICBmb2xkZXIubnVtVW5wYWNrU3ViU3RyZWFtcyA9IDE7CisgICAgICAgIH0KKyAgICAgICAgaW50IHRvdGFsVW5wYWNrU3RyZWFtcyA9IGFyY2hpdmUuZm9sZGVycy5sZW5ndGg7CisKKyAgICAgICAgaW50IG5pZCA9IGdldFVuc2lnbmVkQnl0ZShoZWFkZXIpOworICAgICAgICBpZiAobmlkID09IE5JRC5rTnVtVW5wYWNrU3RyZWFtKSB7CisgICAgICAgICAgICB0b3RhbFVucGFja1N0cmVhbXMgPSAwOworICAgICAgICAgICAgZm9yIChmaW5hbCBGb2xkZXIgZm9sZGVyIDogYXJjaGl2ZS5mb2xkZXJzKSB7CisgICAgICAgICAgICAgICAgZmluYWwgbG9uZyBudW1TdHJlYW1zID0gcmVhZFVpbnQ2NChoZWFkZXIpOworICAgICAgICAgICAgICAgIGZvbGRlci5udW1VbnBhY2tTdWJTdHJlYW1zID0gKGludCludW1TdHJlYW1zOworICAgICAgICAgICAgICAgIHRvdGFsVW5wYWNrU3RyZWFtcyArPSBudW1TdHJlYW1zOworICAgICAgICAgICAgfQorICAgICAgICAgICAgbmlkID0gZ2V0VW5zaWduZWRCeXRlKGhlYWRlcik7CisgICAgICAgIH0KKworICAgICAgICBmaW5hbCBTdWJTdHJlYW1zSW5mbyBzdWJTdHJlYW1zSW5mbyA9IG5ldyBTdWJTdHJlYW1zSW5mbygpOworICAgICAgICBzdWJTdHJlYW1zSW5mby51bnBhY2tTaXplcyA9IG5ldyBsb25nW3RvdGFsVW5wYWNrU3RyZWFtc107CisgICAgICAgIHN1YlN0cmVhbXNJbmZvLmhhc0NyYyA9IG5ldyBCaXRTZXQodG90YWxVbnBhY2tTdHJlYW1zKTsKKyAgICAgICAgc3ViU3RyZWFtc0luZm8uY3JjcyA9IG5ldyBsb25nW3RvdGFsVW5wYWNrU3RyZWFtc107CisKKyAgICAgICAgaW50IG5leHRVbnBhY2tTdHJlYW0gPSAwOworICAgICAgICBmb3IgKGZpbmFsIEZvbGRlciBmb2xkZXIgOiBhcmNoaXZlLmZvbGRlcnMpIHsKKyAgICAgICAgICAgIGlmIChmb2xkZXIubnVtVW5wYWNrU3ViU3RyZWFtcyA9PSAwKSB7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBsb25nIHN1bSA9IDA7CisgICAgICAgICAgICBpZiAobmlkID09IE5JRC5rU2l6ZSkgeworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZm9sZGVyLm51bVVucGFja1N1YlN0cmVhbXMgLSAxOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgbG9uZyBzaXplID0gcmVhZFVpbnQ2NChoZWFkZXIpOworICAgICAgICAgICAgICAgICAgICBzdWJTdHJlYW1zSW5mby51bnBhY2tTaXplc1tuZXh0VW5wYWNrU3RyZWFtKytdID0gc2l6ZTsKKyAgICAgICAgICAgICAgICAgICAgc3VtICs9IHNpemU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgc3ViU3RyZWFtc0luZm8udW5wYWNrU2l6ZXNbbmV4dFVucGFja1N0cmVhbSsrXSA9IGZvbGRlci5nZXRVbnBhY2tTaXplKCkgLSBzdW07CisgICAgICAgIH0KKyAgICAgICAgaWYgKG5pZCA9PSBOSUQua1NpemUpIHsKKyAgICAgICAgICAgIG5pZCA9IGdldFVuc2lnbmVkQnl0ZShoZWFkZXIpOworICAgICAgICB9CisKKyAgICAgICAgaW50IG51bURpZ2VzdHMgPSAwOworICAgICAgICBmb3IgKGZpbmFsIEZvbGRlciBmb2xkZXIgOiBhcmNoaXZlLmZvbGRlcnMpIHsKKyAgICAgICAgICAgIGlmIChmb2xkZXIubnVtVW5wYWNrU3ViU3RyZWFtcyAhPSAxIHx8ICFmb2xkZXIuaGFzQ3JjKSB7CisgICAgICAgICAgICAgICAgbnVtRGlnZXN0cyArPSBmb2xkZXIubnVtVW5wYWNrU3ViU3RyZWFtczsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmIChuaWQgPT0gTklELmtDUkMpIHsKKyAgICAgICAgICAgIGZpbmFsIEJpdFNldCBoYXNNaXNzaW5nQ3JjID0gcmVhZEFsbE9yQml0cyhoZWFkZXIsIG51bURpZ2VzdHMpOworICAgICAgICAgICAgZmluYWwgbG9uZ1tdIG1pc3NpbmdDcmNzID0gbmV3IGxvbmdbbnVtRGlnZXN0c107CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bURpZ2VzdHM7IGkrKykgeworICAgICAgICAgICAgICAgIGlmIChoYXNNaXNzaW5nQ3JjLmdldChpKSkgeworICAgICAgICAgICAgICAgICAgICBtaXNzaW5nQ3Jjc1tpXSA9IDB4ZmZmZkZGRkZMICYgaGVhZGVyLmdldEludCgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGludCBuZXh0Q3JjID0gMDsKKyAgICAgICAgICAgIGludCBuZXh0TWlzc2luZ0NyYyA9IDA7CisgICAgICAgICAgICBmb3IgKGZpbmFsIEZvbGRlciBmb2xkZXI6IGFyY2hpdmUuZm9sZGVycykgeworICAgICAgICAgICAgICAgIGlmIChmb2xkZXIubnVtVW5wYWNrU3ViU3RyZWFtcyA9PSAxICYmIGZvbGRlci5oYXNDcmMpIHsKKyAgICAgICAgICAgICAgICAgICAgc3ViU3RyZWFtc0luZm8uaGFzQ3JjLnNldChuZXh0Q3JjLCB0cnVlKTsKKyAgICAgICAgICAgICAgICAgICAgc3ViU3RyZWFtc0luZm8uY3Jjc1tuZXh0Q3JjXSA9IGZvbGRlci5jcmM7CisgICAgICAgICAgICAgICAgICAgICsrbmV4dENyYzsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZvbGRlci5udW1VbnBhY2tTdWJTdHJlYW1zOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHN1YlN0cmVhbXNJbmZvLmhhc0NyYy5zZXQobmV4dENyYywgaGFzTWlzc2luZ0NyYy5nZXQobmV4dE1pc3NpbmdDcmMpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHN1YlN0cmVhbXNJbmZvLmNyY3NbbmV4dENyY10gPSBtaXNzaW5nQ3Jjc1tuZXh0TWlzc2luZ0NyY107CisgICAgICAgICAgICAgICAgICAgICAgICArK25leHRDcmM7CisgICAgICAgICAgICAgICAgICAgICAgICArK25leHRNaXNzaW5nQ3JjOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBuaWQgPSBnZXRVbnNpZ25lZEJ5dGUoaGVhZGVyKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChuaWQgIT0gTklELmtFbmQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiQmFkbHkgdGVybWluYXRlZCBTdWJTdHJlYW1zSW5mbyIpOworICAgICAgICB9CisKKyAgICAgICAgYXJjaGl2ZS5zdWJTdHJlYW1zSW5mbyA9IHN1YlN0cmVhbXNJbmZvOworICAgIH0KKworICAgIHByaXZhdGUgRm9sZGVyIHJlYWRGb2xkZXIoZmluYWwgQnl0ZUJ1ZmZlciBoZWFkZXIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZvbGRlciBmb2xkZXIgPSBuZXcgRm9sZGVyKCk7CisKKyAgICAgICAgZmluYWwgbG9uZyBudW1Db2RlcnMgPSByZWFkVWludDY0KGhlYWRlcik7CisgICAgICAgIGZpbmFsIENvZGVyW10gY29kZXJzID0gbmV3IENvZGVyWyhpbnQpbnVtQ29kZXJzXTsKKyAgICAgICAgbG9uZyB0b3RhbEluU3RyZWFtcyA9IDA7CisgICAgICAgIGxvbmcgdG90YWxPdXRTdHJlYW1zID0gMDsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb2RlcnMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGNvZGVyc1tpXSA9IG5ldyBDb2RlcigpOworICAgICAgICAgICAgZmluYWwgaW50IGJpdHMgPSBnZXRVbnNpZ25lZEJ5dGUoaGVhZGVyKTsKKyAgICAgICAgICAgIGZpbmFsIGludCBpZFNpemUgPSBiaXRzICYgMHhmOworICAgICAgICAgICAgZmluYWwgYm9vbGVhbiBpc1NpbXBsZSA9IChiaXRzICYgMHgxMCkgPT0gMDsKKyAgICAgICAgICAgIGZpbmFsIGJvb2xlYW4gaGFzQXR0cmlidXRlcyA9IChiaXRzICYgMHgyMCkgIT0gMDsKKyAgICAgICAgICAgIGZpbmFsIGJvb2xlYW4gbW9yZUFsdGVybmF0aXZlTWV0aG9kcyA9IChiaXRzICYgMHg4MCkgIT0gMDsKKworICAgICAgICAgICAgY29kZXJzW2ldLmRlY29tcHJlc3Npb25NZXRob2RJZCA9IG5ldyBieXRlW2lkU2l6ZV07CisgICAgICAgICAgICBoZWFkZXIuZ2V0KGNvZGVyc1tpXS5kZWNvbXByZXNzaW9uTWV0aG9kSWQpOworICAgICAgICAgICAgaWYgKGlzU2ltcGxlKSB7CisgICAgICAgICAgICAgICAgY29kZXJzW2ldLm51bUluU3RyZWFtcyA9IDE7CisgICAgICAgICAgICAgICAgY29kZXJzW2ldLm51bU91dFN0cmVhbXMgPSAxOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBjb2RlcnNbaV0ubnVtSW5TdHJlYW1zID0gcmVhZFVpbnQ2NChoZWFkZXIpOworICAgICAgICAgICAgICAgIGNvZGVyc1tpXS5udW1PdXRTdHJlYW1zID0gcmVhZFVpbnQ2NChoZWFkZXIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdG90YWxJblN0cmVhbXMgKz0gY29kZXJzW2ldLm51bUluU3RyZWFtczsKKyAgICAgICAgICAgIHRvdGFsT3V0U3RyZWFtcyArPSBjb2RlcnNbaV0ubnVtT3V0U3RyZWFtczsKKyAgICAgICAgICAgIGlmIChoYXNBdHRyaWJ1dGVzKSB7CisgICAgICAgICAgICAgICAgZmluYWwgbG9uZyBwcm9wZXJ0aWVzU2l6ZSA9IHJlYWRVaW50NjQoaGVhZGVyKTsKKyAgICAgICAgICAgICAgICBjb2RlcnNbaV0ucHJvcGVydGllcyA9IG5ldyBieXRlWyhpbnQpcHJvcGVydGllc1NpemVdOworICAgICAgICAgICAgICAgIGhlYWRlci5nZXQoY29kZXJzW2ldLnByb3BlcnRpZXMpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gd291bGQgbmVlZCB0byBrZWVwIGxvb3BpbmcgYXMgYWJvdmU6CisgICAgICAgICAgICB3aGlsZSAobW9yZUFsdGVybmF0aXZlTWV0aG9kcykgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiQWx0ZXJuYXRpdmUgbWV0aG9kcyBhcmUgdW5zdXBwb3J0ZWQsIHBsZWFzZSByZXBvcnQuICIgKworICAgICAgICAgICAgICAgICAgICAgICAgIlRoZSByZWZlcmVuY2UgaW1wbGVtZW50YXRpb24gZG9lc24ndCBzdXBwb3J0IHRoZW0gZWl0aGVyLiIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGZvbGRlci5jb2RlcnMgPSBjb2RlcnM7CisgICAgICAgIGZvbGRlci50b3RhbElucHV0U3RyZWFtcyA9IHRvdGFsSW5TdHJlYW1zOworICAgICAgICBmb2xkZXIudG90YWxPdXRwdXRTdHJlYW1zID0gdG90YWxPdXRTdHJlYW1zOworCisgICAgICAgIGlmICh0b3RhbE91dFN0cmVhbXMgPT0gMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJUb3RhbCBvdXRwdXQgc3RyZWFtcyBjYW4ndCBiZSAwIik7CisgICAgICAgIH0KKyAgICAgICAgZmluYWwgbG9uZyBudW1CaW5kUGFpcnMgPSB0b3RhbE91dFN0cmVhbXMgLSAxOworICAgICAgICBmaW5hbCBCaW5kUGFpcltdIGJpbmRQYWlycyA9IG5ldyBCaW5kUGFpclsoaW50KW51bUJpbmRQYWlyc107CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYmluZFBhaXJzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBiaW5kUGFpcnNbaV0gPSBuZXcgQmluZFBhaXIoKTsKKyAgICAgICAgICAgIGJpbmRQYWlyc1tpXS5pbkluZGV4ID0gcmVhZFVpbnQ2NChoZWFkZXIpOworICAgICAgICAgICAgYmluZFBhaXJzW2ldLm91dEluZGV4ID0gcmVhZFVpbnQ2NChoZWFkZXIpOworICAgICAgICB9CisgICAgICAgIGZvbGRlci5iaW5kUGFpcnMgPSBiaW5kUGFpcnM7CisKKyAgICAgICAgaWYgKHRvdGFsSW5TdHJlYW1zIDwgbnVtQmluZFBhaXJzKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlRvdGFsIGlucHV0IHN0cmVhbXMgY2FuJ3QgYmUgbGVzcyB0aGFuIHRoZSBudW1iZXIgb2YgYmluZCBwYWlycyIpOworICAgICAgICB9CisgICAgICAgIGZpbmFsIGxvbmcgbnVtUGFja2VkU3RyZWFtcyA9IHRvdGFsSW5TdHJlYW1zIC0gbnVtQmluZFBhaXJzOworICAgICAgICBmaW5hbCBsb25nIHBhY2tlZFN0cmVhbXNbXSA9IG5ldyBsb25nWyhpbnQpbnVtUGFja2VkU3RyZWFtc107CisgICAgICAgIGlmIChudW1QYWNrZWRTdHJlYW1zID09IDEpIHsKKyAgICAgICAgICAgIGludCBpOworICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IChpbnQpdG90YWxJblN0cmVhbXM7IGkrKykgeworICAgICAgICAgICAgICAgIGlmIChmb2xkZXIuZmluZEJpbmRQYWlyRm9ySW5TdHJlYW0oaSkgPCAwKSB7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChpID09IChpbnQpdG90YWxJblN0cmVhbXMpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkNvdWxkbid0IGZpbmQgc3RyZWFtJ3MgYmluZCBwYWlyIGluZGV4Iik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBwYWNrZWRTdHJlYW1zWzBdID0gaTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgKGludCludW1QYWNrZWRTdHJlYW1zOyBpKyspIHsKKyAgICAgICAgICAgICAgICBwYWNrZWRTdHJlYW1zW2ldID0gcmVhZFVpbnQ2NChoZWFkZXIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGZvbGRlci5wYWNrZWRTdHJlYW1zID0gcGFja2VkU3RyZWFtczsKKworICAgICAgICByZXR1cm4gZm9sZGVyOworICAgIH0KKworICAgIHByaXZhdGUgQml0U2V0IHJlYWRBbGxPckJpdHMoZmluYWwgQnl0ZUJ1ZmZlciBoZWFkZXIsIGZpbmFsIGludCBzaXplKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBpbnQgYXJlQWxsRGVmaW5lZCA9IGdldFVuc2lnbmVkQnl0ZShoZWFkZXIpOworICAgICAgICBmaW5hbCBCaXRTZXQgYml0czsKKyAgICAgICAgaWYgKGFyZUFsbERlZmluZWQgIT0gMCkgeworICAgICAgICAgICAgYml0cyA9IG5ldyBCaXRTZXQoc2l6ZSk7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgeworICAgICAgICAgICAgICAgIGJpdHMuc2V0KGksIHRydWUpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgYml0cyA9IHJlYWRCaXRzKGhlYWRlciwgc2l6ZSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGJpdHM7CisgICAgfQorCisgICAgcHJpdmF0ZSBCaXRTZXQgcmVhZEJpdHMoZmluYWwgQnl0ZUJ1ZmZlciBoZWFkZXIsIGZpbmFsIGludCBzaXplKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBCaXRTZXQgYml0cyA9IG5ldyBCaXRTZXQoc2l6ZSk7CisgICAgICAgIGludCBtYXNrID0gMDsKKyAgICAgICAgaW50IGNhY2hlID0gMDsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKKyAgICAgICAgICAgIGlmIChtYXNrID09IDApIHsKKyAgICAgICAgICAgICAgICBtYXNrID0gMHg4MDsKKyAgICAgICAgICAgICAgICBjYWNoZSA9IGdldFVuc2lnbmVkQnl0ZShoZWFkZXIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYml0cy5zZXQoaSwgKGNhY2hlICYgbWFzaykgIT0gMCk7CisgICAgICAgICAgICBtYXNrID4+Pj0gMTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYml0czsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcmVhZEZpbGVzSW5mbyhmaW5hbCBCeXRlQnVmZmVyIGhlYWRlciwgZmluYWwgQXJjaGl2ZSBhcmNoaXZlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBsb25nIG51bUZpbGVzID0gcmVhZFVpbnQ2NChoZWFkZXIpOworICAgICAgICBmaW5hbCBTZXZlblpBcmNoaXZlRW50cnlbXSBmaWxlcyA9IG5ldyBTZXZlblpBcmNoaXZlRW50cnlbKGludCludW1GaWxlc107CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGZpbGVzW2ldID0gbmV3IFNldmVuWkFyY2hpdmVFbnRyeSgpOworICAgICAgICB9CisgICAgICAgIEJpdFNldCBpc0VtcHR5U3RyZWFtID0gbnVsbDsKKyAgICAgICAgQml0U2V0IGlzRW1wdHlGaWxlID0gbnVsbDsKKyAgICAgICAgQml0U2V0IGlzQW50aSA9IG51bGw7CisgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICBmaW5hbCBpbnQgcHJvcGVydHlUeXBlID0gZ2V0VW5zaWduZWRCeXRlKGhlYWRlcik7CisgICAgICAgICAgICBpZiAocHJvcGVydHlUeXBlID09IDApIHsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZpbmFsIGxvbmcgc2l6ZSA9IHJlYWRVaW50NjQoaGVhZGVyKTsKKyAgICAgICAgICAgIHN3aXRjaCAocHJvcGVydHlUeXBlKSB7CisgICAgICAgICAgICAgICAgY2FzZSBOSUQua0VtcHR5U3RyZWFtOiB7CisgICAgICAgICAgICAgICAgICAgIGlzRW1wdHlTdHJlYW0gPSByZWFkQml0cyhoZWFkZXIsIGZpbGVzLmxlbmd0aCk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBjYXNlIE5JRC5rRW1wdHlGaWxlOiB7CisgICAgICAgICAgICAgICAgICAgIGlmIChpc0VtcHR5U3RyZWFtID09IG51bGwpIHsgLy8gcHJvdGVjdCBhZ2FpbnN0IE5QRQorICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJIZWFkZXIgZm9ybWF0IGVycm9yOiBrRW1wdHlTdHJlYW0gbXVzdCBhcHBlYXIgYmVmb3JlIGtFbXB0eUZpbGUiKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBpc0VtcHR5RmlsZSA9IHJlYWRCaXRzKGhlYWRlciwgaXNFbXB0eVN0cmVhbS5jYXJkaW5hbGl0eSgpKTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGNhc2UgTklELmtBbnRpOiB7CisgICAgICAgICAgICAgICAgICAgIGlmIChpc0VtcHR5U3RyZWFtID09IG51bGwpIHsgLy8gcHJvdGVjdCBhZ2FpbnN0IE5QRQorICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJIZWFkZXIgZm9ybWF0IGVycm9yOiBrRW1wdHlTdHJlYW0gbXVzdCBhcHBlYXIgYmVmb3JlIGtBbnRpIik7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgaXNBbnRpID0gcmVhZEJpdHMoaGVhZGVyLCBpc0VtcHR5U3RyZWFtLmNhcmRpbmFsaXR5KCkpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgY2FzZSBOSUQua05hbWU6IHsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGV4dGVybmFsID0gZ2V0VW5zaWduZWRCeXRlKGhlYWRlcik7CisgICAgICAgICAgICAgICAgICAgIGlmIChleHRlcm5hbCAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIk5vdCBpbXBsZW1lbnRlZCIpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGlmICgoKHNpemUgLSAxKSAmIDEpICE9IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiRmlsZSBuYW1lcyBsZW5ndGggaW52YWxpZCIpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBuYW1lcyA9IG5ldyBieXRlWyhpbnQpKHNpemUgLSAxKV07CisgICAgICAgICAgICAgICAgICAgIGhlYWRlci5nZXQobmFtZXMpOworICAgICAgICAgICAgICAgICAgICBpbnQgbmV4dEZpbGUgPSAwOworICAgICAgICAgICAgICAgICAgICBpbnQgbmV4dE5hbWUgPSAwOworICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5hbWVzLmxlbmd0aDsgaSArPSAyKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAobmFtZXNbaV0gPT0gMCAmJiBuYW1lc1tpKzFdID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlc1tuZXh0RmlsZSsrXS5zZXROYW1lKG5ldyBTdHJpbmcobmFtZXMsIG5leHROYW1lLCBpLW5leHROYW1lLCBDaGFyc2V0TmFtZXMuVVRGXzE2TEUpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXh0TmFtZSA9IGkgKyAyOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGlmIChuZXh0TmFtZSAhPSBuYW1lcy5sZW5ndGggfHwgbmV4dEZpbGUgIT0gZmlsZXMubGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkVycm9yIHBhcnNpbmcgZmlsZSBuYW1lcyIpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBjYXNlIE5JRC5rQ1RpbWU6IHsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgQml0U2V0IHRpbWVzRGVmaW5lZCA9IHJlYWRBbGxPckJpdHMoaGVhZGVyLCBmaWxlcy5sZW5ndGgpOworICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgZXh0ZXJuYWwgPSBnZXRVbnNpZ25lZEJ5dGUoaGVhZGVyKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGV4dGVybmFsICE9IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiVW5pbXBsZW1lbnRlZCIpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVzW2ldLnNldEhhc0NyZWF0aW9uRGF0ZSh0aW1lc0RlZmluZWQuZ2V0KGkpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmaWxlc1tpXS5nZXRIYXNDcmVhdGlvbkRhdGUoKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVzW2ldLnNldENyZWF0aW9uRGF0ZShoZWFkZXIuZ2V0TG9uZygpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgY2FzZSBOSUQua0FUaW1lOiB7CisgICAgICAgICAgICAgICAgICAgIGZpbmFsIEJpdFNldCB0aW1lc0RlZmluZWQgPSByZWFkQWxsT3JCaXRzKGhlYWRlciwgZmlsZXMubGVuZ3RoKTsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGV4dGVybmFsID0gZ2V0VW5zaWduZWRCeXRlKGhlYWRlcik7CisgICAgICAgICAgICAgICAgICAgIGlmIChleHRlcm5hbCAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlVuaW1wbGVtZW50ZWQiKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBmaWxlc1tpXS5zZXRIYXNBY2Nlc3NEYXRlKHRpbWVzRGVmaW5lZC5nZXQoaSkpOworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZpbGVzW2ldLmdldEhhc0FjY2Vzc0RhdGUoKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVzW2ldLnNldEFjY2Vzc0RhdGUoaGVhZGVyLmdldExvbmcoKSk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGNhc2UgTklELmtNVGltZTogeworICAgICAgICAgICAgICAgICAgICBmaW5hbCBCaXRTZXQgdGltZXNEZWZpbmVkID0gcmVhZEFsbE9yQml0cyhoZWFkZXIsIGZpbGVzLmxlbmd0aCk7CisgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBleHRlcm5hbCA9IGdldFVuc2lnbmVkQnl0ZShoZWFkZXIpOworICAgICAgICAgICAgICAgICAgICBpZiAoZXh0ZXJuYWwgIT0gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJVbmltcGxlbWVudGVkIik7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgICAgICAgICAgZmlsZXNbaV0uc2V0SGFzTGFzdE1vZGlmaWVkRGF0ZSh0aW1lc0RlZmluZWQuZ2V0KGkpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmaWxlc1tpXS5nZXRIYXNMYXN0TW9kaWZpZWREYXRlKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlc1tpXS5zZXRMYXN0TW9kaWZpZWREYXRlKGhlYWRlci5nZXRMb25nKCkpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBjYXNlIE5JRC5rV2luQXR0cmlidXRlczogeworICAgICAgICAgICAgICAgICAgICBmaW5hbCBCaXRTZXQgYXR0cmlidXRlc0RlZmluZWQgPSByZWFkQWxsT3JCaXRzKGhlYWRlciwgZmlsZXMubGVuZ3RoKTsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGV4dGVybmFsID0gZ2V0VW5zaWduZWRCeXRlKGhlYWRlcik7CisgICAgICAgICAgICAgICAgICAgIGlmIChleHRlcm5hbCAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlVuaW1wbGVtZW50ZWQiKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBmaWxlc1tpXS5zZXRIYXNXaW5kb3dzQXR0cmlidXRlcyhhdHRyaWJ1dGVzRGVmaW5lZC5nZXQoaSkpOworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZpbGVzW2ldLmdldEhhc1dpbmRvd3NBdHRyaWJ1dGVzKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlc1tpXS5zZXRXaW5kb3dzQXR0cmlidXRlcyhoZWFkZXIuZ2V0SW50KCkpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBjYXNlIE5JRC5rU3RhcnRQb3M6IHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJrU3RhcnRQb3MgaXMgdW5zdXBwb3J0ZWQsIHBsZWFzZSByZXBvcnQiKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgY2FzZSBOSUQua0R1bW15OiB7CisgICAgICAgICAgICAgICAgICAgIC8vIDd6IDkuMjAgYXNzZXJ0cyB0aGUgY29udGVudCBpcyBhbGwgemVyb3MgYW5kIGlnbm9yZXMgdGhlIHByb3BlcnR5CisgICAgICAgICAgICAgICAgICAgIC8vIENvbXByZXNzIHVwIHRvIDEuOC4xIHdvdWxkIHRocm93IGFuIGV4Y2VwdGlvbiwgbm93IHdlIGlnbm9yZSBpdCAoc2VlIENPTVBSRVNTLTI4NworCisgICAgICAgICAgICAgICAgICAgIGlmIChza2lwQnl0ZXNGdWxseShoZWFkZXIsIHNpemUpIDwgc2l6ZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJJbmNvbXBsZXRlIGtEdW1teSBwcm9wZXJ0eSIpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHsKKyAgICAgICAgICAgICAgICAgICAgLy8gQ29tcHJlc3MgdXAgdG8gMS44LjEgd291bGQgdGhyb3cgYW4gZXhjZXB0aW9uLCBub3cgd2UgaWdub3JlIGl0IChzZWUgQ09NUFJFU1MtMjg3CisgICAgICAgICAgICAgICAgICAgIGlmIChza2lwQnl0ZXNGdWxseShoZWFkZXIsIHNpemUpIDwgc2l6ZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJJbmNvbXBsZXRlIHByb3BlcnR5IG9mIHR5cGUgIiArIHByb3BlcnR5VHlwZSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGludCBub25FbXB0eUZpbGVDb3VudGVyID0gMDsKKyAgICAgICAgaW50IGVtcHR5RmlsZUNvdW50ZXIgPSAwOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBmaWxlc1tpXS5zZXRIYXNTdHJlYW0oaXNFbXB0eVN0cmVhbSA9PSBudWxsIHx8ICFpc0VtcHR5U3RyZWFtLmdldChpKSk7CisgICAgICAgICAgICBpZiAoZmlsZXNbaV0uaGFzU3RyZWFtKCkpIHsKKyAgICAgICAgICAgICAgICBmaWxlc1tpXS5zZXREaXJlY3RvcnkoZmFsc2UpOworICAgICAgICAgICAgICAgIGZpbGVzW2ldLnNldEFudGlJdGVtKGZhbHNlKTsKKyAgICAgICAgICAgICAgICBmaWxlc1tpXS5zZXRIYXNDcmMoYXJjaGl2ZS5zdWJTdHJlYW1zSW5mby5oYXNDcmMuZ2V0KG5vbkVtcHR5RmlsZUNvdW50ZXIpKTsKKyAgICAgICAgICAgICAgICBmaWxlc1tpXS5zZXRDcmNWYWx1ZShhcmNoaXZlLnN1YlN0cmVhbXNJbmZvLmNyY3Nbbm9uRW1wdHlGaWxlQ291bnRlcl0pOworICAgICAgICAgICAgICAgIGZpbGVzW2ldLnNldFNpemUoYXJjaGl2ZS5zdWJTdHJlYW1zSW5mby51bnBhY2tTaXplc1tub25FbXB0eUZpbGVDb3VudGVyXSk7CisgICAgICAgICAgICAgICAgKytub25FbXB0eUZpbGVDb3VudGVyOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBmaWxlc1tpXS5zZXREaXJlY3RvcnkoaXNFbXB0eUZpbGUgPT0gbnVsbCB8fCAhaXNFbXB0eUZpbGUuZ2V0KGVtcHR5RmlsZUNvdW50ZXIpKTsKKyAgICAgICAgICAgICAgICBmaWxlc1tpXS5zZXRBbnRpSXRlbShpc0FudGkgIT0gbnVsbCAmJiBpc0FudGkuZ2V0KGVtcHR5RmlsZUNvdW50ZXIpKTsKKyAgICAgICAgICAgICAgICBmaWxlc1tpXS5zZXRIYXNDcmMoZmFsc2UpOworICAgICAgICAgICAgICAgIGZpbGVzW2ldLnNldFNpemUoMCk7CisgICAgICAgICAgICAgICAgKytlbXB0eUZpbGVDb3VudGVyOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGFyY2hpdmUuZmlsZXMgPSBmaWxlczsKKyAgICAgICAgY2FsY3VsYXRlU3RyZWFtTWFwKGFyY2hpdmUpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBjYWxjdWxhdGVTdHJlYW1NYXAoZmluYWwgQXJjaGl2ZSBhcmNoaXZlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBTdHJlYW1NYXAgc3RyZWFtTWFwID0gbmV3IFN0cmVhbU1hcCgpOworCisgICAgICAgIGludCBuZXh0Rm9sZGVyUGFja1N0cmVhbUluZGV4ID0gMDsKKyAgICAgICAgZmluYWwgaW50IG51bUZvbGRlcnMgPSBhcmNoaXZlLmZvbGRlcnMgIT0gbnVsbCA/IGFyY2hpdmUuZm9sZGVycy5sZW5ndGggOiAwOworICAgICAgICBzdHJlYW1NYXAuZm9sZGVyRmlyc3RQYWNrU3RyZWFtSW5kZXggPSBuZXcgaW50W251bUZvbGRlcnNdOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bUZvbGRlcnM7IGkrKykgeworICAgICAgICAgICAgc3RyZWFtTWFwLmZvbGRlckZpcnN0UGFja1N0cmVhbUluZGV4W2ldID0gbmV4dEZvbGRlclBhY2tTdHJlYW1JbmRleDsKKyAgICAgICAgICAgIG5leHRGb2xkZXJQYWNrU3RyZWFtSW5kZXggKz0gYXJjaGl2ZS5mb2xkZXJzW2ldLnBhY2tlZFN0cmVhbXMubGVuZ3RoOworICAgICAgICB9CisKKyAgICAgICAgbG9uZyBuZXh0UGFja1N0cmVhbU9mZnNldCA9IDA7CisgICAgICAgIGZpbmFsIGludCBudW1QYWNrU2l6ZXMgPSBhcmNoaXZlLnBhY2tTaXplcyAhPSBudWxsID8gYXJjaGl2ZS5wYWNrU2l6ZXMubGVuZ3RoIDogMDsKKyAgICAgICAgc3RyZWFtTWFwLnBhY2tTdHJlYW1PZmZzZXRzID0gbmV3IGxvbmdbbnVtUGFja1NpemVzXTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1QYWNrU2l6ZXM7IGkrKykgeworICAgICAgICAgICAgc3RyZWFtTWFwLnBhY2tTdHJlYW1PZmZzZXRzW2ldID0gbmV4dFBhY2tTdHJlYW1PZmZzZXQ7CisgICAgICAgICAgICBuZXh0UGFja1N0cmVhbU9mZnNldCArPSBhcmNoaXZlLnBhY2tTaXplc1tpXTsKKyAgICAgICAgfQorCisgICAgICAgIHN0cmVhbU1hcC5mb2xkZXJGaXJzdEZpbGVJbmRleCA9IG5ldyBpbnRbbnVtRm9sZGVyc107CisgICAgICAgIHN0cmVhbU1hcC5maWxlRm9sZGVySW5kZXggPSBuZXcgaW50W2FyY2hpdmUuZmlsZXMubGVuZ3RoXTsKKyAgICAgICAgaW50IG5leHRGb2xkZXJJbmRleCA9IDA7CisgICAgICAgIGludCBuZXh0Rm9sZGVyVW5wYWNrU3RyZWFtSW5kZXggPSAwOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFyY2hpdmUuZmlsZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGlmICghYXJjaGl2ZS5maWxlc1tpXS5oYXNTdHJlYW0oKSAmJiBuZXh0Rm9sZGVyVW5wYWNrU3RyZWFtSW5kZXggPT0gMCkgeworICAgICAgICAgICAgICAgIHN0cmVhbU1hcC5maWxlRm9sZGVySW5kZXhbaV0gPSAtMTsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChuZXh0Rm9sZGVyVW5wYWNrU3RyZWFtSW5kZXggPT0gMCkgeworICAgICAgICAgICAgICAgIGZvciAoOyBuZXh0Rm9sZGVySW5kZXggPCBhcmNoaXZlLmZvbGRlcnMubGVuZ3RoOyArK25leHRGb2xkZXJJbmRleCkgeworICAgICAgICAgICAgICAgICAgICBzdHJlYW1NYXAuZm9sZGVyRmlyc3RGaWxlSW5kZXhbbmV4dEZvbGRlckluZGV4XSA9IGk7CisgICAgICAgICAgICAgICAgICAgIGlmIChhcmNoaXZlLmZvbGRlcnNbbmV4dEZvbGRlckluZGV4XS5udW1VbnBhY2tTdWJTdHJlYW1zID4gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKG5leHRGb2xkZXJJbmRleCA+PSBhcmNoaXZlLmZvbGRlcnMubGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiVG9vIGZldyBmb2xkZXJzIGluIGFyY2hpdmUiKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBzdHJlYW1NYXAuZmlsZUZvbGRlckluZGV4W2ldID0gbmV4dEZvbGRlckluZGV4OworICAgICAgICAgICAgaWYgKCFhcmNoaXZlLmZpbGVzW2ldLmhhc1N0cmVhbSgpKSB7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICArK25leHRGb2xkZXJVbnBhY2tTdHJlYW1JbmRleDsKKyAgICAgICAgICAgIGlmIChuZXh0Rm9sZGVyVW5wYWNrU3RyZWFtSW5kZXggPj0gYXJjaGl2ZS5mb2xkZXJzW25leHRGb2xkZXJJbmRleF0ubnVtVW5wYWNrU3ViU3RyZWFtcykgeworICAgICAgICAgICAgICAgICsrbmV4dEZvbGRlckluZGV4OworICAgICAgICAgICAgICAgIG5leHRGb2xkZXJVbnBhY2tTdHJlYW1JbmRleCA9IDA7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBhcmNoaXZlLnN0cmVhbU1hcCA9IHN0cmVhbU1hcDsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYnVpbGREZWNvZGluZ1N0cmVhbSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIGludCBmb2xkZXJJbmRleCA9IGFyY2hpdmUuc3RyZWFtTWFwLmZpbGVGb2xkZXJJbmRleFtjdXJyZW50RW50cnlJbmRleF07CisgICAgICAgIGlmIChmb2xkZXJJbmRleCA8IDApIHsKKyAgICAgICAgICAgIGRlZmVycmVkQmxvY2tTdHJlYW1zLmNsZWFyKCk7CisgICAgICAgICAgICAvLyBUT0RPOiBwcmV2aW91c2x5IGl0J2QgcmV0dXJuIGFuIGVtcHR5IHN0cmVhbT8KKyAgICAgICAgICAgIC8vIG5ldyBCb3VuZGVkSW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKG5ldyBieXRlWzBdKSwgMCk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgZmluYWwgU2V2ZW5aQXJjaGl2ZUVudHJ5IGZpbGUgPSBhcmNoaXZlLmZpbGVzW2N1cnJlbnRFbnRyeUluZGV4XTsKKyAgICAgICAgaWYgKGN1cnJlbnRGb2xkZXJJbmRleCA9PSBmb2xkZXJJbmRleCkgeworICAgICAgICAgICAgLy8gKENPTVBSRVNTLTMyMCkuCisgICAgICAgICAgICAvLyBUaGUgY3VycmVudCBlbnRyeSBpcyB3aXRoaW4gdGhlIHNhbWUgKHBvdGVudGlhbGx5IG9wZW5lZCkgZm9sZGVyLiBUaGUKKyAgICAgICAgICAgIC8vIHByZXZpb3VzIHN0cmVhbSBoYXMgdG8gYmUgZnVsbHkgZGVjb2RlZCBiZWZvcmUgd2UgY2FuIHN0YXJ0IHJlYWRpbmcKKyAgICAgICAgICAgIC8vIGJ1dCBkb24ndCBkbyBpdCBlYWdlcmx5IC0tIGlmIHRoZSB1c2VyIHNraXBzIG92ZXIgdGhlIGVudGlyZSBmb2xkZXIgbm90aGluZworICAgICAgICAgICAgLy8gaXMgZWZmZWN0aXZlbHkgZGVjb21wcmVzc2VkLgorCisgICAgICAgICAgICBmaWxlLnNldENvbnRlbnRNZXRob2RzKGFyY2hpdmUuZmlsZXNbY3VycmVudEVudHJ5SW5kZXggLSAxXS5nZXRDb250ZW50TWV0aG9kcygpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8vIFdlJ3JlIG9wZW5pbmcgYSBuZXcgZm9sZGVyLiBEaXNjYXJkIGFueSBxdWV1ZWQgc3RyZWFtcy8gZm9sZGVyIHN0cmVhbS4KKyAgICAgICAgICAgIGN1cnJlbnRGb2xkZXJJbmRleCA9IGZvbGRlckluZGV4OworICAgICAgICAgICAgZGVmZXJyZWRCbG9ja1N0cmVhbXMuY2xlYXIoKTsKKyAgICAgICAgICAgIGlmIChjdXJyZW50Rm9sZGVySW5wdXRTdHJlYW0gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGN1cnJlbnRGb2xkZXJJbnB1dFN0cmVhbS5jbG9zZSgpOworICAgICAgICAgICAgICAgIGN1cnJlbnRGb2xkZXJJbnB1dFN0cmVhbSA9IG51bGw7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGZpbmFsIEZvbGRlciBmb2xkZXIgPSBhcmNoaXZlLmZvbGRlcnNbZm9sZGVySW5kZXhdOworICAgICAgICAgICAgZmluYWwgaW50IGZpcnN0UGFja1N0cmVhbUluZGV4ID0gYXJjaGl2ZS5zdHJlYW1NYXAuZm9sZGVyRmlyc3RQYWNrU3RyZWFtSW5kZXhbZm9sZGVySW5kZXhdOworICAgICAgICAgICAgZmluYWwgbG9uZyBmb2xkZXJPZmZzZXQgPSBTSUdOQVRVUkVfSEVBREVSX1NJWkUgKyBhcmNoaXZlLnBhY2tQb3MgKworICAgICAgICAgICAgICAgICAgICBhcmNoaXZlLnN0cmVhbU1hcC5wYWNrU3RyZWFtT2Zmc2V0c1tmaXJzdFBhY2tTdHJlYW1JbmRleF07CisgICAgICAgICAgICBjdXJyZW50Rm9sZGVySW5wdXRTdHJlYW0gPSBidWlsZERlY29kZXJTdGFjayhmb2xkZXIsIGZvbGRlck9mZnNldCwgZmlyc3RQYWNrU3RyZWFtSW5kZXgsIGZpbGUpOworICAgICAgICB9CisKKyAgICAgICAgSW5wdXRTdHJlYW0gZmlsZVN0cmVhbSA9IG5ldyBCb3VuZGVkSW5wdXRTdHJlYW0oY3VycmVudEZvbGRlcklucHV0U3RyZWFtLCBmaWxlLmdldFNpemUoKSk7CisgICAgICAgIGlmIChmaWxlLmdldEhhc0NyYygpKSB7CisgICAgICAgICAgICBmaWxlU3RyZWFtID0gbmV3IENSQzMyVmVyaWZ5aW5nSW5wdXRTdHJlYW0oZmlsZVN0cmVhbSwgZmlsZS5nZXRTaXplKCksIGZpbGUuZ2V0Q3JjVmFsdWUoKSk7CisgICAgICAgIH0KKworICAgICAgICBkZWZlcnJlZEJsb2NrU3RyZWFtcy5hZGQoZmlsZVN0cmVhbSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBJbnB1dFN0cmVhbSBidWlsZERlY29kZXJTdGFjayhmaW5hbCBGb2xkZXIgZm9sZGVyLCBmaW5hbCBsb25nIGZvbGRlck9mZnNldCwKKyAgICAgICAgICAgICAgICBmaW5hbCBpbnQgZmlyc3RQYWNrU3RyZWFtSW5kZXgsIGZpbmFsIFNldmVuWkFyY2hpdmVFbnRyeSBlbnRyeSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY2hhbm5lbC5wb3NpdGlvbihmb2xkZXJPZmZzZXQpOworICAgICAgICBJbnB1dFN0cmVhbSBpbnB1dFN0cmVhbVN0YWNrID0gbmV3IEZpbHRlcklucHV0U3RyZWFtKG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKAorICAgICAgICAgICAgICBuZXcgQm91bmRlZFNlZWthYmxlQnl0ZUNoYW5uZWxJbnB1dFN0cmVhbShjaGFubmVsLAorICAgICAgICAgICAgICAgICAgYXJjaGl2ZS5wYWNrU2l6ZXNbZmlyc3RQYWNrU3RyZWFtSW5kZXhdKSkpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIGludCByZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBpbnQgciA9IGluLnJlYWQoKTsKKyAgICAgICAgICAgICAgICBpZiAociA+PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIGNvdW50KDEpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gcjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIGludCByZWFkKGZpbmFsIGJ5dGVbXSBiKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgICAgIHJldHVybiByZWFkKGIsIDAsIGIubGVuZ3RoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIGludCByZWFkKGZpbmFsIGJ5dGVbXSBiLCBmaW5hbCBpbnQgb2ZmLCBmaW5hbCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgICAgIGZpbmFsIGludCByID0gaW4ucmVhZChiLCBvZmYsIGxlbik7CisgICAgICAgICAgICAgICAgaWYgKHIgPj0gMCkgeworICAgICAgICAgICAgICAgICAgICBjb3VudChyKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIHI7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBwcml2YXRlIHZvaWQgY291bnQoaW50IGMpIHsKKyAgICAgICAgICAgICAgICBjb21wcmVzc2VkQnl0ZXNSZWFkRnJvbUN1cnJlbnRFbnRyeSArPSBjOworICAgICAgICAgICAgfQorICAgICAgICB9OworICAgICAgICBmaW5hbCBMaW5rZWRMaXN0PFNldmVuWk1ldGhvZENvbmZpZ3VyYXRpb24+IG1ldGhvZHMgPSBuZXcgTGlua2VkTGlzdDw+KCk7CisgICAgICAgIGZvciAoZmluYWwgQ29kZXIgY29kZXIgOiBmb2xkZXIuZ2V0T3JkZXJlZENvZGVycygpKSB7CisgICAgICAgICAgICBpZiAoY29kZXIubnVtSW5TdHJlYW1zICE9IDEgfHwgY29kZXIubnVtT3V0U3RyZWFtcyAhPSAxKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJNdWx0aSBpbnB1dC9vdXRwdXQgc3RyZWFtIGNvZGVycyBhcmUgbm90IHlldCBzdXBwb3J0ZWQiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZpbmFsIFNldmVuWk1ldGhvZCBtZXRob2QgPSBTZXZlblpNZXRob2QuYnlJZChjb2Rlci5kZWNvbXByZXNzaW9uTWV0aG9kSWQpOworICAgICAgICAgICAgaW5wdXRTdHJlYW1TdGFjayA9IENvZGVycy5hZGREZWNvZGVyKGZpbGVOYW1lLCBpbnB1dFN0cmVhbVN0YWNrLAorICAgICAgICAgICAgICAgICAgICBmb2xkZXIuZ2V0VW5wYWNrU2l6ZUZvckNvZGVyKGNvZGVyKSwgY29kZXIsIHBhc3N3b3JkKTsKKyAgICAgICAgICAgIG1ldGhvZHMuYWRkRmlyc3QobmV3IFNldmVuWk1ldGhvZENvbmZpZ3VyYXRpb24obWV0aG9kLAorICAgICAgICAgICAgICAgICAgICAgQ29kZXJzLmZpbmRCeU1ldGhvZChtZXRob2QpLmdldE9wdGlvbnNGcm9tQ29kZXIoY29kZXIsIGlucHV0U3RyZWFtU3RhY2spKSk7CisgICAgICAgIH0KKyAgICAgICAgZW50cnkuc2V0Q29udGVudE1ldGhvZHMobWV0aG9kcyk7CisgICAgICAgIGlmIChmb2xkZXIuaGFzQ3JjKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IENSQzMyVmVyaWZ5aW5nSW5wdXRTdHJlYW0oaW5wdXRTdHJlYW1TdGFjaywKKyAgICAgICAgICAgICAgICAgICAgZm9sZGVyLmdldFVucGFja1NpemUoKSwgZm9sZGVyLmNyYyk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGlucHV0U3RyZWFtU3RhY2s7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgYSBieXRlIG9mIGRhdGEuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBieXRlIHJlYWQsIG9yIC0xIGlmIGVuZCBvZiBpbnB1dCBpcyByZWFjaGVkCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBlcnJvciBoYXMgb2NjdXJyZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IHJlYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgYiA9IGdldEN1cnJlbnRTdHJlYW0oKS5yZWFkKCk7CisgICAgICAgIGlmIChiID49IDApIHsKKyAgICAgICAgICAgIHVuY29tcHJlc3NlZEJ5dGVzUmVhZEZyb21DdXJyZW50RW50cnkrKzsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYjsKKyAgICB9CisKKyAgICBwcml2YXRlIElucHV0U3RyZWFtIGdldEN1cnJlbnRTdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoYXJjaGl2ZS5maWxlc1tjdXJyZW50RW50cnlJbmRleF0uZ2V0U2l6ZSgpID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0obmV3IGJ5dGVbMF0pOworICAgICAgICB9CisgICAgICAgIGlmIChkZWZlcnJlZEJsb2NrU3RyZWFtcy5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIk5vIGN1cnJlbnQgN3ogZW50cnkgKGNhbGwgZ2V0TmV4dEVudHJ5KCkgZmlyc3QpLiIpOworICAgICAgICB9CisKKyAgICAgICAgd2hpbGUgKGRlZmVycmVkQmxvY2tTdHJlYW1zLnNpemUoKSA+IDEpIHsKKyAgICAgICAgICAgIC8vIEluIHNvbGlkIGNvbXByZXNzaW9uIG1vZGUgd2UgbmVlZCB0byBkZWNvbXByZXNzIGFsbCBsZWFkaW5nIGZvbGRlcicKKyAgICAgICAgICAgIC8vIHN0cmVhbXMgdG8gZ2V0IGFjY2VzcyB0byBhbiBlbnRyeS4gV2UgZGVmZXIgdGhpcyB1bnRpbCByZWFsbHkgbmVlZGVkCisgICAgICAgICAgICAvLyBzbyB0aGF0IGVudGlyZSBibG9ja3MgY2FuIGJlIHNraXBwZWQgd2l0aG91dCB3YXN0aW5nIHRpbWUgZm9yIGRlY29tcHJlc3Npb24uCisgICAgICAgICAgICB0cnkgKGZpbmFsIElucHV0U3RyZWFtIHN0cmVhbSA9IGRlZmVycmVkQmxvY2tTdHJlYW1zLnJlbW92ZSgwKSkgeworICAgICAgICAgICAgICAgIElPVXRpbHMuc2tpcChzdHJlYW0sIExvbmcuTUFYX1ZBTFVFKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNvbXByZXNzZWRCeXRlc1JlYWRGcm9tQ3VycmVudEVudHJ5ID0gMDsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBkZWZlcnJlZEJsb2NrU3RyZWFtcy5nZXQoMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgZGF0YSBpbnRvIGFuIGFycmF5IG9mIGJ5dGVzLgorICAgICAqCisgICAgICogQHBhcmFtIGIgdGhlIGFycmF5IHRvIHdyaXRlIGRhdGEgdG8KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgcmVhZCwgb3IgLTEgaWYgZW5kIG9mIGlucHV0IGlzIHJlYWNoZWQKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIGhhcyBvY2N1cnJlZAorICAgICAqLworICAgIHB1YmxpYyBpbnQgcmVhZChmaW5hbCBieXRlW10gYikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHJlYWQoYiwgMCwgYi5sZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGRhdGEgaW50byBhbiBhcnJheSBvZiBieXRlcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBiIHRoZSBhcnJheSB0byB3cml0ZSBkYXRhIHRvCisgICAgICogQHBhcmFtIG9mZiBvZmZzZXQgaW50byB0aGUgYnVmZmVyIHRvIHN0YXJ0IGZpbGxpbmcgYXQKKyAgICAgKiBAcGFyYW0gbGVuIG9mIGJ5dGVzIHRvIHJlYWQKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgcmVhZCwgb3IgLTEgaWYgZW5kIG9mIGlucHV0IGlzIHJlYWNoZWQKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIGhhcyBvY2N1cnJlZAorICAgICAqLworICAgIHB1YmxpYyBpbnQgcmVhZChmaW5hbCBieXRlW10gYiwgZmluYWwgaW50IG9mZiwgZmluYWwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IGNudCA9IGdldEN1cnJlbnRTdHJlYW0oKS5yZWFkKGIsIG9mZiwgbGVuKTsKKyAgICAgICAgaWYgKGNudCA+IDApIHsKKyAgICAgICAgICAgIHVuY29tcHJlc3NlZEJ5dGVzUmVhZEZyb21DdXJyZW50RW50cnkgKz0gY250OworICAgICAgICB9CisgICAgICAgIHJldHVybiBjbnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJvdmlkZXMgc3RhdGlzdGljcyBmb3IgYnl0ZXMgcmVhZCBmcm9tIHRoZSBjdXJyZW50IGVudHJ5LgorICAgICAqCisgICAgICogQHJldHVybiBzdGF0aXN0aWNzIGZvciBieXRlcyByZWFkIGZyb20gdGhlIGN1cnJlbnQgZW50cnkKKyAgICAgKiBAc2luY2UgMS4xNworICAgICAqLworICAgIHB1YmxpYyBJbnB1dFN0cmVhbVN0YXRpc3RpY3MgZ2V0U3RhdGlzdGljc0ZvckN1cnJlbnRFbnRyeSgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBJbnB1dFN0cmVhbVN0YXRpc3RpY3MoKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBsb25nIGdldENvbXByZXNzZWRDb3VudCgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gY29tcHJlc3NlZEJ5dGVzUmVhZEZyb21DdXJyZW50RW50cnk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBsb25nIGdldFVuY29tcHJlc3NlZENvdW50KCkgeworICAgICAgICAgICAgICAgIHJldHVybiB1bmNvbXByZXNzZWRCeXRlc1JlYWRGcm9tQ3VycmVudEVudHJ5OworICAgICAgICAgICAgfQorICAgICAgICB9OworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGxvbmcgcmVhZFVpbnQ2NChmaW5hbCBCeXRlQnVmZmVyIGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBsb25nIHJhdGhlciB0aGFuIGludCBhcyBpdCBtaWdodCBnZXQgc2hpZnRlZCBiZXlvbmQgdGhlIHJhbmdlIG9mIGFuIGludAorICAgICAgICBmaW5hbCBsb25nIGZpcnN0Qnl0ZSA9IGdldFVuc2lnbmVkQnl0ZShpbik7CisgICAgICAgIGludCBtYXNrID0gMHg4MDsKKyAgICAgICAgbG9uZyB2YWx1ZSA9IDA7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgODsgaSsrKSB7CisgICAgICAgICAgICBpZiAoKGZpcnN0Qnl0ZSAmIG1hc2spID09IDApIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWUgfCAoKGZpcnN0Qnl0ZSAmIChtYXNrIC0gMSkpIDw8ICg4ICogaSkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZmluYWwgbG9uZyBuZXh0Qnl0ZSA9IGdldFVuc2lnbmVkQnl0ZShpbik7CisgICAgICAgICAgICB2YWx1ZSB8PSBuZXh0Qnl0ZSA8PCAoOCAqIGkpOworICAgICAgICAgICAgbWFzayA+Pj49IDE7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHZhbHVlOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGludCBnZXRVbnNpZ25lZEJ5dGUoQnl0ZUJ1ZmZlciBidWYpIHsKKyAgICAgICAgcmV0dXJuIGJ1Zi5nZXQoKSAmIDB4ZmY7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIHRoZSBzaWduYXR1cmUgbWF0Y2hlcyB3aGF0IGlzIGV4cGVjdGVkIGZvciBhIDd6IGZpbGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc2lnbmF0dXJlCisgICAgICogICAgICAgICAgICB0aGUgYnl0ZXMgdG8gY2hlY2sKKyAgICAgKiBAcGFyYW0gbGVuZ3RoCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRvIGNoZWNrCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGlzIGlzIHRoZSBzaWduYXR1cmUgb2YgYSA3eiBhcmNoaXZlLgorICAgICAqIEBzaW5jZSAxLjgKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gbWF0Y2hlcyhmaW5hbCBieXRlW10gc2lnbmF0dXJlLCBmaW5hbCBpbnQgbGVuZ3RoKSB7CisgICAgICAgIGlmIChsZW5ndGggPCBzZXZlblpTaWduYXR1cmUubGVuZ3RoKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNldmVuWlNpZ25hdHVyZS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgaWYgKHNpZ25hdHVyZVtpXSAhPSBzZXZlblpTaWduYXR1cmVbaV0pIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgbG9uZyBza2lwQnl0ZXNGdWxseShmaW5hbCBCeXRlQnVmZmVyIGlucHV0LCBsb25nIGJ5dGVzVG9Ta2lwKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoYnl0ZXNUb1NraXAgPCAxKSB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorICAgICAgICBpbnQgY3VycmVudCA9IGlucHV0LnBvc2l0aW9uKCk7CisgICAgICAgIGludCBtYXhTa2lwID0gaW5wdXQucmVtYWluaW5nKCk7CisgICAgICAgIGlmIChtYXhTa2lwIDwgYnl0ZXNUb1NraXApIHsKKyAgICAgICAgICAgIGJ5dGVzVG9Ta2lwID0gbWF4U2tpcDsKKyAgICAgICAgfQorICAgICAgICBpbnB1dC5wb3NpdGlvbihjdXJyZW50ICsgKGludCkgYnl0ZXNUb1NraXApOworICAgICAgICByZXR1cm4gYnl0ZXNUb1NraXA7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHJlYWRGdWxseShCeXRlQnVmZmVyIGJ1ZikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnVmLnJld2luZCgpOworICAgICAgICBJT1V0aWxzLnJlYWRGdWxseShjaGFubmVsLCBidWYpOworICAgICAgICBidWYuZmxpcCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICByZXR1cm4gYXJjaGl2ZS50b1N0cmluZygpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIENoYXJzZXRFbmNvZGVyIFBBU1NXT1JEX0VOQ09ERVIgPSBTdGFuZGFyZENoYXJzZXRzLlVURl8xNkxFLm5ld0VuY29kZXIoKTsKKworICAgIHByaXZhdGUgc3RhdGljIGJ5dGVbXSB1dGYxNkRlY29kZShjaGFyW10gY2hhcnMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChjaGFycyA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBCeXRlQnVmZmVyIGVuY29kZWQgPSBQQVNTV09SRF9FTkNPREVSLmVuY29kZShDaGFyQnVmZmVyLndyYXAoY2hhcnMpKTsKKyAgICAgICAgaWYgKGVuY29kZWQuaGFzQXJyYXkoKSkgeworICAgICAgICAgICAgcmV0dXJuIGVuY29kZWQuYXJyYXkoKTsKKyAgICAgICAgfQorICAgICAgICBieXRlW10gZSA9IG5ldyBieXRlW2VuY29kZWQucmVtYWluaW5nKCldOworICAgICAgICBlbmNvZGVkLmdldChlKTsKKyAgICAgICAgcmV0dXJuIGU7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3NldmVuei9TZXZlblpNZXRob2QuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9zZXZlbnovU2V2ZW5aTWV0aG9kLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2M0NDZjYwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9zZXZlbnovU2V2ZW5aTWV0aG9kLmphdmEKQEAgLTAsMCArMSwxMTMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5zZXZlbno7CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCisvKioKKyAqIFRoZSAocGFydGlhbGx5KSBzdXBwb3J0ZWQgY29tcHJlc3Npb24vZW5jcnlwdGlvbiBtZXRob2RzIHVzZWQgaW4gN3ogYXJjaGl2ZXMuCisgKgorICogPHA+QWxsIG1ldGhvZHMgd2l0aCBhIF9GSUxURVIgc3VmZml4IGFyZSB1c2VkIGFzIHByZXByb2Nlc3NvcnMgd2l0aAorICogdGhlIGdvYWwgb2YgY3JlYXRpbmcgYSBiZXR0ZXIgY29tcHJlc3Npb24gcmF0aW8gd2l0aCB0aGUgY29tcHJlc3NvcgorICogdGhhdCBjb21lcyBuZXh0IGluIHRoZSBjaGFpbiBvZiBtZXRob2RzLiAgN3ogd2lsbCBpbiBnZW5lcmFsIG9ubHkKKyAqIGFsbG93IHRoZW0gdG8gYmUgdXNlZCB0b2dldGhlciB3aXRoIGEgInJlYWwiIGNvbXByZXNzaW9uIG1ldGhvZCBidXQKKyAqIENvbW1vbnMgQ29tcHJlc3MgZG9lc24ndCBlbmZvcmNlIHRoaXMuPC9wPgorICoKKyAqIDxwPlRoZSBCQ0pfIGZpbHRlcnMgd29yayBvbiBleGVjdXRhYmxlIGZpbGVzIGZvciB0aGUgZ2l2ZW4gcGxhdGZvcm0KKyAqIGFuZCBjb252ZXJ0IHJlbGF0aXZlIGFkZHJlc3NlcyB0byBhYnNvbHV0ZSBhZGRyZXNzZXMgaW4gQ0FMTAorICogaW5zdHJ1Y3Rpb25zLiAgVGhpcyBtZWFucyB0aGV5IGFyZSBvbmx5IHVzZWZ1bCB3aGVuIGFwcGxpZWQgdG8KKyAqIGV4ZWN1dGFibGVzIG9mIHRoZSBjaG9zZW4gcGxhdGZvcm0uPC9wPgorICovCitwdWJsaWMgZW51bSBTZXZlblpNZXRob2QgeworICAgIC8qKiBubyBjb21wcmVzc2lvbiBhdCBhbGwgKi8KKyAgICBDT1BZKG5ldyBieXRlW10geyAoYnl0ZSkweDAwIH0pLAorICAgIC8qKiBMWk1BIC0gb25seSBzdXBwb3J0ZWQgd2hlbiByZWFkaW5nICovCisgICAgTFpNQShuZXcgYnl0ZVtdIHsgKGJ5dGUpMHgwMywgKGJ5dGUpMHgwMSwgKGJ5dGUpMHgwMSB9KSwKKyAgICAvKiogTFpNQTIgKi8KKyAgICBMWk1BMihuZXcgYnl0ZVtdIHsgKGJ5dGUpMHgyMSB9KSwKKyAgICAvKiogRGVmbGF0ZSAqLworICAgIERFRkxBVEUobmV3IGJ5dGVbXSB7IChieXRlKTB4MDQsIChieXRlKTB4MDEsIChieXRlKTB4MDggfSksCisgICAgLyoqCisgICAgICogRGVmbGF0ZTY0CisgICAgICogQHNpbmNlIDEuMTYKKyAgICAgKi8KKyAgICBERUZMQVRFNjQobmV3IGJ5dGVbXSB7IChieXRlKTB4MDQsIChieXRlKTB4MDEsIChieXRlKTB4MDkgfSksCisgICAgLyoqIEJaSVAyICovCisgICAgQlpJUDIobmV3IGJ5dGVbXSB7IChieXRlKTB4MDQsIChieXRlKTB4MDIsIChieXRlKTB4MDIgfSksCisgICAgLyoqCisgICAgICogQUVTIGVuY3J5cHRpb24gd2l0aCBhIGtleSBsZW5ndGggb2YgMjU2IGJpdCB1c2luZyBTSEEyNTYgZm9yCisgICAgICogaGFzaGVzIC0gb25seSBzdXBwb3J0ZWQgd2hlbiByZWFkaW5nCisgICAgICovCisgICAgQUVTMjU2U0hBMjU2KG5ldyBieXRlW10geyAoYnl0ZSkweDA2LCAoYnl0ZSkweGYxLCAoYnl0ZSkweDA3LCAoYnl0ZSkweDAxIH0pLAorICAgIC8qKgorICAgICAqIEJDSiB4ODYgcGxhdGZvcm0gdmVyc2lvbiAxLgorICAgICAqIEBzaW5jZSAxLjgKKyAgICAgKi8KKyAgICBCQ0pfWDg2X0ZJTFRFUihuZXcgYnl0ZVtdIHsgMHgwMywgMHgwMywgMHgwMSwgMHgwMyB9KSwKKyAgICAvKioKKyAgICAgKiBCQ0ogUG93ZXJQQyBwbGF0Zm9ybS4KKyAgICAgKiBAc2luY2UgMS44CisgICAgICovCisgICAgQkNKX1BQQ19GSUxURVIobmV3IGJ5dGVbXSB7IDB4MDMsIDB4MDMsIDB4MDIsIDB4MDUgfSksCisgICAgLyoqCisgICAgICogQkNKIEk2NCBwbGF0Zm9ybS4KKyAgICAgKiBAc2luY2UgMS44CisgICAgICovCisgICAgQkNKX0lBNjRfRklMVEVSKG5ldyBieXRlW10geyAweDAzLCAweDAzLCAweDA0LCAweDAxIH0pLAorICAgIC8qKgorICAgICAqIEJDSiBBUk0gcGxhdGZvcm0uCisgICAgICogQHNpbmNlIDEuOAorICAgICAqLworICAgIEJDSl9BUk1fRklMVEVSKG5ldyBieXRlW10geyAweDAzLCAweDAzLCAweDA1LCAweDAxIH0pLAorICAgIC8qKgorICAgICAqIEJDSiBBUk0gVGh1bWIgcGxhdGZvcm0uCisgICAgICogQHNpbmNlIDEuOAorICAgICAqLworICAgIEJDSl9BUk1fVEhVTUJfRklMVEVSKG5ldyBieXRlW10geyAweDAzLCAweDAzLCAweDA3LCAweDAxIH0pLAorICAgIC8qKgorICAgICAqIEJDSiBTcGFyYyBwbGF0Zm9ybS4KKyAgICAgKiBAc2luY2UgMS44CisgICAgICovCisgICAgQkNKX1NQQVJDX0ZJTFRFUihuZXcgYnl0ZVtdIHsgMHgwMywgMHgwMywgMHgwOCwgMHgwNSB9KSwKKyAgICAvKioKKyAgICAgKiBEZWx0YSBmaWx0ZXIuCisgICAgICogQHNpbmNlIDEuOAorICAgICAqLworICAgIERFTFRBX0ZJTFRFUihuZXcgYnl0ZVtdIHsgMHgwMyB9KTsKKworICAgIHByaXZhdGUgZmluYWwgYnl0ZVtdIGlkOworCisgICAgU2V2ZW5aTWV0aG9kKGZpbmFsIGJ5dGVbXSBpZCkgeworICAgICAgICB0aGlzLmlkID0gaWQ7CisgICAgfQorCisgICAgYnl0ZVtdIGdldElkKCkgeworICAgICAgICBmaW5hbCBieXRlW10gY29weSA9IG5ldyBieXRlW2lkLmxlbmd0aF07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoaWQsIDAsIGNvcHksIDAsIGlkLmxlbmd0aCk7CisgICAgICAgIHJldHVybiBjb3B5OworICAgIH0KKworICAgIHN0YXRpYyBTZXZlblpNZXRob2QgYnlJZChmaW5hbCBieXRlW10gaWQpIHsKKyAgICAgICAgZm9yIChmaW5hbCBTZXZlblpNZXRob2QgbSA6IFNldmVuWk1ldGhvZC5jbGFzcy5nZXRFbnVtQ29uc3RhbnRzKCkpIHsKKyAgICAgICAgICAgIGlmIChBcnJheXMuZXF1YWxzKG0uaWQsIGlkKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBtOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9zZXZlbnovU2V2ZW5aTWV0aG9kQ29uZmlndXJhdGlvbi5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3NldmVuei9TZXZlblpNZXRob2RDb25maWd1cmF0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmM0N2VlMAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9zZXZlbnovU2V2ZW5aTWV0aG9kQ29uZmlndXJhdGlvbi5qYXZhCkBAIC0wLDAgKzEsODEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5zZXZlbno7CisKKy8qKgorICogQ29tYmluZXMgYSBTZXZlblpNZXRob2Qgd2l0aCBjb25maWd1cmF0aW9uIG9wdGlvbnMgZm9yIHRoZSBtZXRob2QuCisgKgorICogPHA+VGhlIGV4YWN0IHR5cGUgYW5kIGludGVycHJldGF0aW9uIG9mIG9wdGlvbnMgZGVwZW5kcyBvbiB0aGUKKyAqIG1ldGhvZCBiZWluZyBjb25maWd1cmVkLiAgQ3VycmVudGx5IHN1cHBvcnRlZCBhcmU6PC9wPgorICoKKyAqIDx0YWJsZSBzdW1tYXJ5PSJPcHRpb25zIj4KKyAqIDx0cj48dGg+TWV0aG9kPC90aD48dGg+T3B0aW9uIFR5cGU8L3RoPjx0aD5EZXNjcmlwdGlvbjwvdGg+PC90cj4KKyAqIDx0cj48dGQ+QlpJUDI8L3RkPjx0ZD5OdW1iZXI8L3RkPjx0ZD5CbG9jayBTaXplIC0gYW4gbnVtYmVyIGJldHdlZW4gMSBhbmQgOTwvdGQ+PC90cj4KKyAqIDx0cj48dGQ+REVGTEFURTwvdGQ+PHRkPk51bWJlcjwvdGQ+PHRkPkNvbXByZXNzaW9uIExldmVsIC0gYW4gbnVtYmVyIGJldHdlZW4gMSBhbmQgOTwvdGQ+PC90cj4KKyAqIDx0cj48dGQ+TFpNQTI8L3RkPjx0ZD5OdW1iZXI8L3RkPjx0ZD5EaWN0aW9uYXJ5IFNpemUgLSBhIG51bWJlciBiZXR3ZWVuIDQwOTYgYW5kIDc2OCBNaUIgKDc2OCAmbHQ7Jmx0OyAyMCk8L3RkPjwvdHI+CisgKiA8dHI+PHRkPkxaTUEyPC90ZD48dGQ+b3JnLnR1a2FhbmkueHouTFpNQTJPcHRpb25zPC90ZD48dGQ+V2hvbGUgc2V0IG9mIExaTUEyIG9wdGlvbnMuPC90ZD48L3RyPgorICogPHRyPjx0ZD5ERUxUQV9GSUxURVI8L3RkPjx0ZD5OdW1iZXI8L3RkPjx0ZD5EZWx0YSBEaXN0YW5jZSAtIGEgbnVtYmVyIGJldHdlZW4gMSBhbmQgMjU2PC90ZD48L3RyPgorICogPC90YWJsZT4KKyAqCisgKiBASW1tdXRhYmxlCisgKiBAc2luY2UgMS44CisgKi8KK3B1YmxpYyBjbGFzcyBTZXZlblpNZXRob2RDb25maWd1cmF0aW9uIHsKKyAgICBwcml2YXRlIGZpbmFsIFNldmVuWk1ldGhvZCBtZXRob2Q7CisgICAgcHJpdmF0ZSBmaW5hbCBPYmplY3Qgb3B0aW9uczsKKworICAgIC8qKgorICAgICAqIERvZXNuJ3QgY29uZmlndXJlIGFueSBhZGRpdGlvbmFsIG9wdGlvbnMuCisgICAgICogQHBhcmFtIG1ldGhvZCB0aGUgbWV0aG9kIHRvIHVzZQorICAgICAqLworICAgIHB1YmxpYyBTZXZlblpNZXRob2RDb25maWd1cmF0aW9uKGZpbmFsIFNldmVuWk1ldGhvZCBtZXRob2QpIHsKKyAgICAgICAgdGhpcyhtZXRob2QsIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNwZWNpZmllcyBhbmQgbWV0aG9kIHBsdXMgY29uZmlndXJhdGlvbiBvcHRpb25zLgorICAgICAqIEBwYXJhbSBtZXRob2QgdGhlIG1ldGhvZCB0byB1c2UKKyAgICAgKiBAcGFyYW0gb3B0aW9ucyB0aGUgb3B0aW9ucyB0byB1c2UKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgbWV0aG9kIGRvZXNuJ3QgdW5kZXJzdGFuZCB0aGUgb3B0aW9ucyBzcGVjaWZpZWQuCisgICAgICovCisgICAgcHVibGljIFNldmVuWk1ldGhvZENvbmZpZ3VyYXRpb24oZmluYWwgU2V2ZW5aTWV0aG9kIG1ldGhvZCwgZmluYWwgT2JqZWN0IG9wdGlvbnMpIHsKKyAgICAgICAgdGhpcy5tZXRob2QgPSBtZXRob2Q7CisgICAgICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7CisgICAgICAgIGlmIChvcHRpb25zICE9IG51bGwgJiYgIUNvZGVycy5maW5kQnlNZXRob2QobWV0aG9kKS5jYW5BY2NlcHRPcHRpb25zKG9wdGlvbnMpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJUaGUgIiArIG1ldGhvZCArICIgbWV0aG9kIGRvZXNuJ3Qgc3VwcG9ydCBvcHRpb25zIG9mIHR5cGUgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIG9wdGlvbnMuZ2V0Q2xhc3MoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgc3BlY2lmaWVkIG1ldGhvZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBtZXRob2QKKyAgICAgKi8KKyAgICBwdWJsaWMgU2V2ZW5aTWV0aG9kIGdldE1ldGhvZCgpIHsKKyAgICAgICAgcmV0dXJuIG1ldGhvZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgc3BlY2lmaWVkIG9wdGlvbnMuCisgICAgICogQHJldHVybiB0aGUgb3B0aW9ucworICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgZ2V0T3B0aW9ucygpIHsKKyAgICAgICAgcmV0dXJuIG9wdGlvbnM7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvc2V2ZW56L1NldmVuWk91dHB1dEZpbGUuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9zZXZlbnovU2V2ZW5aT3V0cHV0RmlsZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRiNDdmNDQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvc2V2ZW56L1NldmVuWk91dHB1dEZpbGUuamF2YQpAQCAtMCwwICsxLDgxMSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICoKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnNldmVuejsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQ2xvc2VhYmxlOworaW1wb3J0IGphdmEuaW8uRGF0YU91dHB1dDsKK2ltcG9ydCBqYXZhLmlvLkRhdGFPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLm5pby5CeXRlT3JkZXI7CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuU2Vla2FibGVCeXRlQ2hhbm5lbDsKK2ltcG9ydCBqYXZhLm5pby5maWxlLkZpbGVzOworaW1wb3J0IGphdmEubmlvLmZpbGUuU3RhbmRhcmRPcGVuT3B0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkJpdFNldDsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CitpbXBvcnQgamF2YS51dGlsLkRhdGU7CitpbXBvcnQgamF2YS51dGlsLkVudW1TZXQ7CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpbmtlZExpc3Q7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLkNSQzMyOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5BcmNoaXZlRW50cnk7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLkNvdW50aW5nT3V0cHV0U3RyZWFtOworCisvKioKKyAqIFdyaXRlcyBhIDd6IGZpbGUuCisgKiBAc2luY2UgMS42CisgKi8KK3B1YmxpYyBjbGFzcyBTZXZlblpPdXRwdXRGaWxlIGltcGxlbWVudHMgQ2xvc2VhYmxlIHsKKyAgICBwcml2YXRlIGZpbmFsIFNlZWthYmxlQnl0ZUNoYW5uZWwgY2hhbm5lbDsKKyAgICBwcml2YXRlIGZpbmFsIExpc3Q8U2V2ZW5aQXJjaGl2ZUVudHJ5PiBmaWxlcyA9IG5ldyBBcnJheUxpc3Q8PigpOworICAgIHByaXZhdGUgaW50IG51bU5vbkVtcHR5U3RyZWFtcyA9IDA7CisgICAgcHJpdmF0ZSBmaW5hbCBDUkMzMiBjcmMzMiA9IG5ldyBDUkMzMigpOworICAgIHByaXZhdGUgZmluYWwgQ1JDMzIgY29tcHJlc3NlZENyYzMyID0gbmV3IENSQzMyKCk7CisgICAgcHJpdmF0ZSBsb25nIGZpbGVCeXRlc1dyaXR0ZW4gPSAwOworICAgIHByaXZhdGUgYm9vbGVhbiBmaW5pc2hlZCA9IGZhbHNlOworICAgIHByaXZhdGUgQ291bnRpbmdPdXRwdXRTdHJlYW0gY3VycmVudE91dHB1dFN0cmVhbTsKKyAgICBwcml2YXRlIENvdW50aW5nT3V0cHV0U3RyZWFtW10gYWRkaXRpb25hbENvdW50aW5nU3RyZWFtczsKKyAgICBwcml2YXRlIEl0ZXJhYmxlPD8gZXh0ZW5kcyBTZXZlblpNZXRob2RDb25maWd1cmF0aW9uPiBjb250ZW50TWV0aG9kcyA9CisgICAgICAgICAgICBDb2xsZWN0aW9ucy5zaW5nbGV0b25MaXN0KG5ldyBTZXZlblpNZXRob2RDb25maWd1cmF0aW9uKFNldmVuWk1ldGhvZC5MWk1BMikpOworICAgIHByaXZhdGUgZmluYWwgTWFwPFNldmVuWkFyY2hpdmVFbnRyeSwgbG9uZ1tdPiBhZGRpdGlvbmFsU2l6ZXMgPSBuZXcgSGFzaE1hcDw+KCk7CisKKyAgICAvKioKKyAgICAgKiBPcGVucyBmaWxlIHRvIHdyaXRlIGEgN3ogYXJjaGl2ZSB0by4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmaWxlbmFtZSB0aGUgZmlsZSB0byB3cml0ZSB0bworICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgb3BlbmluZyB0aGUgZmlsZSBmYWlscworICAgICAqLworICAgIHB1YmxpYyBTZXZlblpPdXRwdXRGaWxlKGZpbmFsIEZpbGUgZmlsZW5hbWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMoRmlsZXMubmV3Qnl0ZUNoYW5uZWwoZmlsZW5hbWUudG9QYXRoKCksCisgICAgICAgICAgICBFbnVtU2V0Lm9mKFN0YW5kYXJkT3Blbk9wdGlvbi5DUkVBVEUsIFN0YW5kYXJkT3Blbk9wdGlvbi5XUklURSwKKyAgICAgICAgICAgICAgICAgICAgICAgU3RhbmRhcmRPcGVuT3B0aW9uLlRSVU5DQVRFX0VYSVNUSU5HKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByZXBhcmVzIGNoYW5uZWwgdG8gd3JpdGUgYSA3eiBhcmNoaXZlIHRvLgorICAgICAqCisgICAgICogPHA+e0BsaW5rCisgICAgICogb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLlNlZWthYmxlSW5NZW1vcnlCeXRlQ2hhbm5lbH0KKyAgICAgKiBhbGxvd3MgeW91IHRvIHdyaXRlIHRvIGFuIGluLW1lbW9yeSBhcmNoaXZlLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjaGFubmVsIHRoZSBjaGFubmVsIHRvIHdyaXRlIHRvCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiB0aGUgY2hhbm5lbCBjYW5ub3QgYmUgcG9zaXRpb25lZCBwcm9wZXJseQorICAgICAqIEBzaW5jZSAxLjEzCisgICAgICovCisgICAgcHVibGljIFNldmVuWk91dHB1dEZpbGUoZmluYWwgU2Vla2FibGVCeXRlQ2hhbm5lbCBjaGFubmVsKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzLmNoYW5uZWwgPSBjaGFubmVsOworICAgICAgICBjaGFubmVsLnBvc2l0aW9uKFNldmVuWkZpbGUuU0lHTkFUVVJFX0hFQURFUl9TSVpFKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBkZWZhdWx0IGNvbXByZXNzaW9uIG1ldGhvZCB0byB1c2UgZm9yIGVudHJ5IGNvbnRlbnRzIC0gdGhlCisgICAgICogZGVmYXVsdCBpcyBMWk1BMi4KKyAgICAgKgorICAgICAqIDxwPkN1cnJlbnRseSBvbmx5IHtAbGluayBTZXZlblpNZXRob2QjQ09QWX0sIHtAbGluaworICAgICAqIFNldmVuWk1ldGhvZCNMWk1BMn0sIHtAbGluayBTZXZlblpNZXRob2QjQlpJUDJ9IGFuZCB7QGxpbmsKKyAgICAgKiBTZXZlblpNZXRob2QjREVGTEFURX0gYXJlIHN1cHBvcnRlZC48L3A+CisgICAgICoKKyAgICAgKiA8cD5UaGlzIGlzIGEgc2hvcnQgZm9ybSBmb3IgcGFzc2luZyBhIHNpbmdsZS1lbGVtZW50IGl0ZXJhYmxlCisgICAgICogdG8ge0BsaW5rICNzZXRDb250ZW50TWV0aG9kc30uPC9wPgorICAgICAqIEBwYXJhbSBtZXRob2QgdGhlIGRlZmF1bHQgY29tcHJlc3Npb24gbWV0aG9kCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Q29udGVudENvbXByZXNzaW9uKGZpbmFsIFNldmVuWk1ldGhvZCBtZXRob2QpIHsKKyAgICAgICAgc2V0Q29udGVudE1ldGhvZHMoQ29sbGVjdGlvbnMuc2luZ2xldG9uTGlzdChuZXcgU2V2ZW5aTWV0aG9kQ29uZmlndXJhdGlvbihtZXRob2QpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZGVmYXVsdCAoY29tcHJlc3Npb24pIG1ldGhvZHMgdG8gdXNlIGZvciBlbnRyeSBjb250ZW50cyAtIHRoZQorICAgICAqIGRlZmF1bHQgaXMgTFpNQTIuCisgICAgICoKKyAgICAgKiA8cD5DdXJyZW50bHkgb25seSB7QGxpbmsgU2V2ZW5aTWV0aG9kI0NPUFl9LCB7QGxpbmsKKyAgICAgKiBTZXZlblpNZXRob2QjTFpNQTJ9LCB7QGxpbmsgU2V2ZW5aTWV0aG9kI0JaSVAyfSBhbmQge0BsaW5rCisgICAgICogU2V2ZW5aTWV0aG9kI0RFRkxBVEV9IGFyZSBzdXBwb3J0ZWQuPC9wPgorICAgICAqCisgICAgICogPHA+VGhlIG1ldGhvZHMgd2lsbCBiZSBjb25zdWx0ZWQgaW4gaXRlcmF0aW9uIG9yZGVyIHRvIGNyZWF0ZQorICAgICAqIHRoZSBmaW5hbCBvdXRwdXQuPC9wPgorICAgICAqCisgICAgICogQHNpbmNlIDEuOAorICAgICAqIEBwYXJhbSBtZXRob2RzIHRoZSBkZWZhdWx0IChjb21wcmVzc2lvbikgbWV0aG9kcworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldENvbnRlbnRNZXRob2RzKGZpbmFsIEl0ZXJhYmxlPD8gZXh0ZW5kcyBTZXZlblpNZXRob2RDb25maWd1cmF0aW9uPiBtZXRob2RzKSB7CisgICAgICAgIHRoaXMuY29udGVudE1ldGhvZHMgPSByZXZlcnNlKG1ldGhvZHMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENsb3NlcyB0aGUgYXJjaGl2ZSwgY2FsbGluZyB7QGxpbmsgI2ZpbmlzaH0gaWYgbmVjZXNzYXJ5LgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBvbiBlcnJvcgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlmICghZmluaXNoZWQpIHsKKyAgICAgICAgICAgICAgICBmaW5pc2goKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGNoYW5uZWwuY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhbiBhcmNoaXZlIGVudHJ5IHVzaW5nIHRoZSBpbnB1dEZpbGUgYW5kIGVudHJ5TmFtZSBwcm92aWRlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbnB1dEZpbGUgZmlsZSB0byBjcmVhdGUgYW4gZW50cnkgZnJvbQorICAgICAqIEBwYXJhbSBlbnRyeU5hbWUgdGhlIG5hbWUgdG8gdXNlCisgICAgICogQHJldHVybiB0aGUgQXJjaGl2ZUVudHJ5IHNldCB1cCB3aXRoIGRldGFpbHMgZnJvbSB0aGUgZmlsZQorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBvbiBlcnJvcgorICAgICAqLworICAgIHB1YmxpYyBTZXZlblpBcmNoaXZlRW50cnkgY3JlYXRlQXJjaGl2ZUVudHJ5KGZpbmFsIEZpbGUgaW5wdXRGaWxlLAorICAgICAgICAgICAgZmluYWwgU3RyaW5nIGVudHJ5TmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgU2V2ZW5aQXJjaGl2ZUVudHJ5IGVudHJ5ID0gbmV3IFNldmVuWkFyY2hpdmVFbnRyeSgpOworICAgICAgICBlbnRyeS5zZXREaXJlY3RvcnkoaW5wdXRGaWxlLmlzRGlyZWN0b3J5KCkpOworICAgICAgICBlbnRyeS5zZXROYW1lKGVudHJ5TmFtZSk7CisgICAgICAgIGVudHJ5LnNldExhc3RNb2RpZmllZERhdGUobmV3IERhdGUoaW5wdXRGaWxlLmxhc3RNb2RpZmllZCgpKSk7CisgICAgICAgIHJldHVybiBlbnRyeTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWNvcmRzIGFuIGFyY2hpdmUgZW50cnkgdG8gYWRkLgorICAgICAqCisgICAgICogVGhlIGNhbGxlciBtdXN0IHRoZW4gd3JpdGUgdGhlIGNvbnRlbnQgdG8gdGhlIGFyY2hpdmUgYW5kIGNhbGwKKyAgICAgKiB7QGxpbmsgI2Nsb3NlQXJjaGl2ZUVudHJ5KCl9IHRvIGNvbXBsZXRlIHRoZSBwcm9jZXNzLgorICAgICAqCisgICAgICogQHBhcmFtIGFyY2hpdmVFbnRyeSBkZXNjcmliZXMgdGhlIGVudHJ5CisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBvbiBlcnJvcgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHB1dEFyY2hpdmVFbnRyeShmaW5hbCBBcmNoaXZlRW50cnkgYXJjaGl2ZUVudHJ5KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBTZXZlblpBcmNoaXZlRW50cnkgZW50cnkgPSAoU2V2ZW5aQXJjaGl2ZUVudHJ5KSBhcmNoaXZlRW50cnk7CisgICAgICAgIGZpbGVzLmFkZChlbnRyeSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvc2VzIHRoZSBhcmNoaXZlIGVudHJ5LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gb24gZXJyb3IKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBjbG9zZUFyY2hpdmVFbnRyeSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChjdXJyZW50T3V0cHV0U3RyZWFtICE9IG51bGwpIHsKKyAgICAgICAgICAgIGN1cnJlbnRPdXRwdXRTdHJlYW0uZmx1c2goKTsKKyAgICAgICAgICAgIGN1cnJlbnRPdXRwdXRTdHJlYW0uY2xvc2UoKTsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIFNldmVuWkFyY2hpdmVFbnRyeSBlbnRyeSA9IGZpbGVzLmdldChmaWxlcy5zaXplKCkgLSAxKTsKKyAgICAgICAgaWYgKGZpbGVCeXRlc1dyaXR0ZW4gPiAwKSB7IC8vIHRoaXMgaW1wbGllcyBjdXJyZW50T3V0cHV0U3RyZWFtICE9IG51bGwKKyAgICAgICAgICAgIGVudHJ5LnNldEhhc1N0cmVhbSh0cnVlKTsKKyAgICAgICAgICAgICsrbnVtTm9uRW1wdHlTdHJlYW1zOworICAgICAgICAgICAgZW50cnkuc2V0U2l6ZShjdXJyZW50T3V0cHV0U3RyZWFtLmdldEJ5dGVzV3JpdHRlbigpKTsgLy9OT1NPTkFSCisgICAgICAgICAgICBlbnRyeS5zZXRDb21wcmVzc2VkU2l6ZShmaWxlQnl0ZXNXcml0dGVuKTsKKyAgICAgICAgICAgIGVudHJ5LnNldENyY1ZhbHVlKGNyYzMyLmdldFZhbHVlKCkpOworICAgICAgICAgICAgZW50cnkuc2V0Q29tcHJlc3NlZENyY1ZhbHVlKGNvbXByZXNzZWRDcmMzMi5nZXRWYWx1ZSgpKTsKKyAgICAgICAgICAgIGVudHJ5LnNldEhhc0NyYyh0cnVlKTsKKyAgICAgICAgICAgIGlmIChhZGRpdGlvbmFsQ291bnRpbmdTdHJlYW1zICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBsb25nW10gc2l6ZXMgPSBuZXcgbG9uZ1thZGRpdGlvbmFsQ291bnRpbmdTdHJlYW1zLmxlbmd0aF07CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhZGRpdGlvbmFsQ291bnRpbmdTdHJlYW1zLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIHNpemVzW2ldID0gYWRkaXRpb25hbENvdW50aW5nU3RyZWFtc1tpXS5nZXRCeXRlc1dyaXR0ZW4oKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYWRkaXRpb25hbFNpemVzLnB1dChlbnRyeSwgc2l6ZXMpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZW50cnkuc2V0SGFzU3RyZWFtKGZhbHNlKTsKKyAgICAgICAgICAgIGVudHJ5LnNldFNpemUoMCk7CisgICAgICAgICAgICBlbnRyeS5zZXRDb21wcmVzc2VkU2l6ZSgwKTsKKyAgICAgICAgICAgIGVudHJ5LnNldEhhc0NyYyhmYWxzZSk7CisgICAgICAgIH0KKyAgICAgICAgY3VycmVudE91dHB1dFN0cmVhbSA9IG51bGw7CisgICAgICAgIGFkZGl0aW9uYWxDb3VudGluZ1N0cmVhbXMgPSBudWxsOworICAgICAgICBjcmMzMi5yZXNldCgpOworICAgICAgICBjb21wcmVzc2VkQ3JjMzIucmVzZXQoKTsKKyAgICAgICAgZmlsZUJ5dGVzV3JpdHRlbiA9IDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIGEgYnl0ZSB0byB0aGUgY3VycmVudCBhcmNoaXZlIGVudHJ5LgorICAgICAqIEBwYXJhbSBiIFRoZSBieXRlIHRvIGJlIHdyaXR0ZW4uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBvbiBlcnJvcgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHdyaXRlKGZpbmFsIGludCBiKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBnZXRDdXJyZW50T3V0cHV0U3RyZWFtKCkud3JpdGUoYik7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIGEgYnl0ZSBhcnJheSB0byB0aGUgY3VycmVudCBhcmNoaXZlIGVudHJ5LgorICAgICAqIEBwYXJhbSBiIFRoZSBieXRlIGFycmF5IHRvIGJlIHdyaXR0ZW4uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBvbiBlcnJvcgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHdyaXRlKGZpbmFsIGJ5dGVbXSBiKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB3cml0ZShiLCAwLCBiLmxlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIHBhcnQgb2YgYSBieXRlIGFycmF5IHRvIHRoZSBjdXJyZW50IGFyY2hpdmUgZW50cnkuCisgICAgICogQHBhcmFtIGIgVGhlIGJ5dGUgYXJyYXkgdG8gYmUgd3JpdHRlbi4KKyAgICAgKiBAcGFyYW0gb2ZmIG9mZnNldCBpbnRvIHRoZSBhcnJheSB0byBzdGFydCB3cml0aW5nIGZyb20KKyAgICAgKiBAcGFyYW0gbGVuIG51bWJlciBvZiBieXRlcyB0byB3cml0ZQorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gb24gZXJyb3IKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB3cml0ZShmaW5hbCBieXRlW10gYiwgZmluYWwgaW50IG9mZiwgZmluYWwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGxlbiA+IDApIHsKKyAgICAgICAgICAgIGdldEN1cnJlbnRPdXRwdXRTdHJlYW0oKS53cml0ZShiLCBvZmYsIGxlbik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaW5pc2hlcyB0aGUgYWRkaXRpb24gb2YgZW50cmllcyB0byB0aGlzIGFyY2hpdmUsIHdpdGhvdXQgY2xvc2luZyBpdC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgYXJjaGl2ZSBpcyBhbHJlYWR5IGNsb3NlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBmaW5pc2goKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoZmluaXNoZWQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiVGhpcyBhcmNoaXZlIGhhcyBhbHJlYWR5IGJlZW4gZmluaXNoZWQiKTsKKyAgICAgICAgfQorICAgICAgICBmaW5pc2hlZCA9IHRydWU7CisKKyAgICAgICAgZmluYWwgbG9uZyBoZWFkZXJQb3NpdGlvbiA9IGNoYW5uZWwucG9zaXRpb24oKTsKKworICAgICAgICBmaW5hbCBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gaGVhZGVyQmFvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgZmluYWwgRGF0YU91dHB1dFN0cmVhbSBoZWFkZXIgPSBuZXcgRGF0YU91dHB1dFN0cmVhbShoZWFkZXJCYW9zKTsKKworICAgICAgICB3cml0ZUhlYWRlcihoZWFkZXIpOworICAgICAgICBoZWFkZXIuZmx1c2goKTsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGhlYWRlckJ5dGVzID0gaGVhZGVyQmFvcy50b0J5dGVBcnJheSgpOworICAgICAgICBjaGFubmVsLndyaXRlKEJ5dGVCdWZmZXIud3JhcChoZWFkZXJCeXRlcykpOworCisgICAgICAgIGZpbmFsIENSQzMyIGNyYzMyID0gbmV3IENSQzMyKCk7CisgICAgICAgIGNyYzMyLnVwZGF0ZShoZWFkZXJCeXRlcyk7CisKKyAgICAgICAgQnl0ZUJ1ZmZlciBiYiA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUoU2V2ZW5aRmlsZS5zZXZlblpTaWduYXR1cmUubGVuZ3RoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgMiAvKiB2ZXJzaW9uICovCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgNCAvKiBzdGFydCBoZWFkZXIgQ1JDICovCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgOCAvKiBuZXh0IGhlYWRlciBwb3NpdGlvbiAqLworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIDggLyogbmV4dCBoZWFkZXIgbGVuZ3RoICovCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgNCAvKiBuZXh0IGhlYWRlciBDUkMgKi8pCisgICAgICAgICAgICAub3JkZXIoQnl0ZU9yZGVyLkxJVFRMRV9FTkRJQU4pOworICAgICAgICAvLyBzaWduYXR1cmUgaGVhZGVyCisgICAgICAgIGNoYW5uZWwucG9zaXRpb24oMCk7CisgICAgICAgIGJiLnB1dChTZXZlblpGaWxlLnNldmVuWlNpZ25hdHVyZSk7CisgICAgICAgIC8vIHZlcnNpb24KKyAgICAgICAgYmIucHV0KChieXRlKSAwKS5wdXQoKGJ5dGUpIDIpOworCisgICAgICAgIC8vIHBsYWNlaG9sZGVyIGZvciBzdGFydCBoZWFkZXIgQ1JDCisgICAgICAgIGJiLnB1dEludCgwKTsKKworICAgICAgICAvLyBzdGFydCBoZWFkZXIKKyAgICAgICAgYmIucHV0TG9uZyhoZWFkZXJQb3NpdGlvbiAtIFNldmVuWkZpbGUuU0lHTkFUVVJFX0hFQURFUl9TSVpFKQorICAgICAgICAgICAgLnB1dExvbmcoMHhmZmZmRkZGRkwgJiBoZWFkZXJCeXRlcy5sZW5ndGgpCisgICAgICAgICAgICAucHV0SW50KChpbnQpIGNyYzMyLmdldFZhbHVlKCkpOworICAgICAgICBjcmMzMi5yZXNldCgpOworICAgICAgICBjcmMzMi51cGRhdGUoYmIuYXJyYXkoKSwgU2V2ZW5aRmlsZS5zZXZlblpTaWduYXR1cmUubGVuZ3RoICsgNiwgMjApOworICAgICAgICBiYi5wdXRJbnQoU2V2ZW5aRmlsZS5zZXZlblpTaWduYXR1cmUubGVuZ3RoICsgMiwgKGludCkgY3JjMzIuZ2V0VmFsdWUoKSk7CisgICAgICAgIGJiLmZsaXAoKTsKKyAgICAgICAgY2hhbm5lbC53cml0ZShiYik7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBDcmVhdGlvbiBvZiBvdXRwdXQgc3RyZWFtIGlzIGRlZmVycmVkIHVudGlsIGRhdGEgaXMgYWN0dWFsbHkKKyAgICAgKiB3cml0dGVuIGFzIHNvbWUgY29kZWNzIG1pZ2h0IHdyaXRlIGhlYWRlciBpbmZvcm1hdGlvbiBldmVuIGZvcgorICAgICAqIGVtcHR5IHN0cmVhbXMgYW5kIGRpcmVjdG9yaWVzIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIE91dHB1dFN0cmVhbSBnZXRDdXJyZW50T3V0cHV0U3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGN1cnJlbnRPdXRwdXRTdHJlYW0gPT0gbnVsbCkgeworICAgICAgICAgICAgY3VycmVudE91dHB1dFN0cmVhbSA9IHNldHVwRmlsZU91dHB1dFN0cmVhbSgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBjdXJyZW50T3V0cHV0U3RyZWFtOworICAgIH0KKworICAgIHByaXZhdGUgQ291bnRpbmdPdXRwdXRTdHJlYW0gc2V0dXBGaWxlT3V0cHV0U3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGZpbGVzLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiTm8gY3VycmVudCA3eiBlbnRyeSIpOworICAgICAgICB9CisKKyAgICAgICAgT3V0cHV0U3RyZWFtIG91dCA9IG5ldyBPdXRwdXRTdHJlYW1XcmFwcGVyKCk7CisgICAgICAgIGZpbmFsIEFycmF5TGlzdDxDb3VudGluZ091dHB1dFN0cmVhbT4gbW9yZVN0cmVhbXMgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKyAgICAgICAgYm9vbGVhbiBmaXJzdCA9IHRydWU7CisgICAgICAgIGZvciAoZmluYWwgU2V2ZW5aTWV0aG9kQ29uZmlndXJhdGlvbiBtIDogZ2V0Q29udGVudE1ldGhvZHMoZmlsZXMuZ2V0KGZpbGVzLnNpemUoKSAtIDEpKSkgeworICAgICAgICAgICAgaWYgKCFmaXJzdCkgeworICAgICAgICAgICAgICAgIGZpbmFsIENvdW50aW5nT3V0cHV0U3RyZWFtIGNvcyA9IG5ldyBDb3VudGluZ091dHB1dFN0cmVhbShvdXQpOworICAgICAgICAgICAgICAgIG1vcmVTdHJlYW1zLmFkZChjb3MpOworICAgICAgICAgICAgICAgIG91dCA9IGNvczsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIG91dCA9IENvZGVycy5hZGRFbmNvZGVyKG91dCwgbS5nZXRNZXRob2QoKSwgbS5nZXRPcHRpb25zKCkpOworICAgICAgICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIW1vcmVTdHJlYW1zLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgYWRkaXRpb25hbENvdW50aW5nU3RyZWFtcyA9IG1vcmVTdHJlYW1zLnRvQXJyYXkobmV3IENvdW50aW5nT3V0cHV0U3RyZWFtW21vcmVTdHJlYW1zLnNpemUoKV0pOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgQ291bnRpbmdPdXRwdXRTdHJlYW0ob3V0KSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHdyaXRlKGZpbmFsIGludCBiKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgICAgIHN1cGVyLndyaXRlKGIpOworICAgICAgICAgICAgICAgIGNyYzMyLnVwZGF0ZShiKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgdm9pZCB3cml0ZShmaW5hbCBieXRlW10gYikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICBzdXBlci53cml0ZShiKTsKKyAgICAgICAgICAgICAgICBjcmMzMi51cGRhdGUoYik7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIHZvaWQgd3JpdGUoZmluYWwgYnl0ZVtdIGIsIGZpbmFsIGludCBvZmYsIGZpbmFsIGludCBsZW4pCisgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICBzdXBlci53cml0ZShiLCBvZmYsIGxlbik7CisgICAgICAgICAgICAgICAgY3JjMzIudXBkYXRlKGIsIG9mZiwgbGVuKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICB9CisKKyAgICBwcml2YXRlIEl0ZXJhYmxlPD8gZXh0ZW5kcyBTZXZlblpNZXRob2RDb25maWd1cmF0aW9uPiBnZXRDb250ZW50TWV0aG9kcyhmaW5hbCBTZXZlblpBcmNoaXZlRW50cnkgZW50cnkpIHsKKyAgICAgICAgZmluYWwgSXRlcmFibGU8PyBleHRlbmRzIFNldmVuWk1ldGhvZENvbmZpZ3VyYXRpb24+IG1zID0gZW50cnkuZ2V0Q29udGVudE1ldGhvZHMoKTsKKyAgICAgICAgcmV0dXJuIG1zID09IG51bGwgPyBjb250ZW50TWV0aG9kcyA6IG1zOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB3cml0ZUhlYWRlcihmaW5hbCBEYXRhT3V0cHV0IGhlYWRlcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaGVhZGVyLndyaXRlKE5JRC5rSGVhZGVyKTsKKworICAgICAgICBoZWFkZXIud3JpdGUoTklELmtNYWluU3RyZWFtc0luZm8pOworICAgICAgICB3cml0ZVN0cmVhbXNJbmZvKGhlYWRlcik7CisgICAgICAgIHdyaXRlRmlsZXNJbmZvKGhlYWRlcik7CisgICAgICAgIGhlYWRlci53cml0ZShOSUQua0VuZCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlU3RyZWFtc0luZm8oZmluYWwgRGF0YU91dHB1dCBoZWFkZXIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChudW1Ob25FbXB0eVN0cmVhbXMgPiAwKSB7CisgICAgICAgICAgICB3cml0ZVBhY2tJbmZvKGhlYWRlcik7CisgICAgICAgICAgICB3cml0ZVVucGFja0luZm8oaGVhZGVyKTsKKyAgICAgICAgfQorCisgICAgICAgIHdyaXRlU3ViU3RyZWFtc0luZm8oaGVhZGVyKTsKKworICAgICAgICBoZWFkZXIud3JpdGUoTklELmtFbmQpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB3cml0ZVBhY2tJbmZvKGZpbmFsIERhdGFPdXRwdXQgaGVhZGVyKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBoZWFkZXIud3JpdGUoTklELmtQYWNrSW5mbyk7CisKKyAgICAgICAgd3JpdGVVaW50NjQoaGVhZGVyLCAwKTsKKyAgICAgICAgd3JpdGVVaW50NjQoaGVhZGVyLCAweGZmZmZGRkZGTCAmIG51bU5vbkVtcHR5U3RyZWFtcyk7CisKKyAgICAgICAgaGVhZGVyLndyaXRlKE5JRC5rU2l6ZSk7CisgICAgICAgIGZvciAoZmluYWwgU2V2ZW5aQXJjaGl2ZUVudHJ5IGVudHJ5IDogZmlsZXMpIHsKKyAgICAgICAgICAgIGlmIChlbnRyeS5oYXNTdHJlYW0oKSkgeworICAgICAgICAgICAgICAgIHdyaXRlVWludDY0KGhlYWRlciwgZW50cnkuZ2V0Q29tcHJlc3NlZFNpemUoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBoZWFkZXIud3JpdGUoTklELmtDUkMpOworICAgICAgICBoZWFkZXIud3JpdGUoMSk7IC8vICJhbGxBcmVEZWZpbmVkIiA9PSB0cnVlCisgICAgICAgIGZvciAoZmluYWwgU2V2ZW5aQXJjaGl2ZUVudHJ5IGVudHJ5IDogZmlsZXMpIHsKKyAgICAgICAgICAgIGlmIChlbnRyeS5oYXNTdHJlYW0oKSkgeworICAgICAgICAgICAgICAgIGhlYWRlci53cml0ZUludChJbnRlZ2VyLnJldmVyc2VCeXRlcygoaW50KSBlbnRyeS5nZXRDb21wcmVzc2VkQ3JjVmFsdWUoKSkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgaGVhZGVyLndyaXRlKE5JRC5rRW5kKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgd3JpdGVVbnBhY2tJbmZvKGZpbmFsIERhdGFPdXRwdXQgaGVhZGVyKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBoZWFkZXIud3JpdGUoTklELmtVbnBhY2tJbmZvKTsKKworICAgICAgICBoZWFkZXIud3JpdGUoTklELmtGb2xkZXIpOworICAgICAgICB3cml0ZVVpbnQ2NChoZWFkZXIsIG51bU5vbkVtcHR5U3RyZWFtcyk7CisgICAgICAgIGhlYWRlci53cml0ZSgwKTsKKyAgICAgICAgZm9yIChmaW5hbCBTZXZlblpBcmNoaXZlRW50cnkgZW50cnkgOiBmaWxlcykgeworICAgICAgICAgICAgaWYgKGVudHJ5Lmhhc1N0cmVhbSgpKSB7CisgICAgICAgICAgICAgICAgd3JpdGVGb2xkZXIoaGVhZGVyLCBlbnRyeSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBoZWFkZXIud3JpdGUoTklELmtDb2RlcnNVbnBhY2tTaXplKTsKKyAgICAgICAgZm9yIChmaW5hbCBTZXZlblpBcmNoaXZlRW50cnkgZW50cnkgOiBmaWxlcykgeworICAgICAgICAgICAgaWYgKGVudHJ5Lmhhc1N0cmVhbSgpKSB7CisgICAgICAgICAgICAgICAgZmluYWwgbG9uZ1tdIG1vcmVTaXplcyA9IGFkZGl0aW9uYWxTaXplcy5nZXQoZW50cnkpOworICAgICAgICAgICAgICAgIGlmIChtb3JlU2l6ZXMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBmb3IgKGZpbmFsIGxvbmcgcyA6IG1vcmVTaXplcykgeworICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVVaW50NjQoaGVhZGVyLCBzKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB3cml0ZVVpbnQ2NChoZWFkZXIsIGVudHJ5LmdldFNpemUoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBoZWFkZXIud3JpdGUoTklELmtDUkMpOworICAgICAgICBoZWFkZXIud3JpdGUoMSk7IC8vICJhbGxBcmVEZWZpbmVkIiA9PSB0cnVlCisgICAgICAgIGZvciAoZmluYWwgU2V2ZW5aQXJjaGl2ZUVudHJ5IGVudHJ5IDogZmlsZXMpIHsKKyAgICAgICAgICAgIGlmIChlbnRyeS5oYXNTdHJlYW0oKSkgeworICAgICAgICAgICAgICAgIGhlYWRlci53cml0ZUludChJbnRlZ2VyLnJldmVyc2VCeXRlcygoaW50KSBlbnRyeS5nZXRDcmNWYWx1ZSgpKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBoZWFkZXIud3JpdGUoTklELmtFbmQpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB3cml0ZUZvbGRlcihmaW5hbCBEYXRhT3V0cHV0IGhlYWRlciwgZmluYWwgU2V2ZW5aQXJjaGl2ZUVudHJ5IGVudHJ5KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICBpbnQgbnVtQ29kZXJzID0gMDsKKyAgICAgICAgZm9yIChmaW5hbCBTZXZlblpNZXRob2RDb25maWd1cmF0aW9uIG0gOiBnZXRDb250ZW50TWV0aG9kcyhlbnRyeSkpIHsKKyAgICAgICAgICAgIG51bUNvZGVycysrOworICAgICAgICAgICAgd3JpdGVTaW5nbGVDb2RlYyhtLCBib3MpOworICAgICAgICB9CisKKyAgICAgICAgd3JpdGVVaW50NjQoaGVhZGVyLCBudW1Db2RlcnMpOworICAgICAgICBoZWFkZXIud3JpdGUoYm9zLnRvQnl0ZUFycmF5KCkpOworICAgICAgICBmb3IgKGxvbmcgaSA9IDA7IGkgPCBudW1Db2RlcnMgLSAxOyBpKyspIHsKKyAgICAgICAgICAgIHdyaXRlVWludDY0KGhlYWRlciwgaSArIDEpOworICAgICAgICAgICAgd3JpdGVVaW50NjQoaGVhZGVyLCBpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB3cml0ZVNpbmdsZUNvZGVjKGZpbmFsIFNldmVuWk1ldGhvZENvbmZpZ3VyYXRpb24gbSwgZmluYWwgT3V0cHV0U3RyZWFtIGJvcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGlkID0gbS5nZXRNZXRob2QoKS5nZXRJZCgpOworICAgICAgICBmaW5hbCBieXRlW10gcHJvcGVydGllcyA9IENvZGVycy5maW5kQnlNZXRob2QobS5nZXRNZXRob2QoKSkKKyAgICAgICAgICAgIC5nZXRPcHRpb25zQXNQcm9wZXJ0aWVzKG0uZ2V0T3B0aW9ucygpKTsKKworICAgICAgICBpbnQgY29kZWNGbGFncyA9IGlkLmxlbmd0aDsKKyAgICAgICAgaWYgKHByb3BlcnRpZXMubGVuZ3RoID4gMCkgeworICAgICAgICAgICAgY29kZWNGbGFncyB8PSAweDIwOworICAgICAgICB9CisgICAgICAgIGJvcy53cml0ZShjb2RlY0ZsYWdzKTsKKyAgICAgICAgYm9zLndyaXRlKGlkKTsKKworICAgICAgICBpZiAocHJvcGVydGllcy5sZW5ndGggPiAwKSB7CisgICAgICAgICAgICBib3Mud3JpdGUocHJvcGVydGllcy5sZW5ndGgpOworICAgICAgICAgICAgYm9zLndyaXRlKHByb3BlcnRpZXMpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlU3ViU3RyZWFtc0luZm8oZmluYWwgRGF0YU91dHB1dCBoZWFkZXIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGhlYWRlci53cml0ZShOSUQua1N1YlN0cmVhbXNJbmZvKTsKKy8vCisvLyAgICAgICAgaGVhZGVyLndyaXRlKE5JRC5rQ1JDKTsKKy8vICAgICAgICBoZWFkZXIud3JpdGUoMSk7CisvLyAgICAgICAgZm9yIChmaW5hbCBTZXZlblpBcmNoaXZlRW50cnkgZW50cnkgOiBmaWxlcykgeworLy8gICAgICAgICAgICBpZiAoZW50cnkuZ2V0SGFzQ3JjKCkpIHsKKy8vICAgICAgICAgICAgICAgIGhlYWRlci53cml0ZUludChJbnRlZ2VyLnJldmVyc2VCeXRlcyhlbnRyeS5nZXRDcmMoKSkpOworLy8gICAgICAgICAgICB9CisvLyAgICAgICAgfQorLy8KKyAgICAgICAgaGVhZGVyLndyaXRlKE5JRC5rRW5kKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgd3JpdGVGaWxlc0luZm8oZmluYWwgRGF0YU91dHB1dCBoZWFkZXIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGhlYWRlci53cml0ZShOSUQua0ZpbGVzSW5mbyk7CisKKyAgICAgICAgd3JpdGVVaW50NjQoaGVhZGVyLCBmaWxlcy5zaXplKCkpOworCisgICAgICAgIHdyaXRlRmlsZUVtcHR5U3RyZWFtcyhoZWFkZXIpOworICAgICAgICB3cml0ZUZpbGVFbXB0eUZpbGVzKGhlYWRlcik7CisgICAgICAgIHdyaXRlRmlsZUFudGlJdGVtcyhoZWFkZXIpOworICAgICAgICB3cml0ZUZpbGVOYW1lcyhoZWFkZXIpOworICAgICAgICB3cml0ZUZpbGVDVGltZXMoaGVhZGVyKTsKKyAgICAgICAgd3JpdGVGaWxlQVRpbWVzKGhlYWRlcik7CisgICAgICAgIHdyaXRlRmlsZU1UaW1lcyhoZWFkZXIpOworICAgICAgICB3cml0ZUZpbGVXaW5kb3dzQXR0cmlidXRlcyhoZWFkZXIpOworICAgICAgICBoZWFkZXIud3JpdGUoTklELmtFbmQpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB3cml0ZUZpbGVFbXB0eVN0cmVhbXMoZmluYWwgRGF0YU91dHB1dCBoZWFkZXIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJvb2xlYW4gaGFzRW1wdHlTdHJlYW1zID0gZmFsc2U7CisgICAgICAgIGZvciAoZmluYWwgU2V2ZW5aQXJjaGl2ZUVudHJ5IGVudHJ5IDogZmlsZXMpIHsKKyAgICAgICAgICAgIGlmICghZW50cnkuaGFzU3RyZWFtKCkpIHsKKyAgICAgICAgICAgICAgICBoYXNFbXB0eVN0cmVhbXMgPSB0cnVlOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChoYXNFbXB0eVN0cmVhbXMpIHsKKyAgICAgICAgICAgIGhlYWRlci53cml0ZShOSUQua0VtcHR5U3RyZWFtKTsKKyAgICAgICAgICAgIGZpbmFsIEJpdFNldCBlbXB0eVN0cmVhbXMgPSBuZXcgQml0U2V0KGZpbGVzLnNpemUoKSk7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVzLnNpemUoKTsgaSsrKSB7CisgICAgICAgICAgICAgICAgZW1wdHlTdHJlYW1zLnNldChpLCAhZmlsZXMuZ2V0KGkpLmhhc1N0cmVhbSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZpbmFsIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBiYW9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICAgICAgZmluYWwgRGF0YU91dHB1dFN0cmVhbSBvdXQgPSBuZXcgRGF0YU91dHB1dFN0cmVhbShiYW9zKTsKKyAgICAgICAgICAgIHdyaXRlQml0cyhvdXQsIGVtcHR5U3RyZWFtcywgZmlsZXMuc2l6ZSgpKTsKKyAgICAgICAgICAgIG91dC5mbHVzaCgpOworICAgICAgICAgICAgZmluYWwgYnl0ZVtdIGNvbnRlbnRzID0gYmFvcy50b0J5dGVBcnJheSgpOworICAgICAgICAgICAgd3JpdGVVaW50NjQoaGVhZGVyLCBjb250ZW50cy5sZW5ndGgpOworICAgICAgICAgICAgaGVhZGVyLndyaXRlKGNvbnRlbnRzKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB3cml0ZUZpbGVFbXB0eUZpbGVzKGZpbmFsIERhdGFPdXRwdXQgaGVhZGVyKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBib29sZWFuIGhhc0VtcHR5RmlsZXMgPSBmYWxzZTsKKyAgICAgICAgaW50IGVtcHR5U3RyZWFtQ291bnRlciA9IDA7CisgICAgICAgIGZpbmFsIEJpdFNldCBlbXB0eUZpbGVzID0gbmV3IEJpdFNldCgwKTsKKyAgICAgICAgZm9yIChmaW5hbCBTZXZlblpBcmNoaXZlRW50cnkgZmlsZTEgOiBmaWxlcykgeworICAgICAgICAgICAgaWYgKCFmaWxlMS5oYXNTdHJlYW0oKSkgeworICAgICAgICAgICAgICAgIGZpbmFsIGJvb2xlYW4gaXNEaXIgPSBmaWxlMS5pc0RpcmVjdG9yeSgpOworICAgICAgICAgICAgICAgIGVtcHR5RmlsZXMuc2V0KGVtcHR5U3RyZWFtQ291bnRlcisrLCAhaXNEaXIpOworICAgICAgICAgICAgICAgIGhhc0VtcHR5RmlsZXMgfD0gIWlzRGlyOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChoYXNFbXB0eUZpbGVzKSB7CisgICAgICAgICAgICBoZWFkZXIud3JpdGUoTklELmtFbXB0eUZpbGUpOworICAgICAgICAgICAgZmluYWwgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJhb3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgICAgICBmaW5hbCBEYXRhT3V0cHV0U3RyZWFtIG91dCA9IG5ldyBEYXRhT3V0cHV0U3RyZWFtKGJhb3MpOworICAgICAgICAgICAgd3JpdGVCaXRzKG91dCwgZW1wdHlGaWxlcywgZW1wdHlTdHJlYW1Db3VudGVyKTsKKyAgICAgICAgICAgIG91dC5mbHVzaCgpOworICAgICAgICAgICAgZmluYWwgYnl0ZVtdIGNvbnRlbnRzID0gYmFvcy50b0J5dGVBcnJheSgpOworICAgICAgICAgICAgd3JpdGVVaW50NjQoaGVhZGVyLCBjb250ZW50cy5sZW5ndGgpOworICAgICAgICAgICAgaGVhZGVyLndyaXRlKGNvbnRlbnRzKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB3cml0ZUZpbGVBbnRpSXRlbXMoZmluYWwgRGF0YU91dHB1dCBoZWFkZXIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJvb2xlYW4gaGFzQW50aUl0ZW1zID0gZmFsc2U7CisgICAgICAgIGZpbmFsIEJpdFNldCBhbnRpSXRlbXMgPSBuZXcgQml0U2V0KDApOworICAgICAgICBpbnQgYW50aUl0ZW1Db3VudGVyID0gMDsKKyAgICAgICAgZm9yIChmaW5hbCBTZXZlblpBcmNoaXZlRW50cnkgZmlsZTEgOiBmaWxlcykgeworICAgICAgICAgICAgaWYgKCFmaWxlMS5oYXNTdHJlYW0oKSkgeworICAgICAgICAgICAgICAgIGZpbmFsIGJvb2xlYW4gaXNBbnRpID0gZmlsZTEuaXNBbnRpSXRlbSgpOworICAgICAgICAgICAgICAgIGFudGlJdGVtcy5zZXQoYW50aUl0ZW1Db3VudGVyKyssIGlzQW50aSk7CisgICAgICAgICAgICAgICAgaGFzQW50aUl0ZW1zIHw9IGlzQW50aTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoaGFzQW50aUl0ZW1zKSB7CisgICAgICAgICAgICBoZWFkZXIud3JpdGUoTklELmtBbnRpKTsKKyAgICAgICAgICAgIGZpbmFsIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBiYW9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICAgICAgZmluYWwgRGF0YU91dHB1dFN0cmVhbSBvdXQgPSBuZXcgRGF0YU91dHB1dFN0cmVhbShiYW9zKTsKKyAgICAgICAgICAgIHdyaXRlQml0cyhvdXQsIGFudGlJdGVtcywgYW50aUl0ZW1Db3VudGVyKTsKKyAgICAgICAgICAgIG91dC5mbHVzaCgpOworICAgICAgICAgICAgZmluYWwgYnl0ZVtdIGNvbnRlbnRzID0gYmFvcy50b0J5dGVBcnJheSgpOworICAgICAgICAgICAgd3JpdGVVaW50NjQoaGVhZGVyLCBjb250ZW50cy5sZW5ndGgpOworICAgICAgICAgICAgaGVhZGVyLndyaXRlKGNvbnRlbnRzKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB3cml0ZUZpbGVOYW1lcyhmaW5hbCBEYXRhT3V0cHV0IGhlYWRlcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaGVhZGVyLndyaXRlKE5JRC5rTmFtZSk7CisKKyAgICAgICAgZmluYWwgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJhb3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIGZpbmFsIERhdGFPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IERhdGFPdXRwdXRTdHJlYW0oYmFvcyk7CisgICAgICAgIG91dC53cml0ZSgwKTsKKyAgICAgICAgZm9yIChmaW5hbCBTZXZlblpBcmNoaXZlRW50cnkgZW50cnkgOiBmaWxlcykgeworICAgICAgICAgICAgb3V0LndyaXRlKGVudHJ5LmdldE5hbWUoKS5nZXRCeXRlcygiVVRGLTE2TEUiKSk7CisgICAgICAgICAgICBvdXQud3JpdGVTaG9ydCgwKTsKKyAgICAgICAgfQorICAgICAgICBvdXQuZmx1c2goKTsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGNvbnRlbnRzID0gYmFvcy50b0J5dGVBcnJheSgpOworICAgICAgICB3cml0ZVVpbnQ2NChoZWFkZXIsIGNvbnRlbnRzLmxlbmd0aCk7CisgICAgICAgIGhlYWRlci53cml0ZShjb250ZW50cyk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlRmlsZUNUaW1lcyhmaW5hbCBEYXRhT3V0cHV0IGhlYWRlcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IG51bUNyZWF0aW9uRGF0ZXMgPSAwOworICAgICAgICBmb3IgKGZpbmFsIFNldmVuWkFyY2hpdmVFbnRyeSBlbnRyeSA6IGZpbGVzKSB7CisgICAgICAgICAgICBpZiAoZW50cnkuZ2V0SGFzQ3JlYXRpb25EYXRlKCkpIHsKKyAgICAgICAgICAgICAgICArK251bUNyZWF0aW9uRGF0ZXM7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKG51bUNyZWF0aW9uRGF0ZXMgPiAwKSB7CisgICAgICAgICAgICBoZWFkZXIud3JpdGUoTklELmtDVGltZSk7CisKKyAgICAgICAgICAgIGZpbmFsIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBiYW9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICAgICAgZmluYWwgRGF0YU91dHB1dFN0cmVhbSBvdXQgPSBuZXcgRGF0YU91dHB1dFN0cmVhbShiYW9zKTsKKyAgICAgICAgICAgIGlmIChudW1DcmVhdGlvbkRhdGVzICE9IGZpbGVzLnNpemUoKSkgeworICAgICAgICAgICAgICAgIG91dC53cml0ZSgwKTsKKyAgICAgICAgICAgICAgICBmaW5hbCBCaXRTZXQgY1RpbWVzID0gbmV3IEJpdFNldChmaWxlcy5zaXplKCkpOworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZXMuc2l6ZSgpOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgY1RpbWVzLnNldChpLCBmaWxlcy5nZXQoaSkuZ2V0SGFzQ3JlYXRpb25EYXRlKCkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB3cml0ZUJpdHMob3V0LCBjVGltZXMsIGZpbGVzLnNpemUoKSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIG91dC53cml0ZSgxKTsgLy8gImFsbEFyZURlZmluZWQiID09IHRydWUKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIG91dC53cml0ZSgwKTsKKyAgICAgICAgICAgIGZvciAoZmluYWwgU2V2ZW5aQXJjaGl2ZUVudHJ5IGVudHJ5IDogZmlsZXMpIHsKKyAgICAgICAgICAgICAgICBpZiAoZW50cnkuZ2V0SGFzQ3JlYXRpb25EYXRlKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgb3V0LndyaXRlTG9uZyhMb25nLnJldmVyc2VCeXRlcygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZXZlblpBcmNoaXZlRW50cnkuamF2YVRpbWVUb050ZnNUaW1lKGVudHJ5LmdldENyZWF0aW9uRGF0ZSgpKSkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIG91dC5mbHVzaCgpOworICAgICAgICAgICAgZmluYWwgYnl0ZVtdIGNvbnRlbnRzID0gYmFvcy50b0J5dGVBcnJheSgpOworICAgICAgICAgICAgd3JpdGVVaW50NjQoaGVhZGVyLCBjb250ZW50cy5sZW5ndGgpOworICAgICAgICAgICAgaGVhZGVyLndyaXRlKGNvbnRlbnRzKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB3cml0ZUZpbGVBVGltZXMoZmluYWwgRGF0YU91dHB1dCBoZWFkZXIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCBudW1BY2Nlc3NEYXRlcyA9IDA7CisgICAgICAgIGZvciAoZmluYWwgU2V2ZW5aQXJjaGl2ZUVudHJ5IGVudHJ5IDogZmlsZXMpIHsKKyAgICAgICAgICAgIGlmIChlbnRyeS5nZXRIYXNBY2Nlc3NEYXRlKCkpIHsKKyAgICAgICAgICAgICAgICArK251bUFjY2Vzc0RhdGVzOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChudW1BY2Nlc3NEYXRlcyA+IDApIHsKKyAgICAgICAgICAgIGhlYWRlci53cml0ZShOSUQua0FUaW1lKTsKKworICAgICAgICAgICAgZmluYWwgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJhb3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgICAgICBmaW5hbCBEYXRhT3V0cHV0U3RyZWFtIG91dCA9IG5ldyBEYXRhT3V0cHV0U3RyZWFtKGJhb3MpOworICAgICAgICAgICAgaWYgKG51bUFjY2Vzc0RhdGVzICE9IGZpbGVzLnNpemUoKSkgeworICAgICAgICAgICAgICAgIG91dC53cml0ZSgwKTsKKyAgICAgICAgICAgICAgICBmaW5hbCBCaXRTZXQgYVRpbWVzID0gbmV3IEJpdFNldChmaWxlcy5zaXplKCkpOworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZXMuc2l6ZSgpOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgYVRpbWVzLnNldChpLCBmaWxlcy5nZXQoaSkuZ2V0SGFzQWNjZXNzRGF0ZSgpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgd3JpdGVCaXRzKG91dCwgYVRpbWVzLCBmaWxlcy5zaXplKCkpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBvdXQud3JpdGUoMSk7IC8vICJhbGxBcmVEZWZpbmVkIiA9PSB0cnVlCisgICAgICAgICAgICB9CisgICAgICAgICAgICBvdXQud3JpdGUoMCk7CisgICAgICAgICAgICBmb3IgKGZpbmFsIFNldmVuWkFyY2hpdmVFbnRyeSBlbnRyeSA6IGZpbGVzKSB7CisgICAgICAgICAgICAgICAgaWYgKGVudHJ5LmdldEhhc0FjY2Vzc0RhdGUoKSkgeworICAgICAgICAgICAgICAgICAgICBvdXQud3JpdGVMb25nKExvbmcucmV2ZXJzZUJ5dGVzKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNldmVuWkFyY2hpdmVFbnRyeS5qYXZhVGltZVRvTnRmc1RpbWUoZW50cnkuZ2V0QWNjZXNzRGF0ZSgpKSkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIG91dC5mbHVzaCgpOworICAgICAgICAgICAgZmluYWwgYnl0ZVtdIGNvbnRlbnRzID0gYmFvcy50b0J5dGVBcnJheSgpOworICAgICAgICAgICAgd3JpdGVVaW50NjQoaGVhZGVyLCBjb250ZW50cy5sZW5ndGgpOworICAgICAgICAgICAgaGVhZGVyLndyaXRlKGNvbnRlbnRzKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB3cml0ZUZpbGVNVGltZXMoZmluYWwgRGF0YU91dHB1dCBoZWFkZXIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCBudW1MYXN0TW9kaWZpZWREYXRlcyA9IDA7CisgICAgICAgIGZvciAoZmluYWwgU2V2ZW5aQXJjaGl2ZUVudHJ5IGVudHJ5IDogZmlsZXMpIHsKKyAgICAgICAgICAgIGlmIChlbnRyeS5nZXRIYXNMYXN0TW9kaWZpZWREYXRlKCkpIHsKKyAgICAgICAgICAgICAgICArK251bUxhc3RNb2RpZmllZERhdGVzOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChudW1MYXN0TW9kaWZpZWREYXRlcyA+IDApIHsKKyAgICAgICAgICAgIGhlYWRlci53cml0ZShOSUQua01UaW1lKTsKKworICAgICAgICAgICAgZmluYWwgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJhb3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgICAgICBmaW5hbCBEYXRhT3V0cHV0U3RyZWFtIG91dCA9IG5ldyBEYXRhT3V0cHV0U3RyZWFtKGJhb3MpOworICAgICAgICAgICAgaWYgKG51bUxhc3RNb2RpZmllZERhdGVzICE9IGZpbGVzLnNpemUoKSkgeworICAgICAgICAgICAgICAgIG91dC53cml0ZSgwKTsKKyAgICAgICAgICAgICAgICBmaW5hbCBCaXRTZXQgbVRpbWVzID0gbmV3IEJpdFNldChmaWxlcy5zaXplKCkpOworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZXMuc2l6ZSgpOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgbVRpbWVzLnNldChpLCBmaWxlcy5nZXQoaSkuZ2V0SGFzTGFzdE1vZGlmaWVkRGF0ZSgpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgd3JpdGVCaXRzKG91dCwgbVRpbWVzLCBmaWxlcy5zaXplKCkpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBvdXQud3JpdGUoMSk7IC8vICJhbGxBcmVEZWZpbmVkIiA9PSB0cnVlCisgICAgICAgICAgICB9CisgICAgICAgICAgICBvdXQud3JpdGUoMCk7CisgICAgICAgICAgICBmb3IgKGZpbmFsIFNldmVuWkFyY2hpdmVFbnRyeSBlbnRyeSA6IGZpbGVzKSB7CisgICAgICAgICAgICAgICAgaWYgKGVudHJ5LmdldEhhc0xhc3RNb2RpZmllZERhdGUoKSkgeworICAgICAgICAgICAgICAgICAgICBvdXQud3JpdGVMb25nKExvbmcucmV2ZXJzZUJ5dGVzKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNldmVuWkFyY2hpdmVFbnRyeS5qYXZhVGltZVRvTnRmc1RpbWUoZW50cnkuZ2V0TGFzdE1vZGlmaWVkRGF0ZSgpKSkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIG91dC5mbHVzaCgpOworICAgICAgICAgICAgZmluYWwgYnl0ZVtdIGNvbnRlbnRzID0gYmFvcy50b0J5dGVBcnJheSgpOworICAgICAgICAgICAgd3JpdGVVaW50NjQoaGVhZGVyLCBjb250ZW50cy5sZW5ndGgpOworICAgICAgICAgICAgaGVhZGVyLndyaXRlKGNvbnRlbnRzKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB3cml0ZUZpbGVXaW5kb3dzQXR0cmlidXRlcyhmaW5hbCBEYXRhT3V0cHV0IGhlYWRlcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IG51bVdpbmRvd3NBdHRyaWJ1dGVzID0gMDsKKyAgICAgICAgZm9yIChmaW5hbCBTZXZlblpBcmNoaXZlRW50cnkgZW50cnkgOiBmaWxlcykgeworICAgICAgICAgICAgaWYgKGVudHJ5LmdldEhhc1dpbmRvd3NBdHRyaWJ1dGVzKCkpIHsKKyAgICAgICAgICAgICAgICArK251bVdpbmRvd3NBdHRyaWJ1dGVzOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChudW1XaW5kb3dzQXR0cmlidXRlcyA+IDApIHsKKyAgICAgICAgICAgIGhlYWRlci53cml0ZShOSUQua1dpbkF0dHJpYnV0ZXMpOworCisgICAgICAgICAgICBmaW5hbCBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYmFvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgICAgIGZpbmFsIERhdGFPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IERhdGFPdXRwdXRTdHJlYW0oYmFvcyk7CisgICAgICAgICAgICBpZiAobnVtV2luZG93c0F0dHJpYnV0ZXMgIT0gZmlsZXMuc2l6ZSgpKSB7CisgICAgICAgICAgICAgICAgb3V0LndyaXRlKDApOworICAgICAgICAgICAgICAgIGZpbmFsIEJpdFNldCBhdHRyaWJ1dGVzID0gbmV3IEJpdFNldChmaWxlcy5zaXplKCkpOworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZXMuc2l6ZSgpOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlcy5zZXQoaSwgZmlsZXMuZ2V0KGkpLmdldEhhc1dpbmRvd3NBdHRyaWJ1dGVzKCkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB3cml0ZUJpdHMob3V0LCBhdHRyaWJ1dGVzLCBmaWxlcy5zaXplKCkpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBvdXQud3JpdGUoMSk7IC8vICJhbGxBcmVEZWZpbmVkIiA9PSB0cnVlCisgICAgICAgICAgICB9CisgICAgICAgICAgICBvdXQud3JpdGUoMCk7CisgICAgICAgICAgICBmb3IgKGZpbmFsIFNldmVuWkFyY2hpdmVFbnRyeSBlbnRyeSA6IGZpbGVzKSB7CisgICAgICAgICAgICAgICAgaWYgKGVudHJ5LmdldEhhc1dpbmRvd3NBdHRyaWJ1dGVzKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgb3V0LndyaXRlSW50KEludGVnZXIucmV2ZXJzZUJ5dGVzKGVudHJ5LmdldFdpbmRvd3NBdHRyaWJ1dGVzKCkpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBvdXQuZmx1c2goKTsKKyAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBjb250ZW50cyA9IGJhb3MudG9CeXRlQXJyYXkoKTsKKyAgICAgICAgICAgIHdyaXRlVWludDY0KGhlYWRlciwgY29udGVudHMubGVuZ3RoKTsKKyAgICAgICAgICAgIGhlYWRlci53cml0ZShjb250ZW50cyk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgd3JpdGVVaW50NjQoZmluYWwgRGF0YU91dHB1dCBoZWFkZXIsIGxvbmcgdmFsdWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCBmaXJzdEJ5dGUgPSAwOworICAgICAgICBpbnQgbWFzayA9IDB4ODA7CisgICAgICAgIGludCBpOworICAgICAgICBmb3IgKGkgPSAwOyBpIDwgODsgaSsrKSB7CisgICAgICAgICAgICBpZiAodmFsdWUgPCAoKDFMIDw8ICggNyAgKiAoaSArIDEpKSkpKSB7CisgICAgICAgICAgICAgICAgZmlyc3RCeXRlIHw9ICh2YWx1ZSA+Pj4gKDggKiBpKSk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmaXJzdEJ5dGUgfD0gbWFzazsKKyAgICAgICAgICAgIG1hc2sgPj4+PSAxOworICAgICAgICB9CisgICAgICAgIGhlYWRlci53cml0ZShmaXJzdEJ5dGUpOworICAgICAgICBmb3IgKDsgaSA+IDA7IGktLSkgeworICAgICAgICAgICAgaGVhZGVyLndyaXRlKChpbnQpICgweGZmICYgdmFsdWUpKTsKKyAgICAgICAgICAgIHZhbHVlID4+Pj0gODsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB3cml0ZUJpdHMoZmluYWwgRGF0YU91dHB1dCBoZWFkZXIsIGZpbmFsIEJpdFNldCBiaXRzLCBmaW5hbCBpbnQgbGVuZ3RoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgY2FjaGUgPSAwOworICAgICAgICBpbnQgc2hpZnQgPSA3OworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBjYWNoZSB8PSAoKGJpdHMuZ2V0KGkpID8gMSA6IDApIDw8IHNoaWZ0KTsKKyAgICAgICAgICAgIGlmICgtLXNoaWZ0IDwgMCkgeworICAgICAgICAgICAgICAgIGhlYWRlci53cml0ZShjYWNoZSk7CisgICAgICAgICAgICAgICAgc2hpZnQgPSA3OworICAgICAgICAgICAgICAgIGNhY2hlID0gMDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoc2hpZnQgIT0gNykgeworICAgICAgICAgICAgaGVhZGVyLndyaXRlKGNhY2hlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIDxUPiBJdGVyYWJsZTxUPiByZXZlcnNlKGZpbmFsIEl0ZXJhYmxlPFQ+IGkpIHsKKyAgICAgICAgZmluYWwgTGlua2VkTGlzdDxUPiBsID0gbmV3IExpbmtlZExpc3Q8PigpOworICAgICAgICBmb3IgKGZpbmFsIFQgdCA6IGkpIHsKKyAgICAgICAgICAgIGwuYWRkRmlyc3QodCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGw7CisgICAgfQorCisgICAgcHJpdmF0ZSBjbGFzcyBPdXRwdXRTdHJlYW1XcmFwcGVyIGV4dGVuZHMgT3V0cHV0U3RyZWFtIHsKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEJVRl9TSVpFID0gODE5MjsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBCeXRlQnVmZmVyIGJ1ZmZlciA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUoQlVGX1NJWkUpOworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgd3JpdGUoZmluYWwgaW50IGIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBidWZmZXIuY2xlYXIoKTsKKyAgICAgICAgICAgIGJ1ZmZlci5wdXQoKGJ5dGUpIGIpLmZsaXAoKTsKKyAgICAgICAgICAgIGNoYW5uZWwud3JpdGUoYnVmZmVyKTsKKyAgICAgICAgICAgIGNvbXByZXNzZWRDcmMzMi51cGRhdGUoYik7CisgICAgICAgICAgICBmaWxlQnl0ZXNXcml0dGVuKys7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgd3JpdGUoZmluYWwgYnl0ZVtdIGIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBPdXRwdXRTdHJlYW1XcmFwcGVyLnRoaXMud3JpdGUoYiwgMCwgYi5sZW5ndGgpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIHdyaXRlKGZpbmFsIGJ5dGVbXSBiLCBmaW5hbCBpbnQgb2ZmLCBmaW5hbCBpbnQgbGVuKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGlmIChsZW4gPiBCVUZfU0laRSkgeworICAgICAgICAgICAgICAgIGNoYW5uZWwud3JpdGUoQnl0ZUJ1ZmZlci53cmFwKGIsIG9mZiwgbGVuKSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGJ1ZmZlci5jbGVhcigpOworICAgICAgICAgICAgICAgIGJ1ZmZlci5wdXQoYiwgb2ZmLCBsZW4pLmZsaXAoKTsKKyAgICAgICAgICAgICAgICBjaGFubmVsLndyaXRlKGJ1ZmZlcik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjb21wcmVzc2VkQ3JjMzIudXBkYXRlKGIsIG9mZiwgbGVuKTsKKyAgICAgICAgICAgIGZpbGVCeXRlc1dyaXR0ZW4gKz0gbGVuOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIGZsdXNoKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIC8vIG5vIHJlYXNvbiB0byBmbHVzaCB0aGUgY2hhbm5lbAorICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIC8vIHRoZSBmaWxlIHdpbGwgYmUgY2xvc2VkIGJ5IHRoZSBjb250YWluaW5nIGNsYXNzJ3MgY2xvc2UgbWV0aG9kCisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvc2V2ZW56L1N0YXJ0SGVhZGVyLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvc2V2ZW56L1N0YXJ0SGVhZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTMzYWNhNwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9zZXZlbnovU3RhcnRIZWFkZXIuamF2YQpAQCAtMCwwICsxLDI0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuc2V2ZW56OworCitjbGFzcyBTdGFydEhlYWRlciB7CisgICAgbG9uZyBuZXh0SGVhZGVyT2Zmc2V0OworICAgIGxvbmcgbmV4dEhlYWRlclNpemU7CisgICAgbG9uZyBuZXh0SGVhZGVyQ3JjOworfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3NldmVuei9TdHJlYW1NYXAuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9zZXZlbnovU3RyZWFtTWFwLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWExMGUxZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9zZXZlbnovU3RyZWFtTWFwLmphdmEKQEAgLTAsMCArMSwzOCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICoKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnNldmVuejsKKworLy8vIE1hcCBiZXR3ZWVuIGZvbGRlcnMsIGZpbGVzIGFuZCBzdHJlYW1zLgorY2xhc3MgU3RyZWFtTWFwIHsKKyAgICAvLy8gVGhlIGZpcnN0IEFyY2hpdmUucGFja1N0cmVhbSBpbmRleCBvZiBlYWNoIGZvbGRlci4KKyAgICBpbnRbXSBmb2xkZXJGaXJzdFBhY2tTdHJlYW1JbmRleDsKKyAgICAvLy8gT2Zmc2V0IHRvIGJlZ2lubmluZyBvZiB0aGlzIHBhY2sgc3RyZWFtJ3MgZGF0YSwgcmVsYXRpdmUgdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUgZmlyc3QgcGFjayBzdHJlYW0uCisgICAgbG9uZ1tdIHBhY2tTdHJlYW1PZmZzZXRzOworICAgIC8vLyBJbmRleCBvZiBmaXJzdCBmaWxlIGZvciBlYWNoIGZvbGRlci4KKyAgICBpbnRbXSBmb2xkZXJGaXJzdEZpbGVJbmRleDsKKyAgICAvLy8gSW5kZXggb2YgZm9sZGVyIGZvciBlYWNoIGZpbGUuCisgICAgaW50W10gZmlsZUZvbGRlckluZGV4OworCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuICJTdHJlYW1NYXAgd2l0aCBpbmRpY2VzIG9mICIgKyBmb2xkZXJGaXJzdFBhY2tTdHJlYW1JbmRleC5sZW5ndGgKKyAgICAgICAgICAgICsgIiBmb2xkZXJzLCBvZmZzZXRzIG9mICIgKyBwYWNrU3RyZWFtT2Zmc2V0cy5sZW5ndGggKyAiIHBhY2tlZCBzdHJlYW1zLCIKKyAgICAgICAgICAgICsgIiBmaXJzdCBmaWxlcyBvZiAiICsgZm9sZGVyRmlyc3RGaWxlSW5kZXgubGVuZ3RoICsgIiBmb2xkZXJzIGFuZCIKKyAgICAgICAgICAgICsgIiBmb2xkZXIgaW5kaWNlcyBmb3IgIiArIGZpbGVGb2xkZXJJbmRleC5sZW5ndGggKyAiIGZpbGVzIjsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvc2V2ZW56L1N1YlN0cmVhbXNJbmZvLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvc2V2ZW56L1N1YlN0cmVhbXNJbmZvLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTVmYWJjNgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9zZXZlbnovU3ViU3RyZWFtc0luZm8uamF2YQpAQCAtMCwwICsxLDMwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuc2V2ZW56OworCitpbXBvcnQgamF2YS51dGlsLkJpdFNldDsKKworLy8vIFByb3BlcnRpZXMgZm9yIG5vbi1lbXB0eSBmaWxlcy4KK2NsYXNzIFN1YlN0cmVhbXNJbmZvIHsKKyAgICAvLy8gVW5wYWNrZWQgc2l6ZSBvZiBlYWNoIHVucGFja2VkIHN0cmVhbS4KKyAgICBsb25nW10gdW5wYWNrU2l6ZXM7CisgICAgLy8vIFdoZXRoZXIgQ1JDIGlzIHByZXNlbnQgZm9yIGVhY2ggdW5wYWNrZWQgc3RyZWFtLgorICAgIEJpdFNldCBoYXNDcmM7CisgICAgLy8vIENSQ3Mgb2YgdW5wYWNrZWQgc3RyZWFtcywgaWYgcHJlc2VudC4KKyAgICBsb25nW10gY3JjczsKK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9zZXZlbnovcGFja2FnZS5odG1sIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3NldmVuei9wYWNrYWdlLmh0bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTc1NzAzYgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9zZXZlbnovcGFja2FnZS5odG1sCkBAIC0wLDAgKzEsMjQgQEAKKzxodG1sPgorPCEtLQorCisgICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAgIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAgICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorCisgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisKKyAgIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAgIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAgIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAgIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorCistLT4KKyAgPGJvZHk+CisgICAgPHA+UHJvdmlkZXMgY2xhc3NlcyBmb3IgcmVhZGluZyBhbmQgd3JpdGluZyBhcmNoaXZlcyB1c2luZworICAgICAgdGhlIDd6IGZvcm1hdC48L3A+CisgIDwvYm9keT4KKzwvaHRtbD4KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy90YXIvVGFyQXJjaGl2ZUVudHJ5LmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvdGFyL1RhckFyY2hpdmVFbnRyeS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFjOThmMGEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvdGFyL1RhckFyY2hpdmVFbnRyeS5qYXZhCkBAIC0wLDAgKzEsMTQ0MCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMudGFyOworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5EYXRlOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLkFyY2hpdmVFbnRyeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcC5aaXBFbmNvZGluZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuQXJjaGl2ZVV0aWxzOworCisvKioKKyAqIFRoaXMgY2xhc3MgcmVwcmVzZW50cyBhbiBlbnRyeSBpbiBhIFRhciBhcmNoaXZlLiBJdCBjb25zaXN0cworICogb2YgdGhlIGVudHJ5J3MgaGVhZGVyLCBhcyB3ZWxsIGFzIHRoZSBlbnRyeSdzIEZpbGUuIEVudHJpZXMKKyAqIGNhbiBiZSBpbnN0YW50aWF0ZWQgaW4gb25lIG9mIHRocmVlIHdheXMsIGRlcGVuZGluZyBvbiBob3cKKyAqIHRoZXkgYXJlIHRvIGJlIHVzZWQuCisgKiA8cD4KKyAqIFRhckVudHJpZXMgdGhhdCBhcmUgY3JlYXRlZCBmcm9tIHRoZSBoZWFkZXIgYnl0ZXMgcmVhZCBmcm9tCisgKiBhbiBhcmNoaXZlIGFyZSBpbnN0YW50aWF0ZWQgd2l0aCB0aGUgVGFyRW50cnkoIGJ5dGVbXSApCisgKiBjb25zdHJ1Y3Rvci4gVGhlc2UgZW50cmllcyB3aWxsIGJlIHVzZWQgd2hlbiBleHRyYWN0aW5nIGZyb20KKyAqIG9yIGxpc3RpbmcgdGhlIGNvbnRlbnRzIG9mIGFuIGFyY2hpdmUuIFRoZXNlIGVudHJpZXMgaGF2ZSB0aGVpcgorICogaGVhZGVyIGZpbGxlZCBpbiB1c2luZyB0aGUgaGVhZGVyIGJ5dGVzLiBUaGV5IGFsc28gc2V0IHRoZSBGaWxlCisgKiB0byBudWxsLCBzaW5jZSB0aGV5IHJlZmVyZW5jZSBhbiBhcmNoaXZlIGVudHJ5IG5vdCBhIGZpbGUuCisgKiA8cD4KKyAqIFRhckVudHJpZXMgdGhhdCBhcmUgY3JlYXRlZCBmcm9tIEZpbGVzIHRoYXQgYXJlIHRvIGJlIHdyaXR0ZW4KKyAqIGludG8gYW4gYXJjaGl2ZSBhcmUgaW5zdGFudGlhdGVkIHdpdGggdGhlIFRhckVudHJ5KCBGaWxlICkKKyAqIGNvbnN0cnVjdG9yLiBUaGVzZSBlbnRyaWVzIGhhdmUgdGhlaXIgaGVhZGVyIGZpbGxlZCBpbiB1c2luZworICogdGhlIEZpbGUncyBpbmZvcm1hdGlvbi4gVGhleSBhbHNvIGtlZXAgYSByZWZlcmVuY2UgdG8gdGhlIEZpbGUKKyAqIGZvciBjb252ZW5pZW5jZSB3aGVuIHdyaXRpbmcgZW50cmllcy4KKyAqIDxwPgorICogRmluYWxseSwgVGFyRW50cmllcyBjYW4gYmUgY29uc3RydWN0ZWQgZnJvbSBub3RoaW5nIGJ1dCBhIG5hbWUuCisgKiBUaGlzIGFsbG93cyB0aGUgcHJvZ3JhbW1lciB0byBjb25zdHJ1Y3QgdGhlIGVudHJ5IGJ5IGhhbmQsIGZvcgorICogaW5zdGFuY2Ugd2hlbiBvbmx5IGFuIElucHV0U3RyZWFtIGlzIGF2YWlsYWJsZSBmb3Igd3JpdGluZyB0bworICogdGhlIGFyY2hpdmUsIGFuZCB0aGUgaGVhZGVyIGluZm9ybWF0aW9uIGlzIGNvbnN0cnVjdGVkIGZyb20KKyAqIG90aGVyIGluZm9ybWF0aW9uLiBJbiB0aGlzIGNhc2UgdGhlIGhlYWRlciBmaWVsZHMgYXJlIHNldCB0bworICogZGVmYXVsdHMgYW5kIHRoZSBGaWxlIGlzIHNldCB0byBudWxsLgorICoKKyAqIDxwPgorICogVGhlIEMgc3RydWN0dXJlIGZvciBhIFRhciBFbnRyeSdzIGhlYWRlciBpczoKKyAqIDxwcmU+CisgKiBzdHJ1Y3QgaGVhZGVyIHsKKyAqIGNoYXIgbmFtZVsxMDBdOyAgICAgLy8gVGFyQ29uc3RhbnRzLk5BTUVMRU4gICAgLSBvZmZzZXQgICAwCisgKiBjaGFyIG1vZGVbOF07ICAgICAgIC8vIFRhckNvbnN0YW50cy5NT0RFTEVOICAgIC0gb2Zmc2V0IDEwMAorICogY2hhciB1aWRbOF07ICAgICAgICAvLyBUYXJDb25zdGFudHMuVUlETEVOICAgICAtIG9mZnNldCAxMDgKKyAqIGNoYXIgZ2lkWzhdOyAgICAgICAgLy8gVGFyQ29uc3RhbnRzLkdJRExFTiAgICAgLSBvZmZzZXQgMTE2CisgKiBjaGFyIHNpemVbMTJdOyAgICAgIC8vIFRhckNvbnN0YW50cy5TSVpFTEVOICAgIC0gb2Zmc2V0IDEyNAorICogY2hhciBtdGltZVsxMl07ICAgICAvLyBUYXJDb25zdGFudHMuTU9EVElNRUxFTiAtIG9mZnNldCAxMzYKKyAqIGNoYXIgY2hrc3VtWzhdOyAgICAgLy8gVGFyQ29uc3RhbnRzLkNIS1NVTUxFTiAgLSBvZmZzZXQgMTQ4CisgKiBjaGFyIGxpbmtmbGFnWzFdOyAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgIC0gb2Zmc2V0IDE1NgorICogY2hhciBsaW5rbmFtZVsxMDBdOyAvLyBUYXJDb25zdGFudHMuTkFNRUxFTiAgICAtIG9mZnNldCAxNTcKKyAqIFRoZSBmb2xsb3dpbmcgZmllbGRzIGFyZSBvbmx5IHByZXNlbnQgaW4gbmV3LXN0eWxlIFBPU0lYIHRhciBhcmNoaXZlczoKKyAqIGNoYXIgbWFnaWNbNl07ICAgICAgLy8gVGFyQ29uc3RhbnRzLk1BR0lDTEVOICAgLSBvZmZzZXQgMjU3CisgKiBjaGFyIHZlcnNpb25bMl07ICAgIC8vIFRhckNvbnN0YW50cy5WRVJTSU9OTEVOIC0gb2Zmc2V0IDI2MworICogY2hhciB1bmFtZVszMl07ICAgICAvLyBUYXJDb25zdGFudHMuVU5BTUVMRU4gICAtIG9mZnNldCAyNjUKKyAqIGNoYXIgZ25hbWVbMzJdOyAgICAgLy8gVGFyQ29uc3RhbnRzLkdOQU1FTEVOICAgLSBvZmZzZXQgMjk3CisgKiBjaGFyIGRldm1ham9yWzhdOyAgIC8vIFRhckNvbnN0YW50cy5ERVZMRU4gICAgIC0gb2Zmc2V0IDMyOQorICogY2hhciBkZXZtaW5vcls4XTsgICAvLyBUYXJDb25zdGFudHMuREVWTEVOICAgICAtIG9mZnNldCAzMzcKKyAqIGNoYXIgcHJlZml4WzE1NV07ICAgLy8gVGFyQ29uc3RhbnRzLlBSRUZJWExFTiAgLSBvZmZzZXQgMzQ1CisgKiAvLyBVc2VkIGlmICJuYW1lIiBmaWVsZCBpcyBub3QgbG9uZyBlbm91Z2ggdG8gaG9sZCB0aGUgcGF0aAorICogY2hhciBwYWRbMTJdOyAgICAgICAvLyBOVUxzICAgICAgICAgICAgICAgICAgICAtIG9mZnNldCA1MDAKKyAqIH0gaGVhZGVyOworICogQWxsIHVudXNlZCBieXRlcyBhcmUgc2V0IHRvIG51bGwuCisgKiBOZXctc3R5bGUgR05VIHRhciBmaWxlcyBhcmUgc2xpZ2h0bHkgZGlmZmVyZW50IGZyb20gdGhlIGFib3ZlLgorICogRm9yIHZhbHVlcyBvZiBzaXplIGxhcmdlciB0aGFuIDA3Nzc3Nzc3Nzc3N0wgKDExIDdzKQorICogb3IgdWlkIGFuZCBnaWQgbGFyZ2VyIHRoYW4gMDc3Nzc3NzdMICg3IDdzKQorICogdGhlIHNpZ24gYml0IG9mIHRoZSBmaXJzdCBieXRlIGlzIHNldCwgYW5kIHRoZSByZXN0IG9mIHRoZQorICogZmllbGQgaXMgdGhlIGJpbmFyeSByZXByZXNlbnRhdGlvbiBvZiB0aGUgbnVtYmVyLgorICogU2VlIFRhclV0aWxzLnBhcnNlT2N0YWxPckJpbmFyeS4KKyAqIDwvcHJlPgorICoKKyAqIDxwPgorICogVGhlIEMgc3RydWN0dXJlIGZvciBhIG9sZCBHTlUgVGFyIEVudHJ5J3MgaGVhZGVyIGlzOgorICogPHByZT4KKyAqIHN0cnVjdCBvbGRnbnVfaGVhZGVyIHsKKyAqIGNoYXIgdW51c2VkX3BhZDFbMzQ1XTsgLy8gVGFyQ29uc3RhbnRzLlBBRDFMRU5fR05VICAgICAgIC0gb2Zmc2V0IDAKKyAqIGNoYXIgYXRpbWVbMTJdOyAgICAgICAgLy8gVGFyQ29uc3RhbnRzLkFUSU1FTEVOX0dOVSAgICAgIC0gb2Zmc2V0IDM0NQorICogY2hhciBjdGltZVsxMl07ICAgICAgICAvLyBUYXJDb25zdGFudHMuQ1RJTUVMRU5fR05VICAgICAgLSBvZmZzZXQgMzU3CisgKiBjaGFyIG9mZnNldFsxMl07ICAgICAgIC8vIFRhckNvbnN0YW50cy5PRkZTRVRMRU5fR05VICAgICAtIG9mZnNldCAzNjkKKyAqIGNoYXIgbG9uZ25hbWVzWzRdOyAgICAgLy8gVGFyQ29uc3RhbnRzLkxPTkdOQU1FU0xFTl9HTlUgIC0gb2Zmc2V0IDM4MQorICogY2hhciB1bnVzZWRfcGFkMjsgICAgICAvLyBUYXJDb25zdGFudHMuUEFEMkxFTl9HTlUgICAgICAgLSBvZmZzZXQgMzg1CisgKiBzdHJ1Y3Qgc3BhcnNlIHNwWzRdOyAgIC8vIFRhckNvbnN0YW50cy5TUEFSU0VMRU5fR05VICAgICAtIG9mZnNldCAzODYKKyAqIGNoYXIgaXNleHRlbmRlZDsgICAgICAgLy8gVGFyQ29uc3RhbnRzLklTRVhURU5ERURMRU5fR05VIC0gb2Zmc2V0IDQ4MgorICogY2hhciByZWFsc2l6ZVsxMl07ICAgICAvLyBUYXJDb25zdGFudHMuUkVBTFNJWkVMRU5fR05VICAgLSBvZmZzZXQgNDgzCisgKiBjaGFyIHVudXNlZF9wYWRbMTddOyAgIC8vIFRhckNvbnN0YW50cy5QQUQzTEVOX0dOVSAgICAgICAtIG9mZnNldCA0OTUKKyAqIH07CisgKiA8L3ByZT4KKyAqIFdoZXJlYXMsICJzdHJ1Y3Qgc3BhcnNlIiBpczoKKyAqIDxwcmU+CisgKiBzdHJ1Y3Qgc3BhcnNlIHsKKyAqIGNoYXIgb2Zmc2V0WzEyXTsgICAvLyBvZmZzZXQgMAorICogY2hhciBudW1ieXRlc1sxMl07IC8vIG9mZnNldCAxMgorICogfTsKKyAqIDwvcHJlPgorICoKKyAqIDxwPgorICogVGhlIEMgc3RydWN0dXJlIGZvciBhIHhzdGFyIChKw7ZyZyBTY2hpbGxpbmcgc3RhcikgVGFyIEVudHJ5J3MgaGVhZGVyIGlzOgorICogPHByZT4KKyAqIHN0cnVjdCBzdGFyX2hlYWRlciB7CisgKiAgY2hhciBuYW1lWzEwMF07CQkvLyBvZmZzZXQgICAwCisgKiAgY2hhciBtb2RlWzhdOwkJLy8gb2Zmc2V0IDEwMAorICogIGNoYXIgdWlkWzhdOwkJLy8gb2Zmc2V0IDEwOAorICogIGNoYXIgZ2lkWzhdOwkJLy8gb2Zmc2V0IDExNgorICogIGNoYXIgc2l6ZVsxMl07CQkvLyBvZmZzZXQgMTI0CisgKiAgY2hhciBtdGltZVsxMl07CQkvLyBvZmZzZXQgMTM2CisgKiAgY2hhciBjaGtzdW1bOF07CQkvLyBvZmZzZXQgMTQ4CisgKiAgY2hhciB0eXBlZmxhZzsJCS8vIG9mZnNldCAxNTYKKyAqICBjaGFyIGxpbmtuYW1lWzEwMF07CQkvLyBvZmZzZXQgMTU3CisgKiAgY2hhciBtYWdpY1s2XTsJCS8vIG9mZnNldCAyNTcKKyAqICBjaGFyIHZlcnNpb25bMl07CQkvLyBvZmZzZXQgMjYzCisgKiAgY2hhciB1bmFtZVszMl07CQkvLyBvZmZzZXQgMjY1CisgKiAgY2hhciBnbmFtZVszMl07CQkvLyBvZmZzZXQgMjk3CisgKiAgY2hhciBkZXZtYWpvcls4XTsJCS8vIG9mZnNldCAzMjkKKyAqICBjaGFyIGRldm1pbm9yWzhdOwkJLy8gb2Zmc2V0IDMzNworICogIGNoYXIgcHJlZml4WzEzMV07CQkvLyBvZmZzZXQgMzQ1CisgKiAgY2hhciBhdGltZVsxMl07ICAgICAgICAgICAgIC8vIG9mZnNldCA0NzYKKyAqICBjaGFyIGN0aW1lWzEyXTsgICAgICAgICAgICAgLy8gb2Zmc2V0IDQ4OAorICogIGNoYXIgbWZpbGxbOF07ICAgICAgICAgICAgICAvLyBvZmZzZXQgNTAwCisgKiAgY2hhciB4bWFnaWNbNF07ICAgICAgICAgICAgIC8vIG9mZnNldCA1MDggICJ0YXIiCisgKiB9OworICogPC9wcmU+CisgKiA8cD53aGljaCBpcyBpZGVudGljYWwgdG8gbmV3LXN0eWxlIFBPU0lYIHVwIHRvIHRoZSBmaXJzdCAxMzAgYnl0ZXMgb2YgdGhlIHByZWZpeC48L3A+CisgKgorICogQE5vdFRocmVhZFNhZmUKKyAqLworCitwdWJsaWMgY2xhc3MgVGFyQXJjaGl2ZUVudHJ5IGltcGxlbWVudHMgQXJjaGl2ZUVudHJ5LCBUYXJDb25zdGFudHMgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRhckFyY2hpdmVFbnRyeVtdIEVNUFRZX1RBUl9BUkNISVZFX0VOVFJJRVMgPSBuZXcgVGFyQXJjaGl2ZUVudHJ5WzBdOworCisgICAgLyoqIFRoZSBlbnRyeSdzIG5hbWUuICovCisgICAgcHJpdmF0ZSBTdHJpbmcgbmFtZSA9ICIiOworCisgICAgLyoqIFdoZXRoZXIgdG8gYWxsb3cgbGVhZGluZyBzbGFzaGVzIG9yIGRyaXZlIG5hbWVzIGluc2lkZSB0aGUgbmFtZSAqLworICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiBwcmVzZXJ2ZUFic29sdXRlUGF0aDsKKworICAgIC8qKiBUaGUgZW50cnkncyBwZXJtaXNzaW9uIG1vZGUuICovCisgICAgcHJpdmF0ZSBpbnQgbW9kZTsKKworICAgIC8qKiBUaGUgZW50cnkncyB1c2VyIGlkLiAqLworICAgIHByaXZhdGUgbG9uZyB1c2VySWQgPSAwOworCisgICAgLyoqIFRoZSBlbnRyeSdzIGdyb3VwIGlkLiAqLworICAgIHByaXZhdGUgbG9uZyBncm91cElkID0gMDsKKworICAgIC8qKiBUaGUgZW50cnkncyBzaXplLiAqLworICAgIHByaXZhdGUgbG9uZyBzaXplID0gMDsKKworICAgIC8qKiBUaGUgZW50cnkncyBtb2RpZmljYXRpb24gdGltZS4gKi8KKyAgICBwcml2YXRlIGxvbmcgbW9kVGltZTsKKworICAgIC8qKiBJZiB0aGUgaGVhZGVyIGNoZWNrc3VtIGlzIHJlYXNvbmFibHkgY29ycmVjdC4gKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gY2hlY2tTdW1PSzsKKworICAgIC8qKiBUaGUgZW50cnkncyBsaW5rIGZsYWcuICovCisgICAgcHJpdmF0ZSBieXRlIGxpbmtGbGFnOworCisgICAgLyoqIFRoZSBlbnRyeSdzIGxpbmsgbmFtZS4gKi8KKyAgICBwcml2YXRlIFN0cmluZyBsaW5rTmFtZSA9ICIiOworCisgICAgLyoqIFRoZSBlbnRyeSdzIG1hZ2ljIHRhZy4gKi8KKyAgICBwcml2YXRlIFN0cmluZyBtYWdpYyA9IE1BR0lDX1BPU0lYOworICAgIC8qKiBUaGUgdmVyc2lvbiBvZiB0aGUgZm9ybWF0ICovCisgICAgcHJpdmF0ZSBTdHJpbmcgdmVyc2lvbiA9IFZFUlNJT05fUE9TSVg7CisKKyAgICAvKiogVGhlIGVudHJ5J3MgdXNlciBuYW1lLiAqLworICAgIHByaXZhdGUgU3RyaW5nIHVzZXJOYW1lOworCisgICAgLyoqIFRoZSBlbnRyeSdzIGdyb3VwIG5hbWUuICovCisgICAgcHJpdmF0ZSBTdHJpbmcgZ3JvdXBOYW1lID0gIiI7CisKKyAgICAvKiogVGhlIGVudHJ5J3MgbWFqb3IgZGV2aWNlIG51bWJlci4gKi8KKyAgICBwcml2YXRlIGludCBkZXZNYWpvciA9IDA7CisKKyAgICAvKiogVGhlIGVudHJ5J3MgbWlub3IgZGV2aWNlIG51bWJlci4gKi8KKyAgICBwcml2YXRlIGludCBkZXZNaW5vciA9IDA7CisKKyAgICAvKiogSWYgYW4gZXh0ZW5zaW9uIHNwYXJzZSBoZWFkZXIgZm9sbG93cy4gKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gaXNFeHRlbmRlZDsKKworICAgIC8qKiBUaGUgZW50cnkncyByZWFsIHNpemUgaW4gY2FzZSBvZiBhIHNwYXJzZSBmaWxlLiAqLworICAgIHByaXZhdGUgbG9uZyByZWFsU2l6ZTsKKworICAgIC8qKiBpcyB0aGlzIGVudHJ5IGEgR05VIHNwYXJzZSBlbnRyeSB1c2luZyBvbmUgb2YgdGhlIFBBWCBmb3JtYXRzPyAqLworICAgIHByaXZhdGUgYm9vbGVhbiBwYXhHTlVTcGFyc2U7CisKKyAgICAvKiogaXMgdGhpcyBlbnRyeSBhIHN0YXIgc3BhcnNlIGVudHJ5IHVzaW5nIHRoZSBQQVggaGVhZGVyPyAqLworICAgIHByaXZhdGUgYm9vbGVhbiBzdGFyU3BhcnNlOworCisgICAgLyoqIFRoZSBlbnRyeSdzIGZpbGUgcmVmZXJlbmNlICovCisgICAgcHJpdmF0ZSBmaW5hbCBGaWxlIGZpbGU7CisKKyAgICAvKiogRXh0cmEsIHVzZXIgc3VwcGxpZWQgcGF4IGhlYWRlcnMgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBNYXA8U3RyaW5nLFN0cmluZz4gZXh0cmFQYXhIZWFkZXJzID0gbmV3IEhhc2hNYXA8PigpOworCisgICAgLyoqIE1heGltdW0gbGVuZ3RoIG9mIGEgdXNlcidzIG5hbWUgaW4gdGhlIHRhciBmaWxlICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFYX05BTUVMRU4gPSAzMTsKKworICAgIC8qKiBEZWZhdWx0IHBlcm1pc3Npb25zIGJpdHMgZm9yIGRpcmVjdG9yaWVzICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9ESVJfTU9ERSA9IDA0MDc1NTsKKworICAgIC8qKiBEZWZhdWx0IHBlcm1pc3Npb25zIGJpdHMgZm9yIGZpbGVzICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9GSUxFX01PREUgPSAwMTAwNjQ0OworCisgICAgLyoqIENvbnZlcnQgbWlsbGlzIHRvIHNlY29uZHMgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNSUxMSVNfUEVSX1NFQ09ORCA9IDEwMDA7CisKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdCBhbiBlbXB0eSBlbnRyeSBhbmQgcHJlcGFyZXMgdGhlIGhlYWRlciB2YWx1ZXMuCisgICAgICovCisgICAgcHJpdmF0ZSBUYXJBcmNoaXZlRW50cnkoYm9vbGVhbiBwcmVzZXJ2ZUFic29sdXRlUGF0aCkgeworICAgICAgICBTdHJpbmcgdXNlciA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgidXNlci5uYW1lIiwgIiIpOworCisgICAgICAgIGlmICh1c2VyLmxlbmd0aCgpID4gTUFYX05BTUVMRU4pIHsKKyAgICAgICAgICAgIHVzZXIgPSB1c2VyLnN1YnN0cmluZygwLCBNQVhfTkFNRUxFTik7CisgICAgICAgIH0KKworICAgICAgICB0aGlzLnVzZXJOYW1lID0gdXNlcjsKKyAgICAgICAgdGhpcy5maWxlID0gbnVsbDsKKyAgICAgICAgdGhpcy5wcmVzZXJ2ZUFic29sdXRlUGF0aCA9IHByZXNlcnZlQWJzb2x1dGVQYXRoOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdCBhbiBlbnRyeSB3aXRoIG9ubHkgYSBuYW1lLiBUaGlzIGFsbG93cyB0aGUgcHJvZ3JhbW1lcgorICAgICAqIHRvIGNvbnN0cnVjdCB0aGUgZW50cnkncyBoZWFkZXIgImJ5IGhhbmQiLiBGaWxlIGlzIHNldCB0byBudWxsLgorICAgICAqCisgICAgICogPHA+VGhlIGVudHJ5J3MgbmFtZSB3aWxsIGJlIHRoZSB2YWx1ZSBvZiB0aGUge0Bjb2RlIG5hbWV9CisgICAgICogYXJndW1lbnQgd2l0aCBhbGwgZmlsZSBzZXBhcmF0b3JzIHJlcGxhY2VkIGJ5IGZvcndhcmQgc2xhc2hlcworICAgICAqIGFuZCBsZWFkaW5nIHNsYXNoZXMgYXMgd2VsbCBhcyBXaW5kb3dzIGRyaXZlIGxldHRlcnMgc3RyaXBwZWQuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgdGhlIGVudHJ5IG5hbWUKKyAgICAgKi8KKyAgICBwdWJsaWMgVGFyQXJjaGl2ZUVudHJ5KGZpbmFsIFN0cmluZyBuYW1lKSB7CisgICAgICAgIHRoaXMobmFtZSwgZmFsc2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdCBhbiBlbnRyeSB3aXRoIG9ubHkgYSBuYW1lLiBUaGlzIGFsbG93cyB0aGUgcHJvZ3JhbW1lcgorICAgICAqIHRvIGNvbnN0cnVjdCB0aGUgZW50cnkncyBoZWFkZXIgImJ5IGhhbmQiLiBGaWxlIGlzIHNldCB0byBudWxsLgorICAgICAqCisgICAgICogPHA+VGhlIGVudHJ5J3MgbmFtZSB3aWxsIGJlIHRoZSB2YWx1ZSBvZiB0aGUge0Bjb2RlIG5hbWV9CisgICAgICogYXJndW1lbnQgd2l0aCBhbGwgZmlsZSBzZXBhcmF0b3JzIHJlcGxhY2VkIGJ5IGZvcndhcmQgc2xhc2hlcy4KKyAgICAgKiBMZWFkaW5nIHNsYXNoZXMgYW5kIFdpbmRvd3MgZHJpdmUgbGV0dGVycyBhcmUgc3RyaXBwZWQgaWYKKyAgICAgKiB7QGNvZGUgcHJlc2VydmVBYnNvbHV0ZVBhdGh9IGlzIHtAY29kZSBmYWxzZX0uPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgdGhlIGVudHJ5IG5hbWUKKyAgICAgKiBAcGFyYW0gcHJlc2VydmVBYnNvbHV0ZVBhdGggd2hldGhlciB0byBhbGxvdyBsZWFkaW5nIHNsYXNoZXMKKyAgICAgKiBvciBkcml2ZSBsZXR0ZXJzIGluIHRoZSBuYW1lLgorICAgICAqCisgICAgICogQHNpbmNlIDEuMQorICAgICAqLworICAgIHB1YmxpYyBUYXJBcmNoaXZlRW50cnkoU3RyaW5nIG5hbWUsIGZpbmFsIGJvb2xlYW4gcHJlc2VydmVBYnNvbHV0ZVBhdGgpIHsKKyAgICAgICAgdGhpcyhwcmVzZXJ2ZUFic29sdXRlUGF0aCk7CisKKyAgICAgICAgbmFtZSA9IG5vcm1hbGl6ZUZpbGVOYW1lKG5hbWUsIHByZXNlcnZlQWJzb2x1dGVQYXRoKTsKKyAgICAgICAgZmluYWwgYm9vbGVhbiBpc0RpciA9IG5hbWUuZW5kc1dpdGgoIi8iKTsKKworICAgICAgICB0aGlzLm5hbWUgPSBuYW1lOworICAgICAgICB0aGlzLm1vZGUgPSBpc0RpciA/IERFRkFVTFRfRElSX01PREUgOiBERUZBVUxUX0ZJTEVfTU9ERTsKKyAgICAgICAgdGhpcy5saW5rRmxhZyA9IGlzRGlyID8gTEZfRElSIDogTEZfTk9STUFMOworICAgICAgICB0aGlzLm1vZFRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKSAvIE1JTExJU19QRVJfU0VDT05EOworICAgICAgICB0aGlzLnVzZXJOYW1lID0gIiI7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGFuIGVudHJ5IHdpdGggYSBuYW1lIGFuZCBhIGxpbmsgZmxhZy4KKyAgICAgKgorICAgICAqIDxwPlRoZSBlbnRyeSdzIG5hbWUgd2lsbCBiZSB0aGUgdmFsdWUgb2YgdGhlIHtAY29kZSBuYW1lfQorICAgICAqIGFyZ3VtZW50IHdpdGggYWxsIGZpbGUgc2VwYXJhdG9ycyByZXBsYWNlZCBieSBmb3J3YXJkIHNsYXNoZXMKKyAgICAgKiBhbmQgbGVhZGluZyBzbGFzaGVzIGFzIHdlbGwgYXMgV2luZG93cyBkcml2ZSBsZXR0ZXJzCisgICAgICogc3RyaXBwZWQuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgdGhlIGVudHJ5IG5hbWUKKyAgICAgKiBAcGFyYW0gbGlua0ZsYWcgdGhlIGVudHJ5IGxpbmsgZmxhZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgVGFyQXJjaGl2ZUVudHJ5KGZpbmFsIFN0cmluZyBuYW1lLCBmaW5hbCBieXRlIGxpbmtGbGFnKSB7CisgICAgICAgIHRoaXMobmFtZSwgbGlua0ZsYWcsIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3QgYW4gZW50cnkgd2l0aCBhIG5hbWUgYW5kIGEgbGluayBmbGFnLgorICAgICAqCisgICAgICogPHA+VGhlIGVudHJ5J3MgbmFtZSB3aWxsIGJlIHRoZSB2YWx1ZSBvZiB0aGUge0Bjb2RlIG5hbWV9CisgICAgICogYXJndW1lbnQgd2l0aCBhbGwgZmlsZSBzZXBhcmF0b3JzIHJlcGxhY2VkIGJ5IGZvcndhcmQgc2xhc2hlcy4KKyAgICAgKiBMZWFkaW5nIHNsYXNoZXMgYW5kIFdpbmRvd3MgZHJpdmUgbGV0dGVycyBhcmUgc3RyaXBwZWQgaWYKKyAgICAgKiB7QGNvZGUgcHJlc2VydmVBYnNvbHV0ZVBhdGh9IGlzIHtAY29kZSBmYWxzZX0uPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgdGhlIGVudHJ5IG5hbWUKKyAgICAgKiBAcGFyYW0gbGlua0ZsYWcgdGhlIGVudHJ5IGxpbmsgZmxhZy4KKyAgICAgKiBAcGFyYW0gcHJlc2VydmVBYnNvbHV0ZVBhdGggd2hldGhlciB0byBhbGxvdyBsZWFkaW5nIHNsYXNoZXMKKyAgICAgKiBvciBkcml2ZSBsZXR0ZXJzIGluIHRoZSBuYW1lLgorICAgICAqCisgICAgICogQHNpbmNlIDEuNQorICAgICAqLworICAgIHB1YmxpYyBUYXJBcmNoaXZlRW50cnkoZmluYWwgU3RyaW5nIG5hbWUsIGZpbmFsIGJ5dGUgbGlua0ZsYWcsIGZpbmFsIGJvb2xlYW4gcHJlc2VydmVBYnNvbHV0ZVBhdGgpIHsKKyAgICAgICAgdGhpcyhuYW1lLCBwcmVzZXJ2ZUFic29sdXRlUGF0aCk7CisgICAgICAgIHRoaXMubGlua0ZsYWcgPSBsaW5rRmxhZzsKKyAgICAgICAgaWYgKGxpbmtGbGFnID09IExGX0dOVVRZUEVfTE9OR05BTUUpIHsKKyAgICAgICAgICAgIG1hZ2ljID0gTUFHSUNfR05VOworICAgICAgICAgICAgdmVyc2lvbiA9IFZFUlNJT05fR05VX1NQQUNFOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGFuIGVudHJ5IGZvciBhIGZpbGUuIEZpbGUgaXMgc2V0IHRvIGZpbGUsIGFuZCB0aGUKKyAgICAgKiBoZWFkZXIgaXMgY29uc3RydWN0ZWQgZnJvbSBpbmZvcm1hdGlvbiBmcm9tIHRoZSBmaWxlLgorICAgICAqIFRoZSBuYW1lIGlzIHNldCBmcm9tIHRoZSBub3JtYWxpemVkIGZpbGUgcGF0aC4KKyAgICAgKgorICAgICAqIDxwPlRoZSBlbnRyeSdzIG5hbWUgd2lsbCBiZSB0aGUgdmFsdWUgb2YgdGhlIHtAY29kZSBmaWxlfSdzCisgICAgICogcGF0aCB3aXRoIGFsbCBmaWxlIHNlcGFyYXRvcnMgcmVwbGFjZWQgYnkgZm9yd2FyZCBzbGFzaGVzIGFuZAorICAgICAqIGxlYWRpbmcgc2xhc2hlcyBhcyB3ZWxsIGFzIFdpbmRvd3MgZHJpdmUgbGV0dGVycyBzdHJpcHBlZC4gVGhlCisgICAgICogbmFtZSB3aWxsIGVuZCBpbiBhIHNsYXNoIGlmIHRoZSB7QGNvZGUgZmlsZX0gcmVwcmVzZW50cyBhCisgICAgICogZGlyZWN0b3J5LjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmaWxlIFRoZSBmaWxlIHRoYXQgdGhlIGVudHJ5IHJlcHJlc2VudHMuCisgICAgICovCisgICAgcHVibGljIFRhckFyY2hpdmVFbnRyeShmaW5hbCBGaWxlIGZpbGUpIHsKKyAgICAgICAgdGhpcyhmaWxlLCBmaWxlLmdldFBhdGgoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGFuIGVudHJ5IGZvciBhIGZpbGUuIEZpbGUgaXMgc2V0IHRvIGZpbGUsIGFuZCB0aGUKKyAgICAgKiBoZWFkZXIgaXMgY29uc3RydWN0ZWQgZnJvbSBpbmZvcm1hdGlvbiBmcm9tIHRoZSBmaWxlLgorICAgICAqCisgICAgICogPHA+VGhlIGVudHJ5J3MgbmFtZSB3aWxsIGJlIHRoZSB2YWx1ZSBvZiB0aGUge0Bjb2RlIGZpbGVOYW1lfQorICAgICAqIGFyZ3VtZW50IHdpdGggYWxsIGZpbGUgc2VwYXJhdG9ycyByZXBsYWNlZCBieSBmb3J3YXJkIHNsYXNoZXMKKyAgICAgKiBhbmQgbGVhZGluZyBzbGFzaGVzIGFzIHdlbGwgYXMgV2luZG93cyBkcml2ZSBsZXR0ZXJzIHN0cmlwcGVkLgorICAgICAqIFRoZSBuYW1lIHdpbGwgZW5kIGluIGEgc2xhc2ggaWYgdGhlIHtAY29kZSBmaWxlfSByZXByZXNlbnRzIGEKKyAgICAgKiBkaXJlY3RvcnkuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGZpbGUgVGhlIGZpbGUgdGhhdCB0aGUgZW50cnkgcmVwcmVzZW50cy4KKyAgICAgKiBAcGFyYW0gZmlsZU5hbWUgdGhlIG5hbWUgdG8gYmUgdXNlZCBmb3IgdGhlIGVudHJ5LgorICAgICAqLworICAgIHB1YmxpYyBUYXJBcmNoaXZlRW50cnkoZmluYWwgRmlsZSBmaWxlLCBmaW5hbCBTdHJpbmcgZmlsZU5hbWUpIHsKKyAgICAgICAgZmluYWwgU3RyaW5nIG5vcm1hbGl6ZWROYW1lID0gbm9ybWFsaXplRmlsZU5hbWUoZmlsZU5hbWUsIGZhbHNlKTsKKyAgICAgICAgdGhpcy5maWxlID0gZmlsZTsKKworICAgICAgICBpZiAoZmlsZS5pc0RpcmVjdG9yeSgpKSB7CisgICAgICAgICAgICB0aGlzLm1vZGUgPSBERUZBVUxUX0RJUl9NT0RFOworICAgICAgICAgICAgdGhpcy5saW5rRmxhZyA9IExGX0RJUjsKKworICAgICAgICAgICAgZmluYWwgaW50IG5hbWVMZW5ndGggPSBub3JtYWxpemVkTmFtZS5sZW5ndGgoKTsKKyAgICAgICAgICAgIGlmIChuYW1lTGVuZ3RoID09IDAgfHwgbm9ybWFsaXplZE5hbWUuY2hhckF0KG5hbWVMZW5ndGggLSAxKSAhPSAnLycpIHsKKyAgICAgICAgICAgICAgICB0aGlzLm5hbWUgPSBub3JtYWxpemVkTmFtZSArICIvIjsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdGhpcy5uYW1lID0gbm9ybWFsaXplZE5hbWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aGlzLm1vZGUgPSBERUZBVUxUX0ZJTEVfTU9ERTsKKyAgICAgICAgICAgIHRoaXMubGlua0ZsYWcgPSBMRl9OT1JNQUw7CisgICAgICAgICAgICB0aGlzLnNpemUgPSBmaWxlLmxlbmd0aCgpOworICAgICAgICAgICAgdGhpcy5uYW1lID0gbm9ybWFsaXplZE5hbWU7CisgICAgICAgIH0KKworICAgICAgICB0aGlzLm1vZFRpbWUgPSBmaWxlLmxhc3RNb2RpZmllZCgpIC8gTUlMTElTX1BFUl9TRUNPTkQ7CisgICAgICAgIHRoaXMudXNlck5hbWUgPSAiIjsKKyAgICAgICAgcHJlc2VydmVBYnNvbHV0ZVBhdGggPSBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3QgYW4gZW50cnkgZnJvbSBhbiBhcmNoaXZlJ3MgaGVhZGVyIGJ5dGVzLiBGaWxlIGlzIHNldAorICAgICAqIHRvIG51bGwuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaGVhZGVyQnVmIFRoZSBoZWFkZXIgYnl0ZXMgZnJvbSBhIHRhciBhcmNoaXZlIGVudHJ5LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIGFueSBvZiB0aGUgbnVtZXJpYyBmaWVsZHMgaGF2ZSBhbiBpbnZhbGlkIGZvcm1hdAorICAgICAqLworICAgIHB1YmxpYyBUYXJBcmNoaXZlRW50cnkoZmluYWwgYnl0ZVtdIGhlYWRlckJ1ZikgeworICAgICAgICB0aGlzKGZhbHNlKTsKKyAgICAgICAgcGFyc2VUYXJIZWFkZXIoaGVhZGVyQnVmKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3QgYW4gZW50cnkgZnJvbSBhbiBhcmNoaXZlJ3MgaGVhZGVyIGJ5dGVzLiBGaWxlIGlzIHNldAorICAgICAqIHRvIG51bGwuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaGVhZGVyQnVmIFRoZSBoZWFkZXIgYnl0ZXMgZnJvbSBhIHRhciBhcmNoaXZlIGVudHJ5LgorICAgICAqIEBwYXJhbSBlbmNvZGluZyBlbmNvZGluZyB0byB1c2UgZm9yIGZpbGUgbmFtZXMKKyAgICAgKiBAc2luY2UgMS40CisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgYW55IG9mIHRoZSBudW1lcmljIGZpZWxkcyBoYXZlIGFuIGludmFsaWQgZm9ybWF0CisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBvbiBlcnJvcgorICAgICAqLworICAgIHB1YmxpYyBUYXJBcmNoaXZlRW50cnkoZmluYWwgYnl0ZVtdIGhlYWRlckJ1ZiwgZmluYWwgWmlwRW5jb2RpbmcgZW5jb2RpbmcpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMoZmFsc2UpOworICAgICAgICBwYXJzZVRhckhlYWRlcihoZWFkZXJCdWYsIGVuY29kaW5nKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmUgaWYgdGhlIHR3byBlbnRyaWVzIGFyZSBlcXVhbC4gRXF1YWxpdHkgaXMgZGV0ZXJtaW5lZAorICAgICAqIGJ5IHRoZSBoZWFkZXIgbmFtZXMgYmVpbmcgZXF1YWwuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaXQgRW50cnkgdG8gYmUgY2hlY2tlZCBmb3IgZXF1YWxpdHkuCisgICAgICogQHJldHVybiBUcnVlIGlmIHRoZSBlbnRyaWVzIGFyZSBlcXVhbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgVGFyQXJjaGl2ZUVudHJ5IGl0KSB7CisgICAgICAgIHJldHVybiBpdCAhPSBudWxsICYmIGdldE5hbWUoKS5lcXVhbHMoaXQuZ2V0TmFtZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmUgaWYgdGhlIHR3byBlbnRyaWVzIGFyZSBlcXVhbC4gRXF1YWxpdHkgaXMgZGV0ZXJtaW5lZAorICAgICAqIGJ5IHRoZSBoZWFkZXIgbmFtZXMgYmVpbmcgZXF1YWwuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaXQgRW50cnkgdG8gYmUgY2hlY2tlZCBmb3IgZXF1YWxpdHkuCisgICAgICogQHJldHVybiBUcnVlIGlmIHRoZSBlbnRyaWVzIGFyZSBlcXVhbC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgT2JqZWN0IGl0KSB7CisgICAgICAgIGlmIChpdCA9PSBudWxsIHx8IGdldENsYXNzKCkgIT0gaXQuZ2V0Q2xhc3MoKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIHJldHVybiBlcXVhbHMoKFRhckFyY2hpdmVFbnRyeSkgaXQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEhhc2hjb2RlcyBhcmUgYmFzZWQgb24gZW50cnkgbmFtZXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBlbnRyeSBoYXNoY29kZQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIHJldHVybiBnZXROYW1lKCkuaGFzaENvZGUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmUgaWYgdGhlIGdpdmVuIGVudHJ5IGlzIGEgZGVzY2VuZGFudCBvZiB0aGlzIGVudHJ5LgorICAgICAqIERlc2NlbmRhbmN5IGlzIGRldGVybWluZWQgYnkgdGhlIG5hbWUgb2YgdGhlIGRlc2NlbmRhbnQKKyAgICAgKiBzdGFydGluZyB3aXRoIHRoaXMgZW50cnkncyBuYW1lLgorICAgICAqCisgICAgICogQHBhcmFtIGRlc2MgRW50cnkgdG8gYmUgY2hlY2tlZCBhcyBhIGRlc2NlbmRlbnQgb2YgdGhpcy4KKyAgICAgKiBAcmV0dXJuIFRydWUgaWYgZW50cnkgaXMgYSBkZXNjZW5kYW50IG9mIHRoaXMuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNEZXNjZW5kZW50KGZpbmFsIFRhckFyY2hpdmVFbnRyeSBkZXNjKSB7CisgICAgICAgIHJldHVybiBkZXNjLmdldE5hbWUoKS5zdGFydHNXaXRoKGdldE5hbWUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoaXMgZW50cnkncyBuYW1lLgorICAgICAqCisgICAgICogPHA+VGhpcyBtZXRob2QgcmV0dXJucyB0aGUgcmF3IG5hbWUgYXMgaXQgaXMgc3RvcmVkIGluc2lkZSBvZiB0aGUgYXJjaGl2ZS48L3A+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoaXMgZW50cnkncyBuYW1lLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsKKyAgICAgICAgcmV0dXJuIG5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoaXMgZW50cnkncyBuYW1lLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgVGhpcyBlbnRyeSdzIG5ldyBuYW1lLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE5hbWUoZmluYWwgU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgdGhpcy5uYW1lID0gbm9ybWFsaXplRmlsZU5hbWUobmFtZSwgdGhpcy5wcmVzZXJ2ZUFic29sdXRlUGF0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBtb2RlIGZvciB0aGlzIGVudHJ5CisgICAgICoKKyAgICAgKiBAcGFyYW0gbW9kZSB0aGUgbW9kZSBmb3IgdGhpcyBlbnRyeQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE1vZGUoZmluYWwgaW50IG1vZGUpIHsKKyAgICAgICAgdGhpcy5tb2RlID0gbW9kZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhpcyBlbnRyeSdzIGxpbmsgbmFtZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhpcyBlbnRyeSdzIGxpbmsgbmFtZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldExpbmtOYW1lKCkgeworICAgICAgICByZXR1cm4gbGlua05hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoaXMgZW50cnkncyBsaW5rIG5hbWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbGluayB0aGUgbGluayBuYW1lIHRvIHVzZS4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjEKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRMaW5rTmFtZShmaW5hbCBTdHJpbmcgbGluaykgeworICAgICAgICB0aGlzLmxpbmtOYW1lID0gbGluazsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhpcyBlbnRyeSdzIHVzZXIgaWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoaXMgZW50cnkncyB1c2VyIGlkLgorICAgICAqIEBkZXByZWNhdGVkIHVzZSAjZ2V0TG9uZ1VzZXJJZCBpbnN0ZWFkIGFzIHVzZXIgaWRzIGNhbiBiZQorICAgICAqIGJpZ2dlciB0aGFuIHtAbGluayBJbnRlZ2VyI01BWF9WQUxVRX0KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBpbnQgZ2V0VXNlcklkKCkgeworICAgICAgICByZXR1cm4gKGludCkgKHVzZXJJZCAmIDB4ZmZmZmZmZmYpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGlzIGVudHJ5J3MgdXNlciBpZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB1c2VySWQgVGhpcyBlbnRyeSdzIG5ldyB1c2VyIGlkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFVzZXJJZChmaW5hbCBpbnQgdXNlcklkKSB7CisgICAgICAgIHNldFVzZXJJZCgobG9uZykgdXNlcklkKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhpcyBlbnRyeSdzIHVzZXIgaWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoaXMgZW50cnkncyB1c2VyIGlkLgorICAgICAqIEBzaW5jZSAxLjEwCisgICAgICovCisgICAgcHVibGljIGxvbmcgZ2V0TG9uZ1VzZXJJZCgpIHsKKyAgICAgICAgcmV0dXJuIHVzZXJJZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhpcyBlbnRyeSdzIHVzZXIgaWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdXNlcklkIFRoaXMgZW50cnkncyBuZXcgdXNlciBpZC4KKyAgICAgKiBAc2luY2UgMS4xMAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFVzZXJJZChmaW5hbCBsb25nIHVzZXJJZCkgeworICAgICAgICB0aGlzLnVzZXJJZCA9IHVzZXJJZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhpcyBlbnRyeSdzIGdyb3VwIGlkLgorICAgICAqCisgICAgICogQHJldHVybiBUaGlzIGVudHJ5J3MgZ3JvdXAgaWQuCisgICAgICogQGRlcHJlY2F0ZWQgdXNlICNnZXRMb25nR3JvdXBJZCBpbnN0ZWFkIGFzIGdyb3VwIGlkcyBjYW4gYmUKKyAgICAgKiBiaWdnZXIgdGhhbiB7QGxpbmsgSW50ZWdlciNNQVhfVkFMVUV9CisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgaW50IGdldEdyb3VwSWQoKSB7CisgICAgICAgIHJldHVybiAoaW50KSAoZ3JvdXBJZCAmIDB4ZmZmZmZmZmYpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGlzIGVudHJ5J3MgZ3JvdXAgaWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZ3JvdXBJZCBUaGlzIGVudHJ5J3MgbmV3IGdyb3VwIGlkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEdyb3VwSWQoZmluYWwgaW50IGdyb3VwSWQpIHsKKyAgICAgICAgc2V0R3JvdXBJZCgobG9uZykgZ3JvdXBJZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoaXMgZW50cnkncyBncm91cCBpZC4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjEwCisgICAgICogQHJldHVybiBUaGlzIGVudHJ5J3MgZ3JvdXAgaWQuCisgICAgICovCisgICAgcHVibGljIGxvbmcgZ2V0TG9uZ0dyb3VwSWQoKSB7CisgICAgICAgIHJldHVybiBncm91cElkOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGlzIGVudHJ5J3MgZ3JvdXAgaWQuCisgICAgICoKKyAgICAgKiBAc2luY2UgMS4xMAorICAgICAqIEBwYXJhbSBncm91cElkIFRoaXMgZW50cnkncyBuZXcgZ3JvdXAgaWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0R3JvdXBJZChmaW5hbCBsb25nIGdyb3VwSWQpIHsKKyAgICAgICAgdGhpcy5ncm91cElkID0gZ3JvdXBJZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhpcyBlbnRyeSdzIHVzZXIgbmFtZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhpcyBlbnRyeSdzIHVzZXIgbmFtZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFVzZXJOYW1lKCkgeworICAgICAgICByZXR1cm4gdXNlck5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoaXMgZW50cnkncyB1c2VyIG5hbWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdXNlck5hbWUgVGhpcyBlbnRyeSdzIG5ldyB1c2VyIG5hbWUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0VXNlck5hbWUoZmluYWwgU3RyaW5nIHVzZXJOYW1lKSB7CisgICAgICAgIHRoaXMudXNlck5hbWUgPSB1c2VyTmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhpcyBlbnRyeSdzIGdyb3VwIG5hbWUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoaXMgZW50cnkncyBncm91cCBuYW1lLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0R3JvdXBOYW1lKCkgeworICAgICAgICByZXR1cm4gZ3JvdXBOYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGlzIGVudHJ5J3MgZ3JvdXAgbmFtZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBncm91cE5hbWUgVGhpcyBlbnRyeSdzIG5ldyBncm91cCBuYW1lLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEdyb3VwTmFtZShmaW5hbCBTdHJpbmcgZ3JvdXBOYW1lKSB7CisgICAgICAgIHRoaXMuZ3JvdXBOYW1lID0gZ3JvdXBOYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlbmllbmNlIG1ldGhvZCB0byBzZXQgdGhpcyBlbnRyeSdzIGdyb3VwIGFuZCB1c2VyIGlkcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSB1c2VySWQgVGhpcyBlbnRyeSdzIG5ldyB1c2VyIGlkLgorICAgICAqIEBwYXJhbSBncm91cElkIFRoaXMgZW50cnkncyBuZXcgZ3JvdXAgaWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0SWRzKGZpbmFsIGludCB1c2VySWQsIGZpbmFsIGludCBncm91cElkKSB7CisgICAgICAgIHNldFVzZXJJZCh1c2VySWQpOworICAgICAgICBzZXRHcm91cElkKGdyb3VwSWQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlbmllbmNlIG1ldGhvZCB0byBzZXQgdGhpcyBlbnRyeSdzIGdyb3VwIGFuZCB1c2VyIG5hbWVzLgorICAgICAqCisgICAgICogQHBhcmFtIHVzZXJOYW1lIFRoaXMgZW50cnkncyBuZXcgdXNlciBuYW1lLgorICAgICAqIEBwYXJhbSBncm91cE5hbWUgVGhpcyBlbnRyeSdzIG5ldyBncm91cCBuYW1lLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE5hbWVzKGZpbmFsIFN0cmluZyB1c2VyTmFtZSwgZmluYWwgU3RyaW5nIGdyb3VwTmFtZSkgeworICAgICAgICBzZXRVc2VyTmFtZSh1c2VyTmFtZSk7CisgICAgICAgIHNldEdyb3VwTmFtZShncm91cE5hbWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGlzIGVudHJ5J3MgbW9kaWZpY2F0aW9uIHRpbWUuIFRoZSBwYXJhbWV0ZXIgcGFzc2VkCisgICAgICogdG8gdGhpcyBtZXRob2QgaXMgaW4gIkphdmEgdGltZSIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGltZSBUaGlzIGVudHJ5J3MgbmV3IG1vZGlmaWNhdGlvbiB0aW1lLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE1vZFRpbWUoZmluYWwgbG9uZyB0aW1lKSB7CisgICAgICAgIG1vZFRpbWUgPSB0aW1lIC8gTUlMTElTX1BFUl9TRUNPTkQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoaXMgZW50cnkncyBtb2RpZmljYXRpb24gdGltZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0aW1lIFRoaXMgZW50cnkncyBuZXcgbW9kaWZpY2F0aW9uIHRpbWUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TW9kVGltZShmaW5hbCBEYXRlIHRpbWUpIHsKKyAgICAgICAgbW9kVGltZSA9IHRpbWUuZ2V0VGltZSgpIC8gTUlMTElTX1BFUl9TRUNPTkQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoaXMgZW50cnkncyBtb2RpZmljYXRpb24gdGltZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGltZSBUaGlzIGVudHJ5J3MgbmV3IG1vZGlmaWNhdGlvbiB0aW1lLgorICAgICAqLworICAgIHB1YmxpYyBEYXRlIGdldE1vZFRpbWUoKSB7CisgICAgICAgIHJldHVybiBuZXcgRGF0ZShtb2RUaW1lICogTUlMTElTX1BFUl9TRUNPTkQpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBEYXRlIGdldExhc3RNb2RpZmllZERhdGUoKSB7CisgICAgICAgIHJldHVybiBnZXRNb2RUaW1lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoaXMgZW50cnkncyBjaGVja3N1bSBzdGF0dXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGlmIHRoZSBoZWFkZXIgY2hlY2tzdW0gaXMgcmVhc29uYWJseSBjb3JyZWN0CisgICAgICogQHNlZSBUYXJVdGlscyN2ZXJpZnlDaGVja1N1bShieXRlW10pCisgICAgICogQHNpbmNlIDEuNQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzQ2hlY2tTdW1PSygpIHsKKyAgICAgICAgcmV0dXJuIGNoZWNrU3VtT0s7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoaXMgZW50cnkncyBmaWxlLgorICAgICAqCisgICAgICogPHA+VGhpcyBtZXRob2QgaXMgb25seSB1c2VmdWwgZm9yIGVudHJpZXMgY3JlYXRlZCBmcm9tIGEge0Bjb2RlCisgICAgICogRmlsZX0gYnV0IG5vdCBmb3IgZW50cmllcyByZWFkIGZyb20gYW4gYXJjaGl2ZS48L3A+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoaXMgZW50cnkncyBmaWxlLgorICAgICAqLworICAgIHB1YmxpYyBGaWxlIGdldEZpbGUoKSB7CisgICAgICAgIHJldHVybiBmaWxlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGlzIGVudHJ5J3MgbW9kZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhpcyBlbnRyeSdzIG1vZGUuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRNb2RlKCkgeworICAgICAgICByZXR1cm4gbW9kZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhpcyBlbnRyeSdzIGZpbGUgc2l6ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhpcyBlbnRyeSdzIGZpbGUgc2l6ZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgbG9uZyBnZXRTaXplKCkgeworICAgICAgICByZXR1cm4gc2l6ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhpcyBlbnRyeSdzIGZpbGUgc2l6ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzaXplIFRoaXMgZW50cnkncyBuZXcgZmlsZSBzaXplLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBzaXplIGlzICZsdDsgMC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRTaXplKGZpbmFsIGxvbmcgc2l6ZSkgeworICAgICAgICBpZiAoc2l6ZSA8IDApeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiU2l6ZSBpcyBvdXQgb2YgcmFuZ2U6ICIrc2l6ZSk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5zaXplID0gc2l6ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhpcyBlbnRyeSdzIG1ham9yIGRldmljZSBudW1iZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoaXMgZW50cnkncyBtYWpvciBkZXZpY2UgbnVtYmVyLgorICAgICAqIEBzaW5jZSAxLjQKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldERldk1ham9yKCkgeworICAgICAgICByZXR1cm4gZGV2TWFqb3I7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoaXMgZW50cnkncyBtYWpvciBkZXZpY2UgbnVtYmVyLgorICAgICAqCisgICAgICogQHBhcmFtIGRldk5vIFRoaXMgZW50cnkncyBtYWpvciBkZXZpY2UgbnVtYmVyLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBkZXZObyBpcyAmbHQ7IDAuCisgICAgICogQHNpbmNlIDEuNAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldERldk1ham9yKGZpbmFsIGludCBkZXZObykgeworICAgICAgICBpZiAoZGV2Tm8gPCAwKXsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIk1ham9yIGRldmljZSBudW1iZXIgaXMgb3V0IG9mICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAicmFuZ2U6ICIgKyBkZXZObyk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5kZXZNYWpvciA9IGRldk5vOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGlzIGVudHJ5J3MgbWlub3IgZGV2aWNlIG51bWJlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhpcyBlbnRyeSdzIG1pbm9yIGRldmljZSBudW1iZXIuCisgICAgICogQHNpbmNlIDEuNAorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0RGV2TWlub3IoKSB7CisgICAgICAgIHJldHVybiBkZXZNaW5vcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhpcyBlbnRyeSdzIG1pbm9yIGRldmljZSBudW1iZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGV2Tm8gVGhpcyBlbnRyeSdzIG1pbm9yIGRldmljZSBudW1iZXIuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIGRldk5vIGlzICZsdDsgMC4KKyAgICAgKiBAc2luY2UgMS40CisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RGV2TWlub3IoZmluYWwgaW50IGRldk5vKSB7CisgICAgICAgIGlmIChkZXZObyA8IDApeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiTWlub3IgZGV2aWNlIG51bWJlciBpcyBvdXQgb2YgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICJyYW5nZTogIiArIGRldk5vKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmRldk1pbm9yID0gZGV2Tm87CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIGluIGNhc2Ugb2YgYW4gb2xkZ251IHNwYXJzZSBmaWxlIGlmIGFuIGV4dGVuc2lvbgorICAgICAqIHNwYXJzZSBoZWFkZXIgZm9sbG93cy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBhbiBleHRlbnNpb24gb2xkZ251IHNwYXJzZSBoZWFkZXIgZm9sbG93cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0V4dGVuZGVkKCkgeworICAgICAgICByZXR1cm4gaXNFeHRlbmRlZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhpcyBlbnRyeSdzIHJlYWwgZmlsZSBzaXplIGluIGNhc2Ugb2YgYSBzcGFyc2UgZmlsZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhpcyBlbnRyeSdzIHJlYWwgZmlsZSBzaXplLgorICAgICAqLworICAgIHB1YmxpYyBsb25nIGdldFJlYWxTaXplKCkgeworICAgICAgICByZXR1cm4gcmVhbFNpemU7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGUgaWYgdGhpcyBlbnRyeSBpcyBhIEdOVSBzcGFyc2UgYmxvY2suCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhpcyBpcyBhIHNwYXJzZSBleHRlbnNpb24gcHJvdmlkZWQgYnkgR05VIHRhcgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzR05VU3BhcnNlKCkgeworICAgICAgICByZXR1cm4gaXNPbGRHTlVTcGFyc2UoKSB8fCBpc1BheEdOVVNwYXJzZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlIGlmIHRoaXMgZW50cnkgaXMgYSBHTlUgb3Igc3RhciBzcGFyc2UgYmxvY2sgdXNpbmcgdGhlCisgICAgICogb2xkZ251IGZvcm1hdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGlzIGlzIGEgc3BhcnNlIGV4dGVuc2lvbiBwcm92aWRlZCBieSBHTlUgdGFyIG9yIHN0YXIKKyAgICAgKiBAc2luY2UgMS4xMQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzT2xkR05VU3BhcnNlKCkgeworICAgICAgICByZXR1cm4gbGlua0ZsYWcgPT0gTEZfR05VVFlQRV9TUEFSU0U7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGUgaWYgdGhpcyBlbnRyeSBpcyBhIEdOVSBzcGFyc2UgYmxvY2sgdXNpbmcgb25lIG9mIHRoZQorICAgICAqIFBBWCBmb3JtYXRzLgorICAgICAqCisgICAgICogQHJldHVybiB0cnVlIGlmIHRoaXMgaXMgYSBzcGFyc2UgZXh0ZW5zaW9uIHByb3ZpZGVkIGJ5IEdOVSB0YXIKKyAgICAgKiBAc2luY2UgMS4xMQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzUGF4R05VU3BhcnNlKCkgeworICAgICAgICByZXR1cm4gcGF4R05VU3BhcnNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlIGlmIHRoaXMgZW50cnkgaXMgYSBzdGFyIHNwYXJzZSBibG9jayB1c2luZyBQQVggaGVhZGVycy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGlzIGlzIGEgc3BhcnNlIGV4dGVuc2lvbiBwcm92aWRlZCBieSBzdGFyCisgICAgICogQHNpbmNlIDEuMTEKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc1N0YXJTcGFyc2UoKSB7CisgICAgICAgIHJldHVybiBzdGFyU3BhcnNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlIGlmIHRoaXMgZW50cnkgaXMgYSBHTlUgbG9uZyBsaW5rbmFtZSBibG9jaworICAgICAqCisgICAgICogQHJldHVybiB0cnVlIGlmIHRoaXMgaXMgYSBsb25nIG5hbWUgZXh0ZW5zaW9uIHByb3ZpZGVkIGJ5IEdOVSB0YXIKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0dOVUxvbmdMaW5rRW50cnkoKSB7CisgICAgICAgIHJldHVybiBsaW5rRmxhZyA9PSBMRl9HTlVUWVBFX0xPTkdMSU5LOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlIGlmIHRoaXMgZW50cnkgaXMgYSBHTlUgbG9uZyBuYW1lIGJsb2NrCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhpcyBpcyBhIGxvbmcgbmFtZSBleHRlbnNpb24gcHJvdmlkZWQgYnkgR05VIHRhcgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzR05VTG9uZ05hbWVFbnRyeSgpIHsKKyAgICAgICAgcmV0dXJuIGxpbmtGbGFnID09IExGX0dOVVRZUEVfTE9OR05BTUU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2sgaWYgdGhpcyBpcyBhIFBheCBoZWFkZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIGlzIGEgUGF4IGhlYWRlci4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjEKKyAgICAgKgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzUGF4SGVhZGVyKCkgeworICAgICAgICByZXR1cm4gbGlua0ZsYWcgPT0gTEZfUEFYX0VYVEVOREVEX0hFQURFUl9MQworICAgICAgICAgICAgfHwgbGlua0ZsYWcgPT0gTEZfUEFYX0VYVEVOREVEX0hFQURFUl9VQzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVjayBpZiB0aGlzIGlzIGEgUGF4IGhlYWRlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMgaXMgYSBQYXggaGVhZGVyLgorICAgICAqCisgICAgICogQHNpbmNlIDEuMQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzR2xvYmFsUGF4SGVhZGVyKCkgeworICAgICAgICByZXR1cm4gbGlua0ZsYWcgPT0gTEZfUEFYX0dMT0JBTF9FWFRFTkRFRF9IRUFERVI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHdoZXRoZXIgb3Igbm90IHRoaXMgZW50cnkgcmVwcmVzZW50cyBhIGRpcmVjdG9yeS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGlzIGVudHJ5IGlzIGEgZGlyZWN0b3J5LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGlzRGlyZWN0b3J5KCkgeworICAgICAgICBpZiAoZmlsZSAhPSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gZmlsZS5pc0RpcmVjdG9yeSgpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGxpbmtGbGFnID09IExGX0RJUikgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gIWlzUGF4SGVhZGVyKCkgJiYgIWlzR2xvYmFsUGF4SGVhZGVyKCkgJiYgZ2V0TmFtZSgpLmVuZHNXaXRoKCIvIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2sgaWYgdGhpcyBpcyBhICJub3JtYWwgZmlsZSIKKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjIKKyAgICAgKiBAcmV0dXJuIHdoZXRoZXIgdGhpcyBpcyBhICJub3JtYWwgZmlsZSIKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0ZpbGUoKSB7CisgICAgICAgIGlmIChmaWxlICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBmaWxlLmlzRmlsZSgpOworICAgICAgICB9CisgICAgICAgIGlmIChsaW5rRmxhZyA9PSBMRl9PTEROT1JNIHx8IGxpbmtGbGFnID09IExGX05PUk1BTCkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuICFnZXROYW1lKCkuZW5kc1dpdGgoIi8iKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVjayBpZiB0aGlzIGlzIGEgc3ltYm9saWMgbGluayBlbnRyeS4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjIKKyAgICAgKiBAcmV0dXJuIHdoZXRoZXIgdGhpcyBpcyBhIHN5bWJvbGljIGxpbmsKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc1N5bWJvbGljTGluaygpIHsKKyAgICAgICAgcmV0dXJuIGxpbmtGbGFnID09IExGX1NZTUxJTks7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2sgaWYgdGhpcyBpcyBhIGxpbmsgZW50cnkuCisgICAgICoKKyAgICAgKiBAc2luY2UgMS4yCisgICAgICogQHJldHVybiB3aGV0aGVyIHRoaXMgaXMgYSBsaW5rIGVudHJ5CisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNMaW5rKCkgeworICAgICAgICByZXR1cm4gbGlua0ZsYWcgPT0gTEZfTElOSzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVjayBpZiB0aGlzIGlzIGEgY2hhcmFjdGVyIGRldmljZSBlbnRyeS4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjIKKyAgICAgKiBAcmV0dXJuIHdoZXRoZXIgdGhpcyBpcyBhIGNoYXJhY3RlciBkZXZpY2UKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0NoYXJhY3RlckRldmljZSgpIHsKKyAgICAgICAgcmV0dXJuIGxpbmtGbGFnID09IExGX0NIUjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVjayBpZiB0aGlzIGlzIGEgYmxvY2sgZGV2aWNlIGVudHJ5LgorICAgICAqCisgICAgICogQHNpbmNlIDEuMgorICAgICAqIEByZXR1cm4gd2hldGhlciB0aGlzIGlzIGEgYmxvY2sgZGV2aWNlCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNCbG9ja0RldmljZSgpIHsKKyAgICAgICAgcmV0dXJuIGxpbmtGbGFnID09IExGX0JMSzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVjayBpZiB0aGlzIGlzIGEgRklGTyAocGlwZSkgZW50cnkuCisgICAgICoKKyAgICAgKiBAc2luY2UgMS4yCisgICAgICogQHJldHVybiB3aGV0aGVyIHRoaXMgaXMgYSBGSUZPIGVudHJ5CisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNGSUZPKCkgeworICAgICAgICByZXR1cm4gbGlua0ZsYWcgPT0gTEZfRklGTzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVjayB3aGV0aGVyIHRoaXMgaXMgYSBzcGFyc2UgZW50cnkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHdoZXRoZXIgdGhpcyBpcyBhIHNwYXJzZSBlbnRyeQorICAgICAqIEBzaW5jZSAxLjExCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNTcGFyc2UoKSB7CisgICAgICAgIHJldHVybiBpc0dOVVNwYXJzZSgpIHx8IGlzU3RhclNwYXJzZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGdldCBleHRyYSBQQVggSGVhZGVycworICAgICAqIEByZXR1cm4gcmVhZC1vbmx5IG1hcCBjb250YWluaW5nIGFueSBleHRyYSBQQVggSGVhZGVycworICAgICAqIEBzaW5jZSAxLjE1CisgICAgICovCisgICAgcHVibGljIE1hcDxTdHJpbmcsIFN0cmluZz4gZ2V0RXh0cmFQYXhIZWFkZXJzKCkgeworICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTWFwKGV4dHJhUGF4SGVhZGVycyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogY2xlYXIgYWxsIGV4dHJhIFBBWCBoZWFkZXJzLgorICAgICAqIEBzaW5jZSAxLjE1CisgICAgICovCisgICAgcHVibGljIHZvaWQgY2xlYXJFeHRyYVBheEhlYWRlcnMoKSB7CisgICAgICAgIGV4dHJhUGF4SGVhZGVycy5jbGVhcigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGFkZCBhIFBBWCBoZWFkZXIgdG8gdGhpcyBlbnRyeS4gSWYgdGhlIGhlYWRlciBjb3JyZXNwb25kcyB0byBhbiBleGlzdGluZyBmaWVsZCBpbiB0aGUgZW50cnksCisgICAgICogdGhhdCBmaWVsZCB3aWxsIGJlIHNldDsgb3RoZXJ3aXNlIHRoZSBoZWFkZXIgd2lsbCBiZSBhZGRlZCB0byB0aGUgZXh0cmFQYXhIZWFkZXJzIE1hcAorICAgICAqIEBwYXJhbSBuYW1lICBUaGUgZnVsbCBuYW1lIG9mIHRoZSBoZWFkZXIgdG8gc2V0LgorICAgICAqIEBwYXJhbSB2YWx1ZSB2YWx1ZSBvZiBoZWFkZXIuCisgICAgICogQHNpbmNlIDEuMTUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGRQYXhIZWFkZXIoU3RyaW5nIG5hbWUsU3RyaW5nIHZhbHVlKSB7CisgICAgICAgICBwcm9jZXNzUGF4SGVhZGVyKG5hbWUsdmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGdldCBuYW1lZCBleHRyYSBQQVggaGVhZGVyCisgICAgICogQHBhcmFtIG5hbWUgVGhlIGZ1bGwgbmFtZSBvZiBhbiBleHRlbmRlZCBQQVggaGVhZGVyIHRvIHJldHJpZXZlCisgICAgICogQHJldHVybiBUaGUgdmFsdWUgb2YgdGhlIGhlYWRlciwgaWYgYW55LgorICAgICAqIEBzaW5jZSAxLjE1CisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRFeHRyYVBheEhlYWRlcihTdHJpbmcgbmFtZSkgeworICAgICAgICByZXR1cm4gZXh0cmFQYXhIZWFkZXJzLmdldChuYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGUgdGhlIGVudHJ5IHVzaW5nIGEgbWFwIG9mIHBheCBoZWFkZXJzLgorICAgICAqIEBwYXJhbSBoZWFkZXJzCisgICAgICogQHNpbmNlIDEuMTUKKyAgICAgKi8KKyAgICB2b2lkIHVwZGF0ZUVudHJ5RnJvbVBheEhlYWRlcnMoTWFwPFN0cmluZywgU3RyaW5nPiBoZWFkZXJzKSB7CisgICAgICAgIGZvciAoZmluYWwgTWFwLkVudHJ5PFN0cmluZywgU3RyaW5nPiBlbnQgOiBoZWFkZXJzLmVudHJ5U2V0KCkpIHsKKyAgICAgICAgICAgIGZpbmFsIFN0cmluZyBrZXkgPSBlbnQuZ2V0S2V5KCk7CisgICAgICAgICAgICBmaW5hbCBTdHJpbmcgdmFsID0gZW50LmdldFZhbHVlKCk7CisgICAgICAgICAgICBwcm9jZXNzUGF4SGVhZGVyKGtleSwgdmFsLCBoZWFkZXJzKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIHByb2Nlc3Mgb25lIHBheCBoZWFkZXIsIHVzaW5nIHRoZSBlbnRyaWVzIGV4dHJhUGF4SGVhZGVycyBtYXAgYXMgc291cmNlIGZvciBleHRyYSBoZWFkZXJzCisgICAgICogdXNlZCB3aGVuIGhhbmRsaW5nIGVudHJpZXMgZm9yIHNwYXJzZSBmaWxlcy4KKyAgICAgKiBAcGFyYW0ga2V5CisgICAgICogQHBhcmFtIHZhbAorICAgICAqIEBzaW5jZSAxLjE1CisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHByb2Nlc3NQYXhIZWFkZXIoU3RyaW5nIGtleSwgU3RyaW5nIHZhbCkgeworICAgICAgICBwcm9jZXNzUGF4SGVhZGVyKGtleSx2YWwsZXh0cmFQYXhIZWFkZXJzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcm9jZXNzIG9uZSBwYXggaGVhZGVyLCB1c2luZyB0aGUgc3VwcGxpZWQgbWFwIGFzIHNvdXJjZSBmb3IgZXh0cmEgaGVhZGVycyB0byBiZSB1c2VkIHdoZW4gaGFuZGxpbmcKKyAgICAgKiBlbnRyaWVzIGZvciBzcGFyc2UgZmlsZXMKKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXkgIHRoZSBoZWFkZXIgbmFtZS4KKyAgICAgKiBAcGFyYW0gdmFsICB0aGUgaGVhZGVyIHZhbHVlLgorICAgICAqIEBwYXJhbSBoZWFkZXJzICBtYXAgb2YgaGVhZGVycyB1c2VkIGZvciBkZWFsaW5nIHdpdGggc3BhcnNlIGZpbGUuCisgICAgICogQHNpbmNlIDEuMTUKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcHJvY2Vzc1BheEhlYWRlcihTdHJpbmcga2V5LCBTdHJpbmcgdmFsLCBNYXA8U3RyaW5nLCBTdHJpbmc+IGhlYWRlcnMpIHsKKyAgICAvKgorICAgICAqIFRoZSBmb2xsb3dpbmcgaGVhZGVycyBhcmUgZGVmaW5lZCBmb3IgUGF4LgorICAgICAqIGF0aW1lLCBjdGltZSwgY2hhcnNldDogY2Fubm90IHVzZSB0aGVzZSB3aXRob3V0IGNoYW5naW5nIFRhckFyY2hpdmVFbnRyeSBmaWVsZHMKKyAgICAgKiBtdGltZQorICAgICAqIGNvbW1lbnQKKyAgICAgKiBnaWQsIGduYW1lCisgICAgICogbGlua3BhdGgKKyAgICAgKiBzaXplCisgICAgICogdWlkLHVuYW1lCisgICAgICogU0NISUxZLmRldm1pbm9yLCBTQ0hJTFkuZGV2bWFqb3I6IGRvbid0IGhhdmUgc2V0dGVycy9nZXR0ZXJzIGZvciB0aG9zZQorICAgICAqCisgICAgICogR05VIHNwYXJzZSBmaWxlcyB1c2UgYWRkaXRpb25hbCBtZW1iZXJzLCB3ZSB1c2UKKyAgICAgKiBHTlUuc3BhcnNlLnNpemUgdG8gZGV0ZWN0IHRoZSAwLjAgYW5kIDAuMSB2ZXJzaW9ucyBhbmQKKyAgICAgKiBHTlUuc3BhcnNlLnJlYWxzaXplIGZvciAxLjAuCisgICAgICoKKyAgICAgKiBzdGFyIGZpbGVzIHVzZSBhZGRpdGlvbmFsIG1lbWJlcnMgb2Ygd2hpY2ggd2UgdXNlCisgICAgICogU0NISUxZLmZpbGV0eXBlIGluIG9yZGVyIHRvIGRldGVjdCBzdGFyIHNwYXJzZSBmaWxlcy4KKyAgICAgKgorICAgICAqIElmIGNhbGxlZCBmcm9tIGFkZEV4dHJhUGF4SGVhZGVyLCB0aGVzZSBhZGRpdGlvbmFsIGhlYWRlcnMgbXVzdCBiZSBhbHJlYWR5IHByZXNlbnQgLgorICAgICAqLworICAgICAgICBzd2l0Y2ggKGtleSkgeworICAgICAgICAgICAgY2FzZSAicGF0aCI6CisgICAgICAgICAgICAgICAgc2V0TmFtZSh2YWwpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSAibGlua3BhdGgiOgorICAgICAgICAgICAgICAgIHNldExpbmtOYW1lKHZhbCk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlICJnaWQiOgorICAgICAgICAgICAgICAgIHNldEdyb3VwSWQoTG9uZy5wYXJzZUxvbmcodmFsKSk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlICJnbmFtZSI6CisgICAgICAgICAgICAgICAgc2V0R3JvdXBOYW1lKHZhbCk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlICJ1aWQiOgorICAgICAgICAgICAgICAgIHNldFVzZXJJZChMb25nLnBhcnNlTG9uZyh2YWwpKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgInVuYW1lIjoKKyAgICAgICAgICAgICAgICBzZXRVc2VyTmFtZSh2YWwpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSAic2l6ZSI6CisgICAgICAgICAgICAgICAgc2V0U2l6ZShMb25nLnBhcnNlTG9uZyh2YWwpKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgIm10aW1lIjoKKyAgICAgICAgICAgICAgICBzZXRNb2RUaW1lKChsb25nKSAoRG91YmxlLnBhcnNlRG91YmxlKHZhbCkgKiAxMDAwKSk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlICJTQ0hJTFkuZGV2bWlub3IiOgorICAgICAgICAgICAgICAgIHNldERldk1pbm9yKEludGVnZXIucGFyc2VJbnQodmFsKSk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlICJTQ0hJTFkuZGV2bWFqb3IiOgorICAgICAgICAgICAgICAgIHNldERldk1ham9yKEludGVnZXIucGFyc2VJbnQodmFsKSk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlICJHTlUuc3BhcnNlLnNpemUiOgorICAgICAgICAgICAgICAgIGZpbGxHTlVTcGFyc2UweERhdGEoaGVhZGVycyk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlICJHTlUuc3BhcnNlLnJlYWxzaXplIjoKKyAgICAgICAgICAgICAgICBmaWxsR05VU3BhcnNlMXhEYXRhKGhlYWRlcnMpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSAiU0NISUxZLmZpbGV0eXBlIjoKKyAgICAgICAgICAgICAgICBpZiAoInNwYXJzZSIuZXF1YWxzKHZhbCkpIHsKKyAgICAgICAgICAgICAgICAgICAgZmlsbFN0YXJTcGFyc2VEYXRhKGhlYWRlcnMpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgZXh0cmFQYXhIZWFkZXJzLnB1dChrZXksdmFsKTsKKyAgICAgICAgfQorICAgIH0KKworCisKKyAgICAvKioKKyAgICAgKiBJZiB0aGlzIGVudHJ5IHJlcHJlc2VudHMgYSBmaWxlLCBhbmQgdGhlIGZpbGUgaXMgYSBkaXJlY3RvcnksIHJldHVybgorICAgICAqIGFuIGFycmF5IG9mIFRhckVudHJpZXMgZm9yIHRoaXMgZW50cnkncyBjaGlsZHJlbi4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIGlzIG9ubHkgdXNlZnVsIGZvciBlbnRyaWVzIGNyZWF0ZWQgZnJvbSBhIHtAY29kZQorICAgICAqIEZpbGV9IGJ1dCBub3QgZm9yIGVudHJpZXMgcmVhZCBmcm9tIGFuIGFyY2hpdmUuPC9wPgorICAgICAqCisgICAgICogQHJldHVybiBBbiBhcnJheSBvZiBUYXJFbnRyeSdzIGZvciB0aGlzIGVudHJ5J3MgY2hpbGRyZW4uCisgICAgICovCisgICAgcHVibGljIFRhckFyY2hpdmVFbnRyeVtdIGdldERpcmVjdG9yeUVudHJpZXMoKSB7CisgICAgICAgIGlmIChmaWxlID09IG51bGwgfHwgIWZpbGUuaXNEaXJlY3RvcnkoKSkgeworICAgICAgICAgICAgcmV0dXJuIEVNUFRZX1RBUl9BUkNISVZFX0VOVFJJRVM7CisgICAgICAgIH0KKworICAgICAgICBmaW5hbCBTdHJpbmdbXSBsaXN0ID0gZmlsZS5saXN0KCk7CisgICAgICAgIGlmIChsaXN0ID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBFTVBUWV9UQVJfQVJDSElWRV9FTlRSSUVTOworICAgICAgICB9CisgICAgICAgIGZpbmFsIFRhckFyY2hpdmVFbnRyeVtdIHJlc3VsdCA9IG5ldyBUYXJBcmNoaXZlRW50cnlbbGlzdC5sZW5ndGhdOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVzdWx0Lmxlbmd0aDsgKytpKSB7CisgICAgICAgICAgICByZXN1bHRbaV0gPSBuZXcgVGFyQXJjaGl2ZUVudHJ5KG5ldyBGaWxlKGZpbGUsIGxpc3RbaV0pKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGUgYW4gZW50cnkncyBoZWFkZXIgaW5mb3JtYXRpb24gdG8gYSBoZWFkZXIgYnVmZmVyLgorICAgICAqCisgICAgICogPHA+VGhpcyBtZXRob2QgZG9lcyBub3QgdXNlIHRoZSBzdGFyL0dOVSB0YXIvQlNEIHRhciBleHRlbnNpb25zLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvdXRidWYgVGhlIHRhciBlbnRyeSBoZWFkZXIgYnVmZmVyIHRvIGZpbGwgaW4uCisgICAgICovCisgICAgcHVibGljIHZvaWQgd3JpdGVFbnRyeUhlYWRlcihmaW5hbCBieXRlW10gb3V0YnVmKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB3cml0ZUVudHJ5SGVhZGVyKG91dGJ1ZiwgVGFyVXRpbHMuREVGQVVMVF9FTkNPRElORywgZmFsc2UpOworICAgICAgICB9IGNhdGNoIChmaW5hbCBJT0V4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICB3cml0ZUVudHJ5SGVhZGVyKG91dGJ1ZiwgVGFyVXRpbHMuRkFMTEJBQ0tfRU5DT0RJTkcsIGZhbHNlKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKGZpbmFsIElPRXhjZXB0aW9uIGV4MikgeworICAgICAgICAgICAgICAgIC8vIGltcG9zc2libGUKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihleDIpOyAvL05PU09OQVIKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlIGFuIGVudHJ5J3MgaGVhZGVyIGluZm9ybWF0aW9uIHRvIGEgaGVhZGVyIGJ1ZmZlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvdXRidWYgVGhlIHRhciBlbnRyeSBoZWFkZXIgYnVmZmVyIHRvIGZpbGwgaW4uCisgICAgICogQHBhcmFtIGVuY29kaW5nIGVuY29kaW5nIHRvIHVzZSB3aGVuIHdyaXRpbmcgdGhlIGZpbGUgbmFtZS4KKyAgICAgKiBAcGFyYW0gc3Rhck1vZGUgd2hldGhlciB0byB1c2UgdGhlIHN0YXIvR05VIHRhci9CU0QgdGFyCisgICAgICogZXh0ZW5zaW9uIGZvciBudW1lcmljIGZpZWxkcyBpZiB0aGVpciB2YWx1ZSBkb2Vzbid0IGZpdCBpbiB0aGUKKyAgICAgKiBtYXhpbXVtIHNpemUgb2Ygc3RhbmRhcmQgdGFyIGFyY2hpdmVzCisgICAgICogQHNpbmNlIDEuNAorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gb24gZXJyb3IKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB3cml0ZUVudHJ5SGVhZGVyKGZpbmFsIGJ5dGVbXSBvdXRidWYsIGZpbmFsIFppcEVuY29kaW5nIGVuY29kaW5nLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgYm9vbGVhbiBzdGFyTW9kZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IG9mZnNldCA9IDA7CisKKyAgICAgICAgb2Zmc2V0ID0gVGFyVXRpbHMuZm9ybWF0TmFtZUJ5dGVzKG5hbWUsIG91dGJ1Ziwgb2Zmc2V0LCBOQU1FTEVOLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5jb2RpbmcpOworICAgICAgICBvZmZzZXQgPSB3cml0ZUVudHJ5SGVhZGVyRmllbGQobW9kZSwgb3V0YnVmLCBvZmZzZXQsIE1PREVMRU4sIHN0YXJNb2RlKTsKKyAgICAgICAgb2Zmc2V0ID0gd3JpdGVFbnRyeUhlYWRlckZpZWxkKHVzZXJJZCwgb3V0YnVmLCBvZmZzZXQsIFVJRExFTiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJNb2RlKTsKKyAgICAgICAgb2Zmc2V0ID0gd3JpdGVFbnRyeUhlYWRlckZpZWxkKGdyb3VwSWQsIG91dGJ1Ziwgb2Zmc2V0LCBHSURMRU4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFyTW9kZSk7CisgICAgICAgIG9mZnNldCA9IHdyaXRlRW50cnlIZWFkZXJGaWVsZChzaXplLCBvdXRidWYsIG9mZnNldCwgU0laRUxFTiwgc3Rhck1vZGUpOworICAgICAgICBvZmZzZXQgPSB3cml0ZUVudHJ5SGVhZGVyRmllbGQobW9kVGltZSwgb3V0YnVmLCBvZmZzZXQsIE1PRFRJTUVMRU4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFyTW9kZSk7CisKKyAgICAgICAgZmluYWwgaW50IGNzT2Zmc2V0ID0gb2Zmc2V0OworCisgICAgICAgIGZvciAoaW50IGMgPSAwOyBjIDwgQ0hLU1VNTEVOOyArK2MpIHsKKyAgICAgICAgICAgIG91dGJ1ZltvZmZzZXQrK10gPSAoYnl0ZSkgJyAnOworICAgICAgICB9CisKKyAgICAgICAgb3V0YnVmW29mZnNldCsrXSA9IGxpbmtGbGFnOworICAgICAgICBvZmZzZXQgPSBUYXJVdGlscy5mb3JtYXROYW1lQnl0ZXMobGlua05hbWUsIG91dGJ1Ziwgb2Zmc2V0LCBOQU1FTEVOLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5jb2RpbmcpOworICAgICAgICBvZmZzZXQgPSBUYXJVdGlscy5mb3JtYXROYW1lQnl0ZXMobWFnaWMsIG91dGJ1Ziwgb2Zmc2V0LCBNQUdJQ0xFTik7CisgICAgICAgIG9mZnNldCA9IFRhclV0aWxzLmZvcm1hdE5hbWVCeXRlcyh2ZXJzaW9uLCBvdXRidWYsIG9mZnNldCwgVkVSU0lPTkxFTik7CisgICAgICAgIG9mZnNldCA9IFRhclV0aWxzLmZvcm1hdE5hbWVCeXRlcyh1c2VyTmFtZSwgb3V0YnVmLCBvZmZzZXQsIFVOQU1FTEVOLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5jb2RpbmcpOworICAgICAgICBvZmZzZXQgPSBUYXJVdGlscy5mb3JtYXROYW1lQnl0ZXMoZ3JvdXBOYW1lLCBvdXRidWYsIG9mZnNldCwgR05BTUVMRU4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmNvZGluZyk7CisgICAgICAgIG9mZnNldCA9IHdyaXRlRW50cnlIZWFkZXJGaWVsZChkZXZNYWpvciwgb3V0YnVmLCBvZmZzZXQsIERFVkxFTiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJNb2RlKTsKKyAgICAgICAgb2Zmc2V0ID0gd3JpdGVFbnRyeUhlYWRlckZpZWxkKGRldk1pbm9yLCBvdXRidWYsIG9mZnNldCwgREVWTEVOLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Rhck1vZGUpOworCisgICAgICAgIHdoaWxlIChvZmZzZXQgPCBvdXRidWYubGVuZ3RoKSB7CisgICAgICAgICAgICBvdXRidWZbb2Zmc2V0KytdID0gMDsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIGxvbmcgY2hrID0gVGFyVXRpbHMuY29tcHV0ZUNoZWNrU3VtKG91dGJ1Zik7CisKKyAgICAgICAgVGFyVXRpbHMuZm9ybWF0Q2hlY2tTdW1PY3RhbEJ5dGVzKGNoaywgb3V0YnVmLCBjc09mZnNldCwgQ0hLU1VNTEVOKTsKKyAgICB9CisKKyAgICBwcml2YXRlIGludCB3cml0ZUVudHJ5SGVhZGVyRmllbGQoZmluYWwgbG9uZyB2YWx1ZSwgZmluYWwgYnl0ZVtdIG91dGJ1ZiwgZmluYWwgaW50IG9mZnNldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGxlbmd0aCwgZmluYWwgYm9vbGVhbiBzdGFyTW9kZSkgeworICAgICAgICBpZiAoIXN0YXJNb2RlICYmICh2YWx1ZSA8IDAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgdmFsdWUgPj0gMUwgPDwgMyAqIChsZW5ndGggLSAxKSkpIHsKKyAgICAgICAgICAgIC8vIHZhbHVlIGRvZXNuJ3QgZml0IGludG8gZmllbGQgd2hlbiB3cml0dGVuIGFzIG9jdGFsCisgICAgICAgICAgICAvLyBudW1iZXIsIHdpbGwgYmUgd3JpdHRlbiB0byBQQVggaGVhZGVyIG9yIGNhdXNlcyBhbgorICAgICAgICAgICAgLy8gZXJyb3IKKyAgICAgICAgICAgIHJldHVybiBUYXJVdGlscy5mb3JtYXRMb25nT2N0YWxCeXRlcygwLCBvdXRidWYsIG9mZnNldCwgbGVuZ3RoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gVGFyVXRpbHMuZm9ybWF0TG9uZ09jdGFsT3JCaW5hcnlCeXRlcyh2YWx1ZSwgb3V0YnVmLCBvZmZzZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2UgYW4gZW50cnkncyBoZWFkZXIgaW5mb3JtYXRpb24gZnJvbSBhIGhlYWRlciBidWZmZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaGVhZGVyIFRoZSB0YXIgZW50cnkgaGVhZGVyIGJ1ZmZlciB0byBnZXQgaW5mb3JtYXRpb24gZnJvbS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBhbnkgb2YgdGhlIG51bWVyaWMgZmllbGRzIGhhdmUgYW4gaW52YWxpZCBmb3JtYXQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwYXJzZVRhckhlYWRlcihmaW5hbCBieXRlW10gaGVhZGVyKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwYXJzZVRhckhlYWRlcihoZWFkZXIsIFRhclV0aWxzLkRFRkFVTFRfRU5DT0RJTkcpOworICAgICAgICB9IGNhdGNoIChmaW5hbCBJT0V4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwYXJzZVRhckhlYWRlcihoZWFkZXIsIFRhclV0aWxzLkRFRkFVTFRfRU5DT0RJTkcsIHRydWUpOworICAgICAgICAgICAgfSBjYXRjaCAoZmluYWwgSU9FeGNlcHRpb24gZXgyKSB7CisgICAgICAgICAgICAgICAgLy8gbm90IHJlYWxseSBwb3NzaWJsZQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGV4Mik7IC8vTk9TT05BUgorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2UgYW4gZW50cnkncyBoZWFkZXIgaW5mb3JtYXRpb24gZnJvbSBhIGhlYWRlciBidWZmZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaGVhZGVyIFRoZSB0YXIgZW50cnkgaGVhZGVyIGJ1ZmZlciB0byBnZXQgaW5mb3JtYXRpb24gZnJvbS4KKyAgICAgKiBAcGFyYW0gZW5jb2RpbmcgZW5jb2RpbmcgdG8gdXNlIGZvciBmaWxlIG5hbWVzCisgICAgICogQHNpbmNlIDEuNAorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIGFueSBvZiB0aGUgbnVtZXJpYyBmaWVsZHMKKyAgICAgKiBoYXZlIGFuIGludmFsaWQgZm9ybWF0CisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBvbiBlcnJvcgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHBhcnNlVGFySGVhZGVyKGZpbmFsIGJ5dGVbXSBoZWFkZXIsIGZpbmFsIFppcEVuY29kaW5nIGVuY29kaW5nKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBwYXJzZVRhckhlYWRlcihoZWFkZXIsIGVuY29kaW5nLCBmYWxzZSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHBhcnNlVGFySGVhZGVyKGZpbmFsIGJ5dGVbXSBoZWFkZXIsIGZpbmFsIFppcEVuY29kaW5nIGVuY29kaW5nLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBib29sZWFuIG9sZFN0eWxlKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgb2Zmc2V0ID0gMDsKKworICAgICAgICBuYW1lID0gb2xkU3R5bGUgPyBUYXJVdGlscy5wYXJzZU5hbWUoaGVhZGVyLCBvZmZzZXQsIE5BTUVMRU4pCisgICAgICAgICAgICA6IFRhclV0aWxzLnBhcnNlTmFtZShoZWFkZXIsIG9mZnNldCwgTkFNRUxFTiwgZW5jb2RpbmcpOworICAgICAgICBvZmZzZXQgKz0gTkFNRUxFTjsKKyAgICAgICAgbW9kZSA9IChpbnQpIFRhclV0aWxzLnBhcnNlT2N0YWxPckJpbmFyeShoZWFkZXIsIG9mZnNldCwgTU9ERUxFTik7CisgICAgICAgIG9mZnNldCArPSBNT0RFTEVOOworICAgICAgICB1c2VySWQgPSAoaW50KSBUYXJVdGlscy5wYXJzZU9jdGFsT3JCaW5hcnkoaGVhZGVyLCBvZmZzZXQsIFVJRExFTik7CisgICAgICAgIG9mZnNldCArPSBVSURMRU47CisgICAgICAgIGdyb3VwSWQgPSAoaW50KSBUYXJVdGlscy5wYXJzZU9jdGFsT3JCaW5hcnkoaGVhZGVyLCBvZmZzZXQsIEdJRExFTik7CisgICAgICAgIG9mZnNldCArPSBHSURMRU47CisgICAgICAgIHNpemUgPSBUYXJVdGlscy5wYXJzZU9jdGFsT3JCaW5hcnkoaGVhZGVyLCBvZmZzZXQsIFNJWkVMRU4pOworICAgICAgICBvZmZzZXQgKz0gU0laRUxFTjsKKyAgICAgICAgbW9kVGltZSA9IFRhclV0aWxzLnBhcnNlT2N0YWxPckJpbmFyeShoZWFkZXIsIG9mZnNldCwgTU9EVElNRUxFTik7CisgICAgICAgIG9mZnNldCArPSBNT0RUSU1FTEVOOworICAgICAgICBjaGVja1N1bU9LID0gVGFyVXRpbHMudmVyaWZ5Q2hlY2tTdW0oaGVhZGVyKTsKKyAgICAgICAgb2Zmc2V0ICs9IENIS1NVTUxFTjsKKyAgICAgICAgbGlua0ZsYWcgPSBoZWFkZXJbb2Zmc2V0KytdOworICAgICAgICBsaW5rTmFtZSA9IG9sZFN0eWxlID8gVGFyVXRpbHMucGFyc2VOYW1lKGhlYWRlciwgb2Zmc2V0LCBOQU1FTEVOKQorICAgICAgICAgICAgOiBUYXJVdGlscy5wYXJzZU5hbWUoaGVhZGVyLCBvZmZzZXQsIE5BTUVMRU4sIGVuY29kaW5nKTsKKyAgICAgICAgb2Zmc2V0ICs9IE5BTUVMRU47CisgICAgICAgIG1hZ2ljID0gVGFyVXRpbHMucGFyc2VOYW1lKGhlYWRlciwgb2Zmc2V0LCBNQUdJQ0xFTik7CisgICAgICAgIG9mZnNldCArPSBNQUdJQ0xFTjsKKyAgICAgICAgdmVyc2lvbiA9IFRhclV0aWxzLnBhcnNlTmFtZShoZWFkZXIsIG9mZnNldCwgVkVSU0lPTkxFTik7CisgICAgICAgIG9mZnNldCArPSBWRVJTSU9OTEVOOworICAgICAgICB1c2VyTmFtZSA9IG9sZFN0eWxlID8gVGFyVXRpbHMucGFyc2VOYW1lKGhlYWRlciwgb2Zmc2V0LCBVTkFNRUxFTikKKyAgICAgICAgICAgIDogVGFyVXRpbHMucGFyc2VOYW1lKGhlYWRlciwgb2Zmc2V0LCBVTkFNRUxFTiwgZW5jb2RpbmcpOworICAgICAgICBvZmZzZXQgKz0gVU5BTUVMRU47CisgICAgICAgIGdyb3VwTmFtZSA9IG9sZFN0eWxlID8gVGFyVXRpbHMucGFyc2VOYW1lKGhlYWRlciwgb2Zmc2V0LCBHTkFNRUxFTikKKyAgICAgICAgICAgIDogVGFyVXRpbHMucGFyc2VOYW1lKGhlYWRlciwgb2Zmc2V0LCBHTkFNRUxFTiwgZW5jb2RpbmcpOworICAgICAgICBvZmZzZXQgKz0gR05BTUVMRU47CisgICAgICAgIGlmIChsaW5rRmxhZyA9PSBMRl9DSFIgfHwgbGlua0ZsYWcgPT0gTEZfQkxLKSB7CisgICAgICAgICAgICBkZXZNYWpvciA9IChpbnQpIFRhclV0aWxzLnBhcnNlT2N0YWxPckJpbmFyeShoZWFkZXIsIG9mZnNldCwgREVWTEVOKTsKKyAgICAgICAgICAgIG9mZnNldCArPSBERVZMRU47CisgICAgICAgICAgICBkZXZNaW5vciA9IChpbnQpIFRhclV0aWxzLnBhcnNlT2N0YWxPckJpbmFyeShoZWFkZXIsIG9mZnNldCwgREVWTEVOKTsKKyAgICAgICAgICAgIG9mZnNldCArPSBERVZMRU47CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBvZmZzZXQgKz0gMiAqIERFVkxFTjsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIGludCB0eXBlID0gZXZhbHVhdGVUeXBlKGhlYWRlcik7CisgICAgICAgIHN3aXRjaCAodHlwZSkgeworICAgICAgICBjYXNlIEZPUk1BVF9PTERHTlU6IHsKKyAgICAgICAgICAgIG9mZnNldCArPSBBVElNRUxFTl9HTlU7CisgICAgICAgICAgICBvZmZzZXQgKz0gQ1RJTUVMRU5fR05VOworICAgICAgICAgICAgb2Zmc2V0ICs9IE9GRlNFVExFTl9HTlU7CisgICAgICAgICAgICBvZmZzZXQgKz0gTE9OR05BTUVTTEVOX0dOVTsKKyAgICAgICAgICAgIG9mZnNldCArPSBQQUQyTEVOX0dOVTsKKyAgICAgICAgICAgIG9mZnNldCArPSBTUEFSU0VMRU5fR05VOworICAgICAgICAgICAgaXNFeHRlbmRlZCA9IFRhclV0aWxzLnBhcnNlQm9vbGVhbihoZWFkZXIsIG9mZnNldCk7CisgICAgICAgICAgICBvZmZzZXQgKz0gSVNFWFRFTkRFRExFTl9HTlU7CisgICAgICAgICAgICByZWFsU2l6ZSA9IFRhclV0aWxzLnBhcnNlT2N0YWwoaGVhZGVyLCBvZmZzZXQsIFJFQUxTSVpFTEVOX0dOVSk7CisgICAgICAgICAgICBvZmZzZXQgKz0gUkVBTFNJWkVMRU5fR05VOyAvLyBOT1NPTkFSIC0gYXNzaWdubWVudCBhcyBkb2N1bWVudGF0aW9uCisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBjYXNlIEZPUk1BVF9YU1RBUjogeworICAgICAgICAgICAgZmluYWwgU3RyaW5nIHhzdGFyUHJlZml4ID0gb2xkU3R5bGUKKyAgICAgICAgICAgICAgICA/IFRhclV0aWxzLnBhcnNlTmFtZShoZWFkZXIsIG9mZnNldCwgUFJFRklYTEVOX1hTVEFSKQorICAgICAgICAgICAgICAgIDogVGFyVXRpbHMucGFyc2VOYW1lKGhlYWRlciwgb2Zmc2V0LCBQUkVGSVhMRU5fWFNUQVIsIGVuY29kaW5nKTsKKyAgICAgICAgICAgIGlmICh4c3RhclByZWZpeC5sZW5ndGgoKSA+IDApIHsKKyAgICAgICAgICAgICAgICBuYW1lID0geHN0YXJQcmVmaXggKyAiLyIgKyBuYW1lOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgY2FzZSBGT1JNQVRfUE9TSVg6CisgICAgICAgIGRlZmF1bHQ6IHsKKyAgICAgICAgICAgIGZpbmFsIFN0cmluZyBwcmVmaXggPSBvbGRTdHlsZQorICAgICAgICAgICAgICAgID8gVGFyVXRpbHMucGFyc2VOYW1lKGhlYWRlciwgb2Zmc2V0LCBQUkVGSVhMRU4pCisgICAgICAgICAgICAgICAgOiBUYXJVdGlscy5wYXJzZU5hbWUoaGVhZGVyLCBvZmZzZXQsIFBSRUZJWExFTiwgZW5jb2RpbmcpOworICAgICAgICAgICAgLy8gU3VuT1MgdGFyIC1FIGRvZXMgbm90IGFkZCAvIHRvIGRpcmVjdG9yeSBuYW1lcywgc28gZml4CisgICAgICAgICAgICAvLyB1cCB0byBiZSBjb25zaXN0ZW50CisgICAgICAgICAgICBpZiAoaXNEaXJlY3RvcnkoKSAmJiAhbmFtZS5lbmRzV2l0aCgiLyIpKXsKKyAgICAgICAgICAgICAgICBuYW1lID0gbmFtZSArICIvIjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChwcmVmaXgubGVuZ3RoKCkgPiAwKXsKKyAgICAgICAgICAgICAgICBuYW1lID0gcHJlZml4ICsgIi8iICsgbmFtZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU3RyaXBzIFdpbmRvd3MnIGRyaXZlIGxldHRlciBhcyB3ZWxsIGFzIGFueSBsZWFkaW5nIHNsYXNoZXMsCisgICAgICogdHVybnMgcGF0aCBzZXBhcmF0b3JzIGludG8gZm9yd2FyZCBzbGFoZXMuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIG5vcm1hbGl6ZUZpbGVOYW1lKFN0cmluZyBmaWxlTmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgYm9vbGVhbiBwcmVzZXJ2ZUFic29sdXRlUGF0aCkgeworICAgICAgICBpZiAoIXByZXNlcnZlQWJzb2x1dGVQYXRoKSB7CisgICAgICAgICAgICBmaW5hbCBTdHJpbmcgb3NuYW1lID0gU3lzdGVtLmdldFByb3BlcnR5KCJvcy5uYW1lIikudG9Mb3dlckNhc2UoTG9jYWxlLkVOR0xJU0gpOworCisgICAgICAgICAgICBpZiAob3NuYW1lICE9IG51bGwpIHsKKworICAgICAgICAgICAgICAgIC8vIFN0cmlwIG9mZiBkcml2ZSBsZXR0ZXJzIQorICAgICAgICAgICAgICAgIC8vIFJFVklFVyBXb3VsZCBhIGJldHRlciBjaGVjayBiZSAiKEZpbGUuc2VwYXJhdG9yID09ICdcJykiPworCisgICAgICAgICAgICAgICAgaWYgKG9zbmFtZS5zdGFydHNXaXRoKCJ3aW5kb3dzIikpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGZpbGVOYW1lLmxlbmd0aCgpID4gMikgeworICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgY2hhciBjaDEgPSBmaWxlTmFtZS5jaGFyQXQoMCk7CisgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBjaGFyIGNoMiA9IGZpbGVOYW1lLmNoYXJBdCgxKTsKKworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNoMiA9PSAnOicKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiAoY2gxID49ICdhJyAmJiBjaDEgPD0gJ3onCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IGNoMSA+PSAnQScgJiYgY2gxIDw9ICdaJykpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlTmFtZSA9IGZpbGVOYW1lLnN1YnN0cmluZygyKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAob3NuYW1lLmNvbnRhaW5zKCJuZXR3YXJlIikpIHsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGNvbG9uID0gZmlsZU5hbWUuaW5kZXhPZignOicpOworICAgICAgICAgICAgICAgICAgICBpZiAoY29sb24gIT0gLTEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVOYW1lID0gZmlsZU5hbWUuc3Vic3RyaW5nKGNvbG9uICsgMSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBmaWxlTmFtZSA9IGZpbGVOYW1lLnJlcGxhY2UoRmlsZS5zZXBhcmF0b3JDaGFyLCAnLycpOworCisgICAgICAgIC8vIE5vIGFic29sdXRlIHBhdGhuYW1lcworICAgICAgICAvLyBXaW5kb3dzIChhbmQgUG9zaXg/KSBwYXRocyBjYW4gc3RhcnQgd2l0aCAiXFxOZXR3b3JrRHJpdmVcIiwKKyAgICAgICAgLy8gc28gd2UgbG9vcCBvbiBzdGFydGluZyAvJ3MuCisgICAgICAgIHdoaWxlICghcHJlc2VydmVBYnNvbHV0ZVBhdGggJiYgZmlsZU5hbWUuc3RhcnRzV2l0aCgiLyIpKSB7CisgICAgICAgICAgICBmaWxlTmFtZSA9IGZpbGVOYW1lLnN1YnN0cmluZygxKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmlsZU5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogRXZhbHVhdGUgYW4gZW50cnkncyBoZWFkZXIgZm9ybWF0IGZyb20gYSBoZWFkZXIgYnVmZmVyLgorICAgICAqCisgICAgICogQHBhcmFtIGhlYWRlciBUaGUgdGFyIGVudHJ5IGhlYWRlciBidWZmZXIgdG8gZXZhbHVhdGUgdGhlIGZvcm1hdCBmb3IuCisgICAgICogQHJldHVybiBmb3JtYXQgdHlwZQorICAgICAqLworICAgIHByaXZhdGUgaW50IGV2YWx1YXRlVHlwZShmaW5hbCBieXRlW10gaGVhZGVyKSB7CisgICAgICAgIGlmIChBcmNoaXZlVXRpbHMubWF0Y2hBc2NpaUJ1ZmZlcihNQUdJQ19HTlUsIGhlYWRlciwgTUFHSUNfT0ZGU0VULCBNQUdJQ0xFTikpIHsKKyAgICAgICAgICAgIHJldHVybiBGT1JNQVRfT0xER05VOworICAgICAgICB9CisgICAgICAgIGlmIChBcmNoaXZlVXRpbHMubWF0Y2hBc2NpaUJ1ZmZlcihNQUdJQ19QT1NJWCwgaGVhZGVyLCBNQUdJQ19PRkZTRVQsIE1BR0lDTEVOKSkgeworICAgICAgICAgICAgaWYgKEFyY2hpdmVVdGlscy5tYXRjaEFzY2lpQnVmZmVyKE1BR0lDX1hTVEFSLCBoZWFkZXIsIFhTVEFSX01BR0lDX09GRlNFVCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYU1RBUl9NQUdJQ19MRU4pKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIEZPUk1BVF9YU1RBUjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBGT1JNQVRfUE9TSVg7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgdm9pZCBmaWxsR05VU3BhcnNlMHhEYXRhKGZpbmFsIE1hcDxTdHJpbmcsIFN0cmluZz4gaGVhZGVycykgeworICAgICAgICBwYXhHTlVTcGFyc2UgPSB0cnVlOworICAgICAgICByZWFsU2l6ZSA9IEludGVnZXIucGFyc2VJbnQoaGVhZGVycy5nZXQoIkdOVS5zcGFyc2Uuc2l6ZSIpKTsKKyAgICAgICAgaWYgKGhlYWRlcnMuY29udGFpbnNLZXkoIkdOVS5zcGFyc2UubmFtZSIpKSB7CisgICAgICAgICAgICAvLyB2ZXJzaW9uIDAuMQorICAgICAgICAgICAgbmFtZSA9IGhlYWRlcnMuZ2V0KCJHTlUuc3BhcnNlLm5hbWUiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHZvaWQgZmlsbEdOVVNwYXJzZTF4RGF0YShmaW5hbCBNYXA8U3RyaW5nLCBTdHJpbmc+IGhlYWRlcnMpIHsKKyAgICAgICAgcGF4R05VU3BhcnNlID0gdHJ1ZTsKKyAgICAgICAgcmVhbFNpemUgPSBJbnRlZ2VyLnBhcnNlSW50KGhlYWRlcnMuZ2V0KCJHTlUuc3BhcnNlLnJlYWxzaXplIikpOworICAgICAgICBuYW1lID0gaGVhZGVycy5nZXQoIkdOVS5zcGFyc2UubmFtZSIpOworICAgIH0KKworICAgIHZvaWQgZmlsbFN0YXJTcGFyc2VEYXRhKGZpbmFsIE1hcDxTdHJpbmcsIFN0cmluZz4gaGVhZGVycykgeworICAgICAgICBzdGFyU3BhcnNlID0gdHJ1ZTsKKyAgICAgICAgaWYgKGhlYWRlcnMuY29udGFpbnNLZXkoIlNDSElMWS5yZWFsc2l6ZSIpKSB7CisgICAgICAgICAgICByZWFsU2l6ZSA9IExvbmcucGFyc2VMb25nKGhlYWRlcnMuZ2V0KCJTQ0hJTFkucmVhbHNpemUiKSk7CisgICAgICAgIH0KKyAgICB9Cit9CisKZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy90YXIvVGFyQXJjaGl2ZUlucHV0U3RyZWFtLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvdGFyL1RhckFyY2hpdmVJbnB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRhYWY3MjkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvdGFyL1RhckFyY2hpdmVJbnB1dFN0cmVhbS5qYXZhCkBAIC0wLDAgKzEsNzE0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKgorICovCisKKy8qCisgKiBUaGlzIHBhY2thZ2UgaXMgYmFzZWQgb24gdGhlIHdvcmsgZG9uZSBieSBUaW1vdGh5IEdlcmFyZCBFbmRyZXMKKyAqICh0aW1lQGljZS5jb20pIHRvIHdob20gdGhlIEFudCBwcm9qZWN0IGlzIHZlcnkgZ3JhdGVmdWwgZm9yIGhpcyBncmVhdCBjb2RlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy50YXI7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZUVudHJ5OworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZUlucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwLlppcEVuY29kaW5nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwLlppcEVuY29kaW5nSGVscGVyOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5BcmNoaXZlVXRpbHM7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLkNoYXJzZXROYW1lczsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuSU9VdGlsczsKKworLyoqCisgKiBUaGUgVGFySW5wdXRTdHJlYW0gcmVhZHMgYSBVTklYIHRhciBhcmNoaXZlIGFzIGFuIElucHV0U3RyZWFtLgorICogbWV0aG9kcyBhcmUgcHJvdmlkZWQgdG8gcG9zaXRpb24gYXQgZWFjaCBzdWNjZXNzaXZlIGVudHJ5IGluCisgKiB0aGUgYXJjaGl2ZSwgYW5kIHRoZSByZWFkIGVhY2ggZW50cnkgYXMgYSBub3JtYWwgaW5wdXQgc3RyZWFtCisgKiB1c2luZyByZWFkKCkuCisgKiBATm90VGhyZWFkU2FmZQorICovCitwdWJsaWMgY2xhc3MgVGFyQXJjaGl2ZUlucHV0U3RyZWFtIGV4dGVuZHMgQXJjaGl2ZUlucHV0U3RyZWFtIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBTTUFMTF9CVUZGRVJfU0laRSA9IDI1NjsKKworICAgIHByaXZhdGUgZmluYWwgYnl0ZVtdIHNtYWxsQnVmID0gbmV3IGJ5dGVbU01BTExfQlVGRkVSX1NJWkVdOworCisgICAgLyoqIFRoZSBzaXplIHRoZSBUQVIgaGVhZGVyICovCisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgcmVjb3JkU2l6ZTsKKworICAgIC8qKiBUaGUgc2l6ZSBvZiBhIGJsb2NrICovCisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgYmxvY2tTaXplOworCisgICAgLyoqIFRydWUgaWYgZmlsZSBoYXMgaGl0IEVPRiAqLworICAgIHByaXZhdGUgYm9vbGVhbiBoYXNIaXRFT0Y7CisKKyAgICAvKiogU2l6ZSBvZiB0aGUgY3VycmVudCBlbnRyeSAqLworICAgIHByaXZhdGUgbG9uZyBlbnRyeVNpemU7CisKKyAgICAvKiogSG93IGZhciBpbnRvIHRoZSBlbnRyeSB0aGUgc3RyZWFtIGlzIGF0ICovCisgICAgcHJpdmF0ZSBsb25nIGVudHJ5T2Zmc2V0OworCisgICAgLyoqIEFuIGlucHV0IHN0cmVhbSB0byByZWFkIGZyb20gKi8KKyAgICBwcml2YXRlIGZpbmFsIElucHV0U3RyZWFtIGlzOworCisgICAgLyoqIFRoZSBtZXRhLWRhdGEgYWJvdXQgdGhlIGN1cnJlbnQgZW50cnkgKi8KKyAgICBwcml2YXRlIFRhckFyY2hpdmVFbnRyeSBjdXJyRW50cnk7CisKKyAgICAvKiogVGhlIGVuY29kaW5nIG9mIHRoZSBmaWxlICovCisgICAgcHJpdmF0ZSBmaW5hbCBaaXBFbmNvZGluZyB6aXBFbmNvZGluZzsKKworICAgIC8vIHRoZSBwcm92aWRlZCBlbmNvZGluZyAoZm9yIHVuaXQgdGVzdHMpCisgICAgZmluYWwgU3RyaW5nIGVuY29kaW5nOworCisgICAgLy8gdGhlIGdsb2JhbCBQQVggaGVhZGVyCisgICAgcHJpdmF0ZSBNYXA8U3RyaW5nLCBTdHJpbmc+IGdsb2JhbFBheEhlYWRlcnMgPSBuZXcgSGFzaE1hcDw+KCk7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvciBmb3IgVGFySW5wdXRTdHJlYW0uCisgICAgICogQHBhcmFtIGlzIHRoZSBpbnB1dCBzdHJlYW0gdG8gdXNlCisgICAgICovCisgICAgcHVibGljIFRhckFyY2hpdmVJbnB1dFN0cmVhbShmaW5hbCBJbnB1dFN0cmVhbSBpcykgeworICAgICAgICB0aGlzKGlzLCBUYXJDb25zdGFudHMuREVGQVVMVF9CTEtTSVpFLCBUYXJDb25zdGFudHMuREVGQVVMVF9SQ0RTSVpFKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvciBmb3IgVGFySW5wdXRTdHJlYW0uCisgICAgICogQHBhcmFtIGlzIHRoZSBpbnB1dCBzdHJlYW0gdG8gdXNlCisgICAgICogQHBhcmFtIGVuY29kaW5nIG5hbWUgb2YgdGhlIGVuY29kaW5nIHRvIHVzZSBmb3IgZmlsZSBuYW1lcworICAgICAqIEBzaW5jZSAxLjQKKyAgICAgKi8KKyAgICBwdWJsaWMgVGFyQXJjaGl2ZUlucHV0U3RyZWFtKGZpbmFsIElucHV0U3RyZWFtIGlzLCBmaW5hbCBTdHJpbmcgZW5jb2RpbmcpIHsKKyAgICAgICAgdGhpcyhpcywgVGFyQ29uc3RhbnRzLkRFRkFVTFRfQkxLU0laRSwgVGFyQ29uc3RhbnRzLkRFRkFVTFRfUkNEU0laRSwKKyAgICAgICAgICAgICBlbmNvZGluZyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IgZm9yIFRhcklucHV0U3RyZWFtLgorICAgICAqIEBwYXJhbSBpcyB0aGUgaW5wdXQgc3RyZWFtIHRvIHVzZQorICAgICAqIEBwYXJhbSBibG9ja1NpemUgdGhlIGJsb2NrIHNpemUgdG8gdXNlCisgICAgICovCisgICAgcHVibGljIFRhckFyY2hpdmVJbnB1dFN0cmVhbShmaW5hbCBJbnB1dFN0cmVhbSBpcywgZmluYWwgaW50IGJsb2NrU2l6ZSkgeworICAgICAgICB0aGlzKGlzLCBibG9ja1NpemUsIFRhckNvbnN0YW50cy5ERUZBVUxUX1JDRFNJWkUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yIGZvciBUYXJJbnB1dFN0cmVhbS4KKyAgICAgKiBAcGFyYW0gaXMgdGhlIGlucHV0IHN0cmVhbSB0byB1c2UKKyAgICAgKiBAcGFyYW0gYmxvY2tTaXplIHRoZSBibG9jayBzaXplIHRvIHVzZQorICAgICAqIEBwYXJhbSBlbmNvZGluZyBuYW1lIG9mIHRoZSBlbmNvZGluZyB0byB1c2UgZm9yIGZpbGUgbmFtZXMKKyAgICAgKiBAc2luY2UgMS40CisgICAgICovCisgICAgcHVibGljIFRhckFyY2hpdmVJbnB1dFN0cmVhbShmaW5hbCBJbnB1dFN0cmVhbSBpcywgZmluYWwgaW50IGJsb2NrU2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBlbmNvZGluZykgeworICAgICAgICB0aGlzKGlzLCBibG9ja1NpemUsIFRhckNvbnN0YW50cy5ERUZBVUxUX1JDRFNJWkUsIGVuY29kaW5nKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvciBmb3IgVGFySW5wdXRTdHJlYW0uCisgICAgICogQHBhcmFtIGlzIHRoZSBpbnB1dCBzdHJlYW0gdG8gdXNlCisgICAgICogQHBhcmFtIGJsb2NrU2l6ZSB0aGUgYmxvY2sgc2l6ZSB0byB1c2UKKyAgICAgKiBAcGFyYW0gcmVjb3JkU2l6ZSB0aGUgcmVjb3JkIHNpemUgdG8gdXNlCisgICAgICovCisgICAgcHVibGljIFRhckFyY2hpdmVJbnB1dFN0cmVhbShmaW5hbCBJbnB1dFN0cmVhbSBpcywgZmluYWwgaW50IGJsb2NrU2l6ZSwgZmluYWwgaW50IHJlY29yZFNpemUpIHsKKyAgICAgICAgdGhpcyhpcywgYmxvY2tTaXplLCByZWNvcmRTaXplLCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvciBmb3IgVGFySW5wdXRTdHJlYW0uCisgICAgICogQHBhcmFtIGlzIHRoZSBpbnB1dCBzdHJlYW0gdG8gdXNlCisgICAgICogQHBhcmFtIGJsb2NrU2l6ZSB0aGUgYmxvY2sgc2l6ZSB0byB1c2UKKyAgICAgKiBAcGFyYW0gcmVjb3JkU2l6ZSB0aGUgcmVjb3JkIHNpemUgdG8gdXNlCisgICAgICogQHBhcmFtIGVuY29kaW5nIG5hbWUgb2YgdGhlIGVuY29kaW5nIHRvIHVzZSBmb3IgZmlsZSBuYW1lcworICAgICAqIEBzaW5jZSAxLjQKKyAgICAgKi8KKyAgICBwdWJsaWMgVGFyQXJjaGl2ZUlucHV0U3RyZWFtKGZpbmFsIElucHV0U3RyZWFtIGlzLCBmaW5hbCBpbnQgYmxvY2tTaXplLCBmaW5hbCBpbnQgcmVjb3JkU2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBlbmNvZGluZykgeworICAgICAgICB0aGlzLmlzID0gaXM7CisgICAgICAgIHRoaXMuaGFzSGl0RU9GID0gZmFsc2U7CisgICAgICAgIHRoaXMuZW5jb2RpbmcgPSBlbmNvZGluZzsKKyAgICAgICAgdGhpcy56aXBFbmNvZGluZyA9IFppcEVuY29kaW5nSGVscGVyLmdldFppcEVuY29kaW5nKGVuY29kaW5nKTsKKyAgICAgICAgdGhpcy5yZWNvcmRTaXplID0gcmVjb3JkU2l6ZTsKKyAgICAgICAgdGhpcy5ibG9ja1NpemUgPSBibG9ja1NpemU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvc2VzIHRoaXMgc3RyZWFtLiBDYWxscyB0aGUgVGFyQnVmZmVyJ3MgY2xvc2UoKSBtZXRob2QuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBvbiBlcnJvcgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaXMuY2xvc2UoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIHJlY29yZCBzaXplIGJlaW5nIHVzZWQgYnkgdGhpcyBzdHJlYW0ncyBidWZmZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoZSBUYXJCdWZmZXIgcmVjb3JkIHNpemUuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRSZWNvcmRTaXplKCkgeworICAgICAgICByZXR1cm4gcmVjb3JkU2l6ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIGF2YWlsYWJsZSBkYXRhIHRoYXQgY2FuIGJlIHJlYWQgZnJvbSB0aGUgY3VycmVudAorICAgICAqIGVudHJ5IGluIHRoZSBhcmNoaXZlLiBUaGlzIGRvZXMgbm90IGluZGljYXRlIGhvdyBtdWNoIGRhdGEKKyAgICAgKiBpcyBsZWZ0IGluIHRoZSBlbnRpcmUgYXJjaGl2ZSwgb25seSBpbiB0aGUgY3VycmVudCBlbnRyeS4KKyAgICAgKiBUaGlzIHZhbHVlIGlzIGRldGVybWluZWQgZnJvbSB0aGUgZW50cnkncyBzaXplIGhlYWRlciBmaWVsZAorICAgICAqIGFuZCB0aGUgYW1vdW50IG9mIGRhdGEgYWxyZWFkeSByZWFkIGZyb20gdGhlIGN1cnJlbnQgZW50cnkuCisgICAgICogSW50ZWdlci5NQVhfVkFMVUUgaXMgcmV0dXJuZWQgaW4gY2FzZSBtb3JlIHRoYW4gSW50ZWdlci5NQVhfVkFMVUUKKyAgICAgKiBieXRlcyBhcmUgbGVmdCBpbiB0aGUgY3VycmVudCBlbnRyeSBpbiB0aGUgYXJjaGl2ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhlIG51bWJlciBvZiBhdmFpbGFibGUgYnl0ZXMgZm9yIHRoZSBjdXJyZW50IGVudHJ5LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gZm9yIHNpZ25hdHVyZQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgYXZhaWxhYmxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGlzRGlyZWN0b3J5KCkpIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgICAgIGlmIChlbnRyeVNpemUgLSBlbnRyeU9mZnNldCA+IEludGVnZXIuTUFYX1ZBTFVFKSB7CisgICAgICAgICAgICByZXR1cm4gSW50ZWdlci5NQVhfVkFMVUU7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIChpbnQpIChlbnRyeVNpemUgLSBlbnRyeU9mZnNldCk7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBTa2lwcyBvdmVyIGFuZCBkaXNjYXJkcyA8Y29kZT5uPC9jb2RlPiBieXRlcyBvZiBkYXRhIGZyb20gdGhpcyBpbnB1dAorICAgICAqIHN0cmVhbS4gVGhlIDxjb2RlPnNraXA8L2NvZGU+IG1ldGhvZCBtYXksIGZvciBhIHZhcmlldHkgb2YgcmVhc29ucywgZW5kCisgICAgICogdXAgc2tpcHBpbmcgb3ZlciBzb21lIHNtYWxsZXIgbnVtYmVyIG9mIGJ5dGVzLCBwb3NzaWJseSA8Y29kZT4wPC9jb2RlPi4KKyAgICAgKiBUaGlzIG1heSByZXN1bHQgZnJvbSBhbnkgb2YgYSBudW1iZXIgb2YgY29uZGl0aW9uczsgcmVhY2hpbmcgZW5kIG9mIGZpbGUKKyAgICAgKiBvciBlbmQgb2YgZW50cnkgYmVmb3JlIDxjb2RlPm48L2NvZGU+IGJ5dGVzIGhhdmUgYmVlbiBza2lwcGVkOyBhcmUgb25seQorICAgICAqIHR3byBwb3NzaWJpbGl0aWVzLiBUaGUgYWN0dWFsIG51bWJlciBvZiBieXRlcyBza2lwcGVkIGlzIHJldHVybmVkLiBJZgorICAgICAqIDxjb2RlPm48L2NvZGU+IGlzIG5lZ2F0aXZlLCBubyBieXRlcyBhcmUgc2tpcHBlZC4KKyAgICAgKgorICAgICAqCisgICAgICogQHBhcmFtIG4KKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gYmUgc2tpcHBlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBhY3R1YWwgbnVtYmVyIG9mIGJ5dGVzIHNraXBwZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHNvbWUgb3RoZXIgSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgbG9uZyBza2lwKGZpbmFsIGxvbmcgbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKG4gPD0gMCB8fCBpc0RpcmVjdG9yeSgpKSB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIGxvbmcgYXZhaWxhYmxlID0gZW50cnlTaXplIC0gZW50cnlPZmZzZXQ7CisgICAgICAgIGZpbmFsIGxvbmcgc2tpcHBlZCA9IElPVXRpbHMuc2tpcChpcywgTWF0aC5taW4obiwgYXZhaWxhYmxlKSk7CisgICAgICAgIGNvdW50KHNraXBwZWQpOworICAgICAgICBlbnRyeU9mZnNldCArPSBza2lwcGVkOworICAgICAgICByZXR1cm4gc2tpcHBlZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTaW5jZSB3ZSBkbyBub3Qgc3VwcG9ydCBtYXJraW5nIGp1c3QgeWV0LCB3ZSByZXR1cm4gZmFsc2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIEZhbHNlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIG1hcmtTdXBwb3J0ZWQoKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTaW5jZSB3ZSBkbyBub3Qgc3VwcG9ydCBtYXJraW5nIGp1c3QgeWV0LCB3ZSBkbyBub3RoaW5nLgorICAgICAqCisgICAgICogQHBhcmFtIG1hcmtMaW1pdCBUaGUgbGltaXQgdG8gbWFyay4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBtYXJrKGZpbmFsIGludCBtYXJrTGltaXQpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTaW5jZSB3ZSBkbyBub3Qgc3VwcG9ydCBtYXJraW5nIGp1c3QgeWV0LCB3ZSBkbyBub3RoaW5nLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCByZXNldCgpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIG5leHQgZW50cnkgaW4gdGhpcyB0YXIgYXJjaGl2ZS4gVGhpcyB3aWxsIHNraXAKKyAgICAgKiBvdmVyIGFueSByZW1haW5pbmcgZGF0YSBpbiB0aGUgY3VycmVudCBlbnRyeSwgaWYgdGhlcmUKKyAgICAgKiBpcyBvbmUsIGFuZCBwbGFjZSB0aGUgaW5wdXQgc3RyZWFtIGF0IHRoZSBoZWFkZXIgb2YgdGhlCisgICAgICogbmV4dCBlbnRyeSwgYW5kIHJlYWQgdGhlIGhlYWRlciBhbmQgaW5zdGFudGlhdGUgYSBuZXcKKyAgICAgKiBUYXJFbnRyeSBmcm9tIHRoZSBoZWFkZXIgYnl0ZXMgYW5kIHJldHVybiB0aGF0IGVudHJ5LgorICAgICAqIElmIHRoZXJlIGFyZSBubyBtb3JlIGVudHJpZXMgaW4gdGhlIGFyY2hpdmUsIG51bGwgd2lsbAorICAgICAqIGJlIHJldHVybmVkIHRvIGluZGljYXRlIHRoYXQgdGhlIGVuZCBvZiB0aGUgYXJjaGl2ZSBoYXMKKyAgICAgKiBiZWVuIHJlYWNoZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoZSBuZXh0IFRhckVudHJ5IGluIHRoZSBhcmNoaXZlLCBvciBudWxsLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gb24gZXJyb3IKKyAgICAgKi8KKyAgICBwdWJsaWMgVGFyQXJjaGl2ZUVudHJ5IGdldE5leHRUYXJFbnRyeSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChpc0F0RU9GKCkpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGN1cnJFbnRyeSAhPSBudWxsKSB7CisgICAgICAgICAgICAvKiBTa2lwIHdpbGwgb25seSBnbyB0byB0aGUgZW5kIG9mIHRoZSBjdXJyZW50IGVudHJ5ICovCisgICAgICAgICAgICBJT1V0aWxzLnNraXAodGhpcywgTG9uZy5NQVhfVkFMVUUpOworCisgICAgICAgICAgICAvKiBza2lwIHRvIHRoZSBlbmQgb2YgdGhlIGxhc3QgcmVjb3JkICovCisgICAgICAgICAgICBza2lwUmVjb3JkUGFkZGluZygpOworICAgICAgICB9CisKKyAgICAgICAgZmluYWwgYnl0ZVtdIGhlYWRlckJ1ZiA9IGdldFJlY29yZCgpOworCisgICAgICAgIGlmIChoZWFkZXJCdWYgPT0gbnVsbCkgeworICAgICAgICAgICAgLyogaGl0IEVPRiAqLworICAgICAgICAgICAgY3VyckVudHJ5ID0gbnVsbDsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGN1cnJFbnRyeSA9IG5ldyBUYXJBcmNoaXZlRW50cnkoaGVhZGVyQnVmLCB6aXBFbmNvZGluZyk7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkVycm9yIGRldGVjdGVkIHBhcnNpbmcgdGhlIGhlYWRlciIsIGUpOworICAgICAgICB9CisKKyAgICAgICAgZW50cnlPZmZzZXQgPSAwOworICAgICAgICBlbnRyeVNpemUgPSBjdXJyRW50cnkuZ2V0U2l6ZSgpOworCisgICAgICAgIGlmIChjdXJyRW50cnkuaXNHTlVMb25nTGlua0VudHJ5KCkpIHsKKyAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBsb25nTGlua0RhdGEgPSBnZXRMb25nTmFtZURhdGEoKTsKKyAgICAgICAgICAgIGlmIChsb25nTGlua0RhdGEgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIC8vIEJ1Z3ppbGxhOiA0MDMzNAorICAgICAgICAgICAgICAgIC8vIE1hbGZvcm1lZCB0YXIgZmlsZSAtIGxvbmcgbGluayBlbnRyeSBuYW1lIG5vdCBmb2xsb3dlZCBieQorICAgICAgICAgICAgICAgIC8vIGVudHJ5CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjdXJyRW50cnkuc2V0TGlua05hbWUoemlwRW5jb2RpbmcuZGVjb2RlKGxvbmdMaW5rRGF0YSkpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGN1cnJFbnRyeS5pc0dOVUxvbmdOYW1lRW50cnkoKSkgeworICAgICAgICAgICAgZmluYWwgYnl0ZVtdIGxvbmdOYW1lRGF0YSA9IGdldExvbmdOYW1lRGF0YSgpOworICAgICAgICAgICAgaWYgKGxvbmdOYW1lRGF0YSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgLy8gQnVnemlsbGE6IDQwMzM0CisgICAgICAgICAgICAgICAgLy8gTWFsZm9ybWVkIHRhciBmaWxlIC0gbG9uZyBlbnRyeSBuYW1lIG5vdCBmb2xsb3dlZCBieQorICAgICAgICAgICAgICAgIC8vIGVudHJ5CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjdXJyRW50cnkuc2V0TmFtZSh6aXBFbmNvZGluZy5kZWNvZGUobG9uZ05hbWVEYXRhKSk7CisgICAgICAgIH0KKworICAgICAgICBpZiAoY3VyckVudHJ5LmlzR2xvYmFsUGF4SGVhZGVyKCkpeyAvLyBQcm9jZXNzIEdsb2JhbCBQYXggaGVhZGVycworICAgICAgICAgICAgcmVhZEdsb2JhbFBheEhlYWRlcnMoKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChjdXJyRW50cnkuaXNQYXhIZWFkZXIoKSl7IC8vIFByb2Nlc3MgUGF4IGhlYWRlcnMKKyAgICAgICAgICAgIHBheEhlYWRlcnMoKTsKKyAgICAgICAgfSBlbHNlIGlmICghZ2xvYmFsUGF4SGVhZGVycy5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIGFwcGx5UGF4SGVhZGVyc1RvQ3VycmVudEVudHJ5KGdsb2JhbFBheEhlYWRlcnMpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGN1cnJFbnRyeS5pc09sZEdOVVNwYXJzZSgpKXsgLy8gUHJvY2VzcyBzcGFyc2UgZmlsZXMKKyAgICAgICAgICAgIHJlYWRPbGRHTlVTcGFyc2UoKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIElmIHRoZSBzaXplIG9mIHRoZSBuZXh0IGVsZW1lbnQgaW4gdGhlIGFyY2hpdmUgaGFzIGNoYW5nZWQKKyAgICAgICAgLy8gZHVlIHRvIGEgbmV3IHNpemUgYmVpbmcgcmVwb3J0ZWQgaW4gdGhlIHBvc2l4IGhlYWRlcgorICAgICAgICAvLyBpbmZvcm1hdGlvbiwgd2UgdXBkYXRlIGVudHJ5U2l6ZSBoZXJlIHNvIHRoYXQgaXQgY29udGFpbnMKKyAgICAgICAgLy8gdGhlIGNvcnJlY3QgdmFsdWUuCisgICAgICAgIGVudHJ5U2l6ZSA9IGN1cnJFbnRyeS5nZXRTaXplKCk7CisKKyAgICAgICAgcmV0dXJuIGN1cnJFbnRyeTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgbGFzdCByZWNvcmQgYmxvY2sgc2hvdWxkIGJlIHdyaXR0ZW4gYXQgdGhlIGZ1bGwgc2l6ZSwgc28gc2tpcCBhbnkKKyAgICAgKiBhZGRpdGlvbmFsIHNwYWNlIHVzZWQgdG8gZmlsbCBhIHJlY29yZCBhZnRlciBhbiBlbnRyeQorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBza2lwUmVjb3JkUGFkZGluZygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICghaXNEaXJlY3RvcnkoKSAmJiB0aGlzLmVudHJ5U2l6ZSA+IDAgJiYgdGhpcy5lbnRyeVNpemUgJSB0aGlzLnJlY29yZFNpemUgIT0gMCkgeworICAgICAgICAgICAgZmluYWwgbG9uZyBudW1SZWNvcmRzID0gKHRoaXMuZW50cnlTaXplIC8gdGhpcy5yZWNvcmRTaXplKSArIDE7CisgICAgICAgICAgICBmaW5hbCBsb25nIHBhZGRpbmcgPSAobnVtUmVjb3JkcyAqIHRoaXMucmVjb3JkU2l6ZSkgLSB0aGlzLmVudHJ5U2l6ZTsKKyAgICAgICAgICAgIGZpbmFsIGxvbmcgc2tpcHBlZCA9IElPVXRpbHMuc2tpcChpcywgcGFkZGluZyk7CisgICAgICAgICAgICBjb3VudChza2lwcGVkKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgbmV4dCBlbnRyeSBpbiB0aGlzIHRhciBhcmNoaXZlIGFzIGxvbmduYW1lIGRhdGEuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoZSBuZXh0IGVudHJ5IGluIHRoZSBhcmNoaXZlIGFzIGxvbmduYW1lIGRhdGEsIG9yIG51bGwuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBvbiBlcnJvcgorICAgICAqLworICAgIHByb3RlY3RlZCBieXRlW10gZ2V0TG9uZ05hbWVEYXRhKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gcmVhZCBpbiB0aGUgbmFtZQorICAgICAgICBmaW5hbCBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gbG9uZ05hbWUgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIGludCBsZW5ndGggPSAwOworICAgICAgICB3aGlsZSAoKGxlbmd0aCA9IHJlYWQoc21hbGxCdWYpKSA+PSAwKSB7CisgICAgICAgICAgICBsb25nTmFtZS53cml0ZShzbWFsbEJ1ZiwgMCwgbGVuZ3RoKTsKKyAgICAgICAgfQorICAgICAgICBnZXROZXh0RW50cnkoKTsKKyAgICAgICAgaWYgKGN1cnJFbnRyeSA9PSBudWxsKSB7CisgICAgICAgICAgICAvLyBCdWd6aWxsYTogNDAzMzQKKyAgICAgICAgICAgIC8vIE1hbGZvcm1lZCB0YXIgZmlsZSAtIGxvbmcgZW50cnkgbmFtZSBub3QgZm9sbG93ZWQgYnkgZW50cnkKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIGJ5dGVbXSBsb25nTmFtZURhdGEgPSBsb25nTmFtZS50b0J5dGVBcnJheSgpOworICAgICAgICAvLyByZW1vdmUgdHJhaWxpbmcgbnVsbCB0ZXJtaW5hdG9yKHMpCisgICAgICAgIGxlbmd0aCA9IGxvbmdOYW1lRGF0YS5sZW5ndGg7CisgICAgICAgIHdoaWxlIChsZW5ndGggPiAwICYmIGxvbmdOYW1lRGF0YVtsZW5ndGggLSAxXSA9PSAwKSB7CisgICAgICAgICAgICAtLWxlbmd0aDsKKyAgICAgICAgfQorICAgICAgICBpZiAobGVuZ3RoICE9IGxvbmdOYW1lRGF0YS5sZW5ndGgpIHsKKyAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBsID0gbmV3IGJ5dGVbbGVuZ3RoXTsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkobG9uZ05hbWVEYXRhLCAwLCBsLCAwLCBsZW5ndGgpOworICAgICAgICAgICAgbG9uZ05hbWVEYXRhID0gbDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbG9uZ05hbWVEYXRhOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgbmV4dCByZWNvcmQgaW4gdGhpcyB0YXIgYXJjaGl2ZS4gVGhpcyB3aWxsIHNraXAKKyAgICAgKiBvdmVyIGFueSByZW1haW5pbmcgZGF0YSBpbiB0aGUgY3VycmVudCBlbnRyeSwgaWYgdGhlcmUKKyAgICAgKiBpcyBvbmUsIGFuZCBwbGFjZSB0aGUgaW5wdXQgc3RyZWFtIGF0IHRoZSBoZWFkZXIgb2YgdGhlCisgICAgICogbmV4dCBlbnRyeS4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZXJlIGFyZSBubyBtb3JlIGVudHJpZXMgaW4gdGhlIGFyY2hpdmUsIG51bGwgd2lsbCBiZQorICAgICAqIHJldHVybmVkIHRvIGluZGljYXRlIHRoYXQgdGhlIGVuZCBvZiB0aGUgYXJjaGl2ZSBoYXMgYmVlbgorICAgICAqIHJlYWNoZWQuICBBdCB0aGUgc2FtZSB0aW1lIHRoZSB7QGNvZGUgaGFzSGl0RU9GfSBtYXJrZXIgd2lsbCBiZQorICAgICAqIHNldCB0byB0cnVlLjwvcD4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhlIG5leHQgaGVhZGVyIGluIHRoZSBhcmNoaXZlLCBvciBudWxsLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gb24gZXJyb3IKKyAgICAgKi8KKyAgICBwcml2YXRlIGJ5dGVbXSBnZXRSZWNvcmQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBieXRlW10gaGVhZGVyQnVmID0gcmVhZFJlY29yZCgpOworICAgICAgICBzZXRBdEVPRihpc0VPRlJlY29yZChoZWFkZXJCdWYpKTsKKyAgICAgICAgaWYgKGlzQXRFT0YoKSAmJiBoZWFkZXJCdWYgIT0gbnVsbCkgeworICAgICAgICAgICAgdHJ5VG9Db25zdW1lU2Vjb25kRU9GUmVjb3JkKCk7CisgICAgICAgICAgICBjb25zdW1lUmVtYWluZGVyT2ZMYXN0QmxvY2soKTsKKyAgICAgICAgICAgIGhlYWRlckJ1ZiA9IG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGhlYWRlckJ1ZjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmUgaWYgYW4gYXJjaGl2ZSByZWNvcmQgaW5kaWNhdGUgRW5kIG9mIEFyY2hpdmUuIEVuZCBvZgorICAgICAqIGFyY2hpdmUgaXMgaW5kaWNhdGVkIGJ5IGEgcmVjb3JkIHRoYXQgY29uc2lzdHMgZW50aXJlbHkgb2YgbnVsbCBieXRlcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZWNvcmQgVGhlIHJlY29yZCBkYXRhIHRvIGNoZWNrLgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgcmVjb3JkIGRhdGEgaXMgYW4gRW5kIG9mIEFyY2hpdmUKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBpc0VPRlJlY29yZChmaW5hbCBieXRlW10gcmVjb3JkKSB7CisgICAgICAgIHJldHVybiByZWNvcmQgPT0gbnVsbCB8fCBBcmNoaXZlVXRpbHMuaXNBcnJheVplcm8ocmVjb3JkLCByZWNvcmRTaXplKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkIGEgcmVjb3JkIGZyb20gdGhlIGlucHV0IHN0cmVhbSBhbmQgcmV0dXJuIHRoZSBkYXRhLgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgcmVjb3JkIGRhdGEgb3IgbnVsbCBpZiBFT0YgaGFzIGJlZW4gaGl0LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gb24gZXJyb3IKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYnl0ZVtdIHJlYWRSZWNvcmQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCisgICAgICAgIGZpbmFsIGJ5dGVbXSByZWNvcmQgPSBuZXcgYnl0ZVtyZWNvcmRTaXplXTsKKworICAgICAgICBmaW5hbCBpbnQgcmVhZE5vdyA9IElPVXRpbHMucmVhZEZ1bGx5KGlzLCByZWNvcmQpOworICAgICAgICBjb3VudChyZWFkTm93KTsKKyAgICAgICAgaWYgKHJlYWROb3cgIT0gcmVjb3JkU2l6ZSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gcmVjb3JkOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByZWFkR2xvYmFsUGF4SGVhZGVycygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGdsb2JhbFBheEhlYWRlcnMgPSBwYXJzZVBheEhlYWRlcnModGhpcyk7CisgICAgICAgIGdldE5leHRFbnRyeSgpOyAvLyBHZXQgdGhlIGFjdHVhbCBmaWxlIGVudHJ5CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHBheEhlYWRlcnMoKSB0aHJvd3MgSU9FeGNlcHRpb257CisgICAgICAgIGZpbmFsIE1hcDxTdHJpbmcsIFN0cmluZz4gaGVhZGVycyA9IHBhcnNlUGF4SGVhZGVycyh0aGlzKTsKKyAgICAgICAgZ2V0TmV4dEVudHJ5KCk7IC8vIEdldCB0aGUgYWN0dWFsIGZpbGUgZW50cnkKKyAgICAgICAgYXBwbHlQYXhIZWFkZXJzVG9DdXJyZW50RW50cnkoaGVhZGVycyk7CisgICAgfQorCisgICAgLy8gTk9URSwgdXNpbmcgYSBNYXAgaGVyZSBtYWtlcyBpdCBpbXBvc3NpYmxlIHRvIGV2ZXIgc3VwcG9ydCBHTlUKKyAgICAvLyBzcGFyc2UgZmlsZXMgdXNpbmcgdGhlIFBBWCBGb3JtYXQgMC4wLCBzZWUKKyAgICAvLyBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL3Rhci9tYW51YWwvaHRtbF9zZWN0aW9uL3Rhcl85Mi5odG1sI1NFQzE4OAorICAgIE1hcDxTdHJpbmcsIFN0cmluZz4gcGFyc2VQYXhIZWFkZXJzKGZpbmFsIElucHV0U3RyZWFtIGkpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIE1hcDxTdHJpbmcsIFN0cmluZz4gaGVhZGVycyA9IG5ldyBIYXNoTWFwPD4oZ2xvYmFsUGF4SGVhZGVycyk7CisgICAgICAgIC8vIEZvcm1hdCBpcyAibGVuZ3RoIGtleXdvcmQ9dmFsdWVcbiI7CisgICAgICAgIHdoaWxlKHRydWUpeyAvLyBnZXQgbGVuZ3RoCisgICAgICAgICAgICBpbnQgY2g7CisgICAgICAgICAgICBpbnQgbGVuID0gMDsKKyAgICAgICAgICAgIGludCByZWFkID0gMDsKKyAgICAgICAgICAgIHdoaWxlKChjaCA9IGkucmVhZCgpKSAhPSAtMSkgeworICAgICAgICAgICAgICAgIHJlYWQrKzsKKyAgICAgICAgICAgICAgICBpZiAoY2ggPT0gJ1xuJykgeyAvLyBibGFuayBsaW5lIGluIGhlYWRlcgorICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNoID09ICcgJyl7IC8vIEVuZCBvZiBsZW5ndGggc3RyaW5nCisgICAgICAgICAgICAgICAgICAgIC8vIEdldCBrZXl3b3JkCisgICAgICAgICAgICAgICAgICAgIGZpbmFsIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBjb2xsID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICAgICAgICAgICAgICB3aGlsZSgoY2ggPSBpLnJlYWQoKSkgIT0gLTEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJlYWQrKzsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjaCA9PSAnPScpeyAvLyBlbmQgb2Yga2V5d29yZAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBrZXl3b3JkID0gY29sbC50b1N0cmluZyhDaGFyc2V0TmFtZXMuVVRGXzgpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEdldCByZXN0IG9mIGVudHJ5CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IHJlc3RMZW4gPSBsZW4gLSByZWFkOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXN0TGVuID09IDEpIHsgLy8gb25seSBOTAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWFkZXJzLnJlbW92ZShrZXl3b3JkKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBieXRlW10gcmVzdCA9IG5ldyBieXRlW3Jlc3RMZW5dOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgZ290ID0gSU9VdGlscy5yZWFkRnVsbHkoaSwgcmVzdCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChnb3QgIT0gcmVzdExlbikgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJGYWlsZWQgdG8gcmVhZCAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiUGF4aGVhZGVyLiBFeHBlY3RlZCAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyByZXN0TGVuCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIGJ5dGVzLCByZWFkICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGdvdCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRHJvcCB0cmFpbGluZyBOTAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgdmFsdWUgPSBuZXcgU3RyaW5nKHJlc3QsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdExlbiAtIDEsIENoYXJzZXROYW1lcy5VVEZfOCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlYWRlcnMucHV0KGtleXdvcmQsIHZhbHVlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBjb2xsLndyaXRlKChieXRlKSBjaCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7IC8vIFByb2Nlc3NlZCBzaW5nbGUgaGVhZGVyCisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGxlbiAqPSAxMDsKKyAgICAgICAgICAgICAgICBsZW4gKz0gY2ggLSAnMCc7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoY2ggPT0gLTEpeyAvLyBFT0YKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaGVhZGVyczsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYXBwbHlQYXhIZWFkZXJzVG9DdXJyZW50RW50cnkoZmluYWwgTWFwPFN0cmluZywgU3RyaW5nPiBoZWFkZXJzKSB7CisgICAgICAgIGN1cnJFbnRyeS51cGRhdGVFbnRyeUZyb21QYXhIZWFkZXJzKGhlYWRlcnMpOworCisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkcyB0aGUgc3BhcnNlIGNodW5rcyBmcm9tIHRoZSBjdXJyZW50IGVudHJ5IHRvIHRoZSBzcGFyc2UgY2h1bmtzLAorICAgICAqIGluY2x1ZGluZyBhbnkgYWRkaXRpb25hbCBzcGFyc2UgZW50cmllcyBmb2xsb3dpbmcgdGhlIGN1cnJlbnQgZW50cnkuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIG9uIGVycm9yCisgICAgICoKKyAgICAgKiBAdG9kbyBTcGFyc2UgZmlsZXMgZ2V0IG5vdCB5ZXQgcmVhbGx5IHByb2Nlc3NlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcmVhZE9sZEdOVVNwYXJzZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8qIHdlIGRvIG5vdCByZWFsbHkgcHJvY2VzcyBzcGFyc2UgZmlsZXMgeWV0CisgICAgICAgIHNwYXJzZXMgPSBuZXcgQXJyYXlMaXN0KCk7CisgICAgICAgIHNwYXJzZXMuYWRkQWxsKGN1cnJFbnRyeS5nZXRTcGFyc2VzKCkpOworICAgICAgICAqLworICAgICAgICBpZiAoY3VyckVudHJ5LmlzRXh0ZW5kZWQoKSkgeworICAgICAgICAgICAgVGFyQXJjaGl2ZVNwYXJzZUVudHJ5IGVudHJ5OworICAgICAgICAgICAgZG8geworICAgICAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBoZWFkZXJCdWYgPSBnZXRSZWNvcmQoKTsKKyAgICAgICAgICAgICAgICBpZiAoaGVhZGVyQnVmID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgY3VyckVudHJ5ID0gbnVsbDsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGVudHJ5ID0gbmV3IFRhckFyY2hpdmVTcGFyc2VFbnRyeShoZWFkZXJCdWYpOworICAgICAgICAgICAgICAgIC8qIHdlIGRvIG5vdCByZWFsbHkgcHJvY2VzcyBzcGFyc2UgZmlsZXMgeWV0CisgICAgICAgICAgICAgICAgc3BhcnNlcy5hZGRBbGwoZW50cnkuZ2V0U3BhcnNlcygpKTsKKyAgICAgICAgICAgICAgICAqLworICAgICAgICAgICAgfSB3aGlsZSAoZW50cnkuaXNFeHRlbmRlZCgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgYm9vbGVhbiBpc0RpcmVjdG9yeSgpIHsKKyAgICAgICAgcmV0dXJuIGN1cnJFbnRyeSAhPSBudWxsICYmIGN1cnJFbnRyeS5pc0RpcmVjdG9yeSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5leHQgQXJjaGl2ZSBFbnRyeSBpbiB0aGlzIFN0cmVhbS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5leHQgZW50cnksCisgICAgICogICAgICAgICBvciB7QGNvZGUgbnVsbH0gaWYgdGhlcmUgYXJlIG5vIG1vcmUgZW50cmllcworICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgdGhlIG5leHQgZW50cnkgY291bGQgbm90IGJlIHJlYWQKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQXJjaGl2ZUVudHJ5IGdldE5leHRFbnRyeSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBnZXROZXh0VGFyRW50cnkoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUcmllcyB0byByZWFkIHRoZSBuZXh0IHJlY29yZCByZXdpbmRpbmcgdGhlIHN0cmVhbSBpZiBpdCBpcyBub3QgYSBFT0YgcmVjb3JkLgorICAgICAqCisgICAgICogPHA+VGhpcyBpcyBtZWFudCB0byBwcm90ZWN0IGFnYWluc3QgY2FzZXMgd2hlcmUgYSB0YXIKKyAgICAgKiBpbXBsZW1lbnRhdGlvbiBoYXMgd3JpdHRlbiBvbmx5IG9uZSBFT0YgcmVjb3JkIHdoZW4gdHdvIGFyZQorICAgICAqIGV4cGVjdGVkLiAgQWN0dWFsbHkgdGhpcyB3b24ndCBoZWxwIHNpbmNlIGEgbm9uLWNvbmZvcm1pbmcKKyAgICAgKiBpbXBsZW1lbnRhdGlvbiBsaWtlbHkgd29uJ3QgZmlsbCBmdWxsIGJsb2NrcyBjb25zaXN0aW5nIG9mIC0gYnkKKyAgICAgKiBkZWZhdWx0IC0gdGVuIHJlY29yZHMgZWl0aGVyIHNvIHdlIHByb2JhYmx5IGhhdmUgYWxyZWFkeSByZWFkCisgICAgICogYmV5b25kIHRoZSBhcmNoaXZlIGFueXdheS48L3A+CisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHRyeVRvQ29uc3VtZVNlY29uZEVPRlJlY29yZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJvb2xlYW4gc2hvdWxkUmVzZXQgPSB0cnVlOworICAgICAgICBmaW5hbCBib29sZWFuIG1hcmtlZCA9IGlzLm1hcmtTdXBwb3J0ZWQoKTsKKyAgICAgICAgaWYgKG1hcmtlZCkgeworICAgICAgICAgICAgaXMubWFyayhyZWNvcmRTaXplKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgc2hvdWxkUmVzZXQgPSAhaXNFT0ZSZWNvcmQocmVhZFJlY29yZCgpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmIChzaG91bGRSZXNldCAmJiBtYXJrZWQpIHsKKyAgICAgICAgICAgICAgICBwdXNoZWRCYWNrQnl0ZXMocmVjb3JkU2l6ZSk7CisgICAgICAgICAgICAJaXMucmVzZXQoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGJ5dGVzIGZyb20gdGhlIGN1cnJlbnQgdGFyIGFyY2hpdmUgZW50cnkuCisgICAgICoKKyAgICAgKiBUaGlzIG1ldGhvZCBpcyBhd2FyZSBvZiB0aGUgYm91bmRhcmllcyBvZiB0aGUgY3VycmVudAorICAgICAqIGVudHJ5IGluIHRoZSBhcmNoaXZlIGFuZCB3aWxsIGRlYWwgd2l0aCB0aGVtIGFzIGlmIHRoZXkKKyAgICAgKiB3ZXJlIHRoaXMgc3RyZWFtJ3Mgc3RhcnQgYW5kIEVPRi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBidWYgVGhlIGJ1ZmZlciBpbnRvIHdoaWNoIHRvIHBsYWNlIGJ5dGVzIHJlYWQuCisgICAgICogQHBhcmFtIG9mZnNldCBUaGUgb2Zmc2V0IGF0IHdoaWNoIHRvIHBsYWNlIGJ5dGVzIHJlYWQuCisgICAgICogQHBhcmFtIG51bVRvUmVhZCBUaGUgbnVtYmVyIG9mIGJ5dGVzIHRvIHJlYWQuCisgICAgICogQHJldHVybiBUaGUgbnVtYmVyIG9mIGJ5dGVzIHJlYWQsIG9yIC0xIGF0IEVPRi4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIG9uIGVycm9yCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCByZWFkKGZpbmFsIGJ5dGVbXSBidWYsIGZpbmFsIGludCBvZmZzZXQsIGludCBudW1Ub1JlYWQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgCWludCB0b3RhbFJlYWQgPSAwOworCisgICAgICAgIGlmIChpc0F0RU9GKCkgfHwgaXNEaXJlY3RvcnkoKSB8fCBlbnRyeU9mZnNldCA+PSBlbnRyeVNpemUpIHsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChjdXJyRW50cnkgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiTm8gY3VycmVudCB0YXIgZW50cnkiKTsKKyAgICAgICAgfQorCisgICAgICAgIG51bVRvUmVhZCA9IE1hdGgubWluKG51bVRvUmVhZCwgYXZhaWxhYmxlKCkpOworCisgICAgICAgIHRvdGFsUmVhZCA9IGlzLnJlYWQoYnVmLCBvZmZzZXQsIG51bVRvUmVhZCk7CisKKyAgICAgICAgaWYgKHRvdGFsUmVhZCA9PSAtMSkgeworICAgICAgICAgICAgaWYgKG51bVRvUmVhZCA+IDApIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlRydW5jYXRlZCBUQVIgYXJjaGl2ZSIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgc2V0QXRFT0YodHJ1ZSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBjb3VudCh0b3RhbFJlYWQpOworICAgICAgICAgICAgZW50cnlPZmZzZXQgKz0gdG90YWxSZWFkOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIHRvdGFsUmVhZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXaGV0aGVyIHRoaXMgY2xhc3MgaXMgYWJsZSB0byByZWFkIHRoZSBnaXZlbiBlbnRyeS4KKyAgICAgKgorICAgICAqIDxwPk1heSByZXR1cm4gZmFsc2UgaWYgdGhlIGN1cnJlbnQgZW50cnkgaXMgYSBzcGFyc2UgZmlsZS48L3A+CisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gY2FuUmVhZEVudHJ5RGF0YShmaW5hbCBBcmNoaXZlRW50cnkgYWUpIHsKKyAgICAgICAgaWYgKGFlIGluc3RhbmNlb2YgVGFyQXJjaGl2ZUVudHJ5KSB7CisgICAgICAgICAgICBmaW5hbCBUYXJBcmNoaXZlRW50cnkgdGUgPSAoVGFyQXJjaGl2ZUVudHJ5KSBhZTsKKyAgICAgICAgICAgIHJldHVybiAhdGUuaXNTcGFyc2UoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBjdXJyZW50IFRBUiBBcmNoaXZlIEVudHJ5IHRoYXQgdGhpcyBpbnB1dCBzdHJlYW0gaXMgcHJvY2Vzc2luZworICAgICAqCisgICAgICogQHJldHVybiBUaGUgY3VycmVudCBBcmNoaXZlIEVudHJ5CisgICAgICovCisgICAgcHVibGljIFRhckFyY2hpdmVFbnRyeSBnZXRDdXJyZW50RW50cnkoKSB7CisgICAgICAgIHJldHVybiBjdXJyRW50cnk7CisgICAgfQorCisgICAgcHJvdGVjdGVkIGZpbmFsIHZvaWQgc2V0Q3VycmVudEVudHJ5KGZpbmFsIFRhckFyY2hpdmVFbnRyeSBlKSB7CisgICAgICAgIGN1cnJFbnRyeSA9IGU7CisgICAgfQorCisgICAgcHJvdGVjdGVkIGZpbmFsIGJvb2xlYW4gaXNBdEVPRigpIHsKKyAgICAgICAgcmV0dXJuIGhhc0hpdEVPRjsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgZmluYWwgdm9pZCBzZXRBdEVPRihmaW5hbCBib29sZWFuIGIpIHsKKyAgICAgICAgaGFzSGl0RU9GID0gYjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBpcyBpbnZva2VkIG9uY2UgdGhlIGVuZCBvZiB0aGUgYXJjaGl2ZSBpcyBoaXQsIGl0CisgICAgICogdHJpZXMgdG8gY29uc3VtZSB0aGUgcmVtYWluaW5nIGJ5dGVzIHVuZGVyIHRoZSBhc3N1bXB0aW9uIHRoYXQKKyAgICAgKiB0aGUgdG9vbCBjcmVhdGluZyB0aGlzIGFyY2hpdmUgaGFzIHBhZGRlZCB0aGUgbGFzdCBibG9jay4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgY29uc3VtZVJlbWFpbmRlck9mTGFzdEJsb2NrKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgbG9uZyBieXRlc1JlYWRPZkxhc3RCbG9jayA9IGdldEJ5dGVzUmVhZCgpICUgYmxvY2tTaXplOworICAgICAgICBpZiAoYnl0ZXNSZWFkT2ZMYXN0QmxvY2sgPiAwKSB7CisgICAgICAgICAgICBmaW5hbCBsb25nIHNraXBwZWQgPSBJT1V0aWxzLnNraXAoaXMsIGJsb2NrU2l6ZSAtIGJ5dGVzUmVhZE9mTGFzdEJsb2NrKTsKKyAgICAgICAgICAgIGNvdW50KHNraXBwZWQpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIHRoZSBzaWduYXR1cmUgbWF0Y2hlcyB3aGF0IGlzIGV4cGVjdGVkIGZvciBhIHRhciBmaWxlLgorICAgICAqCisgICAgICogQHBhcmFtIHNpZ25hdHVyZQorICAgICAqICAgICAgICAgICAgdGhlIGJ5dGVzIHRvIGNoZWNrCisgICAgICogQHBhcmFtIGxlbmd0aAorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBieXRlcyB0byBjaGVjaworICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhpcyBzdHJlYW0gaXMgYSB0YXIgYXJjaGl2ZSBzdHJlYW0sIGZhbHNlIG90aGVyd2lzZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBtYXRjaGVzKGZpbmFsIGJ5dGVbXSBzaWduYXR1cmUsIGZpbmFsIGludCBsZW5ndGgpIHsKKyAgICAgICAgaWYgKGxlbmd0aCA8IFRhckNvbnN0YW50cy5WRVJTSU9OX09GRlNFVCtUYXJDb25zdGFudHMuVkVSU0lPTkxFTikgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgaWYgKEFyY2hpdmVVdGlscy5tYXRjaEFzY2lpQnVmZmVyKFRhckNvbnN0YW50cy5NQUdJQ19QT1NJWCwKKyAgICAgICAgICAgICAgICBzaWduYXR1cmUsIFRhckNvbnN0YW50cy5NQUdJQ19PRkZTRVQsIFRhckNvbnN0YW50cy5NQUdJQ0xFTikKKyAgICAgICAgICAgICYmCisgICAgICAgICAgICBBcmNoaXZlVXRpbHMubWF0Y2hBc2NpaUJ1ZmZlcihUYXJDb25zdGFudHMuVkVSU0lPTl9QT1NJWCwKKyAgICAgICAgICAgICAgICBzaWduYXR1cmUsIFRhckNvbnN0YW50cy5WRVJTSU9OX09GRlNFVCwgVGFyQ29uc3RhbnRzLlZFUlNJT05MRU4pCisgICAgICAgICAgICAgICAgKXsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmIChBcmNoaXZlVXRpbHMubWF0Y2hBc2NpaUJ1ZmZlcihUYXJDb25zdGFudHMuTUFHSUNfR05VLAorICAgICAgICAgICAgICAgIHNpZ25hdHVyZSwgVGFyQ29uc3RhbnRzLk1BR0lDX09GRlNFVCwgVGFyQ29uc3RhbnRzLk1BR0lDTEVOKQorICAgICAgICAgICAgJiYKKyAgICAgICAgICAgICgKKyAgICAgICAgICAgICBBcmNoaXZlVXRpbHMubWF0Y2hBc2NpaUJ1ZmZlcihUYXJDb25zdGFudHMuVkVSU0lPTl9HTlVfU1BBQ0UsCisgICAgICAgICAgICAgICAgc2lnbmF0dXJlLCBUYXJDb25zdGFudHMuVkVSU0lPTl9PRkZTRVQsIFRhckNvbnN0YW50cy5WRVJTSU9OTEVOKQorICAgICAgICAgICAgfHwKKyAgICAgICAgICAgIEFyY2hpdmVVdGlscy5tYXRjaEFzY2lpQnVmZmVyKFRhckNvbnN0YW50cy5WRVJTSU9OX0dOVV9aRVJPLAorICAgICAgICAgICAgICAgIHNpZ25hdHVyZSwgVGFyQ29uc3RhbnRzLlZFUlNJT05fT0ZGU0VULCBUYXJDb25zdGFudHMuVkVSU0lPTkxFTikKKyAgICAgICAgICAgICkKKyAgICAgICAgICAgICAgICApeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgLy8gQ09NUFJFU1MtMTA3IC0gcmVjb2duaXNlIEFudCB0YXIgZmlsZXMKKyAgICAgICAgcmV0dXJuIEFyY2hpdmVVdGlscy5tYXRjaEFzY2lpQnVmZmVyKFRhckNvbnN0YW50cy5NQUdJQ19BTlQsCisgICAgICAgICAgICAgICAgc2lnbmF0dXJlLCBUYXJDb25zdGFudHMuTUFHSUNfT0ZGU0VULCBUYXJDb25zdGFudHMuTUFHSUNMRU4pCisgICAgICAgICAgICAgICAgJiYKKyAgICAgICAgICAgICAgICBBcmNoaXZlVXRpbHMubWF0Y2hBc2NpaUJ1ZmZlcihUYXJDb25zdGFudHMuVkVSU0lPTl9BTlQsCisgICAgICAgICAgICAgICAgICAgICAgICBzaWduYXR1cmUsIFRhckNvbnN0YW50cy5WRVJTSU9OX09GRlNFVCwgVGFyQ29uc3RhbnRzLlZFUlNJT05MRU4pOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3Rhci9UYXJBcmNoaXZlT3V0cHV0U3RyZWFtLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvdGFyL1RhckFyY2hpdmVPdXRwdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNzUwZTIyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3Rhci9UYXJBcmNoaXZlT3V0cHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSw2OTkgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnRhcjsKKworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uU3RyaW5nV3JpdGVyOworaW1wb3J0IGphdmEuaW8uVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkRhdGU7CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLkFyY2hpdmVFbnRyeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLkFyY2hpdmVPdXRwdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXAuWmlwRW5jb2Rpbmc7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXAuWmlwRW5jb2RpbmdIZWxwZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLkNoYXJzZXROYW1lczsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuQ291bnRpbmdPdXRwdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLkZpeGVkTGVuZ3RoQmxvY2tPdXRwdXRTdHJlYW07CisKKy8qKgorICogVGhlIFRhck91dHB1dFN0cmVhbSB3cml0ZXMgYSBVTklYIHRhciBhcmNoaXZlIGFzIGFuIE91dHB1dFN0cmVhbS4gTWV0aG9kcyBhcmUgcHJvdmlkZWQgdG8gcHV0CisgKiBlbnRyaWVzLCBhbmQgdGhlbiB3cml0ZSB0aGVpciBjb250ZW50cyBieSB3cml0aW5nIHRvIHRoaXMgc3RyZWFtIHVzaW5nIHdyaXRlKCkuCisgKgorICogPHA+dGFyIGFyY2hpdmVzIGNvbnNpc3Qgb2YgYSBzZXF1ZW5jZSBvZiByZWNvcmRzIG9mIDUxMiBieXRlcyBlYWNoCisgKiB0aGF0IGFyZSBncm91cGVkIGludG8gYmxvY2tzLiBQcmlvciB0byBBcGFjaGUgQ29tbW9ucyBDb21wcmVzcyAxLjE0CisgKiBpdCBoYXMgYmVlbiBwb3NzaWJsZSB0byBjb25maWd1cmUgYSByZWNvcmQgc2l6ZSBkaWZmZXJlbnQgZnJvbSA1MTIKKyAqIGJ5dGVzIGFuZCBhcmJpdHJhcnkgYmxvY2sgc2l6ZXMuIFN0YXJ0aW5nIHdpdGggQ29tcHJlc3MgMS4xNSA1MTIgaXMKKyAqIHRoZSBvbmx5IHZhbGlkIG9wdGlvbiBmb3IgdGhlIHJlY29yZCBzaXplIGFuZCB0aGUgYmxvY2sgc2l6ZSBtdXN0CisgKiBiZSBhIG11bHRpcGxlIG9mIDUxMi4gQWxzbyB0aGUgZGVmYXVsdCBibG9jayBzaXplIGNoYW5nZWQgZnJvbQorICogMTAyNDAgYnl0ZXMgcHJpb3IgdG8gQ29tcHJlc3MgMS4xNSB0byA1MTIgYnl0ZXMgd2l0aCBDb21wcmVzcworICogMS4xNS48L3A+CisgKgorICogQE5vdFRocmVhZFNhZmUKKyAqLworcHVibGljIGNsYXNzIFRhckFyY2hpdmVPdXRwdXRTdHJlYW0gZXh0ZW5kcyBBcmNoaXZlT3V0cHV0U3RyZWFtIHsKKworICAgIC8qKgorICAgICAqIEZhaWwgaWYgYSBsb25nIGZpbGUgbmFtZSBpcyByZXF1aXJlZCBpbiB0aGUgYXJjaGl2ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HRklMRV9FUlJPUiA9IDA7CisKKyAgICAvKioKKyAgICAgKiBMb25nIHBhdGhzIHdpbGwgYmUgdHJ1bmNhdGVkIGluIHRoZSBhcmNoaXZlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdGSUxFX1RSVU5DQVRFID0gMTsKKworICAgIC8qKgorICAgICAqIEdOVSB0YXIgZXh0ZW5zaW9ucyBhcmUgdXNlZCB0byBzdG9yZSBsb25nIGZpbGUgbmFtZXMgaW4gdGhlIGFyY2hpdmUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR0ZJTEVfR05VID0gMjsKKworICAgIC8qKgorICAgICAqIFBPU0lYL1BBWCBleHRlbnNpb25zIGFyZSB1c2VkIHRvIHN0b3JlIGxvbmcgZmlsZSBuYW1lcyBpbiB0aGUgYXJjaGl2ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HRklMRV9QT1NJWCA9IDM7CisKKyAgICAvKioKKyAgICAgKiBGYWlsIGlmIGEgYmlnIG51bWJlciAoZS5nLiBzaXplICZndDsgOEdpQikgaXMgcmVxdWlyZWQgaW4gdGhlIGFyY2hpdmUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQklHTlVNQkVSX0VSUk9SID0gMDsKKworICAgIC8qKgorICAgICAqIHN0YXIvR05VIHRhci9CU0QgdGFyIGV4dGVuc2lvbnMgYXJlIHVzZWQgdG8gc3RvcmUgYmlnIG51bWJlciBpbiB0aGUgYXJjaGl2ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCSUdOVU1CRVJfU1RBUiA9IDE7CisKKyAgICAvKioKKyAgICAgKiBQT1NJWC9QQVggZXh0ZW5zaW9ucyBhcmUgdXNlZCB0byBzdG9yZSBiaWcgbnVtYmVycyBpbiB0aGUgYXJjaGl2ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCSUdOVU1CRVJfUE9TSVggPSAyOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBSRUNPUkRfU0laRSA9IDUxMjsKKworICAgIHByaXZhdGUgbG9uZyBjdXJyU2l6ZTsKKyAgICBwcml2YXRlIFN0cmluZyBjdXJyTmFtZTsKKyAgICBwcml2YXRlIGxvbmcgY3VyckJ5dGVzOworICAgIHByaXZhdGUgZmluYWwgYnl0ZVtdIHJlY29yZEJ1ZjsKKyAgICBwcml2YXRlIGludCBsb25nRmlsZU1vZGUgPSBMT05HRklMRV9FUlJPUjsKKyAgICBwcml2YXRlIGludCBiaWdOdW1iZXJNb2RlID0gQklHTlVNQkVSX0VSUk9SOworICAgIHByaXZhdGUgaW50IHJlY29yZHNXcml0dGVuOworICAgIHByaXZhdGUgZmluYWwgaW50IHJlY29yZHNQZXJCbG9jazsKKworICAgIHByaXZhdGUgYm9vbGVhbiBjbG9zZWQgPSBmYWxzZTsKKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyBpZiBwdXRBcmNoaXZlRW50cnkgaGFzIGJlZW4gY2FsbGVkIHdpdGhvdXQgY2xvc2VBcmNoaXZlRW50cnkKKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gaGF2ZVVuY2xvc2VkRW50cnkgPSBmYWxzZTsKKworICAgIC8qKgorICAgICAqIGluZGljYXRlcyBpZiB0aGlzIGFyY2hpdmUgaXMgZmluaXNoZWQKKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gZmluaXNoZWQgPSBmYWxzZTsKKworICAgIHByaXZhdGUgZmluYWwgRml4ZWRMZW5ndGhCbG9ja091dHB1dFN0cmVhbSBvdXQ7CisgICAgcHJpdmF0ZSBmaW5hbCBDb3VudGluZ091dHB1dFN0cmVhbSBjb3VudGluZ091dDsKKworICAgIHByaXZhdGUgZmluYWwgWmlwRW5jb2RpbmcgemlwRW5jb2Rpbmc7CisKKyAgICAvLyB0aGUgcHJvdmlkZWQgZW5jb2RpbmcgKGZvciB1bml0IHRlc3RzKQorICAgIGZpbmFsIFN0cmluZyBlbmNvZGluZzsKKworICAgIHByaXZhdGUgYm9vbGVhbiBhZGRQYXhIZWFkZXJzRm9yTm9uQXNjaWlOYW1lcyA9IGZhbHNlOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFppcEVuY29kaW5nIEFTQ0lJID0KKyAgICAgICAgWmlwRW5jb2RpbmdIZWxwZXIuZ2V0WmlwRW5jb2RpbmcoIkFTQ0lJIik7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQkxPQ0tfU0laRV9VTlNQRUNJRklFRCA9IC01MTE7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvciBmb3IgVGFyQXJjaGl2ZU91dHB1dFN0cmVhbS4KKyAgICAgKgorICAgICAqIDxwPlVzZXMgYSBibG9jayBzaXplIG9mIDUxMiBieXRlcy48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gb3MgdGhlIG91dHB1dCBzdHJlYW0gdG8gdXNlCisgICAgICovCisgICAgcHVibGljIFRhckFyY2hpdmVPdXRwdXRTdHJlYW0oZmluYWwgT3V0cHV0U3RyZWFtIG9zKSB7CisgICAgICAgIHRoaXMob3MsIEJMT0NLX1NJWkVfVU5TUEVDSUZJRUQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yIGZvciBUYXJBcmNoaXZlT3V0cHV0U3RyZWFtLgorICAgICAqCisgICAgICogPHA+VXNlcyBhIGJsb2NrIHNpemUgb2YgNTEyIGJ5dGVzLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvcyB0aGUgb3V0cHV0IHN0cmVhbSB0byB1c2UKKyAgICAgKiBAcGFyYW0gZW5jb2RpbmcgbmFtZSBvZiB0aGUgZW5jb2RpbmcgdG8gdXNlIGZvciBmaWxlIG5hbWVzCisgICAgICogQHNpbmNlIDEuNAorICAgICAqLworICAgIHB1YmxpYyBUYXJBcmNoaXZlT3V0cHV0U3RyZWFtKGZpbmFsIE91dHB1dFN0cmVhbSBvcywgZmluYWwgU3RyaW5nIGVuY29kaW5nKSB7CisgICAgICAgIHRoaXMob3MsIEJMT0NLX1NJWkVfVU5TUEVDSUZJRUQsIGVuY29kaW5nKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvciBmb3IgVGFyQXJjaGl2ZU91dHB1dFN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvcyB0aGUgb3V0cHV0IHN0cmVhbSB0byB1c2UKKyAgICAgKiBAcGFyYW0gYmxvY2tTaXplIHRoZSBibG9jayBzaXplIHRvIHVzZS4gTXVzdCBiZSBhIG11bHRpcGxlIG9mIDUxMiBieXRlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgVGFyQXJjaGl2ZU91dHB1dFN0cmVhbShmaW5hbCBPdXRwdXRTdHJlYW0gb3MsIGZpbmFsIGludCBibG9ja1NpemUpIHsKKyAgICAgICAgdGhpcyhvcywgYmxvY2tTaXplLCBudWxsKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yIGZvciBUYXJBcmNoaXZlT3V0cHV0U3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtIG9zIHRoZSBvdXRwdXQgc3RyZWFtIHRvIHVzZQorICAgICAqIEBwYXJhbSBibG9ja1NpemUgdGhlIGJsb2NrIHNpemUgdG8gdXNlCisgICAgICogQHBhcmFtIHJlY29yZFNpemUgdGhlIHJlY29yZCBzaXplIHRvIHVzZS4gTXVzdCBiZSA1MTIgYnl0ZXMuCisgICAgICogQGRlcHJlY2F0ZWQgcmVjb3JkU2l6ZSBtdXN0IGFsd2F5cyBiZSA1MTIgYnl0ZXMuIEFuIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3aWxsIGJlIHRocm93bgorICAgICAqIGlmIGFueSBvdGhlciB2YWx1ZSBpcyB1c2VkCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgVGFyQXJjaGl2ZU91dHB1dFN0cmVhbShmaW5hbCBPdXRwdXRTdHJlYW0gb3MsIGZpbmFsIGludCBibG9ja1NpemUsCisgICAgICAgIGZpbmFsIGludCByZWNvcmRTaXplKSB7CisgICAgICAgIHRoaXMob3MsIGJsb2NrU2l6ZSwgcmVjb3JkU2l6ZSwgbnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IgZm9yIFRhckFyY2hpdmVPdXRwdXRTdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3MgdGhlIG91dHB1dCBzdHJlYW0gdG8gdXNlCisgICAgICogQHBhcmFtIGJsb2NrU2l6ZSB0aGUgYmxvY2sgc2l6ZSB0byB1c2UgLiBNdXN0IGJlIGEgbXVsdGlwbGUgb2YgNTEyIGJ5dGVzLgorICAgICAqIEBwYXJhbSByZWNvcmRTaXplIHRoZSByZWNvcmQgc2l6ZSB0byB1c2UuIE11c3QgYmUgNTEyIGJ5dGVzLgorICAgICAqIEBwYXJhbSBlbmNvZGluZyBuYW1lIG9mIHRoZSBlbmNvZGluZyB0byB1c2UgZm9yIGZpbGUgbmFtZXMKKyAgICAgKiBAc2luY2UgMS40CisgICAgICogQGRlcHJlY2F0ZWQgcmVjb3JkU2l6ZSBtdXN0IGFsd2F5cyBiZSA1MTIgYnl0ZXMuIEFuIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3aWxsIGJlIHRocm93bgorICAgICAqIGlmIGFueSBvdGhlciB2YWx1ZSBpcyB1c2VkLgorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIFRhckFyY2hpdmVPdXRwdXRTdHJlYW0oZmluYWwgT3V0cHV0U3RyZWFtIG9zLCBmaW5hbCBpbnQgYmxvY2tTaXplLAorICAgICAgICBmaW5hbCBpbnQgcmVjb3JkU2l6ZSwgZmluYWwgU3RyaW5nIGVuY29kaW5nKSB7CisgICAgICAgIHRoaXMob3MsIGJsb2NrU2l6ZSwgZW5jb2RpbmcpOworICAgICAgICBpZiAocmVjb3JkU2l6ZSAhPSBSRUNPUkRfU0laRSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAiVGFyIHJlY29yZCBzaXplIG11c3QgYWx3YXlzIGJlIDUxMiBieXRlcy4gQXR0ZW1wdCB0byBzZXQgc2l6ZSBvZiAiICsgcmVjb3JkU2l6ZSk7CisgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yIGZvciBUYXJBcmNoaXZlT3V0cHV0U3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtIG9zIHRoZSBvdXRwdXQgc3RyZWFtIHRvIHVzZQorICAgICAqIEBwYXJhbSBibG9ja1NpemUgdGhlIGJsb2NrIHNpemUgdG8gdXNlLiBNdXN0IGJlIGEgbXVsdGlwbGUgb2YgNTEyIGJ5dGVzLgorICAgICAqIEBwYXJhbSBlbmNvZGluZyBuYW1lIG9mIHRoZSBlbmNvZGluZyB0byB1c2UgZm9yIGZpbGUgbmFtZXMKKyAgICAgKiBAc2luY2UgMS40CisgICAgICovCisgICAgcHVibGljIFRhckFyY2hpdmVPdXRwdXRTdHJlYW0oZmluYWwgT3V0cHV0U3RyZWFtIG9zLCBmaW5hbCBpbnQgYmxvY2tTaXplLAorICAgICAgICBmaW5hbCBTdHJpbmcgZW5jb2RpbmcpIHsKKyAgICAgICAgaW50IHJlYWxCbG9ja1NpemU7CisgICAgICAgIGlmIChCTE9DS19TSVpFX1VOU1BFQ0lGSUVEID09IGJsb2NrU2l6ZSkgeworICAgICAgICAgICAgcmVhbEJsb2NrU2l6ZSA9IFJFQ09SRF9TSVpFOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmVhbEJsb2NrU2l6ZSA9IGJsb2NrU2l6ZTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChyZWFsQmxvY2tTaXplIDw9MCB8fCByZWFsQmxvY2tTaXplICUgUkVDT1JEX1NJWkUgIT0gMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiQmxvY2sgc2l6ZSBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgNTEyIGJ5dGVzLiBBdHRlbXB0IHRvIHVzZSBzZXQgc2l6ZSBvZiAiICsgYmxvY2tTaXplKTsKKyAgICAgICAgfQorICAgICAgICBvdXQgPSBuZXcgRml4ZWRMZW5ndGhCbG9ja091dHB1dFN0cmVhbShjb3VudGluZ091dCA9IG5ldyBDb3VudGluZ091dHB1dFN0cmVhbShvcyksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFQ09SRF9TSVpFKTsKKyAgICAgICAgdGhpcy5lbmNvZGluZyA9IGVuY29kaW5nOworICAgICAgICB0aGlzLnppcEVuY29kaW5nID0gWmlwRW5jb2RpbmdIZWxwZXIuZ2V0WmlwRW5jb2RpbmcoZW5jb2RpbmcpOworCisgICAgICAgIHRoaXMucmVjb3JkQnVmID0gbmV3IGJ5dGVbUkVDT1JEX1NJWkVdOworICAgICAgICB0aGlzLnJlY29yZHNQZXJCbG9jayA9IHJlYWxCbG9ja1NpemUgLyBSRUNPUkRfU0laRTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIGxvbmcgZmlsZSBtb2RlLiBUaGlzIGNhbiBiZSBMT05HRklMRV9FUlJPUigwKSwgTE9OR0ZJTEVfVFJVTkNBVEUoMSkgb3IKKyAgICAgKiBMT05HRklMRV9HTlUoMikuIFRoaXMgc3BlY2lmaWVzIHRoZSB0cmVhdG1lbnQgb2YgbG9uZyBmaWxlIG5hbWVzIChuYW1lcyAmZ3Q7PQorICAgICAqIFRhckNvbnN0YW50cy5OQU1FTEVOKS4gRGVmYXVsdCBpcyBMT05HRklMRV9FUlJPUi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsb25nRmlsZU1vZGUgdGhlIG1vZGUgdG8gdXNlCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TG9uZ0ZpbGVNb2RlKGZpbmFsIGludCBsb25nRmlsZU1vZGUpIHsKKyAgICAgICAgdGhpcy5sb25nRmlsZU1vZGUgPSBsb25nRmlsZU1vZGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBiaWcgbnVtYmVyIG1vZGUuIFRoaXMgY2FuIGJlIEJJR05VTUJFUl9FUlJPUigwKSwgQklHTlVNQkVSX1BPU0lYKDEpIG9yCisgICAgICogQklHTlVNQkVSX1NUQVIoMikuIFRoaXMgc3BlY2lmaWVzIHRoZSB0cmVhdG1lbnQgb2YgYmlnIGZpbGVzIChzaXplcyAmZ3Q7CisgICAgICogVGFyQ29uc3RhbnRzLk1BWFNJWkUpIGFuZCBvdGhlciBudW1lcmljIHZhbHVlcyB0byBiaWcgdG8gZml0IGludG8gYSB0cmFkaXRpb25hbCB0YXIgaGVhZGVyLgorICAgICAqIERlZmF1bHQgaXMgQklHTlVNQkVSX0VSUk9SLgorICAgICAqCisgICAgICogQHBhcmFtIGJpZ051bWJlck1vZGUgdGhlIG1vZGUgdG8gdXNlCisgICAgICogQHNpbmNlIDEuNAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEJpZ051bWJlck1vZGUoZmluYWwgaW50IGJpZ051bWJlck1vZGUpIHsKKyAgICAgICAgdGhpcy5iaWdOdW1iZXJNb2RlID0gYmlnTnVtYmVyTW9kZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXaGV0aGVyIHRvIGFkZCBhIFBBWCBleHRlbnNpb24gaGVhZGVyIGZvciBub24tQVNDSUkgZmlsZSBuYW1lcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBiIHdoZXRoZXIgdG8gYWRkIGEgUEFYIGV4dGVuc2lvbiBoZWFkZXIgZm9yIG5vbi1BU0NJSSBmaWxlIG5hbWVzLgorICAgICAqIEBzaW5jZSAxLjQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRBZGRQYXhIZWFkZXJzRm9yTm9uQXNjaWlOYW1lcyhmaW5hbCBib29sZWFuIGIpIHsKKyAgICAgICAgYWRkUGF4SGVhZGVyc0Zvck5vbkFzY2lpTmFtZXMgPSBiOworICAgIH0KKworICAgIEBEZXByZWNhdGVkCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRDb3VudCgpIHsKKyAgICAgICAgcmV0dXJuIChpbnQpIGdldEJ5dGVzV3JpdHRlbigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBsb25nIGdldEJ5dGVzV3JpdHRlbigpIHsKKyAgICAgICAgcmV0dXJuIGNvdW50aW5nT3V0LmdldEJ5dGVzV3JpdHRlbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVuZHMgdGhlIFRBUiBhcmNoaXZlIHdpdGhvdXQgY2xvc2luZyB0aGUgdW5kZXJseWluZyBPdXRwdXRTdHJlYW0uCisgICAgICoKKyAgICAgKiBBbiBhcmNoaXZlIGNvbnNpc3RzIG9mIGEgc2VyaWVzIG9mIGZpbGUgZW50cmllcyB0ZXJtaW5hdGVkIGJ5IGFuCisgICAgICogZW5kLW9mLWFyY2hpdmUgZW50cnksIHdoaWNoIGNvbnNpc3RzIG9mIHR3byA1MTIgYmxvY2tzIG9mIHplcm8gYnl0ZXMuCisgICAgICogUE9TSVguMSByZXF1aXJlcyB0d28gRU9GIHJlY29yZHMsIGxpa2Ugc29tZSBvdGhlciBpbXBsZW1lbnRhdGlvbnMuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIG9uIGVycm9yCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZmluaXNoKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGZpbmlzaGVkKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlRoaXMgYXJjaGl2ZSBoYXMgYWxyZWFkeSBiZWVuIGZpbmlzaGVkIik7CisgICAgICAgIH0KKworICAgICAgICBpZiAoaGF2ZVVuY2xvc2VkRW50cnkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiVGhpcyBhcmNoaXZlIGNvbnRhaW5zIHVuY2xvc2VkIGVudHJpZXMuIik7CisgICAgICAgIH0KKyAgICAgICAgd3JpdGVFT0ZSZWNvcmQoKTsKKyAgICAgICAgd3JpdGVFT0ZSZWNvcmQoKTsKKyAgICAgICAgcGFkQXNOZWVkZWQoKTsKKyAgICAgICAgb3V0LmZsdXNoKCk7CisgICAgICAgIGZpbmlzaGVkID0gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbG9zZXMgdGhlIHVuZGVybHlpbmcgT3V0cHV0U3RyZWFtLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBvbiBlcnJvcgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlmICghZmluaXNoZWQpIHsKKyAgICAgICAgICAgICAgICBmaW5pc2goKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmICghY2xvc2VkKSB7CisgICAgICAgICAgICAgICAgb3V0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgY2xvc2VkID0gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgcmVjb3JkIHNpemUgYmVpbmcgdXNlZCBieSB0aGlzIHN0cmVhbSdzIFRhckJ1ZmZlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhlIFRhckJ1ZmZlciByZWNvcmQgc2l6ZS4KKyAgICAgKiBAZGVwcmVjYXRlZAorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIGludCBnZXRSZWNvcmRTaXplKCkgeworICAgICAgICByZXR1cm4gUkVDT1JEX1NJWkU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHV0IGFuIGVudHJ5IG9uIHRoZSBvdXRwdXQgc3RyZWFtLiBUaGlzIHdyaXRlcyB0aGUgZW50cnkncyBoZWFkZXIgcmVjb3JkIGFuZCBwb3NpdGlvbnMgdGhlCisgICAgICogb3V0cHV0IHN0cmVhbSBmb3Igd3JpdGluZyB0aGUgY29udGVudHMgb2YgdGhlIGVudHJ5LiBPbmNlIHRoaXMgbWV0aG9kIGlzIGNhbGxlZCwgdGhlIHN0cmVhbQorICAgICAqIGlzIHJlYWR5IGZvciBjYWxscyB0byB3cml0ZSgpIHRvIHdyaXRlIHRoZSBlbnRyeSdzIGNvbnRlbnRzLiBPbmNlIHRoZSBjb250ZW50cyBhcmUgd3JpdHRlbiwKKyAgICAgKiBjbG9zZUFyY2hpdmVFbnRyeSgpIDxCPk1VU1Q8L0I+IGJlIGNhbGxlZCB0byBlbnN1cmUgdGhhdCBhbGwgYnVmZmVyZWQgZGF0YSBpcyBjb21wbGV0ZWx5CisgICAgICogd3JpdHRlbiB0byB0aGUgb3V0cHV0IHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcmNoaXZlRW50cnkgVGhlIFRhckVudHJ5IHRvIGJlIHdyaXR0ZW4gdG8gdGhlIGFyY2hpdmUuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBvbiBlcnJvcgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIGlmIGFyY2hpdmVFbnRyeSBpcyBub3QgYW4gaW5zdGFuY2Ugb2YgVGFyQXJjaGl2ZUVudHJ5CisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcHV0QXJjaGl2ZUVudHJ5KGZpbmFsIEFyY2hpdmVFbnRyeSBhcmNoaXZlRW50cnkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChmaW5pc2hlZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJTdHJlYW0gaGFzIGFscmVhZHkgYmVlbiBmaW5pc2hlZCIpOworICAgICAgICB9CisgICAgICAgIGZpbmFsIFRhckFyY2hpdmVFbnRyeSBlbnRyeSA9IChUYXJBcmNoaXZlRW50cnkpIGFyY2hpdmVFbnRyeTsKKyAgICAgICAgaWYgKGVudHJ5LmlzR2xvYmFsUGF4SGVhZGVyKCkpIHsKKyAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBkYXRhID0gZW5jb2RlRXh0ZW5kZWRQYXhIZWFkZXJzQ29udGVudHMoZW50cnkuZ2V0RXh0cmFQYXhIZWFkZXJzKCkpOworICAgICAgICAgICAgZW50cnkuc2V0U2l6ZShkYXRhLmxlbmd0aCk7CisgICAgICAgICAgICBlbnRyeS53cml0ZUVudHJ5SGVhZGVyKHJlY29yZEJ1ZiwgemlwRW5jb2RpbmcsIGJpZ051bWJlck1vZGUgPT0gQklHTlVNQkVSX1NUQVIpOworICAgICAgICAgICAgd3JpdGVSZWNvcmQocmVjb3JkQnVmKTsKKyAgICAgICAgICAgIGN1cnJTaXplPSBlbnRyeS5nZXRTaXplKCk7CisgICAgICAgICAgICBjdXJyQnl0ZXMgPSAwOworICAgICAgICAgICAgdGhpcy5oYXZlVW5jbG9zZWRFbnRyeSA9IHRydWU7CisgICAgICAgICAgICB3cml0ZShkYXRhKTsKKyAgICAgICAgICAgIGNsb3NlQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBmaW5hbCBNYXA8U3RyaW5nLCBTdHJpbmc+IHBheEhlYWRlcnMgPSBuZXcgSGFzaE1hcDw+KCk7CisgICAgICAgICAgICBmaW5hbCBTdHJpbmcgZW50cnlOYW1lID0gZW50cnkuZ2V0TmFtZSgpOworICAgICAgICAgICAgZmluYWwgYm9vbGVhbiBwYXhIZWFkZXJDb250YWluc1BhdGggPSBoYW5kbGVMb25nTmFtZShlbnRyeSwgZW50cnlOYW1lLCBwYXhIZWFkZXJzLCAicGF0aCIsCisgICAgICAgICAgICAgICAgVGFyQ29uc3RhbnRzLkxGX0dOVVRZUEVfTE9OR05BTUUsICJmaWxlIG5hbWUiKTsKKworICAgICAgICAgICAgZmluYWwgU3RyaW5nIGxpbmtOYW1lID0gZW50cnkuZ2V0TGlua05hbWUoKTsKKyAgICAgICAgICAgIGZpbmFsIGJvb2xlYW4gcGF4SGVhZGVyQ29udGFpbnNMaW5rUGF0aCA9IGxpbmtOYW1lICE9IG51bGwgJiYgbGlua05hbWUubGVuZ3RoKCkgPiAwCisgICAgICAgICAgICAgICAgJiYgaGFuZGxlTG9uZ05hbWUoZW50cnksIGxpbmtOYW1lLCBwYXhIZWFkZXJzLCAibGlua3BhdGgiLAorICAgICAgICAgICAgICAgIFRhckNvbnN0YW50cy5MRl9HTlVUWVBFX0xPTkdMSU5LLCAibGluayBuYW1lIik7CisKKyAgICAgICAgICAgIGlmIChiaWdOdW1iZXJNb2RlID09IEJJR05VTUJFUl9QT1NJWCkgeworICAgICAgICAgICAgICAgIGFkZFBheEhlYWRlcnNGb3JCaWdOdW1iZXJzKHBheEhlYWRlcnMsIGVudHJ5KTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoYmlnTnVtYmVyTW9kZSAhPSBCSUdOVU1CRVJfU1RBUikgeworICAgICAgICAgICAgICAgIGZhaWxGb3JCaWdOdW1iZXJzKGVudHJ5KTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKGFkZFBheEhlYWRlcnNGb3JOb25Bc2NpaU5hbWVzICYmICFwYXhIZWFkZXJDb250YWluc1BhdGgKKyAgICAgICAgICAgICAgICAmJiAhQVNDSUkuY2FuRW5jb2RlKGVudHJ5TmFtZSkpIHsKKyAgICAgICAgICAgICAgICBwYXhIZWFkZXJzLnB1dCgicGF0aCIsIGVudHJ5TmFtZSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChhZGRQYXhIZWFkZXJzRm9yTm9uQXNjaWlOYW1lcyAmJiAhcGF4SGVhZGVyQ29udGFpbnNMaW5rUGF0aAorICAgICAgICAgICAgICAgICYmIChlbnRyeS5pc0xpbmsoKSB8fCBlbnRyeS5pc1N5bWJvbGljTGluaygpKQorICAgICAgICAgICAgICAgICYmICFBU0NJSS5jYW5FbmNvZGUobGlua05hbWUpKSB7CisgICAgICAgICAgICAgICAgcGF4SGVhZGVycy5wdXQoImxpbmtwYXRoIiwgbGlua05hbWUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcGF4SGVhZGVycy5wdXRBbGwoZW50cnkuZ2V0RXh0cmFQYXhIZWFkZXJzKCkpOworCisgICAgICAgICAgICBpZiAocGF4SGVhZGVycy5zaXplKCkgPiAwKSB7CisgICAgICAgICAgICAgICAgd3JpdGVQYXhIZWFkZXJzKGVudHJ5LCBlbnRyeU5hbWUsIHBheEhlYWRlcnMpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBlbnRyeS53cml0ZUVudHJ5SGVhZGVyKHJlY29yZEJ1ZiwgemlwRW5jb2RpbmcsIGJpZ051bWJlck1vZGUgPT0gQklHTlVNQkVSX1NUQVIpOworICAgICAgICAgICAgd3JpdGVSZWNvcmQocmVjb3JkQnVmKTsKKworICAgICAgICAgICAgY3VyckJ5dGVzID0gMDsKKworICAgICAgICAgICAgaWYgKGVudHJ5LmlzRGlyZWN0b3J5KCkpIHsKKyAgICAgICAgICAgICAgICBjdXJyU2l6ZSA9IDA7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGN1cnJTaXplID0gZW50cnkuZ2V0U2l6ZSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgY3Vyck5hbWUgPSBlbnRyeU5hbWU7CisgICAgICAgICAgICBoYXZlVW5jbG9zZWRFbnRyeSA9IHRydWU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbG9zZSBhbiBlbnRyeS4gVGhpcyBtZXRob2QgTVVTVCBiZSBjYWxsZWQgZm9yIGFsbCBmaWxlIGVudHJpZXMgdGhhdCBjb250YWluIGRhdGEuIFRoZSByZWFzb24KKyAgICAgKiBpcyB0aGF0IHdlIG11c3QgYnVmZmVyIGRhdGEgd3JpdHRlbiB0byB0aGUgc3RyZWFtIGluIG9yZGVyIHRvIHNhdGlzZnkgdGhlIGJ1ZmZlcidzIHJlY29yZAorICAgICAqIGJhc2VkIHdyaXRlcy4gVGh1cywgdGhlcmUgbWF5IGJlIGRhdGEgZnJhZ21lbnRzIHN0aWxsIGJlaW5nIGFzc2VtYmxlZCB0aGF0IG11c3QgYmUgd3JpdHRlbiB0bworICAgICAqIHRoZSBvdXRwdXQgc3RyZWFtIGJlZm9yZSB0aGlzIGVudHJ5IGlzIGNsb3NlZCBhbmQgdGhlIG5leHQgZW50cnkgd3JpdHRlbi4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gb24gZXJyb3IKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbG9zZUFyY2hpdmVFbnRyeSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChmaW5pc2hlZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJTdHJlYW0gaGFzIGFscmVhZHkgYmVlbiBmaW5pc2hlZCIpOworICAgICAgICB9CisgICAgICAgIGlmICghaGF2ZVVuY2xvc2VkRW50cnkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiTm8gY3VycmVudCBlbnRyeSB0byBjbG9zZSIpOworICAgICAgICB9CisgICAgICAgIG91dC5mbHVzaEJsb2NrKCk7CisgICAgICAgIGlmIChjdXJyQnl0ZXMgPCBjdXJyU2l6ZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJlbnRyeSAnIiArIGN1cnJOYW1lICsgIicgY2xvc2VkIGF0ICciCisgICAgICAgICAgICAgICAgKyBjdXJyQnl0ZXMKKyAgICAgICAgICAgICAgICArICInIGJlZm9yZSB0aGUgJyIgKyBjdXJyU2l6ZQorICAgICAgICAgICAgICAgICsgIicgYnl0ZXMgc3BlY2lmaWVkIGluIHRoZSBoZWFkZXIgd2VyZSB3cml0dGVuIik7CisgICAgICAgIH0KKyAgICAgICAgcmVjb3Jkc1dyaXR0ZW4gKz0gKGN1cnJTaXplIC8gUkVDT1JEX1NJWkUpOworICAgICAgICBpZiAoMCAhPSBjdXJyU2l6ZSAlIFJFQ09SRF9TSVpFKSB7CisgICAgICAgICAgICByZWNvcmRzV3JpdHRlbisrOworICAgICAgICB9CisgICAgICAgIGhhdmVVbmNsb3NlZEVudHJ5ID0gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIGJ5dGVzIHRvIHRoZSBjdXJyZW50IHRhciBhcmNoaXZlIGVudHJ5LiBUaGlzIG1ldGhvZCBpcyBhd2FyZSBvZiB0aGUgY3VycmVudCBlbnRyeSBhbmQKKyAgICAgKiB3aWxsIHRocm93IGFuIGV4Y2VwdGlvbiBpZiB5b3UgYXR0ZW1wdCB0byB3cml0ZSBieXRlcyBwYXN0IHRoZSBsZW5ndGggc3BlY2lmaWVkIGZvciB0aGUKKyAgICAgKiBjdXJyZW50IGVudHJ5LgorICAgICAqCisgICAgICogQHBhcmFtIHdCdWYgVGhlIGJ1ZmZlciB0byB3cml0ZSB0byB0aGUgYXJjaGl2ZS4KKyAgICAgKiBAcGFyYW0gd09mZnNldCBUaGUgb2Zmc2V0IGluIHRoZSBidWZmZXIgZnJvbSB3aGljaCB0byBnZXQgYnl0ZXMuCisgICAgICogQHBhcmFtIG51bVRvV3JpdGUgVGhlIG51bWJlciBvZiBieXRlcyB0byB3cml0ZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIG9uIGVycm9yCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGUoZmluYWwgYnl0ZVtdIHdCdWYsIGludCB3T2Zmc2V0LCBpbnQgbnVtVG9Xcml0ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFoYXZlVW5jbG9zZWRFbnRyeSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiTm8gY3VycmVudCB0YXIgZW50cnkiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoY3VyckJ5dGVzICsgbnVtVG9Xcml0ZSA+IGN1cnJTaXplKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oInJlcXVlc3QgdG8gd3JpdGUgJyIgKyBudW1Ub1dyaXRlCisgICAgICAgICAgICAgICAgKyAiJyBieXRlcyBleGNlZWRzIHNpemUgaW4gaGVhZGVyIG9mICciCisgICAgICAgICAgICAgICAgKyBjdXJyU2l6ZSArICInIGJ5dGVzIGZvciBlbnRyeSAnIgorICAgICAgICAgICAgICAgICsgY3Vyck5hbWUgKyAiJyIpOworICAgICAgICB9CisgICAgICAgIG91dC53cml0ZSh3QnVmLCB3T2Zmc2V0LCBudW1Ub1dyaXRlKTsKKyAgICAgICAgY3VyckJ5dGVzICs9IG51bVRvV3JpdGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIGEgUEFYIGV4dGVuZGVkIGhlYWRlciB3aXRoIHRoZSBnaXZlbiBtYXAgYXMgY29udGVudHMuCisgICAgICoKKyAgICAgKiBAc2luY2UgMS40CisgICAgICovCisgICAgdm9pZCB3cml0ZVBheEhlYWRlcnMoZmluYWwgVGFyQXJjaGl2ZUVudHJ5IGVudHJ5LAorICAgICAgICBmaW5hbCBTdHJpbmcgZW50cnlOYW1lLAorICAgICAgICBmaW5hbCBNYXA8U3RyaW5nLCBTdHJpbmc+IGhlYWRlcnMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBuYW1lID0gIi4vUGF4SGVhZGVycy5YLyIgKyBzdHJpcFRvN0JpdHMoZW50cnlOYW1lKTsKKyAgICAgICAgaWYgKG5hbWUubGVuZ3RoKCkgPj0gVGFyQ29uc3RhbnRzLk5BTUVMRU4pIHsKKyAgICAgICAgICAgIG5hbWUgPSBuYW1lLnN1YnN0cmluZygwLCBUYXJDb25zdGFudHMuTkFNRUxFTiAtIDEpOworICAgICAgICB9CisgICAgICAgIGZpbmFsIFRhckFyY2hpdmVFbnRyeSBwZXggPSBuZXcgVGFyQXJjaGl2ZUVudHJ5KG5hbWUsCisgICAgICAgICAgICBUYXJDb25zdGFudHMuTEZfUEFYX0VYVEVOREVEX0hFQURFUl9MQyk7CisgICAgICAgIHRyYW5zZmVyTW9kVGltZShlbnRyeSwgcGV4KTsKKworICAgICAgICBmaW5hbCBieXRlW10gZGF0YSA9IGVuY29kZUV4dGVuZGVkUGF4SGVhZGVyc0NvbnRlbnRzKGhlYWRlcnMpOworICAgICAgICBwZXguc2V0U2l6ZShkYXRhLmxlbmd0aCk7CisgICAgICAgIHB1dEFyY2hpdmVFbnRyeShwZXgpOworICAgICAgICB3cml0ZShkYXRhKTsKKyAgICAgICAgY2xvc2VBcmNoaXZlRW50cnkoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIGJ5dGVbXSBlbmNvZGVFeHRlbmRlZFBheEhlYWRlcnNDb250ZW50cyhNYXA8U3RyaW5nLCBTdHJpbmc+IGhlYWRlcnMpCisgICAgICAgIHRocm93cyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgU3RyaW5nV3JpdGVyIHcgPSBuZXcgU3RyaW5nV3JpdGVyKCk7CisgICAgICAgIGZvciAoZmluYWwgTWFwLkVudHJ5PFN0cmluZywgU3RyaW5nPiBoIDogaGVhZGVycy5lbnRyeVNldCgpKSB7CisgICAgICAgICAgICBmaW5hbCBTdHJpbmcga2V5ID0gaC5nZXRLZXkoKTsKKyAgICAgICAgICAgIGZpbmFsIFN0cmluZyB2YWx1ZSA9IGguZ2V0VmFsdWUoKTsKKyAgICAgICAgICAgIGludCBsZW4gPSBrZXkubGVuZ3RoKCkgKyB2YWx1ZS5sZW5ndGgoKQorICAgICAgICAgICAgICAgICsgMyAvKiBibGFuaywgZXF1YWxzIGFuZCBuZXdsaW5lICovCisgICAgICAgICAgICAgICAgKyAyIC8qIGd1ZXNzIDkgPCBhY3R1YWwgbGVuZ3RoIDwgMTAwICovOworICAgICAgICAgICAgU3RyaW5nIGxpbmUgPSBsZW4gKyAiICIgKyBrZXkgKyAiPSIgKyB2YWx1ZSArICJcbiI7CisgICAgICAgICAgICBpbnQgYWN0dWFsTGVuZ3RoID0gbGluZS5nZXRCeXRlcyhDaGFyc2V0TmFtZXMuVVRGXzgpLmxlbmd0aDsKKyAgICAgICAgICAgIHdoaWxlIChsZW4gIT0gYWN0dWFsTGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgLy8gQWRqdXN0IGZvciBjYXNlcyB3aGVyZSBsZW5ndGggPCAxMCBvciA+IDEwMAorICAgICAgICAgICAgICAgIC8vIG9yIHdoZXJlIFVURi04IGVuY29kaW5nIGlzbid0IGEgc2luZ2xlIG9jdGV0CisgICAgICAgICAgICAgICAgLy8gcGVyIGNoYXJhY3Rlci4KKyAgICAgICAgICAgICAgICAvLyBNdXN0IGJlIGluIGxvb3AgYXMgc2l6ZSBtYXkgZ28gZnJvbSA5OSB0byAxMDAgaW4KKyAgICAgICAgICAgICAgICAvLyBmaXJzdCBwYXNzIHNvIHdlJ2QgbmVlZCBhIHNlY29uZC4KKyAgICAgICAgICAgICAgICBsZW4gPSBhY3R1YWxMZW5ndGg7CisgICAgICAgICAgICAgICAgbGluZSA9IGxlbiArICIgIiArIGtleSArICI9IiArIHZhbHVlICsgIlxuIjsKKyAgICAgICAgICAgICAgICBhY3R1YWxMZW5ndGggPSBsaW5lLmdldEJ5dGVzKENoYXJzZXROYW1lcy5VVEZfOCkubGVuZ3RoOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdy53cml0ZShsaW5lKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdy50b1N0cmluZygpLmdldEJ5dGVzKENoYXJzZXROYW1lcy5VVEZfOCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBTdHJpbmcgc3RyaXBUbzdCaXRzKGZpbmFsIFN0cmluZyBuYW1lKSB7CisgICAgICAgIGZpbmFsIGludCBsZW5ndGggPSBuYW1lLmxlbmd0aCgpOworICAgICAgICBmaW5hbCBTdHJpbmdCdWlsZGVyIHJlc3VsdCA9IG5ldyBTdHJpbmdCdWlsZGVyKGxlbmd0aCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGZpbmFsIGNoYXIgc3RyaXBwZWQgPSAoY2hhcikgKG5hbWUuY2hhckF0KGkpICYgMHg3Rik7CisgICAgICAgICAgICBpZiAoc2hvdWxkQmVSZXBsYWNlZChzdHJpcHBlZCkpIHsKKyAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKCJfIik7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoc3RyaXBwZWQpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGNoYXJhY3RlciBjb3VsZCBsZWFkIHRvIHByb2JsZW1zIHdoZW4gdXNlZCBpbnNpZGUgYSBUYXJBcmNoaXZlRW50cnkgbmFtZQorICAgICAqIGZvciBhIFBBWCBoZWFkZXIuCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIHNob3VsZEJlUmVwbGFjZWQoZmluYWwgY2hhciBjKSB7CisgICAgICAgIHJldHVybiBjID09IDAgLy8gd291bGQgYmUgcmVhZCBhcyBUcmFpbGluZyBudWxsCisgICAgICAgICAgICB8fCBjID09ICcvJyAvLyB3aGVuIHVzZWQgYXMgbGFzdCBjaGFyYWN0ZXIgVEFFIHdpbGwgY29uc2lkZXIgdGhlIFBBWCBoZWFkZXIgYSBkaXJlY3RvcnkKKyAgICAgICAgICAgIHx8IGMgPT0gJ1xcJzsgLy8gc2FtZSBhcyAnLycgYXMgc2xhc2hlcyBnZXQgIm5vcm1hbGl6ZWQiIG9uIFdpbmRvd3MKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZSBhbiBFT0YgKGVuZCBvZiBhcmNoaXZlKSByZWNvcmQgdG8gdGhlIHRhciBhcmNoaXZlLiBBbiBFT0YgcmVjb3JkIGNvbnNpc3RzIG9mIGEgcmVjb3JkCisgICAgICogb2YgYWxsIHplcm9zLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCB3cml0ZUVPRlJlY29yZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEFycmF5cy5maWxsKHJlY29yZEJ1ZiwgKGJ5dGUpIDApOworICAgICAgICB3cml0ZVJlY29yZChyZWNvcmRCdWYpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGZsdXNoKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgb3V0LmZsdXNoKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEFyY2hpdmVFbnRyeSBjcmVhdGVBcmNoaXZlRW50cnkoZmluYWwgRmlsZSBpbnB1dEZpbGUsIGZpbmFsIFN0cmluZyBlbnRyeU5hbWUpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChmaW5pc2hlZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJTdHJlYW0gaGFzIGFscmVhZHkgYmVlbiBmaW5pc2hlZCIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgVGFyQXJjaGl2ZUVudHJ5KGlucHV0RmlsZSwgZW50cnlOYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZSBhbiBhcmNoaXZlIHJlY29yZCB0byB0aGUgYXJjaGl2ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZWNvcmQgVGhlIHJlY29yZCBkYXRhIHRvIHdyaXRlIHRvIHRoZSBhcmNoaXZlLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gb24gZXJyb3IKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgd3JpdGVSZWNvcmQoZmluYWwgYnl0ZVtdIHJlY29yZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHJlY29yZC5sZW5ndGggIT0gUkVDT1JEX1NJWkUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigicmVjb3JkIHRvIHdyaXRlIGhhcyBsZW5ndGggJyIKKyAgICAgICAgICAgICAgICArIHJlY29yZC5sZW5ndGgKKyAgICAgICAgICAgICAgICArICInIHdoaWNoIGlzIG5vdCB0aGUgcmVjb3JkIHNpemUgb2YgJyIKKyAgICAgICAgICAgICAgICArIFJFQ09SRF9TSVpFICsgIiciKTsKKyAgICAgICAgfQorCisgICAgICAgIG91dC53cml0ZShyZWNvcmQpOworICAgICAgICByZWNvcmRzV3JpdHRlbisrOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBwYWRBc05lZWRlZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIGludCBzdGFydCA9IHJlY29yZHNXcml0dGVuICUgcmVjb3Jkc1BlckJsb2NrOworICAgICAgICBpZiAoc3RhcnQgIT0gMCkgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IHN0YXJ0OyBpIDwgcmVjb3Jkc1BlckJsb2NrOyBpKyspIHsKKyAgICAgICAgICAgICAgICB3cml0ZUVPRlJlY29yZCgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGFkZFBheEhlYWRlcnNGb3JCaWdOdW1iZXJzKGZpbmFsIE1hcDxTdHJpbmcsIFN0cmluZz4gcGF4SGVhZGVycywKKyAgICAgICAgZmluYWwgVGFyQXJjaGl2ZUVudHJ5IGVudHJ5KSB7CisgICAgICAgIGFkZFBheEhlYWRlckZvckJpZ051bWJlcihwYXhIZWFkZXJzLCAic2l6ZSIsIGVudHJ5LmdldFNpemUoKSwKKyAgICAgICAgICAgIFRhckNvbnN0YW50cy5NQVhTSVpFKTsKKyAgICAgICAgYWRkUGF4SGVhZGVyRm9yQmlnTnVtYmVyKHBheEhlYWRlcnMsICJnaWQiLCBlbnRyeS5nZXRMb25nR3JvdXBJZCgpLAorICAgICAgICAgICAgVGFyQ29uc3RhbnRzLk1BWElEKTsKKyAgICAgICAgYWRkUGF4SGVhZGVyRm9yQmlnTnVtYmVyKHBheEhlYWRlcnMsICJtdGltZSIsCisgICAgICAgICAgICBlbnRyeS5nZXRNb2RUaW1lKCkuZ2V0VGltZSgpIC8gMTAwMCwKKyAgICAgICAgICAgIFRhckNvbnN0YW50cy5NQVhTSVpFKTsKKyAgICAgICAgYWRkUGF4SGVhZGVyRm9yQmlnTnVtYmVyKHBheEhlYWRlcnMsICJ1aWQiLCBlbnRyeS5nZXRMb25nVXNlcklkKCksCisgICAgICAgICAgICBUYXJDb25zdGFudHMuTUFYSUQpOworICAgICAgICAvLyBzdGFyIGV4dGVuc2lvbnMgYnkgSlx1MDBmNnJnIFNjaGlsbGluZworICAgICAgICBhZGRQYXhIZWFkZXJGb3JCaWdOdW1iZXIocGF4SGVhZGVycywgIlNDSElMWS5kZXZtYWpvciIsCisgICAgICAgICAgICBlbnRyeS5nZXREZXZNYWpvcigpLCBUYXJDb25zdGFudHMuTUFYSUQpOworICAgICAgICBhZGRQYXhIZWFkZXJGb3JCaWdOdW1iZXIocGF4SGVhZGVycywgIlNDSElMWS5kZXZtaW5vciIsCisgICAgICAgICAgICBlbnRyeS5nZXREZXZNaW5vcigpLCBUYXJDb25zdGFudHMuTUFYSUQpOworICAgICAgICAvLyB0aGVyZSBpcyBubyBQQVggaGVhZGVyIGZvciBmaWxlIG1vZGUKKyAgICAgICAgZmFpbEZvckJpZ051bWJlcigibW9kZSIsIGVudHJ5LmdldE1vZGUoKSwgVGFyQ29uc3RhbnRzLk1BWElEKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYWRkUGF4SGVhZGVyRm9yQmlnTnVtYmVyKGZpbmFsIE1hcDxTdHJpbmcsIFN0cmluZz4gcGF4SGVhZGVycywKKyAgICAgICAgZmluYWwgU3RyaW5nIGhlYWRlciwgZmluYWwgbG9uZyB2YWx1ZSwKKyAgICAgICAgZmluYWwgbG9uZyBtYXhWYWx1ZSkgeworICAgICAgICBpZiAodmFsdWUgPCAwIHx8IHZhbHVlID4gbWF4VmFsdWUpIHsKKyAgICAgICAgICAgIHBheEhlYWRlcnMucHV0KGhlYWRlciwgU3RyaW5nLnZhbHVlT2YodmFsdWUpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBmYWlsRm9yQmlnTnVtYmVycyhmaW5hbCBUYXJBcmNoaXZlRW50cnkgZW50cnkpIHsKKyAgICAgICAgZmFpbEZvckJpZ051bWJlcigiZW50cnkgc2l6ZSIsIGVudHJ5LmdldFNpemUoKSwgVGFyQ29uc3RhbnRzLk1BWFNJWkUpOworICAgICAgICBmYWlsRm9yQmlnTnVtYmVyV2l0aFBvc2l4TWVzc2FnZSgiZ3JvdXAgaWQiLCBlbnRyeS5nZXRMb25nR3JvdXBJZCgpLCBUYXJDb25zdGFudHMuTUFYSUQpOworICAgICAgICBmYWlsRm9yQmlnTnVtYmVyKCJsYXN0IG1vZGlmaWNhdGlvbiB0aW1lIiwKKyAgICAgICAgICAgIGVudHJ5LmdldE1vZFRpbWUoKS5nZXRUaW1lKCkgLyAxMDAwLAorICAgICAgICAgICAgVGFyQ29uc3RhbnRzLk1BWFNJWkUpOworICAgICAgICBmYWlsRm9yQmlnTnVtYmVyKCJ1c2VyIGlkIiwgZW50cnkuZ2V0TG9uZ1VzZXJJZCgpLCBUYXJDb25zdGFudHMuTUFYSUQpOworICAgICAgICBmYWlsRm9yQmlnTnVtYmVyKCJtb2RlIiwgZW50cnkuZ2V0TW9kZSgpLCBUYXJDb25zdGFudHMuTUFYSUQpOworICAgICAgICBmYWlsRm9yQmlnTnVtYmVyKCJtYWpvciBkZXZpY2UgbnVtYmVyIiwgZW50cnkuZ2V0RGV2TWFqb3IoKSwKKyAgICAgICAgICAgIFRhckNvbnN0YW50cy5NQVhJRCk7CisgICAgICAgIGZhaWxGb3JCaWdOdW1iZXIoIm1pbm9yIGRldmljZSBudW1iZXIiLCBlbnRyeS5nZXREZXZNaW5vcigpLAorICAgICAgICAgICAgVGFyQ29uc3RhbnRzLk1BWElEKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgZmFpbEZvckJpZ051bWJlcihmaW5hbCBTdHJpbmcgZmllbGQsIGZpbmFsIGxvbmcgdmFsdWUsIGZpbmFsIGxvbmcgbWF4VmFsdWUpIHsKKyAgICAgICAgZmFpbEZvckJpZ051bWJlcihmaWVsZCwgdmFsdWUsIG1heFZhbHVlLCAiIik7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGZhaWxGb3JCaWdOdW1iZXJXaXRoUG9zaXhNZXNzYWdlKGZpbmFsIFN0cmluZyBmaWVsZCwgZmluYWwgbG9uZyB2YWx1ZSwKKyAgICAgICAgZmluYWwgbG9uZyBtYXhWYWx1ZSkgeworICAgICAgICBmYWlsRm9yQmlnTnVtYmVyKGZpZWxkLCB2YWx1ZSwgbWF4VmFsdWUsCisgICAgICAgICAgICAiIFVzZSBTVEFSIG9yIFBPU0lYIGV4dGVuc2lvbnMgdG8gb3ZlcmNvbWUgdGhpcyBsaW1pdCIpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBmYWlsRm9yQmlnTnVtYmVyKGZpbmFsIFN0cmluZyBmaWVsZCwgZmluYWwgbG9uZyB2YWx1ZSwgZmluYWwgbG9uZyBtYXhWYWx1ZSwKKyAgICAgICAgZmluYWwgU3RyaW5nIGFkZGl0aW9uYWxNc2cpIHsKKyAgICAgICAgaWYgKHZhbHVlIDwgMCB8fCB2YWx1ZSA+IG1heFZhbHVlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihmaWVsZCArICIgJyIgKyB2YWx1ZSAvL05PU09OQVIKKyAgICAgICAgICAgICAgICArICInIGlzIHRvbyBiaWcgKCA+ICIKKyAgICAgICAgICAgICAgICArIG1heFZhbHVlICsgIiApLiIgKyBhZGRpdGlvbmFsTXNnKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEhhbmRsZXMgbG9uZyBmaWxlIG9yIGxpbmsgbmFtZXMgYWNjb3JkaW5nIHRvIHRoZSBsb25nRmlsZU1vZGUgc2V0dGluZy4KKyAgICAgKgorICAgICAqIDxwPkkuZS4gaWYgdGhlIGdpdmVuIG5hbWUgaXMgdG9vIGxvbmcgdG8gYmUgd3JpdHRlbiB0byBhIHBsYWluIHRhciBoZWFkZXIgdGhlbiA8dWw+IDxsaT5pdAorICAgICAqIGNyZWF0ZXMgYSBwYXggaGVhZGVyIHdobydzIG5hbWUgaXMgZ2l2ZW4gYnkgdGhlIHBheEhlYWRlck5hbWUgcGFyYW1ldGVyIGlmIGxvbmdGaWxlTW9kZSBpcworICAgICAqIFBPU0lYPC9saT4gPGxpPml0IGNyZWF0ZXMgYSBHTlUgbG9uZ2xpbmsgZW50cnkgd2hvJ3MgdHlwZSBpcyBnaXZlbiBieSB0aGUgbGlua1R5cGUgcGFyYW1ldGVyCisgICAgICogaWYgbG9uZ0ZpbGVNb2RlIGlzIEdOVTwvbGk+IDxsaT5pdCB0aHJvd3MgYW4gZXhjZXB0aW9uIGlmIGxvbmdGaWxlTW9kZSBpcyBFUlJPUjwvbGk+IDxsaT5pdAorICAgICAqIHRydW5jYXRlcyB0aGUgbmFtZSBpZiBsb25nRmlsZU1vZGUgaXMgVFJVTkNBVEU8L2xpPiA8L3VsPjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlbnRyeSBlbnRyeSB0aGUgbmFtZSBiZWxvbmdzIHRvCisgICAgICogQHBhcmFtIG5hbWUgdGhlIG5hbWUgdG8gd3JpdGUKKyAgICAgKiBAcGFyYW0gcGF4SGVhZGVycyBjdXJyZW50IG1hcCBvZiBwYXggaGVhZGVycworICAgICAqIEBwYXJhbSBwYXhIZWFkZXJOYW1lIG5hbWUgb2YgdGhlIHBheCBoZWFkZXIgdG8gd3JpdGUKKyAgICAgKiBAcGFyYW0gbGlua1R5cGUgdHlwZSBvZiB0aGUgR05VIGVudHJ5IHRvIHdyaXRlCisgICAgICogQHBhcmFtIGZpZWxkTmFtZSB0aGUgbmFtZSBvZiB0aGUgZmllbGQKKyAgICAgKiBAcmV0dXJuIHdoZXRoZXIgYSBwYXggaGVhZGVyIGhhcyBiZWVuIHdyaXR0ZW4uCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIGhhbmRsZUxvbmdOYW1lKGZpbmFsIFRhckFyY2hpdmVFbnRyeSBlbnRyeSwgZmluYWwgU3RyaW5nIG5hbWUsCisgICAgICAgIGZpbmFsIE1hcDxTdHJpbmcsIFN0cmluZz4gcGF4SGVhZGVycywKKyAgICAgICAgZmluYWwgU3RyaW5nIHBheEhlYWRlck5hbWUsIGZpbmFsIGJ5dGUgbGlua1R5cGUsIGZpbmFsIFN0cmluZyBmaWVsZE5hbWUpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEJ5dGVCdWZmZXIgZW5jb2RlZE5hbWUgPSB6aXBFbmNvZGluZy5lbmNvZGUobmFtZSk7CisgICAgICAgIGZpbmFsIGludCBsZW4gPSBlbmNvZGVkTmFtZS5saW1pdCgpIC0gZW5jb2RlZE5hbWUucG9zaXRpb24oKTsKKyAgICAgICAgaWYgKGxlbiA+PSBUYXJDb25zdGFudHMuTkFNRUxFTikgeworCisgICAgICAgICAgICBpZiAobG9uZ0ZpbGVNb2RlID09IExPTkdGSUxFX1BPU0lYKSB7CisgICAgICAgICAgICAgICAgcGF4SGVhZGVycy5wdXQocGF4SGVhZGVyTmFtZSwgbmFtZSk7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICB9IGVsc2UgaWYgKGxvbmdGaWxlTW9kZSA9PSBMT05HRklMRV9HTlUpIHsKKyAgICAgICAgICAgICAgICAvLyBjcmVhdGUgYSBUYXJFbnRyeSBmb3IgdGhlIExvbmdMaW5rLCB0aGUgY29udGVudHMKKyAgICAgICAgICAgICAgICAvLyBvZiB3aGljaCBhcmUgdGhlIGxpbmsncyBuYW1lCisgICAgICAgICAgICAgICAgZmluYWwgVGFyQXJjaGl2ZUVudHJ5IGxvbmdMaW5rRW50cnkgPSBuZXcgVGFyQXJjaGl2ZUVudHJ5KFRhckNvbnN0YW50cy5HTlVfTE9OR0xJTkssCisgICAgICAgICAgICAgICAgICAgIGxpbmtUeXBlKTsKKworICAgICAgICAgICAgICAgIGxvbmdMaW5rRW50cnkuc2V0U2l6ZShsZW4gKyAxTCk7IC8vICsxIGZvciBOVUwKKyAgICAgICAgICAgICAgICB0cmFuc2Zlck1vZFRpbWUoZW50cnksIGxvbmdMaW5rRW50cnkpOworICAgICAgICAgICAgICAgIHB1dEFyY2hpdmVFbnRyeShsb25nTGlua0VudHJ5KTsKKyAgICAgICAgICAgICAgICB3cml0ZShlbmNvZGVkTmFtZS5hcnJheSgpLCBlbmNvZGVkTmFtZS5hcnJheU9mZnNldCgpLCBsZW4pOworICAgICAgICAgICAgICAgIHdyaXRlKDApOyAvLyBOVUwgdGVybWluYXRvcgorICAgICAgICAgICAgICAgIGNsb3NlQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKGxvbmdGaWxlTW9kZSAhPSBMT05HRklMRV9UUlVOQ0FURSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGZpZWxkTmFtZSArICIgJyIgKyBuYW1lIC8vTk9TT05BUgorICAgICAgICAgICAgICAgICAgICArICInIGlzIHRvbyBsb25nICggPiAiCisgICAgICAgICAgICAgICAgICAgICsgVGFyQ29uc3RhbnRzLk5BTUVMRU4gKyAiIGJ5dGVzKSIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdHJhbnNmZXJNb2RUaW1lKGZpbmFsIFRhckFyY2hpdmVFbnRyeSBmcm9tLCBmaW5hbCBUYXJBcmNoaXZlRW50cnkgdG8pIHsKKyAgICAgICAgRGF0ZSBmcm9tTW9kVGltZSA9IGZyb20uZ2V0TW9kVGltZSgpOworICAgICAgICBmaW5hbCBsb25nIGZyb21Nb2RUaW1lU2Vjb25kcyA9IGZyb21Nb2RUaW1lLmdldFRpbWUoKSAvIDEwMDA7CisgICAgICAgIGlmIChmcm9tTW9kVGltZVNlY29uZHMgPCAwIHx8IGZyb21Nb2RUaW1lU2Vjb25kcyA+IFRhckNvbnN0YW50cy5NQVhTSVpFKSB7CisgICAgICAgICAgICBmcm9tTW9kVGltZSA9IG5ldyBEYXRlKDApOworICAgICAgICB9CisgICAgICAgIHRvLnNldE1vZFRpbWUoZnJvbU1vZFRpbWUpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy90YXIvVGFyQXJjaGl2ZVNwYXJzZUVudHJ5LmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvdGFyL1RhckFyY2hpdmVTcGFyc2VFbnRyeS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE0OWU3MTgKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvdGFyL1RhckFyY2hpdmVTcGFyc2VFbnRyeS5qYXZhCkBAIC0wLDAgKzEsNjMgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnRhcjsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKKy8qKgorICogVGhpcyBjbGFzcyByZXByZXNlbnRzIGEgc3BhcnNlIGVudHJ5IGluIGEgVGFyIGFyY2hpdmUuCisgKgorICogPHA+CisgKiBUaGUgQyBzdHJ1Y3R1cmUgZm9yIGEgc3BhcnNlIGVudHJ5IGlzOgorICogPHByZT4KKyAqIHN0cnVjdCBwb3NpeF9oZWFkZXIgeworICogc3RydWN0IHNwYXJzZSBzcFsyMV07IC8vIFRhckNvbnN0YW50cy5TUEFSU0VMRU5fR05VX1NQQVJTRSAgICAgLSBvZmZzZXQgMAorICogY2hhciBpc2V4dGVuZGVkOyAgICAgIC8vIFRhckNvbnN0YW50cy5JU0VYVEVOREVETEVOX0dOVV9TUEFSU0UgLSBvZmZzZXQgNTA0CisgKiB9OworICogPC9wcmU+CisgKiBXaGVyZWFzLCAic3RydWN0IHNwYXJzZSIgaXM6CisgKiA8cHJlPgorICogc3RydWN0IHNwYXJzZSB7CisgKiBjaGFyIG9mZnNldFsxMl07ICAgLy8gb2Zmc2V0IDAKKyAqIGNoYXIgbnVtYnl0ZXNbMTJdOyAvLyBvZmZzZXQgMTIKKyAqIH07CisgKiA8L3ByZT4KKyAqLworCitwdWJsaWMgY2xhc3MgVGFyQXJjaGl2ZVNwYXJzZUVudHJ5IGltcGxlbWVudHMgVGFyQ29uc3RhbnRzIHsKKyAgICAvKiogSWYgYW4gZXh0ZW5zaW9uIHNwYXJzZSBoZWFkZXIgZm9sbG93cy4gKi8KKyAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gaXNFeHRlbmRlZDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdCBhbiBlbnRyeSBmcm9tIGFuIGFyY2hpdmUncyBoZWFkZXIgYnl0ZXMuIEZpbGUgaXMgc2V0CisgICAgICogdG8gbnVsbC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBoZWFkZXJCdWYgVGhlIGhlYWRlciBieXRlcyBmcm9tIGEgdGFyIGFyY2hpdmUgZW50cnkuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBvbiB1bmtub3duIGZvcm1hdAorICAgICAqLworICAgIHB1YmxpYyBUYXJBcmNoaXZlU3BhcnNlRW50cnkoZmluYWwgYnl0ZVtdIGhlYWRlckJ1ZikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IG9mZnNldCA9IDA7CisgICAgICAgIG9mZnNldCArPSBTUEFSU0VMRU5fR05VX1NQQVJTRTsKKyAgICAgICAgaXNFeHRlbmRlZCA9IFRhclV0aWxzLnBhcnNlQm9vbGVhbihoZWFkZXJCdWYsIG9mZnNldCk7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaXNFeHRlbmRlZCgpIHsKKyAgICAgICAgcmV0dXJuIGlzRXh0ZW5kZWQ7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3Rhci9UYXJDb25zdGFudHMuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy90YXIvVGFyQ29uc3RhbnRzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzUxODQwZAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy90YXIvVGFyQ29uc3RhbnRzLmphdmEKQEAgLTAsMCArMSwzNTggQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnRhcjsKKworLyoqCisgKiBUaGlzIGludGVyZmFjZSBjb250YWlucyBhbGwgdGhlIGRlZmluaXRpb25zIHVzZWQgaW4gdGhlIHBhY2thZ2UuCisgKgorICogRm9yIHRhciBmb3JtYXRzIChGT1JNQVRfT0xER05VLCBGT1JNQVRfUE9TSVgsIGV0Yy4pIHNlZSBHTlUgdGFyCisgKiA8ST50YXIuaDwvST4gdHlwZSA8ST5lbnVtIGFyY2hpdmVfZm9ybWF0PC9JPgorICovCisvLyBDaGVja1N0eWxlOkludGVyZmFjZUlzVHlwZUNoZWNrIE9GRiAoYmMpCitwdWJsaWMgaW50ZXJmYWNlIFRhckNvbnN0YW50cyB7CisKKyAgICAvKiogRGVmYXVsdCByZWNvcmQgc2l6ZSAqLworICAgIGludCBERUZBVUxUX1JDRFNJWkUgPSA1MTI7CisKKyAgICAvKiogRGVmYXVsdCBibG9jayBzaXplICovCisgICAgaW50IERFRkFVTFRfQkxLU0laRSA9IERFRkFVTFRfUkNEU0laRSAqIDIwOworCisgICAgLyoqCisgICAgICogR05VIGZvcm1hdCBhcyBwZXIgYmVmb3JlIHRhciAxLjEyLgorICAgICAqLworICAgIGludCAgICBGT1JNQVRfT0xER05VID0gMjsKKworICAgIC8qKgorICAgICAqIFB1cmUgUG9zaXggZm9ybWF0LgorICAgICAqLworICAgIGludCAgICBGT1JNQVRfUE9TSVggPSAzOworCisgICAgLyoqCisgICAgICogeHN0YXIgZm9ybWF0IHVzZWQgYnkgSsO2cmcgU2NoaWxsaW5nJ3Mgc3Rhci4KKyAgICAgKi8KKyAgICBpbnQgICAgRk9STUFUX1hTVEFSID0gNDsKKworICAgIC8qKgorICAgICAqIFRoZSBsZW5ndGggb2YgdGhlIG5hbWUgZmllbGQgaW4gYSBoZWFkZXIgYnVmZmVyLgorICAgICAqLworICAgIGludCAgICBOQU1FTEVOID0gMTAwOworCisgICAgLyoqCisgICAgICogVGhlIGxlbmd0aCBvZiB0aGUgbW9kZSBmaWVsZCBpbiBhIGhlYWRlciBidWZmZXIuCisgICAgICovCisgICAgaW50ICAgIE1PREVMRU4gPSA4OworCisgICAgLyoqCisgICAgICogVGhlIGxlbmd0aCBvZiB0aGUgdXNlciBpZCBmaWVsZCBpbiBhIGhlYWRlciBidWZmZXIuCisgICAgICovCisgICAgaW50ICAgIFVJRExFTiA9IDg7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbGVuZ3RoIG9mIHRoZSBncm91cCBpZCBmaWVsZCBpbiBhIGhlYWRlciBidWZmZXIuCisgICAgICovCisgICAgaW50ICAgIEdJRExFTiA9IDg7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbWF4aW11bSB2YWx1ZSBvZiBnaWQvdWlkIGluIGEgdGFyIGFyY2hpdmUgd2hpY2ggY2FuCisgICAgICogYmUgZXhwcmVzc2VkIGluIG9jdGFsIGNoYXIgbm90YXRpb24gKHRoYXQncyA3IHNldmVucywgb2N0YWwpLgorICAgICAqLworICAgIGxvbmcgICAgTUFYSUQgPSAwNzc3Nzc3N0w7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbGVuZ3RoIG9mIHRoZSBjaGVja3N1bSBmaWVsZCBpbiBhIGhlYWRlciBidWZmZXIuCisgICAgICovCisgICAgaW50ICAgIENIS1NVTUxFTiA9IDg7CisKKyAgICAvKioKKyAgICAgKiBPZmZzZXQgb2YgdGhlIGNoZWNrc3VtIGZpZWxkIHdpdGhpbiBoZWFkZXIgcmVjb3JkLgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBpbnQgICAgQ0hLU1VNX09GRlNFVCA9IDE0ODsKKworICAgIC8qKgorICAgICAqIFRoZSBsZW5ndGggb2YgdGhlIHNpemUgZmllbGQgaW4gYSBoZWFkZXIgYnVmZmVyLgorICAgICAqIEluY2x1ZGVzIHRoZSB0cmFpbGluZyBzcGFjZSBvciBOVUwuCisgICAgICovCisgICAgaW50ICAgIFNJWkVMRU4gPSAxMjsKKworICAgIC8qKgorICAgICAqIFRoZSBtYXhpbXVtIHNpemUgb2YgYSBmaWxlIGluIGEgdGFyIGFyY2hpdmUKKyAgICAgKiB3aGljaCBjYW4gYmUgZXhwcmVzc2VkIGluIG9jdGFsIGNoYXIgbm90YXRpb24gKHRoYXQncyAxMSBzZXZlbnMsIG9jdGFsKS4KKyAgICAgKi8KKyAgICBsb25nICAgTUFYU0laRSA9IDA3Nzc3Nzc3Nzc3N0w7CisKKyAgICAvKiogT2Zmc2V0IG9mIHN0YXJ0IG9mIG1hZ2ljIGZpZWxkIHdpdGhpbiBoZWFkZXIgcmVjb3JkICovCisgICAgaW50ICAgIE1BR0lDX09GRlNFVCA9IDI1NzsKKyAgICAvKioKKyAgICAgKiBUaGUgbGVuZ3RoIG9mIHRoZSBtYWdpYyBmaWVsZCBpbiBhIGhlYWRlciBidWZmZXIuCisgICAgICovCisgICAgaW50ICAgIE1BR0lDTEVOID0gNjsKKworICAgIC8qKiBPZmZzZXQgb2Ygc3RhcnQgb2YgbWFnaWMgZmllbGQgd2l0aGluIGhlYWRlciByZWNvcmQgKi8KKyAgICBpbnQgICAgVkVSU0lPTl9PRkZTRVQgPSAyNjM7CisgICAgLyoqCisgICAgICogUHJldmlvdXNseSB0aGlzIHdhcyByZWdhcmRlZCBhcyBwYXJ0IG9mICJtYWdpYyIgZmllbGQsIGJ1dCBpdCBpcyBzZXBhcmF0ZS4KKyAgICAgKi8KKyAgICBpbnQgICAgVkVSU0lPTkxFTiA9IDI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbGVuZ3RoIG9mIHRoZSBtb2RpZmljYXRpb24gdGltZSBmaWVsZCBpbiBhIGhlYWRlciBidWZmZXIuCisgICAgICovCisgICAgaW50ICAgIE1PRFRJTUVMRU4gPSAxMjsKKworICAgIC8qKgorICAgICAqIFRoZSBsZW5ndGggb2YgdGhlIHVzZXIgbmFtZSBmaWVsZCBpbiBhIGhlYWRlciBidWZmZXIuCisgICAgICovCisgICAgaW50ICAgIFVOQU1FTEVOID0gMzI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbGVuZ3RoIG9mIHRoZSBncm91cCBuYW1lIGZpZWxkIGluIGEgaGVhZGVyIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBpbnQgICAgR05BTUVMRU4gPSAzMjsKKworICAgIC8qKgorICAgICAqIFRoZSBsZW5ndGggb2YgZWFjaCBvZiB0aGUgZGV2aWNlIGZpZWxkcyAobWFqb3IgYW5kIG1pbm9yKSBpbiBhIGhlYWRlciBidWZmZXIuCisgICAgICovCisgICAgaW50ICAgIERFVkxFTiA9IDg7CisKKyAgICAvKioKKyAgICAgKiBMZW5ndGggb2YgdGhlIHByZWZpeCBmaWVsZC4KKyAgICAgKgorICAgICAqLworICAgIGludCAgICBQUkVGSVhMRU4gPSAxNTU7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbGVuZ3RoIG9mIHRoZSBhY2Nlc3MgdGltZSBmaWVsZCBpbiBhbiBvbGQgR05VIGhlYWRlciBidWZmZXIuCisgICAgICoKKyAgICAgKi8KKyAgICBpbnQgICAgQVRJTUVMRU5fR05VID0gMTI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbGVuZ3RoIG9mIHRoZSBjcmVhdGVkIHRpbWUgZmllbGQgaW4gYW4gb2xkIEdOVSBoZWFkZXIgYnVmZmVyLgorICAgICAqCisgICAgICovCisgICAgaW50ICAgIENUSU1FTEVOX0dOVSA9IDEyOworCisgICAgLyoqCisgICAgICogVGhlIGxlbmd0aCBvZiB0aGUgbXVsdGl2b2x1bWUgc3RhcnQgb2Zmc2V0IGZpZWxkIGluIGFuIG9sZCBHTlUgaGVhZGVyIGJ1ZmZlci4KKyAgICAgKgorICAgICAqLworICAgIGludCAgICBPRkZTRVRMRU5fR05VID0gMTI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbGVuZ3RoIG9mIHRoZSBsb25nIG5hbWVzIGZpZWxkIGluIGFuIG9sZCBHTlUgaGVhZGVyIGJ1ZmZlci4KKyAgICAgKgorICAgICAqLworICAgIGludCAgICBMT05HTkFNRVNMRU5fR05VID0gNDsKKworICAgIC8qKgorICAgICAqIFRoZSBsZW5ndGggb2YgdGhlIHBhZGRpbmcgZmllbGQgaW4gYW4gb2xkIEdOVSBoZWFkZXIgYnVmZmVyLgorICAgICAqCisgICAgICovCisgICAgaW50ICAgIFBBRDJMRU5fR05VID0gMTsKKworICAgIC8qKgorICAgICAqIFRoZSBzdW0gb2YgdGhlIGxlbmd0aCBvZiBhbGwgc3BhcnNlIGhlYWRlcnMgaW4gYW4gb2xkIEdOVSBoZWFkZXIgYnVmZmVyLgorICAgICAqCisgICAgICovCisgICAgaW50ICAgIFNQQVJTRUxFTl9HTlUgPSA5NjsKKworICAgIC8qKgorICAgICAqIFRoZSBsZW5ndGggb2YgdGhlIGlzIGV4dGVuc2lvbiBmaWVsZCBpbiBhbiBvbGQgR05VIGhlYWRlciBidWZmZXIuCisgICAgICoKKyAgICAgKi8KKyAgICBpbnQgICAgSVNFWFRFTkRFRExFTl9HTlUgPSAxOworCisgICAgLyoqCisgICAgICogVGhlIGxlbmd0aCBvZiB0aGUgcmVhbCBzaXplIGZpZWxkIGluIGFuIG9sZCBHTlUgaGVhZGVyIGJ1ZmZlci4KKyAgICAgKgorICAgICAqLworICAgIGludCAgICBSRUFMU0laRUxFTl9HTlUgPSAxMjsKKworICAgIC8qKgorICAgICAqIFRoZSBzdW0gb2YgdGhlIGxlbmd0aCBvZiBhbGwgc3BhcnNlIGhlYWRlcnMgaW4gYSBzcGFyc2UgaGVhZGVyIGJ1ZmZlci4KKyAgICAgKgorICAgICAqLworICAgIGludCAgICBTUEFSU0VMRU5fR05VX1NQQVJTRSA9IDUwNDsKKworICAgIC8qKgorICAgICAqIFRoZSBsZW5ndGggb2YgdGhlIGlzIGV4dGVuc2lvbiBmaWVsZCBpbiBhIHNwYXJzZSBoZWFkZXIgYnVmZmVyLgorICAgICAqCisgICAgICovCisgICAgaW50ICAgIElTRVhURU5ERURMRU5fR05VX1NQQVJTRSA9IDE7CisKKyAgICAvKioKKyAgICAgKiBMRl8gY29uc3RhbnRzIHJlcHJlc2VudCB0aGUgImxpbmsgZmxhZyIgb2YgYW4gZW50cnksIG9yIG1vcmUgY29tbW9ubHksCisgICAgICogdGhlICJlbnRyeSB0eXBlIi4gVGhpcyBpcyB0aGUgIm9sZCB3YXkiIG9mIGluZGljYXRpbmcgYSBub3JtYWwgZmlsZS4KKyAgICAgKi8KKyAgICBieXRlICAgTEZfT0xETk9STSA9IDA7CisKKyAgICAvKioKKyAgICAgKiBOb3JtYWwgZmlsZSB0eXBlLgorICAgICAqLworICAgIGJ5dGUgICBMRl9OT1JNQUwgPSAoYnl0ZSkgJzAnOworCisgICAgLyoqCisgICAgICogTGluayBmaWxlIHR5cGUuCisgICAgICovCisgICAgYnl0ZSAgIExGX0xJTksgPSAoYnl0ZSkgJzEnOworCisgICAgLyoqCisgICAgICogU3ltYm9saWMgbGluayBmaWxlIHR5cGUuCisgICAgICovCisgICAgYnl0ZSAgIExGX1NZTUxJTksgPSAoYnl0ZSkgJzInOworCisgICAgLyoqCisgICAgICogQ2hhcmFjdGVyIGRldmljZSBmaWxlIHR5cGUuCisgICAgICovCisgICAgYnl0ZSAgIExGX0NIUiA9IChieXRlKSAnMyc7CisKKyAgICAvKioKKyAgICAgKiBCbG9jayBkZXZpY2UgZmlsZSB0eXBlLgorICAgICAqLworICAgIGJ5dGUgICBMRl9CTEsgPSAoYnl0ZSkgJzQnOworCisgICAgLyoqCisgICAgICogRGlyZWN0b3J5IGZpbGUgdHlwZS4KKyAgICAgKi8KKyAgICBieXRlICAgTEZfRElSID0gKGJ5dGUpICc1JzsKKworICAgIC8qKgorICAgICAqIEZJRk8gKHBpcGUpIGZpbGUgdHlwZS4KKyAgICAgKi8KKyAgICBieXRlICAgTEZfRklGTyA9IChieXRlKSAnNic7CisKKyAgICAvKioKKyAgICAgKiBDb250aWd1b3VzIGZpbGUgdHlwZS4KKyAgICAgKi8KKyAgICBieXRlICAgTEZfQ09OVElHID0gKGJ5dGUpICc3JzsKKworICAgIC8qKgorICAgICAqIElkZW50aWZpZXMgdGhlICpuZXh0KiBmaWxlIG9uIHRoZSB0YXBlIGFzIGhhdmluZyBhIGxvbmcgbGlua25hbWUuCisgICAgICovCisgICAgYnl0ZSBMRl9HTlVUWVBFX0xPTkdMSU5LID0gKGJ5dGUpICdLJzsKKworICAgIC8qKgorICAgICAqIElkZW50aWZpZXMgdGhlICpuZXh0KiBmaWxlIG9uIHRoZSB0YXBlIGFzIGhhdmluZyBhIGxvbmcgbmFtZS4KKyAgICAgKi8KKyAgICBieXRlIExGX0dOVVRZUEVfTE9OR05BTUUgPSAoYnl0ZSkgJ0wnOworCisgICAgLyoqCisgICAgICogU3BhcnNlIGZpbGUgdHlwZS4KKyAgICAgKiBAc2luY2UgMS4xLjEKKyAgICAgKi8KKyAgICBieXRlIExGX0dOVVRZUEVfU1BBUlNFID0gKGJ5dGUpICdTJzsKKworICAgIC8vIFNlZSAiaHR0cDovL3d3dy5vcGVuZ3JvdXAub3JnL29ubGluZXB1YnMvMDA5Njk1Mzk5L3V0aWxpdGllcy9wYXguaHRtbCN0YWdfMDRfMTAwXzEzXzAyIgorCisgICAgLyoqCisgICAgICogSWRlbnRpZmllcyB0aGUgZW50cnkgYXMgYSBQYXggZXh0ZW5kZWQgaGVhZGVyLgorICAgICAqIEBzaW5jZSAxLjEKKyAgICAgKi8KKyAgICBieXRlIExGX1BBWF9FWFRFTkRFRF9IRUFERVJfTEMgPSAoYnl0ZSkgJ3gnOworCisgICAgLyoqCisgICAgICogSWRlbnRpZmllcyB0aGUgZW50cnkgYXMgYSBQYXggZXh0ZW5kZWQgaGVhZGVyIChTdW5PUyB0YXIgLUUpLgorICAgICAqCisgICAgICogQHNpbmNlIDEuMQorICAgICAqLworICAgIGJ5dGUgTEZfUEFYX0VYVEVOREVEX0hFQURFUl9VQyA9IChieXRlKSAnWCc7CisKKyAgICAvKioKKyAgICAgKiBJZGVudGlmaWVzIHRoZSBlbnRyeSBhcyBhIFBheCBnbG9iYWwgZXh0ZW5kZWQgaGVhZGVyLgorICAgICAqCisgICAgICogQHNpbmNlIDEuMQorICAgICAqLworICAgIGJ5dGUgTEZfUEFYX0dMT0JBTF9FWFRFTkRFRF9IRUFERVIgPSAoYnl0ZSkgJ2cnOworCisgICAgLyoqCisgICAgICogVGhlIG1hZ2ljIHRhZyByZXByZXNlbnRpbmcgYSBQT1NJWCB0YXIgYXJjaGl2ZS4KKyAgICAgKi8KKyAgICBTdHJpbmcgTUFHSUNfUE9TSVggPSAidXN0YXJcMCI7CisgICAgU3RyaW5nIFZFUlNJT05fUE9TSVggPSAiMDAiOworCisgICAgLyoqCisgICAgICogVGhlIG1hZ2ljIHRhZyByZXByZXNlbnRpbmcgYSBHTlUgdGFyIGFyY2hpdmUuCisgICAgICovCisgICAgU3RyaW5nIE1BR0lDX0dOVSA9ICJ1c3RhciAiOworICAgIC8vIEFwcGVhciB0byBiZSB0d28gcG9zc2libGUgR05VIHZlcnNpb25zCisgICAgU3RyaW5nIFZFUlNJT05fR05VX1NQQUNFID0gIiBcMCI7CisgICAgU3RyaW5nIFZFUlNJT05fR05VX1pFUk8gID0gIjBcMCI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbWFnaWMgdGFnIHJlcHJlc2VudGluZyBhbiBBbnQgdGFyIGFyY2hpdmUuCisgICAgICoKKyAgICAgKiBAc2luY2UgMS4xCisgICAgICovCisgICAgU3RyaW5nIE1BR0lDX0FOVCA9ICJ1c3RhclwwIjsKKworICAgIC8qKgorICAgICAqIFRoZSAidmVyc2lvbiIgcmVwcmVzZW50aW5nIGFuIEFudCB0YXIgYXJjaGl2ZS4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjEKKyAgICAgKi8KKyAgICAvLyBEb2VzIG5vdCBhcHBlYXIgdG8gaGF2ZSBhIHZlcnNpb24sIGhvd2V2ZXIgQW50IGRvZXMgd3JpdGUgOCBieXRlcywKKyAgICAvLyBzbyBhc3N1bWUgdGhlIHZlcnNpb24gaXMgMiBudWxscworICAgIFN0cmluZyBWRVJTSU9OX0FOVCA9ICJcMFwwIjsKKworICAgIC8qKgorICAgICAqIFRoZSBuYW1lIG9mIHRoZSBHTlUgdGFyIGVudHJ5IHdoaWNoIGNvbnRhaW5zIGEgbG9uZyBuYW1lLgorICAgICAqLworICAgIFN0cmluZyBHTlVfTE9OR0xJTksgPSAiLi8uL0BMb25nTGluayI7IC8vIFRPRE8gcmVuYW1lIGFzIExPTkdMSU5LX0dOVSA/CisKKyAgICAvKioKKyAgICAgKiBUaGUgbWFnaXggc3RyaW5nIHVzZWQgaW4gdGhlIGxhc3QgZm91ciBieXRlcyBvZiB0aGUgaGVhZGVyIHRvCisgICAgICogaWRlbnRpZnkgdGhlIHhzdGFyIGZvcm1hdC4KKyAgICAgKiBAc2luY2UgMS4xMQorICAgICAqLworICAgIFN0cmluZyBNQUdJQ19YU1RBUiA9ICJ0YXJcMCI7CisKKyAgICAvKioKKyAgICAgKiBPZmZzZXQgaW5zaWRlIHRoZSBoZWFkZXIgZm9yIHRoZSB4c3RhciBtYWdpYyBieXRlcy4KKyAgICAgKiBAc2luY2UgMS4xMQorICAgICAqLworICAgIGludCBYU1RBUl9NQUdJQ19PRkZTRVQgPSA1MDg7CisKKyAgICAvKioKKyAgICAgKiBMZW5ndGggb2YgdGhlIFhTVEFSIG1hZ2ljLgorICAgICAqIEBzaW5jZSAxLjExCisgICAgICovCisgICAgaW50IFhTVEFSX01BR0lDX0xFTiA9IDQ7CisKKyAgICAvKioKKyAgICAgKiBMZW5ndGggb2YgdGhlIHByZWZpeCBmaWVsZCBpbiB4c3RhciBhcmNoaXZlcy4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjExCisgICAgICovCisgICAgaW50IFBSRUZJWExFTl9YU1RBUiA9IDEzMTsKKworICAgIC8qKgorICAgICAqIFRoZSBsZW5ndGggb2YgdGhlIGFjY2VzcyB0aW1lIGZpZWxkIGluIGEgeHN0YXIgaGVhZGVyIGJ1ZmZlci4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjExCisgICAgICovCisgICAgaW50IEFUSU1FTEVOX1hTVEFSID0gMTI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbGVuZ3RoIG9mIHRoZSBjcmVhdGVkIHRpbWUgZmllbGQgaW4gYSB4c3RhciBoZWFkZXIgYnVmZmVyLgorICAgICAqCisgICAgICogQHNpbmNlIDEuMTEKKyAgICAgKi8KKyAgICBpbnQgQ1RJTUVMRU5fWFNUQVIgPSAxMjsKK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy90YXIvVGFyVXRpbHMuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy90YXIvVGFyVXRpbHMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jODNiY2Y5Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3Rhci9UYXJVdGlscy5qYXZhCkBAIC0wLDAgKzEsNjE0IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy50YXI7CisKK2ltcG9ydCBzdGF0aWMgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy50YXIuVGFyQ29uc3RhbnRzLkNIS1NVTUxFTjsKK2ltcG9ydCBzdGF0aWMgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy50YXIuVGFyQ29uc3RhbnRzLkNIS1NVTV9PRkZTRVQ7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGphdmEubmlvLkJ5dGVCdWZmZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXAuWmlwRW5jb2Rpbmc7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXAuWmlwRW5jb2RpbmdIZWxwZXI7CisKKy8qKgorICogVGhpcyBjbGFzcyBwcm92aWRlcyBzdGF0aWMgdXRpbGl0eSBtZXRob2RzIHRvIHdvcmsgd2l0aCBieXRlIHN0cmVhbXMuCisgKgorICogQEltbXV0YWJsZQorICovCisvLyBDaGVja1N0eWxlOkhpZGVVdGlsaXR5Q2xhc3NDb25zdHJ1Y3RvckNoZWNrIE9GRiAoYmMpCitwdWJsaWMgY2xhc3MgVGFyVXRpbHMgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEJZVEVfTUFTSyA9IDI1NTsKKworICAgIHN0YXRpYyBmaW5hbCBaaXBFbmNvZGluZyBERUZBVUxUX0VOQ09ESU5HID0KKyAgICAgICAgWmlwRW5jb2RpbmdIZWxwZXIuZ2V0WmlwRW5jb2RpbmcobnVsbCk7CisKKyAgICAvKioKKyAgICAgKiBFbmNhcHN1bGF0ZXMgdGhlIGFsZ29yaXRobXMgdXNlZCB1cCB0byBDb21tb25zIENvbXByZXNzIDEuMyBhcworICAgICAqIFppcEVuY29kaW5nLgorICAgICAqLworICAgIHN0YXRpYyBmaW5hbCBaaXBFbmNvZGluZyBGQUxMQkFDS19FTkNPRElORyA9IG5ldyBaaXBFbmNvZGluZygpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIGJvb2xlYW4gY2FuRW5jb2RlKGZpbmFsIFN0cmluZyBuYW1lKSB7IHJldHVybiB0cnVlOyB9CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIEJ5dGVCdWZmZXIgZW5jb2RlKGZpbmFsIFN0cmluZyBuYW1lKSB7CisgICAgICAgICAgICAgICAgZmluYWwgaW50IGxlbmd0aCA9IG5hbWUubGVuZ3RoKCk7CisgICAgICAgICAgICAgICAgZmluYWwgYnl0ZVtdIGJ1ZiA9IG5ldyBieXRlW2xlbmd0aF07CisKKyAgICAgICAgICAgICAgICAvLyBjb3B5IHVudGlsIGVuZCBvZiBpbnB1dCBvciBvdXRwdXQgaXMgcmVhY2hlZC4KKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7CisgICAgICAgICAgICAgICAgICAgIGJ1ZltpXSA9IChieXRlKSBuYW1lLmNoYXJBdChpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIEJ5dGVCdWZmZXIud3JhcChidWYpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgZGVjb2RlKGZpbmFsIGJ5dGVbXSBidWZmZXIpIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBpbnQgbGVuZ3RoID0gYnVmZmVyLmxlbmd0aDsKKyAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmdCdWlsZGVyIHJlc3VsdCA9IG5ldyBTdHJpbmdCdWlsZGVyKGxlbmd0aCk7CisKKyAgICAgICAgICAgICAgICBmb3IgKGZpbmFsIGJ5dGUgYiA6IGJ1ZmZlcikgeworICAgICAgICAgICAgICAgICAgICBpZiAoYiA9PSAwKSB7IC8vIFRyYWlsaW5nIG51bGwKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoKGNoYXIpIChiICYgMHhGRikpOyAvLyBBbGxvdyBmb3Igc2lnbi1leHRlbnNpb24KKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0LnRvU3RyaW5nKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH07CisKKyAgICAvKiogUHJpdmF0ZSBjb25zdHJ1Y3RvciB0byBwcmV2ZW50IGluc3RhbnRpYXRpb24gb2YgdGhpcyB1dGlsaXR5IGNsYXNzLiAqLworICAgIHByaXZhdGUgVGFyVXRpbHMoKXsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZSBhbiBvY3RhbCBzdHJpbmcgZnJvbSBhIGJ1ZmZlci4KKyAgICAgKgorICAgICAqIDxwPkxlYWRpbmcgc3BhY2VzIGFyZSBpZ25vcmVkLgorICAgICAqIFRoZSBidWZmZXIgbXVzdCBjb250YWluIGEgdHJhaWxpbmcgc3BhY2Ugb3IgTlVMLAorICAgICAqIGFuZCBtYXkgY29udGFpbiBhbiBhZGRpdGlvbmFsIHRyYWlsaW5nIHNwYWNlIG9yIE5VTC48L3A+CisgICAgICoKKyAgICAgKiA8cD5UaGUgaW5wdXQgYnVmZmVyIGlzIGFsbG93ZWQgdG8gY29udGFpbiBhbGwgTlVMcywKKyAgICAgKiBpbiB3aGljaCBjYXNlIHRoZSBtZXRob2QgcmV0dXJucyAwTAorICAgICAqICh0aGlzIGFsbG93cyBmb3IgbWlzc2luZyBmaWVsZHMpLjwvcD4KKyAgICAgKgorICAgICAqIDxwPlRvIHdvcmstYXJvdW5kIHNvbWUgdGFyIGltcGxlbWVudGF0aW9ucyB0aGF0IGluc2VydCBhCisgICAgICogbGVhZGluZyBOVUwgdGhpcyBtZXRob2QgcmV0dXJucyAwIGlmIGl0IGRldGVjdHMgYSBsZWFkaW5nIE5VTAorICAgICAqIHNpbmNlIENvbW1vbnMgQ29tcHJlc3MgMS40LjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBidWZmZXIgVGhlIGJ1ZmZlciBmcm9tIHdoaWNoIHRvIHBhcnNlLgorICAgICAqIEBwYXJhbSBvZmZzZXQgVGhlIG9mZnNldCBpbnRvIHRoZSBidWZmZXIgZnJvbSB3aGljaCB0byBwYXJzZS4KKyAgICAgKiBAcGFyYW0gbGVuZ3RoIFRoZSBtYXhpbXVtIG51bWJlciBvZiBieXRlcyB0byBwYXJzZSAtIG11c3QgYmUgYXQgbGVhc3QgMiBieXRlcy4KKyAgICAgKiBAcmV0dXJuIFRoZSBsb25nIHZhbHVlIG9mIHRoZSBvY3RhbCBzdHJpbmcuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIHRyYWlsaW5nIHNwYWNlL05VTCBpcyBtaXNzaW5nIG9yIGlmIGEgaW52YWxpZCBieXRlIGlzIGRldGVjdGVkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbG9uZyBwYXJzZU9jdGFsKGZpbmFsIGJ5dGVbXSBidWZmZXIsIGZpbmFsIGludCBvZmZzZXQsIGZpbmFsIGludCBsZW5ndGgpIHsKKyAgICAgICAgbG9uZyAgICByZXN1bHQgPSAwOworICAgICAgICBpbnQgICAgIGVuZCA9IG9mZnNldCArIGxlbmd0aDsKKyAgICAgICAgaW50ICAgICBzdGFydCA9IG9mZnNldDsKKworICAgICAgICBpZiAobGVuZ3RoIDwgMil7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJMZW5ndGggIitsZW5ndGgrIiBtdXN0IGJlIGF0IGxlYXN0IDIiKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChidWZmZXJbc3RhcnRdID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiAwTDsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFNraXAgbGVhZGluZyBzcGFjZXMKKyAgICAgICAgd2hpbGUgKHN0YXJ0IDwgZW5kKXsKKyAgICAgICAgICAgIGlmIChidWZmZXJbc3RhcnRdID09ICcgJyl7CisgICAgICAgICAgICAgICAgc3RhcnQrKzsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyBUcmltIGFsbCB0cmFpbGluZyBOVUxzIGFuZCBzcGFjZXMuCisgICAgICAgIC8vIFRoZSB1c3RhciBhbmQgUE9TSVggdGFyIHNwZWNzIHJlcXVpcmUgYSB0cmFpbGluZyBOVUwgb3IKKyAgICAgICAgLy8gc3BhY2UgYnV0IHNvbWUgaW1wbGVtZW50YXRpb25zIHVzZSB0aGUgZXh0cmEgZGlnaXQgZm9yIGJpZworICAgICAgICAvLyBzaXplcy91aWRzL2dpZHMgLi4uCisgICAgICAgIGJ5dGUgdHJhaWxlciA9IGJ1ZmZlcltlbmQgLSAxXTsKKyAgICAgICAgd2hpbGUgKHN0YXJ0IDwgZW5kICYmICh0cmFpbGVyID09IDAgfHwgdHJhaWxlciA9PSAnICcpKSB7CisgICAgICAgICAgICBlbmQtLTsKKyAgICAgICAgICAgIHRyYWlsZXIgPSBidWZmZXJbZW5kIC0gMV07CisgICAgICAgIH0KKworICAgICAgICBmb3IgKCA7c3RhcnQgPCBlbmQ7IHN0YXJ0KyspIHsKKyAgICAgICAgICAgIGZpbmFsIGJ5dGUgY3VycmVudEJ5dGUgPSBidWZmZXJbc3RhcnRdOworICAgICAgICAgICAgLy8gQ2hlY2tTdHlsZTpNYWdpY051bWJlciBPRkYKKyAgICAgICAgICAgIGlmIChjdXJyZW50Qnl0ZSA8ICcwJyB8fCBjdXJyZW50Qnl0ZSA+ICc3Jyl7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgICAgIGV4Y2VwdGlvbk1lc3NhZ2UoYnVmZmVyLCBvZmZzZXQsIGxlbmd0aCwgc3RhcnQsIGN1cnJlbnRCeXRlKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXN1bHQgPSAocmVzdWx0IDw8IDMpICsgKGN1cnJlbnRCeXRlIC0gJzAnKTsgLy8gY29udmVydCBmcm9tIEFTQ0lJCisgICAgICAgICAgICAvLyBDaGVja1N0eWxlOk1hZ2ljTnVtYmVyIE9OCisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXB1dGUgdGhlIHZhbHVlIGNvbnRhaW5lZCBpbiBhIGJ5dGUgYnVmZmVyLiAgSWYgdGhlIG1vc3QKKyAgICAgKiBzaWduaWZpY2FudCBiaXQgb2YgdGhlIGZpcnN0IGJ5dGUgaW4gdGhlIGJ1ZmZlciBpcyBzZXQsIHRoaXMKKyAgICAgKiBiaXQgaXMgaWdub3JlZCBhbmQgdGhlIHJlc3Qgb2YgdGhlIGJ1ZmZlciBpcyBpbnRlcnByZXRlZCBhcyBhCisgICAgICogYmluYXJ5IG51bWJlci4gIE90aGVyd2lzZSwgdGhlIGJ1ZmZlciBpcyBpbnRlcnByZXRlZCBhcyBhbgorICAgICAqIG9jdGFsIG51bWJlciBhcyBwZXIgdGhlIHBhcnNlT2N0YWwgZnVuY3Rpb24gYWJvdmUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYnVmZmVyIFRoZSBidWZmZXIgZnJvbSB3aGljaCB0byBwYXJzZS4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0IFRoZSBvZmZzZXQgaW50byB0aGUgYnVmZmVyIGZyb20gd2hpY2ggdG8gcGFyc2UuCisgICAgICogQHBhcmFtIGxlbmd0aCBUaGUgbWF4aW11bSBudW1iZXIgb2YgYnl0ZXMgdG8gcGFyc2UuCisgICAgICogQHJldHVybiBUaGUgbG9uZyB2YWx1ZSBvZiB0aGUgb2N0YWwgb3IgYmluYXJ5IHN0cmluZy4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgdHJhaWxpbmcgc3BhY2UvTlVMIGlzCisgICAgICogbWlzc2luZyBvciBhbiBpbnZhbGlkIGJ5dGUgaXMgZGV0ZWN0ZWQgaW4gYW4gb2N0YWwgbnVtYmVyLCBvcgorICAgICAqIGlmIGEgYmluYXJ5IG51bWJlciB3b3VsZCBleGNlZWQgdGhlIHNpemUgb2YgYSBzaWduZWQgbG9uZworICAgICAqIDY0LWJpdCBpbnRlZ2VyLgorICAgICAqIEBzaW5jZSAxLjQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGxvbmcgcGFyc2VPY3RhbE9yQmluYXJ5KGZpbmFsIGJ5dGVbXSBidWZmZXIsIGZpbmFsIGludCBvZmZzZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgbGVuZ3RoKSB7CisKKyAgICAgICAgaWYgKChidWZmZXJbb2Zmc2V0XSAmIDB4ODApID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiBwYXJzZU9jdGFsKGJ1ZmZlciwgb2Zmc2V0LCBsZW5ndGgpOworICAgICAgICB9CisgICAgICAgIGZpbmFsIGJvb2xlYW4gbmVnYXRpdmUgPSBidWZmZXJbb2Zmc2V0XSA9PSAoYnl0ZSkgMHhmZjsKKyAgICAgICAgaWYgKGxlbmd0aCA8IDkpIHsKKyAgICAgICAgICAgIHJldHVybiBwYXJzZUJpbmFyeUxvbmcoYnVmZmVyLCBvZmZzZXQsIGxlbmd0aCwgbmVnYXRpdmUpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBwYXJzZUJpbmFyeUJpZ0ludGVnZXIoYnVmZmVyLCBvZmZzZXQsIGxlbmd0aCwgbmVnYXRpdmUpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGxvbmcgcGFyc2VCaW5hcnlMb25nKGZpbmFsIGJ5dGVbXSBidWZmZXIsIGZpbmFsIGludCBvZmZzZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGxlbmd0aCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBib29sZWFuIG5lZ2F0aXZlKSB7CisgICAgICAgIGlmIChsZW5ndGggPj0gOSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiQXQgb2Zmc2V0ICIgKyBvZmZzZXQgKyAiLCAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgbGVuZ3RoICsgIiBieXRlIGJpbmFyeSBudW1iZXIiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiBleGNlZWRzIG1heGltdW0gc2lnbmVkIGxvbmciCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiB2YWx1ZSIpOworICAgICAgICB9CisgICAgICAgIGxvbmcgdmFsID0gMDsKKyAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPCBsZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdmFsID0gKHZhbCA8PCA4KSArIChidWZmZXJbb2Zmc2V0ICsgaV0gJiAweGZmKTsKKyAgICAgICAgfQorICAgICAgICBpZiAobmVnYXRpdmUpIHsKKyAgICAgICAgICAgIC8vIDIncyBjb21wbGVtZW50CisgICAgICAgICAgICB2YWwtLTsKKyAgICAgICAgICAgIHZhbCBePSAobG9uZykgTWF0aC5wb3coMi4wLCAobGVuZ3RoIC0gMSkgKiA4LjApIC0gMTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmVnYXRpdmUgPyAtdmFsIDogdmFsOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGxvbmcgcGFyc2VCaW5hcnlCaWdJbnRlZ2VyKGZpbmFsIGJ5dGVbXSBidWZmZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IG9mZnNldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgbGVuZ3RoLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGJvb2xlYW4gbmVnYXRpdmUpIHsKKyAgICAgICAgZmluYWwgYnl0ZVtdIHJlbWFpbmRlciA9IG5ldyBieXRlW2xlbmd0aCAtIDFdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGJ1ZmZlciwgb2Zmc2V0ICsgMSwgcmVtYWluZGVyLCAwLCBsZW5ndGggLSAxKTsKKyAgICAgICAgQmlnSW50ZWdlciB2YWwgPSBuZXcgQmlnSW50ZWdlcihyZW1haW5kZXIpOworICAgICAgICBpZiAobmVnYXRpdmUpIHsKKyAgICAgICAgICAgIC8vIDIncyBjb21wbGVtZW50CisgICAgICAgICAgICB2YWwgPSB2YWwuYWRkKEJpZ0ludGVnZXIudmFsdWVPZigtMSkpLm5vdCgpOworICAgICAgICB9CisgICAgICAgIGlmICh2YWwuYml0TGVuZ3RoKCkgPiA2MykgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiQXQgb2Zmc2V0ICIgKyBvZmZzZXQgKyAiLCAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgbGVuZ3RoICsgIiBieXRlIGJpbmFyeSBudW1iZXIiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiBleGNlZWRzIG1heGltdW0gc2lnbmVkIGxvbmciCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiB2YWx1ZSIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZWdhdGl2ZSA/IC12YWwubG9uZ1ZhbHVlKCkgOiB2YWwubG9uZ1ZhbHVlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2UgYSBib29sZWFuIGJ5dGUgZnJvbSBhIGJ1ZmZlci4KKyAgICAgKiBMZWFkaW5nIHNwYWNlcyBhbmQgTlVMIGFyZSBpZ25vcmVkLgorICAgICAqIFRoZSBidWZmZXIgbWF5IGNvbnRhaW4gdHJhaWxpbmcgc3BhY2VzIG9yIE5VTHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYnVmZmVyIFRoZSBidWZmZXIgZnJvbSB3aGljaCB0byBwYXJzZS4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0IFRoZSBvZmZzZXQgaW50byB0aGUgYnVmZmVyIGZyb20gd2hpY2ggdG8gcGFyc2UuCisgICAgICogQHJldHVybiBUaGUgYm9vbGVhbiB2YWx1ZSBvZiB0aGUgYnl0ZXMuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgYW4gaW52YWxpZCBieXRlIGlzIGRldGVjdGVkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBwYXJzZUJvb2xlYW4oZmluYWwgYnl0ZVtdIGJ1ZmZlciwgZmluYWwgaW50IG9mZnNldCkgeworICAgICAgICByZXR1cm4gYnVmZmVyW29mZnNldF0gPT0gMTsKKyAgICB9CisKKyAgICAvLyBIZWxwZXIgbWV0aG9kIHRvIGdlbmVyYXRlIHRoZSBleGNlcHRpb24gbWVzc2FnZQorICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBleGNlcHRpb25NZXNzYWdlKGZpbmFsIGJ5dGVbXSBidWZmZXIsIGZpbmFsIGludCBvZmZzZXQsCisgICAgICAgICAgICBmaW5hbCBpbnQgbGVuZ3RoLCBmaW5hbCBpbnQgY3VycmVudCwgZmluYWwgYnl0ZSBjdXJyZW50Qnl0ZSkgeworICAgICAgICAvLyBkZWZhdWx0IGNoYXJzZXQgaXMgZ29vZCBlbm91Z2ggZm9yIGFuIGV4Y2VwdGlvbiBtZXNzYWdlLAorICAgICAgICAvLworICAgICAgICAvLyB0aGUgYWx0ZXJuYXRpdmUgd2FzIHRvIG1vZGlmeSBwYXJzZU9jdGFsIGFuZAorICAgICAgICAvLyBwYXJzZU9jdGFsT3JCaW5hcnkgdG8gcmVjZWl2ZSB0aGUgWmlwRW5jb2Rpbmcgb2YgdGhlCisgICAgICAgIC8vIGFyY2hpdmUgKGRlcHJlY2F0aW5nIHRoZSBleGlzdGluZyBwdWJsaWMgbWV0aG9kcywgb2YKKyAgICAgICAgLy8gY291cnNlKSBhbmQgZGVhbGluZyB3aXRoIHRoZSBmYWN0IHRoYXQgWmlwRW5jb2RpbmcjZGVjb2RlCisgICAgICAgIC8vIGNhbiB0aHJvdyBhbiBJT0V4Y2VwdGlvbiB3aGljaCBwYXJzZU9jdGFsKiBkb2Vzbid0IGRlY2xhcmUKKyAgICAgICAgU3RyaW5nIHN0cmluZyA9IG5ldyBTdHJpbmcoYnVmZmVyLCBvZmZzZXQsIGxlbmd0aCk7CisKKyAgICAgICAgc3RyaW5nPXN0cmluZy5yZXBsYWNlQWxsKCJcMCIsICJ7TlVMfSIpOyAvLyBSZXBsYWNlIE5VTHMgdG8gYWxsb3cgc3RyaW5nIHRvIGJlIHByaW50ZWQKKyAgICAgICAgcmV0dXJuICJJbnZhbGlkIGJ5dGUgIitjdXJyZW50Qnl0ZSsiIGF0IG9mZnNldCAiKyhjdXJyZW50LW9mZnNldCkrIiBpbiAnIitzdHJpbmcrIicgbGVuPSIrbGVuZ3RoOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlIGFuIGVudHJ5IG5hbWUgZnJvbSBhIGJ1ZmZlci4KKyAgICAgKiBQYXJzaW5nIHN0b3BzIHdoZW4gYSBOVUwgaXMgZm91bmQKKyAgICAgKiBvciB0aGUgYnVmZmVyIGxlbmd0aCBpcyByZWFjaGVkLgorICAgICAqCisgICAgICogQHBhcmFtIGJ1ZmZlciBUaGUgYnVmZmVyIGZyb20gd2hpY2ggdG8gcGFyc2UuCisgICAgICogQHBhcmFtIG9mZnNldCBUaGUgb2Zmc2V0IGludG8gdGhlIGJ1ZmZlciBmcm9tIHdoaWNoIHRvIHBhcnNlLgorICAgICAqIEBwYXJhbSBsZW5ndGggVGhlIG1heGltdW0gbnVtYmVyIG9mIGJ5dGVzIHRvIHBhcnNlLgorICAgICAqIEByZXR1cm4gVGhlIGVudHJ5IG5hbWUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgcGFyc2VOYW1lKGZpbmFsIGJ5dGVbXSBidWZmZXIsIGZpbmFsIGludCBvZmZzZXQsIGZpbmFsIGludCBsZW5ndGgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBwYXJzZU5hbWUoYnVmZmVyLCBvZmZzZXQsIGxlbmd0aCwgREVGQVVMVF9FTkNPRElORyk7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIElPRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZU5hbWUoYnVmZmVyLCBvZmZzZXQsIGxlbmd0aCwgRkFMTEJBQ0tfRU5DT0RJTkcpOworICAgICAgICAgICAgfSBjYXRjaCAoZmluYWwgSU9FeGNlcHRpb24gZXgyKSB7CisgICAgICAgICAgICAgICAgLy8gaW1wb3NzaWJsZQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGV4Mik7IC8vTk9TT05BUgorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2UgYW4gZW50cnkgbmFtZSBmcm9tIGEgYnVmZmVyLgorICAgICAqIFBhcnNpbmcgc3RvcHMgd2hlbiBhIE5VTCBpcyBmb3VuZAorICAgICAqIG9yIHRoZSBidWZmZXIgbGVuZ3RoIGlzIHJlYWNoZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYnVmZmVyIFRoZSBidWZmZXIgZnJvbSB3aGljaCB0byBwYXJzZS4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0IFRoZSBvZmZzZXQgaW50byB0aGUgYnVmZmVyIGZyb20gd2hpY2ggdG8gcGFyc2UuCisgICAgICogQHBhcmFtIGxlbmd0aCBUaGUgbWF4aW11bSBudW1iZXIgb2YgYnl0ZXMgdG8gcGFyc2UuCisgICAgICogQHBhcmFtIGVuY29kaW5nIG5hbWUgb2YgdGhlIGVuY29kaW5nIHRvIHVzZSBmb3IgZmlsZSBuYW1lcworICAgICAqIEBzaW5jZSAxLjQKKyAgICAgKiBAcmV0dXJuIFRoZSBlbnRyeSBuYW1lLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gb24gZXJyb3IKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBwYXJzZU5hbWUoZmluYWwgYnl0ZVtdIGJ1ZmZlciwgZmluYWwgaW50IG9mZnNldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGxlbmd0aCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgWmlwRW5jb2RpbmcgZW5jb2RpbmcpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisKKyAgICAgICAgaW50IGxlbiA9IDA7CisgICAgICAgIGZvciAoaW50IGkgPSBvZmZzZXQ7IGxlbiA8IGxlbmd0aCAmJiBidWZmZXJbaV0gIT0gMDsgaSsrKSB7CisgICAgICAgICAgICBsZW4rKzsKKyAgICAgICAgfQorICAgICAgICBpZiAobGVuID4gMCkgeworICAgICAgICAgICAgZmluYWwgYnl0ZVtdIGIgPSBuZXcgYnl0ZVtsZW5dOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShidWZmZXIsIG9mZnNldCwgYiwgMCwgbGVuKTsKKyAgICAgICAgICAgIHJldHVybiBlbmNvZGluZy5kZWNvZGUoYik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuICIiOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvcHkgYSBuYW1lIGludG8gYSBidWZmZXIuCisgICAgICogQ29waWVzIGNoYXJhY3RlcnMgZnJvbSB0aGUgbmFtZSBpbnRvIHRoZSBidWZmZXIKKyAgICAgKiBzdGFydGluZyBhdCB0aGUgc3BlY2lmaWVkIG9mZnNldC4KKyAgICAgKiBJZiB0aGUgYnVmZmVyIGlzIGxvbmdlciB0aGFuIHRoZSBuYW1lLCB0aGUgYnVmZmVyCisgICAgICogaXMgZmlsbGVkIHdpdGggdHJhaWxpbmcgTlVMcy4KKyAgICAgKiBJZiB0aGUgbmFtZSBpcyBsb25nZXIgdGhhbiB0aGUgYnVmZmVyLAorICAgICAqIHRoZSBvdXRwdXQgaXMgdHJ1bmNhdGVkLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgVGhlIGhlYWRlciBuYW1lIGZyb20gd2hpY2ggdG8gY29weSB0aGUgY2hhcmFjdGVycy4KKyAgICAgKiBAcGFyYW0gYnVmIFRoZSBidWZmZXIgd2hlcmUgdGhlIG5hbWUgaXMgdG8gYmUgc3RvcmVkLgorICAgICAqIEBwYXJhbSBvZmZzZXQgVGhlIHN0YXJ0aW5nIG9mZnNldCBpbnRvIHRoZSBidWZmZXIKKyAgICAgKiBAcGFyYW0gbGVuZ3RoIFRoZSBtYXhpbXVtIG51bWJlciBvZiBoZWFkZXIgYnl0ZXMgdG8gY29weS4KKyAgICAgKiBAcmV0dXJuIFRoZSB1cGRhdGVkIG9mZnNldCwgaS5lLiBvZmZzZXQgKyBsZW5ndGgKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBmb3JtYXROYW1lQnl0ZXMoZmluYWwgU3RyaW5nIG5hbWUsIGZpbmFsIGJ5dGVbXSBidWYsIGZpbmFsIGludCBvZmZzZXQsIGZpbmFsIGludCBsZW5ndGgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBmb3JtYXROYW1lQnl0ZXMobmFtZSwgYnVmLCBvZmZzZXQsIGxlbmd0aCwgREVGQVVMVF9FTkNPRElORyk7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIElPRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHJldHVybiBmb3JtYXROYW1lQnl0ZXMobmFtZSwgYnVmLCBvZmZzZXQsIGxlbmd0aCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZBTExCQUNLX0VOQ09ESU5HKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKGZpbmFsIElPRXhjZXB0aW9uIGV4MikgeworICAgICAgICAgICAgICAgIC8vIGltcG9zc2libGUKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihleDIpOyAvL05PU09OQVIKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENvcHkgYSBuYW1lIGludG8gYSBidWZmZXIuCisgICAgICogQ29waWVzIGNoYXJhY3RlcnMgZnJvbSB0aGUgbmFtZSBpbnRvIHRoZSBidWZmZXIKKyAgICAgKiBzdGFydGluZyBhdCB0aGUgc3BlY2lmaWVkIG9mZnNldC4KKyAgICAgKiBJZiB0aGUgYnVmZmVyIGlzIGxvbmdlciB0aGFuIHRoZSBuYW1lLCB0aGUgYnVmZmVyCisgICAgICogaXMgZmlsbGVkIHdpdGggdHJhaWxpbmcgTlVMcy4KKyAgICAgKiBJZiB0aGUgbmFtZSBpcyBsb25nZXIgdGhhbiB0aGUgYnVmZmVyLAorICAgICAqIHRoZSBvdXRwdXQgaXMgdHJ1bmNhdGVkLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgVGhlIGhlYWRlciBuYW1lIGZyb20gd2hpY2ggdG8gY29weSB0aGUgY2hhcmFjdGVycy4KKyAgICAgKiBAcGFyYW0gYnVmIFRoZSBidWZmZXIgd2hlcmUgdGhlIG5hbWUgaXMgdG8gYmUgc3RvcmVkLgorICAgICAqIEBwYXJhbSBvZmZzZXQgVGhlIHN0YXJ0aW5nIG9mZnNldCBpbnRvIHRoZSBidWZmZXIKKyAgICAgKiBAcGFyYW0gbGVuZ3RoIFRoZSBtYXhpbXVtIG51bWJlciBvZiBoZWFkZXIgYnl0ZXMgdG8gY29weS4KKyAgICAgKiBAcGFyYW0gZW5jb2RpbmcgbmFtZSBvZiB0aGUgZW5jb2RpbmcgdG8gdXNlIGZvciBmaWxlIG5hbWVzCisgICAgICogQHNpbmNlIDEuNAorICAgICAqIEByZXR1cm4gVGhlIHVwZGF0ZWQgb2Zmc2V0LCBpLmUuIG9mZnNldCArIGxlbmd0aAorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gb24gZXJyb3IKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBmb3JtYXROYW1lQnl0ZXMoZmluYWwgU3RyaW5nIG5hbWUsIGZpbmFsIGJ5dGVbXSBidWYsIGZpbmFsIGludCBvZmZzZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBsZW5ndGgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIFppcEVuY29kaW5nIGVuY29kaW5nKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgbGVuID0gbmFtZS5sZW5ndGgoKTsKKyAgICAgICAgQnl0ZUJ1ZmZlciBiID0gZW5jb2RpbmcuZW5jb2RlKG5hbWUpOworICAgICAgICB3aGlsZSAoYi5saW1pdCgpID4gbGVuZ3RoICYmIGxlbiA+IDApIHsKKyAgICAgICAgICAgIGIgPSBlbmNvZGluZy5lbmNvZGUobmFtZS5zdWJzdHJpbmcoMCwgLS1sZW4pKTsKKyAgICAgICAgfQorICAgICAgICBmaW5hbCBpbnQgbGltaXQgPSBiLmxpbWl0KCkgLSBiLnBvc2l0aW9uKCk7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYi5hcnJheSgpLCBiLmFycmF5T2Zmc2V0KCksIGJ1Ziwgb2Zmc2V0LCBsaW1pdCk7CisKKyAgICAgICAgLy8gUGFkIGFueSByZW1haW5pbmcgb3V0cHV0IGJ5dGVzIHdpdGggTlVMCisgICAgICAgIGZvciAoaW50IGkgPSBsaW1pdDsgaSA8IGxlbmd0aDsgKytpKSB7CisgICAgICAgICAgICBidWZbb2Zmc2V0ICsgaV0gPSAwOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIG9mZnNldCArIGxlbmd0aDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaWxsIGJ1ZmZlciB3aXRoIHVuc2lnbmVkIG9jdGFsIG51bWJlciwgcGFkZGVkIHdpdGggbGVhZGluZyB6ZXJvZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsdWUgbnVtYmVyIHRvIGNvbnZlcnQgdG8gb2N0YWwgLSB0cmVhdGVkIGFzIHVuc2lnbmVkCisgICAgICogQHBhcmFtIGJ1ZmZlciBkZXN0aW5hdGlvbiBidWZmZXIKKyAgICAgKiBAcGFyYW0gb2Zmc2V0IHN0YXJ0aW5nIG9mZnNldCBpbiBidWZmZXIKKyAgICAgKiBAcGFyYW0gbGVuZ3RoIGxlbmd0aCBvZiBidWZmZXIgdG8gZmlsbAorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSB2YWx1ZSB3aWxsIG5vdCBmaXQgaW4gdGhlIGJ1ZmZlcgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBmb3JtYXRVbnNpZ25lZE9jdGFsU3RyaW5nKGZpbmFsIGxvbmcgdmFsdWUsIGZpbmFsIGJ5dGVbXSBidWZmZXIsCisgICAgICAgICAgICBmaW5hbCBpbnQgb2Zmc2V0LCBmaW5hbCBpbnQgbGVuZ3RoKSB7CisgICAgICAgIGludCByZW1haW5pbmcgPSBsZW5ndGg7CisgICAgICAgIHJlbWFpbmluZy0tOworICAgICAgICBpZiAodmFsdWUgPT0gMCkgeworICAgICAgICAgICAgYnVmZmVyW29mZnNldCArIHJlbWFpbmluZy0tXSA9IChieXRlKSAnMCc7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBsb25nIHZhbCA9IHZhbHVlOworICAgICAgICAgICAgZm9yICg7IHJlbWFpbmluZyA+PSAwICYmIHZhbCAhPSAwOyAtLXJlbWFpbmluZykgeworICAgICAgICAgICAgICAgIC8vIENoZWNrU3R5bGU6TWFnaWNOdW1iZXIgT0ZGCisgICAgICAgICAgICAgICAgYnVmZmVyW29mZnNldCArIHJlbWFpbmluZ10gPSAoYnl0ZSkgKChieXRlKSAnMCcgKyAoYnl0ZSkgKHZhbCAmIDcpKTsKKyAgICAgICAgICAgICAgICB2YWwgPSB2YWwgPj4+IDM7CisgICAgICAgICAgICAgICAgLy8gQ2hlY2tTdHlsZTpNYWdpY051bWJlciBPTgorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHZhbCAhPSAwKXsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICAgICAgICAgICAgKHZhbHVlKyI9IitMb25nLnRvT2N0YWxTdHJpbmcodmFsdWUpKyAiIHdpbGwgbm90IGZpdCBpbiBvY3RhbCBudW1iZXIgYnVmZmVyIG9mIGxlbmd0aCAiK2xlbmd0aCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBmb3IgKDsgcmVtYWluaW5nID49IDA7IC0tcmVtYWluaW5nKSB7IC8vIGxlYWRpbmcgemVyb3MKKyAgICAgICAgICAgIGJ1ZmZlcltvZmZzZXQgKyByZW1haW5pbmddID0gKGJ5dGUpICcwJzsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlIGFuIG9jdGFsIGludGVnZXIgaW50byBhIGJ1ZmZlci4KKyAgICAgKgorICAgICAqIFVzZXMge0BsaW5rICNmb3JtYXRVbnNpZ25lZE9jdGFsU3RyaW5nfSB0byBmb3JtYXQKKyAgICAgKiB0aGUgdmFsdWUgYXMgYW4gb2N0YWwgc3RyaW5nIHdpdGggbGVhZGluZyB6ZXJvcy4KKyAgICAgKiBUaGUgY29udmVydGVkIG51bWJlciBpcyBmb2xsb3dlZCBieSBzcGFjZSBhbmQgTlVMCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlIHRvIHdyaXRlCisgICAgICogQHBhcmFtIGJ1ZiBUaGUgYnVmZmVyIHRvIHJlY2VpdmUgdGhlIG91dHB1dAorICAgICAqIEBwYXJhbSBvZmZzZXQgVGhlIHN0YXJ0aW5nIG9mZnNldCBpbnRvIHRoZSBidWZmZXIKKyAgICAgKiBAcGFyYW0gbGVuZ3RoIFRoZSBzaXplIG9mIHRoZSBvdXRwdXQgYnVmZmVyCisgICAgICogQHJldHVybiBUaGUgdXBkYXRlZCBvZmZzZXQsIGkuZSBvZmZzZXQrbGVuZ3RoCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIHZhbHVlIChhbmQgdHJhaWxlcikgd2lsbCBub3QgZml0IGluIHRoZSBidWZmZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBmb3JtYXRPY3RhbEJ5dGVzKGZpbmFsIGxvbmcgdmFsdWUsIGZpbmFsIGJ5dGVbXSBidWYsIGZpbmFsIGludCBvZmZzZXQsIGZpbmFsIGludCBsZW5ndGgpIHsKKworICAgICAgICBpbnQgaWR4PWxlbmd0aC0yOyAvLyBGb3Igc3BhY2UgYW5kIHRyYWlsaW5nIG51bGwKKyAgICAgICAgZm9ybWF0VW5zaWduZWRPY3RhbFN0cmluZyh2YWx1ZSwgYnVmLCBvZmZzZXQsIGlkeCk7CisKKyAgICAgICAgYnVmW29mZnNldCArIGlkeCsrXSA9IChieXRlKSAnICc7IC8vIFRyYWlsaW5nIHNwYWNlCisgICAgICAgIGJ1ZltvZmZzZXQgKyBpZHhdICAgPSAwOyAvLyBUcmFpbGluZyBudWxsCisKKyAgICAgICAgcmV0dXJuIG9mZnNldCArIGxlbmd0aDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZSBhbiBvY3RhbCBsb25nIGludGVnZXIgaW50byBhIGJ1ZmZlci4KKyAgICAgKgorICAgICAqIFVzZXMge0BsaW5rICNmb3JtYXRVbnNpZ25lZE9jdGFsU3RyaW5nfSB0byBmb3JtYXQKKyAgICAgKiB0aGUgdmFsdWUgYXMgYW4gb2N0YWwgc3RyaW5nIHdpdGggbGVhZGluZyB6ZXJvcy4KKyAgICAgKiBUaGUgY29udmVydGVkIG51bWJlciBpcyBmb2xsb3dlZCBieSBhIHNwYWNlLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZSB0byB3cml0ZSBhcyBvY3RhbAorICAgICAqIEBwYXJhbSBidWYgVGhlIGRlc3RpbmF0aW9uYnVmZmVyLgorICAgICAqIEBwYXJhbSBvZmZzZXQgVGhlIHN0YXJ0aW5nIG9mZnNldCBpbnRvIHRoZSBidWZmZXIuCisgICAgICogQHBhcmFtIGxlbmd0aCBUaGUgbGVuZ3RoIG9mIHRoZSBidWZmZXIKKyAgICAgKiBAcmV0dXJuIFRoZSB1cGRhdGVkIG9mZnNldAorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSB2YWx1ZSAoYW5kIHRyYWlsZXIpIHdpbGwgbm90IGZpdCBpbiB0aGUgYnVmZmVyCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgZm9ybWF0TG9uZ09jdGFsQnl0ZXMoZmluYWwgbG9uZyB2YWx1ZSwgZmluYWwgYnl0ZVtdIGJ1ZiwgZmluYWwgaW50IG9mZnNldCwgZmluYWwgaW50IGxlbmd0aCkgeworCisgICAgICAgIGZpbmFsIGludCBpZHg9bGVuZ3RoLTE7IC8vIEZvciBzcGFjZQorCisgICAgICAgIGZvcm1hdFVuc2lnbmVkT2N0YWxTdHJpbmcodmFsdWUsIGJ1Ziwgb2Zmc2V0LCBpZHgpOworICAgICAgICBidWZbb2Zmc2V0ICsgaWR4XSA9IChieXRlKSAnICc7IC8vIFRyYWlsaW5nIHNwYWNlCisKKyAgICAgICAgcmV0dXJuIG9mZnNldCArIGxlbmd0aDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZSBhbiBsb25nIGludGVnZXIgaW50byBhIGJ1ZmZlciBhcyBhbiBvY3RhbCBzdHJpbmcgaWYgdGhpcworICAgICAqIHdpbGwgZml0LCBvciBhcyBhIGJpbmFyeSBudW1iZXIgb3RoZXJ3aXNlLgorICAgICAqCisgICAgICogVXNlcyB7QGxpbmsgI2Zvcm1hdFVuc2lnbmVkT2N0YWxTdHJpbmd9IHRvIGZvcm1hdAorICAgICAqIHRoZSB2YWx1ZSBhcyBhbiBvY3RhbCBzdHJpbmcgd2l0aCBsZWFkaW5nIHplcm9zLgorICAgICAqIFRoZSBjb252ZXJ0ZWQgbnVtYmVyIGlzIGZvbGxvd2VkIGJ5IGEgc3BhY2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlIHRvIHdyaXRlIGludG8gdGhlIGJ1ZmZlci4KKyAgICAgKiBAcGFyYW0gYnVmIFRoZSBkZXN0aW5hdGlvbiBidWZmZXIuCisgICAgICogQHBhcmFtIG9mZnNldCBUaGUgc3RhcnRpbmcgb2Zmc2V0IGludG8gdGhlIGJ1ZmZlci4KKyAgICAgKiBAcGFyYW0gbGVuZ3RoIFRoZSBsZW5ndGggb2YgdGhlIGJ1ZmZlci4KKyAgICAgKiBAcmV0dXJuIFRoZSB1cGRhdGVkIG9mZnNldC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgdmFsdWUgKGFuZCB0cmFpbGVyKQorICAgICAqIHdpbGwgbm90IGZpdCBpbiB0aGUgYnVmZmVyLgorICAgICAqIEBzaW5jZSAxLjQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBmb3JtYXRMb25nT2N0YWxPckJpbmFyeUJ5dGVzKAorICAgICAgICBmaW5hbCBsb25nIHZhbHVlLCBmaW5hbCBieXRlW10gYnVmLCBmaW5hbCBpbnQgb2Zmc2V0LCBmaW5hbCBpbnQgbGVuZ3RoKSB7CisKKyAgICAgICAgLy8gQ2hlY2sgd2hldGhlciB3ZSBhcmUgZGVhbGluZyB3aXRoIFVJRC9HSUQgb3IgU0laRSBmaWVsZAorICAgICAgICBmaW5hbCBsb25nIG1heEFzT2N0YWxDaGFyID0gbGVuZ3RoID09IFRhckNvbnN0YW50cy5VSURMRU4gPyBUYXJDb25zdGFudHMuTUFYSUQgOiBUYXJDb25zdGFudHMuTUFYU0laRTsKKworICAgICAgICBmaW5hbCBib29sZWFuIG5lZ2F0aXZlID0gdmFsdWUgPCAwOworICAgICAgICBpZiAoIW5lZ2F0aXZlICYmIHZhbHVlIDw9IG1heEFzT2N0YWxDaGFyKSB7IC8vIE9LIHRvIHN0b3JlIGFzIG9jdGFsIGNoYXJzCisgICAgICAgICAgICByZXR1cm4gZm9ybWF0TG9uZ09jdGFsQnl0ZXModmFsdWUsIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGxlbmd0aCA8IDkpIHsKKyAgICAgICAgICAgIGZvcm1hdExvbmdCaW5hcnkodmFsdWUsIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgsIG5lZ2F0aXZlKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGZvcm1hdEJpZ0ludGVnZXJCaW5hcnkodmFsdWUsIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgsIG5lZ2F0aXZlKTsKKyAgICAgICAgfQorCisgICAgICAgIGJ1ZltvZmZzZXRdID0gKGJ5dGUpIChuZWdhdGl2ZSA/IDB4ZmYgOiAweDgwKTsKKyAgICAgICAgcmV0dXJuIG9mZnNldCArIGxlbmd0aDsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGZvcm1hdExvbmdCaW5hcnkoZmluYWwgbG9uZyB2YWx1ZSwgZmluYWwgYnl0ZVtdIGJ1ZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IG9mZnNldCwgZmluYWwgaW50IGxlbmd0aCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgYm9vbGVhbiBuZWdhdGl2ZSkgeworICAgICAgICBmaW5hbCBpbnQgYml0cyA9IChsZW5ndGggLSAxKSAqIDg7CisgICAgICAgIGZpbmFsIGxvbmcgbWF4ID0gMUwgPDwgYml0czsKKyAgICAgICAgbG9uZyB2YWwgPSBNYXRoLmFicyh2YWx1ZSk7IC8vIExvbmcuTUlOX1ZBTFVFIHN0YXlzIExvbmcuTUlOX1ZBTFVFCisgICAgICAgIGlmICh2YWwgPCAwIHx8IHZhbCA+PSBtYXgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlZhbHVlICIgKyB2YWx1ZSArCisgICAgICAgICAgICAgICAgIiBpcyB0b28gbGFyZ2UgZm9yICIgKyBsZW5ndGggKyAiIGJ5dGUgZmllbGQuIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG5lZ2F0aXZlKSB7CisgICAgICAgICAgICB2YWwgXj0gbWF4IC0gMTsKKyAgICAgICAgICAgIHZhbCsrOworICAgICAgICAgICAgdmFsIHw9IDB4ZmZMIDw8IGJpdHM7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IG9mZnNldCArIGxlbmd0aCAtIDE7IGkgPj0gb2Zmc2V0OyBpLS0pIHsKKyAgICAgICAgICAgIGJ1ZltpXSA9IChieXRlKSB2YWw7CisgICAgICAgICAgICB2YWwgPj49IDg7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGZvcm1hdEJpZ0ludGVnZXJCaW5hcnkoZmluYWwgbG9uZyB2YWx1ZSwgZmluYWwgYnl0ZVtdIGJ1ZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IG9mZnNldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGxlbmd0aCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgYm9vbGVhbiBuZWdhdGl2ZSkgeworICAgICAgICBmaW5hbCBCaWdJbnRlZ2VyIHZhbCA9IEJpZ0ludGVnZXIudmFsdWVPZih2YWx1ZSk7CisgICAgICAgIGZpbmFsIGJ5dGVbXSBiID0gdmFsLnRvQnl0ZUFycmF5KCk7CisgICAgICAgIGZpbmFsIGludCBsZW4gPSBiLmxlbmd0aDsKKyAgICAgICAgaWYgKGxlbiA+IGxlbmd0aCAtIDEpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlZhbHVlICIgKyB2YWx1ZSArCisgICAgICAgICAgICAgICAgIiBpcyB0b28gbGFyZ2UgZm9yICIgKyBsZW5ndGggKyAiIGJ5dGUgZmllbGQuIik7CisgICAgICAgIH0KKyAgICAgICAgZmluYWwgaW50IG9mZiA9IG9mZnNldCArIGxlbmd0aCAtIGxlbjsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShiLCAwLCBidWYsIG9mZiwgbGVuKTsKKyAgICAgICAgZmluYWwgYnl0ZSBmaWxsID0gKGJ5dGUpIChuZWdhdGl2ZSA/IDB4ZmYgOiAwKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IG9mZnNldCArIDE7IGkgPCBvZmY7IGkrKykgeworICAgICAgICAgICAgYnVmW2ldID0gZmlsbDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyBhbiBvY3RhbCB2YWx1ZSBpbnRvIGEgYnVmZmVyLgorICAgICAqCisgICAgICogVXNlcyB7QGxpbmsgI2Zvcm1hdFVuc2lnbmVkT2N0YWxTdHJpbmd9IHRvIGZvcm1hdAorICAgICAqIHRoZSB2YWx1ZSBhcyBhbiBvY3RhbCBzdHJpbmcgd2l0aCBsZWFkaW5nIHplcm9zLgorICAgICAqIFRoZSBjb252ZXJ0ZWQgbnVtYmVyIGlzIGZvbGxvd2VkIGJ5IE5VTCBhbmQgdGhlbiBzcGFjZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29udmVydAorICAgICAqIEBwYXJhbSBidWYgVGhlIGRlc3RpbmF0aW9uIGJ1ZmZlcgorICAgICAqIEBwYXJhbSBvZmZzZXQgVGhlIHN0YXJ0aW5nIG9mZnNldCBpbnRvIHRoZSBidWZmZXIuCisgICAgICogQHBhcmFtIGxlbmd0aCBUaGUgc2l6ZSBvZiB0aGUgYnVmZmVyLgorICAgICAqIEByZXR1cm4gVGhlIHVwZGF0ZWQgdmFsdWUgb2Ygb2Zmc2V0LCBpLmUuIG9mZnNldCtsZW5ndGgKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgdmFsdWUgKGFuZCB0cmFpbGVyKSB3aWxsIG5vdCBmaXQgaW4gdGhlIGJ1ZmZlcgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IGZvcm1hdENoZWNrU3VtT2N0YWxCeXRlcyhmaW5hbCBsb25nIHZhbHVlLCBmaW5hbCBieXRlW10gYnVmLCBmaW5hbCBpbnQgb2Zmc2V0LCBmaW5hbCBpbnQgbGVuZ3RoKSB7CisKKyAgICAgICAgaW50IGlkeD1sZW5ndGgtMjsgLy8gZm9yIE5VTCBhbmQgc3BhY2UKKyAgICAgICAgZm9ybWF0VW5zaWduZWRPY3RhbFN0cmluZyh2YWx1ZSwgYnVmLCBvZmZzZXQsIGlkeCk7CisKKyAgICAgICAgYnVmW29mZnNldCArIGlkeCsrXSAgID0gMDsgLy8gVHJhaWxpbmcgbnVsbAorICAgICAgICBidWZbb2Zmc2V0ICsgaWR4XSAgICAgPSAoYnl0ZSkgJyAnOyAvLyBUcmFpbGluZyBzcGFjZQorCisgICAgICAgIHJldHVybiBvZmZzZXQgKyBsZW5ndGg7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcHV0ZSB0aGUgY2hlY2tzdW0gb2YgYSB0YXIgZW50cnkgaGVhZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGJ1ZiBUaGUgdGFyIGVudHJ5J3MgaGVhZGVyIGJ1ZmZlci4KKyAgICAgKiBAcmV0dXJuIFRoZSBjb21wdXRlZCBjaGVja3N1bS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGxvbmcgY29tcHV0ZUNoZWNrU3VtKGZpbmFsIGJ5dGVbXSBidWYpIHsKKyAgICAgICAgbG9uZyBzdW0gPSAwOworCisgICAgICAgIGZvciAoZmluYWwgYnl0ZSBlbGVtZW50IDogYnVmKSB7CisgICAgICAgICAgICBzdW0gKz0gQllURV9NQVNLICYgZWxlbWVudDsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBzdW07CisgICAgfQorCisgICAgLyoqCisgICAgICogV2lraXBlZGlhIDxhIGhyZWY9Imh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1Rhcl8oZmlsZV9mb3JtYXQpI0ZpbGVfaGVhZGVyIj5zYXlzPC9hPjoKKyAgICAgKiA8YmxvY2txdW90ZT4KKyAgICAgKiBUaGUgY2hlY2tzdW0gaXMgY2FsY3VsYXRlZCBieSB0YWtpbmcgdGhlIHN1bSBvZiB0aGUgdW5zaWduZWQgYnl0ZSB2YWx1ZXMKKyAgICAgKiBvZiB0aGUgaGVhZGVyIGJsb2NrIHdpdGggdGhlIGVpZ2h0IGNoZWNrc3VtIGJ5dGVzIHRha2VuIHRvIGJlIGFzY2lpCisgICAgICogc3BhY2VzIChkZWNpbWFsIHZhbHVlIDMyKS4gSXQgaXMgc3RvcmVkIGFzIGEgc2l4IGRpZ2l0IG9jdGFsIG51bWJlciB3aXRoCisgICAgICogbGVhZGluZyB6ZXJvZXMgZm9sbG93ZWQgYnkgYSBOVUwgYW5kIHRoZW4gYSBzcGFjZS4gVmFyaW91cworICAgICAqIGltcGxlbWVudGF0aW9ucyBkbyBub3QgYWRoZXJlIHRvIHRoaXMgZm9ybWF0LiBGb3IgYmV0dGVyIGNvbXBhdGliaWxpdHksCisgICAgICogaWdub3JlIGxlYWRpbmcgYW5kIHRyYWlsaW5nIHdoaXRlc3BhY2UsIGFuZCBnZXQgdGhlIGZpcnN0IHNpeCBkaWdpdHMuIEluCisgICAgICogYWRkaXRpb24sIHNvbWUgaGlzdG9yaWMgdGFyIGltcGxlbWVudGF0aW9ucyB0cmVhdGVkIGJ5dGVzIGFzIHNpZ25lZC4KKyAgICAgKiBJbXBsZW1lbnRhdGlvbnMgdHlwaWNhbGx5IGNhbGN1bGF0ZSB0aGUgY2hlY2tzdW0gYm90aCB3YXlzLCBhbmQgdHJlYXQgaXQKKyAgICAgKiBhcyBnb29kIGlmIGVpdGhlciB0aGUgc2lnbmVkIG9yIHVuc2lnbmVkIHN1bSBtYXRjaGVzIHRoZSBpbmNsdWRlZAorICAgICAqIGNoZWNrc3VtLgorICAgICAqIDwvYmxvY2txdW90ZT4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgcmV0dXJuIHZhbHVlIG9mIHRoaXMgbWV0aG9kIHNob3VsZCBiZSB0cmVhdGVkIGFzIGEgYmVzdC1lZmZvcnQKKyAgICAgKiBoZXVyaXN0aWMgcmF0aGVyIHRoYW4gYW4gYWJzb2x1dGUgYW5kIGZpbmFsIHRydXRoLiBUaGUgY2hlY2tzdW0KKyAgICAgKiB2ZXJpZmljYXRpb24gbG9naWMgbWF5IHdlbGwgZXZvbHZlIG92ZXIgdGltZSBhcyBtb3JlIHNwZWNpYWwgY2FzZXMKKyAgICAgKiBhcmUgZW5jb3VudGVyZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaGVhZGVyIHRhciBoZWFkZXIKKyAgICAgKiBAcmV0dXJuIHdoZXRoZXIgdGhlIGNoZWNrc3VtIGlzIHJlYXNvbmFibHkgZ29vZAorICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cHM6Ly9pc3N1ZXMuYXBhY2hlLm9yZy9qaXJhL2Jyb3dzZS9DT01QUkVTUy0xOTEiPkNPTVBSRVNTLTE5MTwvYT4KKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIHZlcmlmeUNoZWNrU3VtKGZpbmFsIGJ5dGVbXSBoZWFkZXIpIHsKKyAgICAgICAgZmluYWwgbG9uZyBzdG9yZWRTdW0gPSBwYXJzZU9jdGFsKGhlYWRlciwgQ0hLU1VNX09GRlNFVCwgQ0hLU1VNTEVOKTsKKyAgICAgICAgbG9uZyB1bnNpZ25lZFN1bSA9IDA7CisgICAgICAgIGxvbmcgc2lnbmVkU3VtID0gMDsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGhlYWRlci5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgYnl0ZSBiID0gaGVhZGVyW2ldOworICAgICAgICAgICAgaWYgKENIS1NVTV9PRkZTRVQgIDw9IGkgJiYgaSA8IENIS1NVTV9PRkZTRVQgKyBDSEtTVU1MRU4pIHsKKyAgICAgICAgICAgICAgICBiID0gJyAnOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdW5zaWduZWRTdW0gKz0gMHhmZiAmIGI7CisgICAgICAgICAgICBzaWduZWRTdW0gKz0gYjsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gc3RvcmVkU3VtID09IHVuc2lnbmVkU3VtIHx8IHN0b3JlZFN1bSA9PSBzaWduZWRTdW07CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvdGFyL3BhY2thZ2UuaHRtbCBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy90YXIvcGFja2FnZS5odG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE0MWYzM2IKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvdGFyL3BhY2thZ2UuaHRtbApAQCAtMCwwICsxLDMwIEBACis8aHRtbD4KKzwhLS0KKworICAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAgIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAgIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKworICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorCisgICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKworLS0+CisgIDxib2R5PgorICAgIDxwPlByb3ZpZGVzIHN0cmVhbSBjbGFzc2VzIGZvciByZWFkaW5nIGFuZCB3cml0aW5nIGFyY2hpdmVzIHVzaW5nCisgICAgICB0aGUgVEFSIGZvcm1hdC48L3A+CisKKyAgICA8cD5UaGVyZSBhcmUgbWFueSBkaWZmZXJlbnQgZm9ybWF0IGRpYWxlY3RzIHRoYXQgY2FsbCB0aGVtc2VsdmVzCisgICAgICBUQVIuICBUaGUgY2xhc3NlcyBvZiB0aGlzIHBhY2thZ2UgY2FuIHJlYWQgYW5kIHdyaXRlIGFyY2hpdmVzIGluCisgICAgICB0aGUgdHJhZGl0aW9uYWwgcHJlLVBPU0lYIDxiPnVzdGFyPC9iPiBmb3JtYXQgYW5kIHN1cHBvcnQgR05VCisgICAgICBzcGVjaWZpYyBleHRlbnNpb25zIGZvciBsb25nIGZpbGVuYW1lcyB0aGF0IEdOVSB0YXIgaXRzZWxmIGJ5CisgICAgICBub3cgcmVmZXJzIHRvIGFzIDxiPm9sZGdudTwvYj4uPC9wPgorICA8L2JvZHk+Cis8L2h0bWw+CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL0Fic3RyYWN0VW5pY29kZUV4dHJhRmllbGQuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvQWJzdHJhY3RVbmljb2RlRXh0cmFGaWVsZC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg0NmM5ZTEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL0Fic3RyYWN0VW5pY29kZUV4dHJhRmllbGQuamF2YQpAQCAtMCwwICsxLDE5MiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICoKKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwOworCitpbXBvcnQgamF2YS5pby5VbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC56aXAuQ1JDMzI7CitpbXBvcnQgamF2YS51dGlsLnppcC5aaXBFeGNlcHRpb247CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuQ2hhcnNldE5hbWVzOworCisvKioKKyAqIEEgY29tbW9uIGJhc2UgY2xhc3MgZm9yIFVuaWNvZGUgZXh0cmEgaW5mb3JtYXRpb24gZXh0cmEgZmllbGRzLgorICogQE5vdFRocmVhZFNhZmUKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEFic3RyYWN0VW5pY29kZUV4dHJhRmllbGQgaW1wbGVtZW50cyBaaXBFeHRyYUZpZWxkIHsKKyAgICBwcml2YXRlIGxvbmcgbmFtZUNSQzMyOworICAgIHByaXZhdGUgYnl0ZVtdIHVuaWNvZGVOYW1lOworICAgIHByaXZhdGUgYnl0ZVtdIGRhdGE7CisKKyAgICBwcm90ZWN0ZWQgQWJzdHJhY3RVbmljb2RlRXh0cmFGaWVsZCgpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBc3NlbWJsZSBhcyB1bmljb2RlIGV4dGVuc2lvbiBmcm9tIHRoZSBuYW1lL2NvbW1lbnQgYW5kCisgICAgICogZW5jb2Rpbmcgb2YgdGhlIG9yaWdpbmFsIHppcCBlbnRyeS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0ZXh0IFRoZSBmaWxlIG5hbWUgb3IgY29tbWVudC4KKyAgICAgKiBAcGFyYW0gYnl0ZXMgVGhlIGVuY29kZWQgb2YgdGhlIGZpbGVuYW1lIG9yIGNvbW1lbnQgaW4gdGhlIHppcAorICAgICAqIGZpbGUuCisgICAgICogQHBhcmFtIG9mZiBUaGUgb2Zmc2V0IG9mIHRoZSBlbmNvZGVkIGZpbGVuYW1lIG9yIGNvbW1lbnQgaW4KKyAgICAgKiA8Y29kZT5ieXRlczwvY29kZT4uCisgICAgICogQHBhcmFtIGxlbiBUaGUgbGVuZ3RoIG9mIHRoZSBlbmNvZGVkIGZpbGVuYW1lIG9yIGNvbW1lbnRpbgorICAgICAqIDxjb2RlPmJ5dGVzPC9jb2RlPi4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgQWJzdHJhY3RVbmljb2RlRXh0cmFGaWVsZChmaW5hbCBTdHJpbmcgdGV4dCwgZmluYWwgYnl0ZVtdIGJ5dGVzLCBmaW5hbCBpbnQgb2ZmLCBmaW5hbCBpbnQgbGVuKSB7CisgICAgICAgIGZpbmFsIENSQzMyIGNyYzMyID0gbmV3IENSQzMyKCk7CisgICAgICAgIGNyYzMyLnVwZGF0ZShieXRlcywgb2ZmLCBsZW4pOworICAgICAgICBuYW1lQ1JDMzIgPSBjcmMzMi5nZXRWYWx1ZSgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB1bmljb2RlTmFtZSA9IHRleHQuZ2V0Qnl0ZXMoQ2hhcnNldE5hbWVzLlVURl84KTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiRkFUQUw6IFVURi04IGVuY29kaW5nIG5vdCBzdXBwb3J0ZWQuIiwgZSk7IC8vTk9TT05BUgorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQXNzZW1ibGUgYXMgdW5pY29kZSBleHRlbnNpb24gZnJvbSB0aGUgbmFtZS9jb21tZW50IGFuZAorICAgICAqIGVuY29kaW5nIG9mIHRoZSBvcmlnaW5hbCB6aXAgZW50cnkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGV4dCBUaGUgZmlsZSBuYW1lIG9yIGNvbW1lbnQuCisgICAgICogQHBhcmFtIGJ5dGVzIFRoZSBlbmNvZGVkIG9mIHRoZSBmaWxlbmFtZSBvciBjb21tZW50IGluIHRoZSB6aXAKKyAgICAgKiBmaWxlLgorICAgICAqLworICAgIHByb3RlY3RlZCBBYnN0cmFjdFVuaWNvZGVFeHRyYUZpZWxkKGZpbmFsIFN0cmluZyB0ZXh0LCBmaW5hbCBieXRlW10gYnl0ZXMpIHsKKyAgICAgICAgdGhpcyh0ZXh0LCBieXRlcywgMCwgYnl0ZXMubGVuZ3RoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYXNzZW1ibGVEYXRhKCkgeworICAgICAgICBpZiAodW5pY29kZU5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgZGF0YSA9IG5ldyBieXRlWzUgKyB1bmljb2RlTmFtZS5sZW5ndGhdOworICAgICAgICAvLyB2ZXJzaW9uIDEKKyAgICAgICAgZGF0YVswXSA9IDB4MDE7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoWmlwTG9uZy5nZXRCeXRlcyhuYW1lQ1JDMzIpLCAwLCBkYXRhLCAxLCA0KTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weSh1bmljb2RlTmFtZSwgMCwgZGF0YSwgNSwgdW5pY29kZU5hbWUubGVuZ3RoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcmV0dXJuIFRoZSBDUkMzMiBjaGVja3N1bSBvZiB0aGUgZmlsZW5hbWUgb3IgY29tbWVudCBhcworICAgICAqICAgICAgICAgZW5jb2RlZCBpbiB0aGUgY2VudHJhbCBkaXJlY3Rvcnkgb2YgdGhlIHppcCBmaWxlLgorICAgICAqLworICAgIHB1YmxpYyBsb25nIGdldE5hbWVDUkMzMigpIHsKKyAgICAgICAgcmV0dXJuIG5hbWVDUkMzMjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcGFyYW0gbmFtZUNSQzMyIFRoZSBDUkMzMiBjaGVja3N1bSBvZiB0aGUgZmlsZW5hbWUgYXMgZW5jb2RlZAorICAgICAqICAgICAgICAgaW4gdGhlIGNlbnRyYWwgZGlyZWN0b3J5IG9mIHRoZSB6aXAgZmlsZSB0byBzZXQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TmFtZUNSQzMyKGZpbmFsIGxvbmcgbmFtZUNSQzMyKSB7CisgICAgICAgIHRoaXMubmFtZUNSQzMyID0gbmFtZUNSQzMyOworICAgICAgICBkYXRhID0gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcmV0dXJuIFRoZSBVVEYtOCBlbmNvZGVkIG5hbWUuCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXRVbmljb2RlTmFtZSgpIHsKKyAgICAgICAgYnl0ZVtdIGIgPSBudWxsOworICAgICAgICBpZiAodW5pY29kZU5hbWUgIT0gbnVsbCkgeworICAgICAgICAgICAgYiA9IG5ldyBieXRlW3VuaWNvZGVOYW1lLmxlbmd0aF07CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHVuaWNvZGVOYW1lLCAwLCBiLCAwLCBiLmxlbmd0aCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGI7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHBhcmFtIHVuaWNvZGVOYW1lIFRoZSBVVEYtOCBlbmNvZGVkIG5hbWUgdG8gc2V0LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFVuaWNvZGVOYW1lKGZpbmFsIGJ5dGVbXSB1bmljb2RlTmFtZSkgeworICAgICAgICBpZiAodW5pY29kZU5hbWUgIT0gbnVsbCkgeworICAgICAgICAgICAgdGhpcy51bmljb2RlTmFtZSA9IG5ldyBieXRlW3VuaWNvZGVOYW1lLmxlbmd0aF07CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHVuaWNvZGVOYW1lLCAwLCB0aGlzLnVuaWNvZGVOYW1lLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmljb2RlTmFtZS5sZW5ndGgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhpcy51bmljb2RlTmFtZSA9IG51bGw7CisgICAgICAgIH0KKyAgICAgICAgZGF0YSA9IG51bGw7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJ5dGVbXSBnZXRDZW50cmFsRGlyZWN0b3J5RGF0YSgpIHsKKyAgICAgICAgaWYgKGRhdGEgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhpcy5hc3NlbWJsZURhdGEoKTsKKyAgICAgICAgfQorICAgICAgICBieXRlW10gYiA9IG51bGw7CisgICAgICAgIGlmIChkYXRhICE9IG51bGwpIHsKKyAgICAgICAgICAgIGIgPSBuZXcgYnl0ZVtkYXRhLmxlbmd0aF07CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGRhdGEsIDAsIGIsIDAsIGIubGVuZ3RoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgWmlwU2hvcnQgZ2V0Q2VudHJhbERpcmVjdG9yeUxlbmd0aCgpIHsKKyAgICAgICAgaWYgKGRhdGEgPT0gbnVsbCkgeworICAgICAgICAgICAgYXNzZW1ibGVEYXRhKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBaaXBTaG9ydChkYXRhICE9IG51bGwgPyBkYXRhLmxlbmd0aCA6IDApOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBieXRlW10gZ2V0TG9jYWxGaWxlRGF0YURhdGEoKSB7CisgICAgICAgIHJldHVybiBnZXRDZW50cmFsRGlyZWN0b3J5RGF0YSgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBaaXBTaG9ydCBnZXRMb2NhbEZpbGVEYXRhTGVuZ3RoKCkgeworICAgICAgICByZXR1cm4gZ2V0Q2VudHJhbERpcmVjdG9yeUxlbmd0aCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHBhcnNlRnJvbUxvY2FsRmlsZURhdGEoZmluYWwgYnl0ZVtdIGJ1ZmZlciwgZmluYWwgaW50IG9mZnNldCwgZmluYWwgaW50IGxlbmd0aCkKKyAgICAgICAgdGhyb3dzIFppcEV4Y2VwdGlvbiB7CisKKyAgICAgICAgaWYgKGxlbmd0aCA8IDUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBaaXBFeGNlcHRpb24oIlVuaUNvZGUgcGF0aCBleHRyYSBkYXRhIG11c3QgaGF2ZSBhdCBsZWFzdCA1IGJ5dGVzLiIpOworICAgICAgICB9CisKKyAgICAgICAgZmluYWwgaW50IHZlcnNpb24gPSBidWZmZXJbb2Zmc2V0XTsKKworICAgICAgICBpZiAodmVyc2lvbiAhPSAweDAxKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgWmlwRXhjZXB0aW9uKCJVbnN1cHBvcnRlZCB2ZXJzaW9uIFsiICsgdmVyc2lvbgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICJdIGZvciBVbmlDb2RlIHBhdGggZXh0cmEgZGF0YS4iKTsKKyAgICAgICAgfQorCisgICAgICAgIG5hbWVDUkMzMiA9IFppcExvbmcuZ2V0VmFsdWUoYnVmZmVyLCBvZmZzZXQgKyAxKTsKKyAgICAgICAgdW5pY29kZU5hbWUgPSBuZXcgYnl0ZVtsZW5ndGggLSA1XTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShidWZmZXIsIG9mZnNldCArIDUsIHVuaWNvZGVOYW1lLCAwLCBsZW5ndGggLSA1KTsKKyAgICAgICAgZGF0YSA9IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogRG9lc24ndCBkbyBhbnl0aGluZyBzcGVjaWFsIHNpbmNlIHRoaXMgY2xhc3MgYWx3YXlzIHVzZXMgdGhlCisgICAgICogc2FtZSBkYXRhIGluIGNlbnRyYWwgZGlyZWN0b3J5IGFuZCBsb2NhbCBmaWxlIGRhdGEuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcGFyc2VGcm9tQ2VudHJhbERpcmVjdG9yeURhdGEoZmluYWwgYnl0ZVtdIGJ1ZmZlciwgZmluYWwgaW50IG9mZnNldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgbGVuZ3RoKQorICAgICAgICB0aHJvd3MgWmlwRXhjZXB0aW9uIHsKKyAgICAgICAgcGFyc2VGcm9tTG9jYWxGaWxlRGF0YShidWZmZXIsIG9mZnNldCwgbGVuZ3RoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL0FzaUV4dHJhRmllbGQuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvQXNpRXh0cmFGaWVsZC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU0YWZhOTUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL0FzaUV4dHJhRmllbGQuamF2YQpAQCAtMCwwICsxLDMzNyBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwOworCitpbXBvcnQgamF2YS51dGlsLnppcC5DUkMzMjsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLlppcEV4Y2VwdGlvbjsKKworLyoqCisgKiBBZGRzIFVuaXggZmlsZSBwZXJtaXNzaW9uIGFuZCBVSUQvR0lEIGZpZWxkcyBhcyB3ZWxsIGFzIHN5bWJvbGljCisgKiBsaW5rIGhhbmRsaW5nLgorICoKKyAqIDxwPlRoaXMgY2xhc3MgdXNlcyB0aGUgQVNpIGV4dHJhIGZpZWxkIGluIHRoZSBmb3JtYXQ6PC9wPgorICogPHByZT4KKyAqICAgICAgICAgVmFsdWUgICAgICAgICBTaXplICAgICAgICAgICAgRGVzY3JpcHRpb24KKyAqICAgICAgICAgLS0tLS0gICAgICAgICAtLS0tICAgICAgICAgICAgLS0tLS0tLS0tLS0KKyAqIChVbml4MykgMHg3NTZlICAgICAgICBTaG9ydCAgICAgICAgICAgdGFnIGZvciB0aGlzIGV4dHJhIGJsb2NrIHR5cGUKKyAqICAgICAgICAgVFNpemUgICAgICAgICBTaG9ydCAgICAgICAgICAgdG90YWwgZGF0YSBzaXplIGZvciB0aGlzIGJsb2NrCisgKiAgICAgICAgIENSQyAgICAgICAgICAgTG9uZyAgICAgICAgICAgIENSQy0zMiBvZiB0aGUgcmVtYWluaW5nIGRhdGEKKyAqICAgICAgICAgTW9kZSAgICAgICAgICBTaG9ydCAgICAgICAgICAgZmlsZSBwZXJtaXNzaW9ucworICogICAgICAgICBTaXpEZXYgICAgICAgIExvbmcgICAgICAgICAgICBzeW1saW5rJ2Qgc2l6ZSBPUiBtYWpvci9taW5vciBkZXYgbnVtCisgKiAgICAgICAgIFVJRCAgICAgICAgICAgU2hvcnQgICAgICAgICAgIHVzZXIgSUQKKyAqICAgICAgICAgR0lEICAgICAgICAgICBTaG9ydCAgICAgICAgICAgZ3JvdXAgSUQKKyAqICAgICAgICAgKHZhci4pICAgICAgICB2YXJpYWJsZSAgICAgICAgc3ltYm9saWMgbGluayBmaWxlbmFtZQorICogPC9wcmU+CisgKiA8cD50YWtlbiBmcm9tIGFwcG5vdGUuaXogKEluZm8tWklQIG5vdGUsIDk4MTExOSkgZm91bmQgYXQgPGEKKyAqIGhyZWY9ImZ0cDovL2Z0cC51dS5uZXQvcHViL2FyY2hpdmluZy96aXAvZG9jLyI+ZnRwOi8vZnRwLnV1Lm5ldC9wdWIvYXJjaGl2aW5nL3ppcC9kb2MvPC9hPjwvcD4KKyAqCisgKiA8cD5TaG9ydCBpcyB0d28gYnl0ZXMgYW5kIExvbmcgaXMgZm91ciBieXRlcyBpbiBiaWcgZW5kaWFuIGJ5dGUgYW5kCisgKiB3b3JkIG9yZGVyLCBkZXZpY2UgbnVtYmVycyBhcmUgY3VycmVudGx5IG5vdCBzdXBwb3J0ZWQuPC9wPgorICogQE5vdFRocmVhZFNhZmUKKyAqCisgKiA8cD5TaW5jZSB0aGUgZG9jdW1lbnRhdGlvbiB0aGlzIGNsYXNzIGlzIGJhc2VkIHVwb24gZG9lc24ndCBtZW50aW9uCisgKiB0aGUgY2hhcmFjdGVyIGVuY29kaW5nIG9mIHRoZSBmaWxlIG5hbWUgYXQgYWxsLCBpdCBpcyBhc3N1bWVkIHRoYXQKKyAqIGl0IHVzZXMgdGhlIGN1cnJlbnQgcGxhdGZvcm0ncyBkZWZhdWx0IGVuY29kaW5nLjwvcD4KKyAqLworcHVibGljIGNsYXNzIEFzaUV4dHJhRmllbGQgaW1wbGVtZW50cyBaaXBFeHRyYUZpZWxkLCBVbml4U3RhdCwgQ2xvbmVhYmxlIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFppcFNob3J0IEhFQURFUl9JRCA9IG5ldyBaaXBTaG9ydCgweDc1NkUpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCAgICAgIFdPUkQgPSA0OworICAgIC8qKgorICAgICAqIFN0YW5kYXJkIFVuaXggc3RhdCgyKSBmaWxlIG1vZGUuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgbW9kZSA9IDA7CisgICAgLyoqCisgICAgICogVXNlciBJRC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCB1aWQgPSAwOworICAgIC8qKgorICAgICAqIEdyb3VwIElELgorICAgICAqLworICAgIHByaXZhdGUgaW50IGdpZCA9IDA7CisgICAgLyoqCisgICAgICogRmlsZSB0aGlzIGVudHJ5IHBvaW50cyB0bywgaWYgaXQgaXMgYSBzeW1ib2xpYyBsaW5rLgorICAgICAqCisgICAgICogPHA+ZW1wdHkgc3RyaW5nIC0gaWYgZW50cnkgaXMgbm90IGEgc3ltYm9saWMgbGluay48L3A+CisgICAgICovCisgICAgcHJpdmF0ZSBTdHJpbmcgbGluayA9ICIiOworICAgIC8qKgorICAgICAqIElzIHRoaXMgYW4gZW50cnkgZm9yIGEgZGlyZWN0b3J5PworICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBkaXJGbGFnID0gZmFsc2U7CisKKyAgICAvKioKKyAgICAgKiBJbnN0YW5jZSB1c2VkIHRvIGNhbGN1bGF0ZSBjaGVja3N1bXMuCisgICAgICovCisgICAgcHJpdmF0ZSBDUkMzMiBjcmMgPSBuZXcgQ1JDMzIoKTsKKworICAgIC8qKiBDb25zdHJ1Y3RvciBmb3IgQXNpRXh0cmFGaWVsZC4gKi8KKyAgICBwdWJsaWMgQXNpRXh0cmFGaWVsZCgpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgSGVhZGVyLUlELgorICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIGZvciB0aGUgaGVhZGVyIGlkIGZvciB0aGlzIGV4dHJhZmllbGQKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgWmlwU2hvcnQgZ2V0SGVhZGVySWQoKSB7CisgICAgICAgIHJldHVybiBIRUFERVJfSUQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogTGVuZ3RoIG9mIHRoZSBleHRyYSBmaWVsZCBpbiB0aGUgbG9jYWwgZmlsZSBkYXRhIC0gd2l0aG91dAorICAgICAqIEhlYWRlci1JRCBvciBsZW5ndGggc3BlY2lmaWVyLgorICAgICAqIEByZXR1cm4gYSA8Y29kZT5aaXBTaG9ydDwvY29kZT4gZm9yIHRoZSBsZW5ndGggb2YgdGhlIGRhdGEgb2YgdGhpcyBleHRyYSBmaWVsZAorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBaaXBTaG9ydCBnZXRMb2NhbEZpbGVEYXRhTGVuZ3RoKCkgeworICAgICAgICByZXR1cm4gbmV3IFppcFNob3J0KFdPUkQgICAgICAgICAvLyBDUkMKKyAgICAgICAgICAgICAgICAgICAgICAgICAgKyAyICAgICAgICAgLy8gTW9kZQorICAgICAgICAgICAgICAgICAgICAgICAgICArIFdPUkQgICAgICAgICAvLyBTaXpEZXYKKyAgICAgICAgICAgICAgICAgICAgICAgICAgKyAyICAgICAgICAgLy8gVUlECisgICAgICAgICAgICAgICAgICAgICAgICAgICsgMiAgICAgICAgIC8vIEdJRAorICAgICAgICAgICAgICAgICAgICAgICAgICArIGdldExpbmtlZEZpbGUoKS5nZXRCeXRlcygpLmxlbmd0aCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFVzZXMgZGVmYXVsdCBjaGFyc2V0IC0gc2VlIGNsYXNzIEphdmFkb2MKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZWxlZ2F0ZSB0byBsb2NhbCBmaWxlIGRhdGEuCisgICAgICogQHJldHVybiB0aGUgY2VudHJhbERpcmVjdG9yeSBsZW5ndGgKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgWmlwU2hvcnQgZ2V0Q2VudHJhbERpcmVjdG9yeUxlbmd0aCgpIHsKKyAgICAgICAgcmV0dXJuIGdldExvY2FsRmlsZURhdGFMZW5ndGgoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgYWN0dWFsIGRhdGEgdG8gcHV0IGludG8gbG9jYWwgZmlsZSBkYXRhIC0gd2l0aG91dCBIZWFkZXItSUQKKyAgICAgKiBvciBsZW5ndGggc3BlY2lmaWVyLgorICAgICAqIEByZXR1cm4gZ2V0IHRoZSBkYXRhCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJ5dGVbXSBnZXRMb2NhbEZpbGVEYXRhRGF0YSgpIHsKKyAgICAgICAgLy8gQ1JDIHdpbGwgYmUgYWRkZWQgbGF0ZXIKKyAgICAgICAgZmluYWwgYnl0ZVtdIGRhdGEgPSBuZXcgYnl0ZVtnZXRMb2NhbEZpbGVEYXRhTGVuZ3RoKCkuZ2V0VmFsdWUoKSAtIFdPUkRdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KFppcFNob3J0LmdldEJ5dGVzKGdldE1vZGUoKSksIDAsIGRhdGEsIDAsIDIpOworCisgICAgICAgIGZpbmFsIGJ5dGVbXSBsaW5rQXJyYXkgPSBnZXRMaW5rZWRGaWxlKCkuZ2V0Qnl0ZXMoKTsgLy8gVXNlcyBkZWZhdWx0IGNoYXJzZXQgLSBzZWUgY2xhc3MgSmF2YWRvYworICAgICAgICAvLyBDaGVja1N0eWxlOk1hZ2ljTnVtYmVyIE9GRgorICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KFppcExvbmcuZ2V0Qnl0ZXMobGlua0FycmF5Lmxlbmd0aCksCisgICAgICAgICAgICAgICAgICAgICAgICAgMCwgZGF0YSwgMiwgV09SRCk7CisKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShaaXBTaG9ydC5nZXRCeXRlcyhnZXRVc2VySWQoKSksCisgICAgICAgICAgICAgICAgICAgICAgICAgMCwgZGF0YSwgNiwgMik7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoWmlwU2hvcnQuZ2V0Qnl0ZXMoZ2V0R3JvdXBJZCgpKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAwLCBkYXRhLCA4LCAyKTsKKworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGxpbmtBcnJheSwgMCwgZGF0YSwgMTAsIGxpbmtBcnJheS5sZW5ndGgpOworICAgICAgICAvLyBDaGVja1N0eWxlOk1hZ2ljTnVtYmVyIE9OCisKKyAgICAgICAgY3JjLnJlc2V0KCk7CisgICAgICAgIGNyYy51cGRhdGUoZGF0YSk7CisgICAgICAgIGZpbmFsIGxvbmcgY2hlY2tzdW0gPSBjcmMuZ2V0VmFsdWUoKTsKKworICAgICAgICBmaW5hbCBieXRlW10gcmVzdWx0ID0gbmV3IGJ5dGVbZGF0YS5sZW5ndGggKyBXT1JEXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShaaXBMb25nLmdldEJ5dGVzKGNoZWNrc3VtKSwgMCwgcmVzdWx0LCAwLCBXT1JEKTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShkYXRhLCAwLCByZXN1bHQsIFdPUkQsIGRhdGEubGVuZ3RoKTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZWxlZ2F0ZSB0byBsb2NhbCBmaWxlIGRhdGEuCisgICAgICogQHJldHVybiB0aGUgbG9jYWwgZmlsZSBkYXRhCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJ5dGVbXSBnZXRDZW50cmFsRGlyZWN0b3J5RGF0YSgpIHsKKyAgICAgICAgcmV0dXJuIGdldExvY2FsRmlsZURhdGFEYXRhKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSB1c2VyIGlkLgorICAgICAqIEBwYXJhbSB1aWQgdGhlIHVzZXIgaWQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRVc2VySWQoZmluYWwgaW50IHVpZCkgeworICAgICAgICB0aGlzLnVpZCA9IHVpZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIHVzZXIgaWQuCisgICAgICogQHJldHVybiB0aGUgdXNlciBpZAorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0VXNlcklkKCkgeworICAgICAgICByZXR1cm4gdWlkOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgZ3JvdXAgaWQuCisgICAgICogQHBhcmFtIGdpZCB0aGUgZ3JvdXAgaWQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRHcm91cElkKGZpbmFsIGludCBnaWQpIHsKKyAgICAgICAgdGhpcy5naWQgPSBnaWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBncm91cCBpZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBncm91cCBpZAorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0R3JvdXBJZCgpIHsKKyAgICAgICAgcmV0dXJuIGdpZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZSB0aGF0IHRoaXMgZW50cnkgaXMgYSBzeW1ib2xpYyBsaW5rIHRvIHRoZSBnaXZlbiBmaWxlbmFtZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lIE5hbWUgb2YgdGhlIGZpbGUgdGhpcyBlbnRyeSBsaW5rcyB0bywgZW1wdHkgU3RyaW5nCisgICAgICogICAgICAgICAgICAgaWYgaXQgaXMgbm90IGEgc3ltYm9saWMgbGluay4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRMaW5rZWRGaWxlKGZpbmFsIFN0cmluZyBuYW1lKSB7CisgICAgICAgIGxpbmsgPSBuYW1lOworICAgICAgICBtb2RlID0gZ2V0TW9kZShtb2RlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBOYW1lIG9mIGxpbmtlZCBmaWxlCisgICAgICoKKyAgICAgKiBAcmV0dXJuIG5hbWUgb2YgdGhlIGZpbGUgdGhpcyBlbnRyeSBsaW5rcyB0byBpZiBpdCBpcyBhCisgICAgICogICAgICAgICBzeW1ib2xpYyBsaW5rLCB0aGUgZW1wdHkgc3RyaW5nIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldExpbmtlZEZpbGUoKSB7CisgICAgICAgIHJldHVybiBsaW5rOworICAgIH0KKworICAgIC8qKgorICAgICAqIElzIHRoaXMgZW50cnkgYSBzeW1ib2xpYyBsaW5rPworICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGlzIGlzIGEgc3ltYm9saWMgbGluaworICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzTGluaygpIHsKKyAgICAgICAgcmV0dXJuIGdldExpbmtlZEZpbGUoKS5sZW5ndGgoKSAhPSAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbGUgbW9kZSBvZiB0aGlzIGZpbGUuCisgICAgICogQHBhcmFtIG1vZGUgdGhlIGZpbGUgbW9kZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE1vZGUoZmluYWwgaW50IG1vZGUpIHsKKyAgICAgICAgdGhpcy5tb2RlID0gZ2V0TW9kZShtb2RlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaWxlIG1vZGUgb2YgdGhpcyBmaWxlLgorICAgICAqIEByZXR1cm4gdGhlIGZpbGUgbW9kZQorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TW9kZSgpIHsKKyAgICAgICAgcmV0dXJuIG1vZGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGUgd2hldGhlciB0aGlzIGVudHJ5IGlzIGEgZGlyZWN0b3J5LgorICAgICAqIEBwYXJhbSBkaXJGbGFnIGlmIHRydWUsIHRoaXMgZW50cnkgaXMgYSBkaXJlY3RvcnkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXREaXJlY3RvcnkoZmluYWwgYm9vbGVhbiBkaXJGbGFnKSB7CisgICAgICAgIHRoaXMuZGlyRmxhZyA9IGRpckZsYWc7CisgICAgICAgIG1vZGUgPSBnZXRNb2RlKG1vZGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIElzIHRoaXMgZW50cnkgYSBkaXJlY3Rvcnk/CisgICAgICogQHJldHVybiB0cnVlIGlmIHRoaXMgZW50cnkgaXMgYSBkaXJlY3RvcnkKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0RpcmVjdG9yeSgpIHsKKyAgICAgICAgcmV0dXJuIGRpckZsYWcgJiYgIWlzTGluaygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBvcHVsYXRlIGRhdGEgZnJvbSB0aGlzIGFycmF5IGFzIGlmIGl0IHdhcyBpbiBsb2NhbCBmaWxlIGRhdGEuCisgICAgICogQHBhcmFtIGRhdGEgYW4gYXJyYXkgb2YgYnl0ZXMKKyAgICAgKiBAcGFyYW0gb2Zmc2V0IHRoZSBzdGFydCBvZmZzZXQKKyAgICAgKiBAcGFyYW0gbGVuZ3RoIHRoZSBudW1iZXIgb2YgYnl0ZXMgaW4gdGhlIGFycmF5IGZyb20gb2Zmc2V0CisgICAgICogQHRocm93cyBaaXBFeGNlcHRpb24gb24gZXJyb3IKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBwYXJzZUZyb21Mb2NhbEZpbGVEYXRhKGZpbmFsIGJ5dGVbXSBkYXRhLCBmaW5hbCBpbnQgb2Zmc2V0LCBmaW5hbCBpbnQgbGVuZ3RoKQorICAgICAgICB0aHJvd3MgWmlwRXhjZXB0aW9uIHsKKworICAgICAgICBmaW5hbCBsb25nIGdpdmVuQ2hlY2tzdW0gPSBaaXBMb25nLmdldFZhbHVlKGRhdGEsIG9mZnNldCk7CisgICAgICAgIGZpbmFsIGJ5dGVbXSB0bXAgPSBuZXcgYnl0ZVtsZW5ndGggLSBXT1JEXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShkYXRhLCBvZmZzZXQgKyBXT1JELCB0bXAsIDAsIGxlbmd0aCAtIFdPUkQpOworICAgICAgICBjcmMucmVzZXQoKTsKKyAgICAgICAgY3JjLnVwZGF0ZSh0bXApOworICAgICAgICBmaW5hbCBsb25nIHJlYWxDaGVja3N1bSA9IGNyYy5nZXRWYWx1ZSgpOworICAgICAgICBpZiAoZ2l2ZW5DaGVja3N1bSAhPSByZWFsQ2hlY2tzdW0pIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBaaXBFeGNlcHRpb24oImJhZCBDUkMgY2hlY2tzdW0gIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIExvbmcudG9IZXhTdHJpbmcoZ2l2ZW5DaGVja3N1bSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIGluc3RlYWQgb2YgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIExvbmcudG9IZXhTdHJpbmcocmVhbENoZWNrc3VtKSk7CisgICAgICAgIH0KKworICAgICAgICBmaW5hbCBpbnQgbmV3TW9kZSA9IFppcFNob3J0LmdldFZhbHVlKHRtcCwgMCk7CisgICAgICAgIC8vIENoZWNrU3R5bGU6TWFnaWNOdW1iZXIgT0ZGCisgICAgICAgIGZpbmFsIGJ5dGVbXSBsaW5rQXJyYXkgPSBuZXcgYnl0ZVsoaW50KSBaaXBMb25nLmdldFZhbHVlKHRtcCwgMildOworICAgICAgICB1aWQgPSBaaXBTaG9ydC5nZXRWYWx1ZSh0bXAsIDYpOworICAgICAgICBnaWQgPSBaaXBTaG9ydC5nZXRWYWx1ZSh0bXAsIDgpOworCisgICAgICAgIGlmIChsaW5rQXJyYXkubGVuZ3RoID09IDApIHsKKyAgICAgICAgICAgIGxpbmsgPSAiIjsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkodG1wLCAxMCwgbGlua0FycmF5LCAwLCBsaW5rQXJyYXkubGVuZ3RoKTsKKyAgICAgICAgICAgIGxpbmsgPSBuZXcgU3RyaW5nKGxpbmtBcnJheSk7IC8vIFVzZXMgZGVmYXVsdCBjaGFyc2V0IC0gc2VlIGNsYXNzIEphdmFkb2MKKyAgICAgICAgfQorICAgICAgICAvLyBDaGVja1N0eWxlOk1hZ2ljTnVtYmVyIE9OCisgICAgICAgIHNldERpcmVjdG9yeSgobmV3TW9kZSAmIERJUl9GTEFHKSAhPSAwKTsKKyAgICAgICAgc2V0TW9kZShuZXdNb2RlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEb2Vzbid0IGRvIGFueXRoaW5nIHNwZWNpYWwgc2luY2UgdGhpcyBjbGFzcyBhbHdheXMgdXNlcyB0aGUKKyAgICAgKiBzYW1lIGRhdGEgaW4gY2VudHJhbCBkaXJlY3RvcnkgYW5kIGxvY2FsIGZpbGUgZGF0YS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBwYXJzZUZyb21DZW50cmFsRGlyZWN0b3J5RGF0YShmaW5hbCBieXRlW10gYnVmZmVyLCBmaW5hbCBpbnQgb2Zmc2V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBsZW5ndGgpCisgICAgICAgIHRocm93cyBaaXBFeGNlcHRpb24geworICAgICAgICBwYXJzZUZyb21Mb2NhbEZpbGVEYXRhKGJ1ZmZlciwgb2Zmc2V0LCBsZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgZmlsZSBtb2RlIGZvciBnaXZlbiBwZXJtaXNzaW9ucyB3aXRoIHRoZSBjb3JyZWN0IGZpbGUgdHlwZS4KKyAgICAgKiBAcGFyYW0gbW9kZSB0aGUgbW9kZQorICAgICAqIEByZXR1cm4gdGhlIHR5cGUgd2l0aCB0aGUgbW9kZQorICAgICAqLworICAgIHByb3RlY3RlZCBpbnQgZ2V0TW9kZShmaW5hbCBpbnQgbW9kZSkgeworICAgICAgICBpbnQgdHlwZSA9IEZJTEVfRkxBRzsKKyAgICAgICAgaWYgKGlzTGluaygpKSB7CisgICAgICAgICAgICB0eXBlID0gTElOS19GTEFHOworICAgICAgICB9IGVsc2UgaWYgKGlzRGlyZWN0b3J5KCkpIHsKKyAgICAgICAgICAgIHR5cGUgPSBESVJfRkxBRzsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdHlwZSB8IChtb2RlICYgUEVSTV9NQVNLKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmluYWwgQXNpRXh0cmFGaWVsZCBjbG9uZWQgPSAoQXNpRXh0cmFGaWVsZCkgc3VwZXIuY2xvbmUoKTsKKyAgICAgICAgICAgIGNsb25lZC5jcmMgPSBuZXcgQ1JDMzIoKTsKKyAgICAgICAgICAgIHJldHVybiBjbG9uZWQ7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGNuZmUpIHsKKyAgICAgICAgICAgIC8vIGltcG9zc2libGUKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGNuZmUpOyAvL05PU09OQVIKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvQmluYXJ5VHJlZS5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9CaW5hcnlUcmVlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWIzYzM3NwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvQmluYXJ5VHJlZS5qYXZhCkBAIC0wLDAgKzEsMTg5IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcDsKKworaW1wb3J0IGphdmEuaW8uRGF0YUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCisvKioKKyAqIEJpbmFyeSB0cmVlIG9mIHBvc2l0aXZlIHZhbHVlcy4KKyAqCisgKiBAYXV0aG9yIEVtbWFudWVsIEJvdXJnCisgKiBAc2luY2UgMS43CisgKi8KK2NsYXNzIEJpbmFyeVRyZWUgeworCisgICAgLyoqIFZhbHVlIGluIHRoZSBhcnJheSBpbmRpY2F0aW5nIGFuIHVuZGVmaW5lZCBub2RlICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFVOREVGSU5FRCA9IC0xOworCisgICAgLyoqIFZhbHVlIGluIHRoZSBhcnJheSBpbmRpY2F0aW5nIGEgbm9uIGxlYWYgbm9kZSAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBOT0RFID0gLTI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgYXJyYXkgcmVwcmVzZW50aW5nIHRoZSBiaW5hcnkgdHJlZS4gVGhlIHJvb3QgaXMgYXQgaW5kZXggMCwKKyAgICAgKiB0aGUgbGVmdCBjaGlsZHJlbiBhcmUgYXQgMippKzEgYW5kIHRoZSByaWdodCBjaGlsZHJlbiBhdCAyKmkrMi4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIGludFtdIHRyZWU7CisKKyAgICBwdWJsaWMgQmluYXJ5VHJlZShmaW5hbCBpbnQgZGVwdGgpIHsKKyAgICAgICAgdHJlZSA9IG5ldyBpbnRbKDEgPDwgKGRlcHRoICsgMSkpIC0gMV07CisgICAgICAgIEFycmF5cy5maWxsKHRyZWUsIFVOREVGSU5FRCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkcyBhIGxlYWYgdG8gdGhlIHRyZWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbm9kZSAgIHRoZSBpbmRleCBvZiB0aGUgbm9kZSB3aGVyZSB0aGUgcGF0aCBpcyBhcHBlbmRlZAorICAgICAqIEBwYXJhbSBwYXRoICAgdGhlIHBhdGggdG8gdGhlIGxlYWYgKGJpdHMgYXJlIHBhcnNlZCBmcm9tIHRoZSByaWdodCB0byB0aGUgbGVmdCkKKyAgICAgKiBAcGFyYW0gZGVwdGggIHRoZSBudW1iZXIgb2Ygbm9kZXMgaW4gdGhlIHBhdGgKKyAgICAgKiBAcGFyYW0gdmFsdWUgIHRoZSB2YWx1ZSBvZiB0aGUgbGVhZiAobXVzdCBiZSBwb3NpdGl2ZSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGRMZWFmKGZpbmFsIGludCBub2RlLCBmaW5hbCBpbnQgcGF0aCwgZmluYWwgaW50IGRlcHRoLCBmaW5hbCBpbnQgdmFsdWUpIHsKKyAgICAgICAgaWYgKGRlcHRoID09IDApIHsKKyAgICAgICAgICAgIC8vIGVuZCBvZiB0aGUgcGF0aCByZWFjaGVkLCBhZGQgdGhlIHZhbHVlIHRvIHRoZSBjdXJyZW50IG5vZGUKKyAgICAgICAgICAgIGlmICh0cmVlW25vZGVdID09IFVOREVGSU5FRCkgeworICAgICAgICAgICAgICAgIHRyZWVbbm9kZV0gPSB2YWx1ZTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiVHJlZSB2YWx1ZSBhdCBpbmRleCAiICsgbm9kZSArICIgaGFzIGFscmVhZHkgYmVlbiBhc3NpZ25lZCAoIiArIHRyZWVbbm9kZV0gKyAiKSIpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gbWFyayB0aGUgY3VycmVudCBub2RlIGFzIGEgbm9uIGxlYWYgbm9kZQorICAgICAgICAgICAgdHJlZVtub2RlXSA9IE5PREU7CisKKyAgICAgICAgICAgIC8vIG1vdmUgZG93biB0aGUgcGF0aCByZWN1cnNpdmVseQorICAgICAgICAgICAgZmluYWwgaW50IG5leHRDaGlsZCA9IDIgKiBub2RlICsgMSArIChwYXRoICYgMSk7CisgICAgICAgICAgICBhZGRMZWFmKG5leHRDaGlsZCwgcGF0aCA+Pj4gMSwgZGVwdGggLSAxLCB2YWx1ZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhIHZhbHVlIGZyb20gdGhlIHNwZWNpZmllZCBiaXQgc3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtIHN0cmVhbQorICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIGRlY29kZWQsIG9yIC0xIGlmIHRoZSBlbmQgb2YgdGhlIHN0cmVhbSBpcyByZWFjaGVkCisgICAgICovCisgICAgcHVibGljIGludCByZWFkKGZpbmFsIEJpdFN0cmVhbSBzdHJlYW0pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCBjdXJyZW50SW5kZXggPSAwOworCisgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICBmaW5hbCBpbnQgYml0ID0gc3RyZWFtLm5leHRCaXQoKTsKKyAgICAgICAgICAgIGlmIChiaXQgPT0gLTEpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGZpbmFsIGludCBjaGlsZEluZGV4ID0gMiAqIGN1cnJlbnRJbmRleCArIDEgKyBiaXQ7CisgICAgICAgICAgICBmaW5hbCBpbnQgdmFsdWUgPSB0cmVlW2NoaWxkSW5kZXhdOworICAgICAgICAgICAgaWYgKHZhbHVlID09IE5PREUpIHsKKyAgICAgICAgICAgICAgICAvLyBjb25zdW1lIHRoZSBuZXh0IGJpdAorICAgICAgICAgICAgICAgIGN1cnJlbnRJbmRleCA9IGNoaWxkSW5kZXg7CisgICAgICAgICAgICB9IGVsc2UgaWYgKHZhbHVlICE9IFVOREVGSU5FRCkgeworICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJUaGUgY2hpbGQgIiArIGJpdCArICIgb2Ygbm9kZSBhdCBpbmRleCAiICsgY3VycmVudEluZGV4ICsgIiBpcyBub3QgZGVmaW5lZCIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBEZWNvZGVzIHRoZSBwYWNrZWQgYmluYXJ5IHRyZWUgZnJvbSB0aGUgc3BlY2lmaWVkIHN0cmVhbS4KKyAgICAgKi8KKyAgICBzdGF0aWMgQmluYXJ5VHJlZSBkZWNvZGUoZmluYWwgSW5wdXRTdHJlYW0gaW4sIGZpbmFsIGludCB0b3RhbE51bWJlck9mVmFsdWVzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyB0aGUgZmlyc3QgYnl0ZSBjb250YWlucyB0aGUgc2l6ZSBvZiB0aGUgc3RydWN0dXJlIG1pbnVzIG9uZQorICAgICAgICBmaW5hbCBpbnQgc2l6ZSA9IGluLnJlYWQoKSArIDE7CisgICAgICAgIGlmIChzaXplID09IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiQ2Fubm90IHJlYWQgdGhlIHNpemUgb2YgdGhlIGVuY29kZWQgdHJlZSwgdW5leHBlY3RlZCBlbmQgb2Ygc3RyZWFtIik7CisgICAgICAgIH0KKworICAgICAgICBmaW5hbCBieXRlW10gZW5jb2RlZFRyZWUgPSBuZXcgYnl0ZVtzaXplXTsKKyAgICAgICAgbmV3IERhdGFJbnB1dFN0cmVhbShpbikucmVhZEZ1bGx5KGVuY29kZWRUcmVlKTsKKworICAgICAgICAvKiogVGhlIG1heGltdW0gYml0IGxlbmd0aCBmb3IgYSB2YWx1ZSAoMTYgb3IgbG93ZXIpICovCisgICAgICAgIGludCBtYXhMZW5ndGggPSAwOworCisgICAgICAgIGZpbmFsIGludFtdIG9yaWdpbmFsQml0TGVuZ3RocyA9IG5ldyBpbnRbdG90YWxOdW1iZXJPZlZhbHVlc107CisgICAgICAgIGludCBwb3MgPSAwOworICAgICAgICBmb3IgKGZpbmFsIGJ5dGUgYiA6IGVuY29kZWRUcmVlKSB7CisgICAgICAgICAgICAvLyBlYWNoIGJ5dGUgZW5jb2RlcyB0aGUgbnVtYmVyIG9mIHZhbHVlcyAodXBwZXIgNCBiaXRzKSBmb3IgYSBiaXQgbGVuZ3RoIChsb3dlciA0IGJpdHMpCisgICAgICAgICAgICBmaW5hbCBpbnQgbnVtYmVyT2ZWYWx1ZXMgPSAoKGIgJiAweEYwKSA+PiA0KSArIDE7CisgICAgICAgICAgICBmaW5hbCBpbnQgYml0TGVuZ3RoID0gKGIgJiAweDBGKSArIDE7CisKKyAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgbnVtYmVyT2ZWYWx1ZXM7IGorKykgeworICAgICAgICAgICAgICAgIG9yaWdpbmFsQml0TGVuZ3Roc1twb3MrK10gPSBiaXRMZW5ndGg7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIG1heExlbmd0aCA9IE1hdGgubWF4KG1heExlbmd0aCwgYml0TGVuZ3RoKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHNvcnQgdGhlIGFycmF5IG9mIGJpdCBsZW5ndGhzIGFuZCBtZW1vcml6ZSB0aGUgcGVybXV0YXRpb24gdXNlZCB0byByZXN0b3JlIHRoZSBvcmRlciBvZiB0aGUgY29kZXMKKyAgICAgICAgZmluYWwgaW50W10gcGVybXV0YXRpb24gPSBuZXcgaW50W29yaWdpbmFsQml0TGVuZ3Rocy5sZW5ndGhdOworICAgICAgICBmb3IgKGludCBrID0gMDsgayA8IHBlcm11dGF0aW9uLmxlbmd0aDsgaysrKSB7CisgICAgICAgICAgICBwZXJtdXRhdGlvbltrXSA9IGs7CisgICAgICAgIH0KKworICAgICAgICBpbnQgYyA9IDA7CisgICAgICAgIGZpbmFsIGludFtdIHNvcnRlZEJpdExlbmd0aHMgPSBuZXcgaW50W29yaWdpbmFsQml0TGVuZ3Rocy5sZW5ndGhdOworICAgICAgICBmb3IgKGludCBrID0gMDsgayA8IG9yaWdpbmFsQml0TGVuZ3Rocy5sZW5ndGg7IGsrKykgeworICAgICAgICAgICAgLy8gaXRlcmF0ZSBvdmVyIHRoZSB2YWx1ZXMKKyAgICAgICAgICAgIGZvciAoaW50IGwgPSAwOyBsIDwgb3JpZ2luYWxCaXRMZW5ndGhzLmxlbmd0aDsgbCsrKSB7CisgICAgICAgICAgICAgICAgLy8gbG9vayBmb3IgdGhlIHZhbHVlIGluIHRoZSBvcmlnaW5hbCBhcnJheQorICAgICAgICAgICAgICAgIGlmIChvcmlnaW5hbEJpdExlbmd0aHNbbF0gPT0gaykgeworICAgICAgICAgICAgICAgICAgICAvLyBwdXQgdGhlIHZhbHVlIGF0IHRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBzb3J0ZWQgYXJyYXkuLi4KKyAgICAgICAgICAgICAgICAgICAgc29ydGVkQml0TGVuZ3Roc1tjXSA9IGs7CisKKyAgICAgICAgICAgICAgICAgICAgLy8gLi4uYW5kIG1lbW9yaXplIHRoZSBwZXJtdXRhdGlvbgorICAgICAgICAgICAgICAgICAgICBwZXJtdXRhdGlvbltjXSA9IGw7CisKKyAgICAgICAgICAgICAgICAgICAgYysrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIGRlY29kZSB0aGUgdmFsdWVzIG9mIHRoZSB0cmVlCisgICAgICAgIGludCBjb2RlID0gMDsKKyAgICAgICAgaW50IGNvZGVJbmNyZW1lbnQgPSAwOworICAgICAgICBpbnQgbGFzdEJpdExlbmd0aCA9IDA7CisKKyAgICAgICAgZmluYWwgaW50W10gY29kZXMgPSBuZXcgaW50W3RvdGFsTnVtYmVyT2ZWYWx1ZXNdOworCisgICAgICAgIGZvciAoaW50IGkgPSB0b3RhbE51bWJlck9mVmFsdWVzIC0gMTsgaSA+PSAwOyBpLS0pIHsKKyAgICAgICAgICAgIGNvZGUgPSBjb2RlICsgY29kZUluY3JlbWVudDsKKyAgICAgICAgICAgIGlmIChzb3J0ZWRCaXRMZW5ndGhzW2ldICE9IGxhc3RCaXRMZW5ndGgpIHsKKyAgICAgICAgICAgICAgICBsYXN0Qml0TGVuZ3RoID0gc29ydGVkQml0TGVuZ3Roc1tpXTsKKyAgICAgICAgICAgICAgICBjb2RlSW5jcmVtZW50ID0gMSA8PCAoMTYgLSBsYXN0Qml0TGVuZ3RoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNvZGVzW3Blcm11dGF0aW9uW2ldXSA9IGNvZGU7CisgICAgICAgIH0KKworICAgICAgICAvLyBidWlsZCB0aGUgdHJlZQorICAgICAgICBmaW5hbCBCaW5hcnlUcmVlIHRyZWUgPSBuZXcgQmluYXJ5VHJlZShtYXhMZW5ndGgpOworCisgICAgICAgIGZvciAoaW50IGsgPSAwOyBrIDwgY29kZXMubGVuZ3RoOyBrKyspIHsKKyAgICAgICAgICAgIGZpbmFsIGludCBiaXRMZW5ndGggPSBvcmlnaW5hbEJpdExlbmd0aHNba107CisgICAgICAgICAgICBpZiAoYml0TGVuZ3RoID4gMCkgeworICAgICAgICAgICAgICAgIHRyZWUuYWRkTGVhZigwLCBJbnRlZ2VyLnJldmVyc2UoY29kZXNba10gPDwgMTYpLCBiaXRMZW5ndGgsIGspOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIHRyZWU7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9CaXRTdHJlYW0uamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvQml0U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmI3MzdiNwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvQml0U3RyZWFtLmphdmEKQEAgLTAsMCArMSw2MSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXA7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLkJpdElucHV0U3RyZWFtOworaW1wb3J0IGphdmEubmlvLkJ5dGVPcmRlcjsKKworLyoqCisgKiBJdGVyYXRlcyBvdmVyIHRoZSBiaXRzIG9mIGFuIElucHV0U3RyZWFtLiBGb3IgZWFjaCBieXRlIHRoZSBiaXRzCisgKiBhcmUgcmVhZCBmcm9tIHRoZSByaWdodCB0byB0aGUgbGVmdC4KKyAqCisgKiBAc2luY2UgMS43CisgKi8KK2NsYXNzIEJpdFN0cmVhbSBleHRlbmRzIEJpdElucHV0U3RyZWFtIHsKKworICAgIEJpdFN0cmVhbShmaW5hbCBJbnB1dFN0cmVhbSBpbikgeworICAgICAgICBzdXBlcihpbiwgQnl0ZU9yZGVyLkxJVFRMRV9FTkRJQU4pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5leHQgYml0LgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgbmV4dCBiaXQgKDAgb3IgMSkgb3IgLTEgaWYgdGhlIGVuZCBvZiB0aGUgc3RyZWFtIGhhcyBiZWVuIHJlYWNoZWQKKyAgICAgKi8KKyAgICBpbnQgbmV4dEJpdCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiAoaW50KSByZWFkQml0cygxKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBpbnRlZ2VyIHZhbHVlIGZvcm1lZCBieSB0aGUgbiBuZXh0IGJpdHMgKHVwIHRvIDggYml0cykuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbiB0aGUgbnVtYmVyIG9mIGJpdHMgcmVhZCAodXAgdG8gOCkKKyAgICAgKiBAcmV0dXJuIFRoZSB2YWx1ZSBmb3JtZWQgYnkgdGhlIG4gYml0cywgb3IgLTEgaWYgdGhlIGVuZCBvZiB0aGUgc3RyZWFtIGhhcyBiZWVuIHJlYWNoZWQKKyAgICAgKi8KKyAgICBsb25nIG5leHRCaXRzKGZpbmFsIGludCBuKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gcmVhZEJpdHMobik7CisgICAgfQorCisgICAgaW50IG5leHRCeXRlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIChpbnQpIHJlYWRCaXRzKDgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvQ2hhcnNldEFjY2Vzc29yLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL0NoYXJzZXRBY2Nlc3Nvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU1MzQyYmUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL0NoYXJzZXRBY2Nlc3Nvci5qYXZhCkBAIC0wLDAgKzEsNDQgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwOworCitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0OworCisvKioKKyAqIEFuIGludGVyZmFjZSBhZGRlZCB0byBhbGxvdyBhY2Nlc3MgdG8gdGhlIGNoYXJhY3RlciBzZXQgYXNzb2NpYXRlZCB3aXRoIGFuIHtAbGluayBOaW9aaXBFbmNvZGluZ30sCisgKiB3aXRob3V0IHJlcXVpcmluZyBhIG5ldyBtZXRob2QgdG8gYmUgYWRkZWQgdG8ge0BsaW5rIFppcEVuY29kaW5nfS4KKyAqIDxwPgorICogVGhpcyBhdm9pZHMgaW50cm9kdWNpbmcgYQorICogcG90ZW50aWFsbHkgYnJlYWtpbmcgY2hhbmdlLCBvciBtYWtpbmcge0BsaW5rIE5pb1ppcEVuY29kaW5nfSBhIHB1YmxpYyBjbGFzcy4KKyAqIDwvcD4KKyAqIEBzaW5jZSAxLjE1CisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgQ2hhcnNldEFjY2Vzc29yIHsKKworICAgIC8qKgorICAgICAqIFByb3ZpZGVzIGFjY2VzcyB0byB0aGUgY2hhcmFjdGVyIHNldCBhc3NvY2lhdGVkIHdpdGggYW4gb2JqZWN0LgorICAgICAqIDxwPgorICAgICAqICAgICBUaGlzIGFsbG93cyBuaW8gb3JpZW50ZWQgY29kZSB0byB1c2UgbW9yZSBuYXR1cmFsIGNoYXJhY3RlciBlbmNvZGluZy9kZWNvZGluZyBtZXRob2RzLAorICAgICAqICAgICB3aGlsc3QgYWxsb3dpbmcgZXhpc3RpbmcgY29kZSB0byBjb250aW51ZSB0byByZWx5IG9uIHNwZWNpYWwtY2FzZSBlcnJvciBoYW5kbGluZyBmb3IgVVRGLTguCisgICAgICogPC9wPgorICAgICAqIEByZXR1cm4gdGhlIGNoYXJhY3RlciBzZXQgYXNzb2NpYXRlZCB3aXRoIHRoaXMgb2JqZWN0CisgICAgICovCisgICAgQ2hhcnNldCBnZXRDaGFyc2V0KCk7Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL0NpcmN1bGFyQnVmZmVyLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL0NpcmN1bGFyQnVmZmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODUwMmU0NgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvQ2lyY3VsYXJCdWZmZXIuamF2YQpAQCAtMCwwICsxLDg4IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcDsKKworLyoqCisgKiBDaXJjdWxhciBieXRlIGJ1ZmZlci4KKyAqCisgKiBAYXV0aG9yIEVtbWFudWVsIEJvdXJnCisgKiBAc2luY2UgMS43CisgKi8KK2NsYXNzIENpcmN1bGFyQnVmZmVyIHsKKworICAgIC8qKiBTaXplIG9mIHRoZSBidWZmZXIgKi8KKyAgICBwcml2YXRlIGZpbmFsIGludCBzaXplOworCisgICAgLyoqIFRoZSBidWZmZXIgKi8KKyAgICBwcml2YXRlIGZpbmFsIGJ5dGVbXSBidWZmZXI7CisKKyAgICAvKiogSW5kZXggb2YgdGhlIG5leHQgZGF0YSB0byBiZSByZWFkIGZyb20gdGhlIGJ1ZmZlciAqLworICAgIHByaXZhdGUgaW50IHJlYWRJbmRleDsKKworICAgIC8qKiBJbmRleCBvZiB0aGUgbmV4dCBkYXRhIHdyaXR0ZW4gaW4gdGhlIGJ1ZmZlciAqLworICAgIHByaXZhdGUgaW50IHdyaXRlSW5kZXg7CisKKyAgICBDaXJjdWxhckJ1ZmZlcihmaW5hbCBpbnQgc2l6ZSkgeworICAgICAgICB0aGlzLnNpemUgPSBzaXplOworICAgICAgICBidWZmZXIgPSBuZXcgYnl0ZVtzaXplXTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZWxscyBpZiBhIG5ldyBieXRlIGNhbiBiZSByZWFkIGZyb20gdGhlIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBhdmFpbGFibGUoKSB7CisgICAgICAgIHJldHVybiByZWFkSW5kZXggIT0gd3JpdGVJbmRleDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgYSBieXRlIHRvIHRoZSBidWZmZXIuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcHV0KGZpbmFsIGludCB2YWx1ZSkgeworICAgICAgICBidWZmZXJbd3JpdGVJbmRleF0gPSAoYnl0ZSkgdmFsdWU7CisgICAgICAgIHdyaXRlSW5kZXggPSAod3JpdGVJbmRleCArIDEpICUgc2l6ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhIGJ5dGUgZnJvbSB0aGUgYnVmZmVyLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0KCkgeworICAgICAgICBpZiAoYXZhaWxhYmxlKCkpIHsKKyAgICAgICAgICAgIGZpbmFsIGludCB2YWx1ZSA9IGJ1ZmZlcltyZWFkSW5kZXhdOworICAgICAgICAgICAgcmVhZEluZGV4ID0gKHJlYWRJbmRleCArIDEpICUgc2l6ZTsKKyAgICAgICAgICAgIHJldHVybiB2YWx1ZSAmIDB4RkY7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvcHkgYSBwcmV2aW91cyBpbnRlcnZhbCBpbiB0aGUgYnVmZmVyIHRvIHRoZSBjdXJyZW50IHBvc2l0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIGRpc3RhbmNlIHRoZSBkaXN0YW5jZSBmcm9tIHRoZSBjdXJyZW50IHdyaXRlIHBvc2l0aW9uCisgICAgICogQHBhcmFtIGxlbmd0aCAgIHRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gY29weQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNvcHkoZmluYWwgaW50IGRpc3RhbmNlLCBmaW5hbCBpbnQgbGVuZ3RoKSB7CisgICAgICAgIGZpbmFsIGludCBwb3MxID0gd3JpdGVJbmRleCAtIGRpc3RhbmNlOworICAgICAgICBmaW5hbCBpbnQgcG9zMiA9IHBvczEgKyBsZW5ndGg7CisgICAgICAgIGZvciAoaW50IGkgPSBwb3MxOyBpIDwgcG9zMjsgaSsrKSB7CisgICAgICAgICAgICBidWZmZXJbd3JpdGVJbmRleF0gPSBidWZmZXJbKGkgKyBzaXplKSAlIHNpemVdOworICAgICAgICAgICAgd3JpdGVJbmRleCA9ICh3cml0ZUluZGV4ICsgMSkgJSBzaXplOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9FeHBsb2RpbmdJbnB1dFN0cmVhbS5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9FeHBsb2RpbmdJbnB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjcwZWIzMDgKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL0V4cGxvZGluZ0lucHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwyMDEgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLkNvdW50aW5nSW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLklucHV0U3RyZWFtU3RhdGlzdGljczsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKKworLyoqCisgKiBUaGUgaW1wbG9kZSBjb21wcmVzc2lvbiBtZXRob2Qgd2FzIGFkZGVkIHRvIFBLWklQIDEuMDEgcmVsZWFzZWQgaW4gMTk4OS4KKyAqIEl0IHdhcyB0aGVuIGRyb3BwZWQgZnJvbSBQS1pJUCAyLjAgcmVsZWFzZWQgaW4gMTk5MyBpbiBmYXZvciBvZiB0aGUgZGVmbGF0ZQorICogbWV0aG9kLgorICogPHA+CisgKiBUaGUgYWxnb3JpdGhtIGlzIGRlc2NyaWJlZCBpbiB0aGUgWklQIEZpbGUgRm9ybWF0IFNwZWNpZmljYXRpb24uCisgKgorICogQHNlZSA8YSBocmVmPSJodHRwczovL3d3dy5wa3dhcmUuY29tL2RvY3VtZW50cy9jYXNlc3R1ZGllcy9BUFBOT1RFLlRYVCI+WklQIEZpbGUgRm9ybWF0IFNwZWNpZmljYXRpb248L2E+CisgKgorICogQGF1dGhvciBFbW1hbnVlbCBCb3VyZworICogQHNpbmNlIDEuNworICovCitjbGFzcyBFeHBsb2RpbmdJbnB1dFN0cmVhbSBleHRlbmRzIElucHV0U3RyZWFtIGltcGxlbWVudHMgSW5wdXRTdHJlYW1TdGF0aXN0aWNzIHsKKworICAgIC8qKiBUaGUgdW5kZXJseWluZyBzdHJlYW0gY29udGFpbmluZyB0aGUgY29tcHJlc3NlZCBkYXRhICovCisgICAgcHJpdmF0ZSBmaW5hbCBJbnB1dFN0cmVhbSBpbjsKKworICAgIC8qKiBUaGUgc3RyZWFtIG9mIGJpdHMgcmVhZCBmcm9tIHRoZSBpbnB1dCBzdHJlYW0gKi8KKyAgICBwcml2YXRlIEJpdFN0cmVhbSBiaXRzOworCisgICAgLyoqIFRoZSBzaXplIG9mIHRoZSBzbGlkaW5nIGRpY3Rpb25hcnkgKDRLIG9yIDhLKSAqLworICAgIHByaXZhdGUgZmluYWwgaW50IGRpY3Rpb25hcnlTaXplOworCisgICAgLyoqIFRoZSBudW1iZXIgb2YgU2hhbm5vbi1GYW5vIHRyZWVzICgyIG9yIDMpICovCisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgbnVtYmVyT2ZUcmVlczsKKworICAgIHByaXZhdGUgZmluYWwgaW50IG1pbmltdW1NYXRjaExlbmd0aDsKKworICAgIC8qKiBUaGUgYmluYXJ5IHRyZWUgY29udGFpbmluZyB0aGUgMjU2IGVuY29kZWQgbGl0ZXJhbHMgKG51bGwgd2hlbiBvbmx5IHR3byB0cmVlcyBhcmUgdXNlZCkgKi8KKyAgICBwcml2YXRlIEJpbmFyeVRyZWUgbGl0ZXJhbFRyZWU7CisKKyAgICAvKiogVGhlIGJpbmFyeSB0cmVlIGNvbnRhaW5pbmcgdGhlIDY0IGVuY29kZWQgbGVuZ3RocyAqLworICAgIHByaXZhdGUgQmluYXJ5VHJlZSBsZW5ndGhUcmVlOworCisgICAgLyoqIFRoZSBiaW5hcnkgdHJlZSBjb250YWluaW5nIHRoZSA2NCBlbmNvZGVkIGRpc3RhbmNlcyAqLworICAgIHByaXZhdGUgQmluYXJ5VHJlZSBkaXN0YW5jZVRyZWU7CisKKyAgICAvKiogT3V0cHV0IGJ1ZmZlciBob2xkaW5nIHRoZSBkZWNvbXByZXNzZWQgZGF0YSAqLworICAgIHByaXZhdGUgZmluYWwgQ2lyY3VsYXJCdWZmZXIgYnVmZmVyID0gbmV3IENpcmN1bGFyQnVmZmVyKDMyICogMTAyNCk7CisKKyAgICBwcml2YXRlIGxvbmcgdW5jb21wcmVzc2VkQ291bnQgPSAwOworCisgICAgcHJpdmF0ZSBsb25nIHRyZWVTaXplcyA9IDA7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBuZXcgc3RyZWFtIGRlY29tcHJlc3NpbmcgdGhlIGNvbnRlbnQgb2YgdGhlIHNwZWNpZmllZCBzdHJlYW0KKyAgICAgKiB1c2luZyB0aGUgZXhwbG9kZSBhbGdvcml0aG0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGljdGlvbmFyeVNpemUgdGhlIHNpemUgb2YgdGhlIHNsaWRpbmcgZGljdGlvbmFyeSAoNDA5NiBvciA4MTkyKQorICAgICAqIEBwYXJhbSBudW1iZXJPZlRyZWVzICB0aGUgbnVtYmVyIG9mIHRyZWVzICgyIG9yIDMpCisgICAgICogQHBhcmFtIGluICAgICAgICAgICAgIHRoZSBjb21wcmVzc2VkIGRhdGEgc3RyZWFtCisgICAgICovCisgICAgcHVibGljIEV4cGxvZGluZ0lucHV0U3RyZWFtKGZpbmFsIGludCBkaWN0aW9uYXJ5U2l6ZSwgZmluYWwgaW50IG51bWJlck9mVHJlZXMsIGZpbmFsIElucHV0U3RyZWFtIGluKSB7CisgICAgICAgIGlmIChkaWN0aW9uYXJ5U2l6ZSAhPSA0MDk2ICYmIGRpY3Rpb25hcnlTaXplICE9IDgxOTIpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlRoZSBkaWN0aW9uYXJ5IHNpemUgbXVzdCBiZSA0MDk2IG9yIDgxOTIiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAobnVtYmVyT2ZUcmVlcyAhPSAyICYmIG51bWJlck9mVHJlZXMgIT0gMykgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiVGhlIG51bWJlciBvZiB0cmVlcyBtdXN0IGJlIDIgb3IgMyIpOworICAgICAgICB9CisgICAgICAgIHRoaXMuZGljdGlvbmFyeVNpemUgPSBkaWN0aW9uYXJ5U2l6ZTsKKyAgICAgICAgdGhpcy5udW1iZXJPZlRyZWVzID0gbnVtYmVyT2ZUcmVlczsKKyAgICAgICAgdGhpcy5taW5pbXVtTWF0Y2hMZW5ndGggPSBudW1iZXJPZlRyZWVzOworICAgICAgICB0aGlzLmluID0gaW47CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgdGhlIGVuY29kZWQgYmluYXJ5IHRyZWVzIGFuZCBwcmVwYXJlcyB0aGUgYml0IHN0cmVhbS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgaW5pdCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChiaXRzID09IG51bGwpIHsKKyAgICAgICAgICAgIHRyeSAoQ291bnRpbmdJbnB1dFN0cmVhbSBpID0gbmV3IENvdW50aW5nSW5wdXRTdHJlYW0oaW4pIHsKKyAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgeworICAgICAgICAgICAgICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gY2xvc2UgaW4KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0pIHsKKyAgICAgICAgICAgICAgICBpZiAobnVtYmVyT2ZUcmVlcyA9PSAzKSB7CisgICAgICAgICAgICAgICAgICAgIGxpdGVyYWxUcmVlID0gQmluYXJ5VHJlZS5kZWNvZGUoaSwgMjU2KTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBsZW5ndGhUcmVlID0gQmluYXJ5VHJlZS5kZWNvZGUoaSwgNjQpOworICAgICAgICAgICAgICAgIGRpc3RhbmNlVHJlZSA9IEJpbmFyeVRyZWUuZGVjb2RlKGksIDY0KTsKKyAgICAgICAgICAgICAgICB0cmVlU2l6ZXMgKz0gaS5nZXRCeXRlc1JlYWQoKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgYml0cyA9IG5ldyBCaXRTdHJlYW0oaW4pOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCByZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFidWZmZXIuYXZhaWxhYmxlKCkpIHsKKyAgICAgICAgICAgIGZpbGxCdWZmZXIoKTsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIGludCByZXQgPSBidWZmZXIuZ2V0KCk7CisgICAgICAgIGlmIChyZXQgPiAtMSkgeworICAgICAgICAgICAgdW5jb21wcmVzc2VkQ291bnQrKzsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmV0OworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzaW5jZSAxLjE3CisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGxvbmcgZ2V0Q29tcHJlc3NlZENvdW50KCkgeworICAgICAgICByZXR1cm4gYml0cy5nZXRCeXRlc1JlYWQoKSArIHRyZWVTaXplczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2luY2UgMS4xNworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBsb25nIGdldFVuY29tcHJlc3NlZENvdW50KCkgeworICAgICAgICByZXR1cm4gdW5jb21wcmVzc2VkQ291bnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNpbmNlIDEuMTcKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGluLmNsb3NlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmlsbCB0aGUgc2xpZGluZyBkaWN0aW9uYXJ5IHdpdGggbW9yZSBkYXRhLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgZmlsbEJ1ZmZlcigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGluaXQoKTsKKworICAgICAgICBmaW5hbCBpbnQgYml0ID0gYml0cy5uZXh0Qml0KCk7CisgICAgICAgIGlmIChiaXQgPT0gMSkgeworICAgICAgICAgICAgLy8gbGl0ZXJhbCB2YWx1ZQorICAgICAgICAgICAgaW50IGxpdGVyYWw7CisgICAgICAgICAgICBpZiAobGl0ZXJhbFRyZWUgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGxpdGVyYWwgPSBsaXRlcmFsVHJlZS5yZWFkKGJpdHMpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBsaXRlcmFsID0gYml0cy5uZXh0Qnl0ZSgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAobGl0ZXJhbCA9PSAtMSkgeworICAgICAgICAgICAgICAgIC8vIGVuZCBvZiBzdHJlYW0gcmVhY2hlZCwgbm90aGluZyBsZWZ0IHRvIGRlY29kZQorICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgYnVmZmVyLnB1dChsaXRlcmFsKTsKKworICAgICAgICB9IGVsc2UgaWYgKGJpdCA9PSAwKSB7CisgICAgICAgICAgICAvLyBiYWNrIHJlZmVyZW5jZQorICAgICAgICAgICAgZmluYWwgaW50IGRpc3RhbmNlTG93U2l6ZSA9IGRpY3Rpb25hcnlTaXplID09IDQwOTYgPyA2IDogNzsKKyAgICAgICAgICAgIGZpbmFsIGludCBkaXN0YW5jZUxvdyA9IChpbnQpIGJpdHMubmV4dEJpdHMoZGlzdGFuY2VMb3dTaXplKTsKKyAgICAgICAgICAgIGZpbmFsIGludCBkaXN0YW5jZUhpZ2ggPSBkaXN0YW5jZVRyZWUucmVhZChiaXRzKTsKKyAgICAgICAgICAgIGlmIChkaXN0YW5jZUhpZ2ggPT0gLTEgJiYgZGlzdGFuY2VMb3cgPD0gMCkgeworICAgICAgICAgICAgICAgIC8vIGVuZCBvZiBzdHJlYW0gcmVhY2hlZCwgbm90aGluZyBsZWZ0IHRvIGRlY29kZQorICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZpbmFsIGludCBkaXN0YW5jZSA9IGRpc3RhbmNlSGlnaCA8PCBkaXN0YW5jZUxvd1NpemUgfCBkaXN0YW5jZUxvdzsKKworICAgICAgICAgICAgaW50IGxlbmd0aCA9IGxlbmd0aFRyZWUucmVhZChiaXRzKTsKKyAgICAgICAgICAgIGlmIChsZW5ndGggPT0gNjMpIHsKKyAgICAgICAgICAgICAgICBsZW5ndGggKz0gYml0cy5uZXh0Qml0cyg4KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGxlbmd0aCArPSBtaW5pbXVtTWF0Y2hMZW5ndGg7CisKKyAgICAgICAgICAgIGJ1ZmZlci5jb3B5KGRpc3RhbmNlICsgMSwgbGVuZ3RoKTsKKyAgICAgICAgfQorICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9FeHRyYUZpZWxkVXRpbHMuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvRXh0cmFGaWVsZFV0aWxzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWVkNmNiOQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvRXh0cmFGaWVsZFV0aWxzLmphdmEKQEAgLTAsMCArMSwzMjggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXA7CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuQ29uY3VycmVudEhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLnppcC5aaXBFeGNlcHRpb247CisKKy8qKgorICogWmlwRXh0cmFGaWVsZCByZWxhdGVkIG1ldGhvZHMKKyAqIEBOb3RUaHJlYWRTYWZlIGJlY2F1c2UgdGhlIEhhc2hNYXAgaXMgbm90IHN5bmNoLgorICovCisvLyBDaGVja1N0eWxlOkhpZGVVdGlsaXR5Q2xhc3NDb25zdHJ1Y3RvckNoZWNrIE9GRiAoYmMpCitwdWJsaWMgY2xhc3MgRXh0cmFGaWVsZFV0aWxzIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBXT1JEID0gNDsKKworICAgIC8qKgorICAgICAqIFN0YXRpYyByZWdpc3RyeSBvZiBrbm93biBleHRyYSBmaWVsZHMuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTWFwPFppcFNob3J0LCBDbGFzczw/Pj4gaW1wbGVtZW50YXRpb25zOworCisgICAgc3RhdGljIHsKKyAgICAgICAgaW1wbGVtZW50YXRpb25zID0gbmV3IENvbmN1cnJlbnRIYXNoTWFwPD4oKTsKKyAgICAgICAgcmVnaXN0ZXIoQXNpRXh0cmFGaWVsZC5jbGFzcyk7CisgICAgICAgIHJlZ2lzdGVyKFg1NDU1X0V4dGVuZGVkVGltZXN0YW1wLmNsYXNzKTsKKyAgICAgICAgcmVnaXN0ZXIoWDc4NzVfTmV3VW5peC5jbGFzcyk7CisgICAgICAgIHJlZ2lzdGVyKEphck1hcmtlci5jbGFzcyk7CisgICAgICAgIHJlZ2lzdGVyKFVuaWNvZGVQYXRoRXh0cmFGaWVsZC5jbGFzcyk7CisgICAgICAgIHJlZ2lzdGVyKFVuaWNvZGVDb21tZW50RXh0cmFGaWVsZC5jbGFzcyk7CisgICAgICAgIHJlZ2lzdGVyKFppcDY0RXh0ZW5kZWRJbmZvcm1hdGlvbkV4dHJhRmllbGQuY2xhc3MpOworICAgICAgICByZWdpc3RlcihYMDAwQV9OVEZTLmNsYXNzKTsKKyAgICAgICAgcmVnaXN0ZXIoWDAwMTRfWDUwOUNlcnRpZmljYXRlcy5jbGFzcyk7CisgICAgICAgIHJlZ2lzdGVyKFgwMDE1X0NlcnRpZmljYXRlSWRGb3JGaWxlLmNsYXNzKTsKKyAgICAgICAgcmVnaXN0ZXIoWDAwMTZfQ2VydGlmaWNhdGVJZEZvckNlbnRyYWxEaXJlY3RvcnkuY2xhc3MpOworICAgICAgICByZWdpc3RlcihYMDAxN19TdHJvbmdFbmNyeXB0aW9uSGVhZGVyLmNsYXNzKTsKKyAgICAgICAgcmVnaXN0ZXIoWDAwMTlfRW5jcnlwdGlvblJlY2lwaWVudENlcnRpZmljYXRlTGlzdC5jbGFzcyk7CisgICAgICAgIHJlZ2lzdGVyKFJlc291cmNlQWxpZ25tZW50RXh0cmFGaWVsZC5jbGFzcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVnaXN0ZXIgYSBaaXBFeHRyYUZpZWxkIGltcGxlbWVudGF0aW9uLgorICAgICAqCisgICAgICogPHA+VGhlIGdpdmVuIGNsYXNzIG11c3QgaGF2ZSBhIG5vLWFyZyBjb25zdHJ1Y3RvciBhbmQgaW1wbGVtZW50CisgICAgICogdGhlIHtAbGluayBaaXBFeHRyYUZpZWxkIFppcEV4dHJhRmllbGQgaW50ZXJmYWNlfS48L3A+CisgICAgICogQHBhcmFtIGMgdGhlIGNsYXNzIHRvIHJlZ2lzdGVyCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHJlZ2lzdGVyKGZpbmFsIENsYXNzPD8+IGMpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZpbmFsIFppcEV4dHJhRmllbGQgemUgPSAoWmlwRXh0cmFGaWVsZCkgYy5uZXdJbnN0YW5jZSgpOworICAgICAgICAgICAgaW1wbGVtZW50YXRpb25zLnB1dCh6ZS5nZXRIZWFkZXJJZCgpLCBjKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgQ2xhc3NDYXN0RXhjZXB0aW9uIGNjKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihjICsgIiBkb2VzblwndCBpbXBsZW1lbnQgWmlwRXh0cmFGaWVsZCIpOyAvL05PU09OQVIKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgSW5zdGFudGlhdGlvbkV4Y2VwdGlvbiBpZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oYyArICIgaXMgbm90IGEgY29uY3JldGUgY2xhc3MiKTsgLy9OT1NPTkFSCisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gaWUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGMgKyAiXCdzIG5vLWFyZyBjb25zdHJ1Y3RvciBpcyBub3QgcHVibGljIik7IC8vTk9TT05BUgorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlIGFuIGluc3RhbmNlIG9mIHRoZSBhcHByb3ByaWF0ZSBFeHRyYUZpZWxkLCBmYWxscyBiYWNrIHRvCisgICAgICoge0BsaW5rIFVucmVjb2duaXplZEV4dHJhRmllbGQgVW5yZWNvZ25pemVkRXh0cmFGaWVsZH0uCisgICAgICogQHBhcmFtIGhlYWRlcklkIHRoZSBoZWFkZXIgaWRlbnRpZmllcgorICAgICAqIEByZXR1cm4gYW4gaW5zdGFuY2Ugb2YgdGhlIGFwcHJvcHJpYXRlIEV4dHJhRmllbGQKKyAgICAgKiBAdGhyb3dzIEluc3RhbnRpYXRpb25FeGNlcHRpb24gaWYgdW5hYmxlIHRvIGluc3RhbnRpYXRlIHRoZSBjbGFzcworICAgICAqIEB0aHJvd3MgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBpZiBub3QgYWxsb3dlZCB0byBpbnN0YW50aWF0ZSB0aGUgY2xhc3MKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFppcEV4dHJhRmllbGQgY3JlYXRlRXh0cmFGaWVsZChmaW5hbCBaaXBTaG9ydCBoZWFkZXJJZCkKKyAgICAgICAgdGhyb3dzIEluc3RhbnRpYXRpb25FeGNlcHRpb24sIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24geworICAgICAgICBmaW5hbCBDbGFzczw/PiBjID0gaW1wbGVtZW50YXRpb25zLmdldChoZWFkZXJJZCk7CisgICAgICAgIGlmIChjICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiAoWmlwRXh0cmFGaWVsZCkgYy5uZXdJbnN0YW5jZSgpOworICAgICAgICB9CisgICAgICAgIGZpbmFsIFVucmVjb2duaXplZEV4dHJhRmllbGQgdSA9IG5ldyBVbnJlY29nbml6ZWRFeHRyYUZpZWxkKCk7CisgICAgICAgIHUuc2V0SGVhZGVySWQoaGVhZGVySWQpOworICAgICAgICByZXR1cm4gdTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTcGxpdCB0aGUgYXJyYXkgaW50byBFeHRyYUZpZWxkcyBhbmQgcG9wdWxhdGUgdGhlbSB3aXRoIHRoZQorICAgICAqIGdpdmVuIGRhdGEgYXMgbG9jYWwgZmlsZSBkYXRhLCB0aHJvd2luZyBhbiBleGNlcHRpb24gaWYgdGhlCisgICAgICogZGF0YSBjYW5ub3QgYmUgcGFyc2VkLgorICAgICAqIEBwYXJhbSBkYXRhIGFuIGFycmF5IG9mIGJ5dGVzIGFzIGl0IGFwcGVhcnMgaW4gbG9jYWwgZmlsZSBkYXRhCisgICAgICogQHJldHVybiBhbiBhcnJheSBvZiBFeHRyYUZpZWxkcworICAgICAqIEB0aHJvd3MgWmlwRXhjZXB0aW9uIG9uIGVycm9yCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBaaXBFeHRyYUZpZWxkW10gcGFyc2UoZmluYWwgYnl0ZVtdIGRhdGEpIHRocm93cyBaaXBFeGNlcHRpb24geworICAgICAgICByZXR1cm4gcGFyc2UoZGF0YSwgdHJ1ZSwgVW5wYXJzZWFibGVFeHRyYUZpZWxkLlRIUk9XKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTcGxpdCB0aGUgYXJyYXkgaW50byBFeHRyYUZpZWxkcyBhbmQgcG9wdWxhdGUgdGhlbSB3aXRoIHRoZQorICAgICAqIGdpdmVuIGRhdGEsIHRocm93aW5nIGFuIGV4Y2VwdGlvbiBpZiB0aGUgZGF0YSBjYW5ub3QgYmUgcGFyc2VkLgorICAgICAqIEBwYXJhbSBkYXRhIGFuIGFycmF5IG9mIGJ5dGVzCisgICAgICogQHBhcmFtIGxvY2FsIHdoZXRoZXIgZGF0YSBvcmlnaW5hdGVzIGZyb20gdGhlIGxvY2FsIGZpbGUgZGF0YQorICAgICAqIG9yIHRoZSBjZW50cmFsIGRpcmVjdG9yeQorICAgICAqIEByZXR1cm4gYW4gYXJyYXkgb2YgRXh0cmFGaWVsZHMKKyAgICAgKiBAdGhyb3dzIFppcEV4Y2VwdGlvbiBvbiBlcnJvcgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgWmlwRXh0cmFGaWVsZFtdIHBhcnNlKGZpbmFsIGJ5dGVbXSBkYXRhLCBmaW5hbCBib29sZWFuIGxvY2FsKQorICAgICAgICB0aHJvd3MgWmlwRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHBhcnNlKGRhdGEsIGxvY2FsLCBVbnBhcnNlYWJsZUV4dHJhRmllbGQuVEhST1cpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNwbGl0IHRoZSBhcnJheSBpbnRvIEV4dHJhRmllbGRzIGFuZCBwb3B1bGF0ZSB0aGVtIHdpdGggdGhlCisgICAgICogZ2l2ZW4gZGF0YS4KKyAgICAgKiBAcGFyYW0gZGF0YSBhbiBhcnJheSBvZiBieXRlcworICAgICAqIEBwYXJhbSBsb2NhbCB3aGV0aGVyIGRhdGEgb3JpZ2luYXRlcyBmcm9tIHRoZSBsb2NhbCBmaWxlIGRhdGEKKyAgICAgKiBvciB0aGUgY2VudHJhbCBkaXJlY3RvcnkKKyAgICAgKiBAcGFyYW0gb25VbnBhcnNlYWJsZURhdGEgd2hhdCB0byBkbyBpZiB0aGUgZXh0cmEgZmllbGQgZGF0YQorICAgICAqIGNhbm5vdCBiZSBwYXJzZWQuCisgICAgICogQHJldHVybiBhbiBhcnJheSBvZiBFeHRyYUZpZWxkcworICAgICAqIEB0aHJvd3MgWmlwRXhjZXB0aW9uIG9uIGVycm9yCisgICAgICoKKyAgICAgKiBAc2luY2UgMS4xCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBaaXBFeHRyYUZpZWxkW10gcGFyc2UoZmluYWwgYnl0ZVtdIGRhdGEsIGZpbmFsIGJvb2xlYW4gbG9jYWwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgVW5wYXJzZWFibGVFeHRyYUZpZWxkIG9uVW5wYXJzZWFibGVEYXRhKQorICAgICAgICB0aHJvd3MgWmlwRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgTGlzdDxaaXBFeHRyYUZpZWxkPiB2ID0gbmV3IEFycmF5TGlzdDw+KCk7CisgICAgICAgIGludCBzdGFydCA9IDA7CisgICAgICAgIExPT1A6CisgICAgICAgIHdoaWxlIChzdGFydCA8PSBkYXRhLmxlbmd0aCAtIFdPUkQpIHsKKyAgICAgICAgICAgIGZpbmFsIFppcFNob3J0IGhlYWRlcklkID0gbmV3IFppcFNob3J0KGRhdGEsIHN0YXJ0KTsKKyAgICAgICAgICAgIGZpbmFsIGludCBsZW5ndGggPSBuZXcgWmlwU2hvcnQoZGF0YSwgc3RhcnQgKyAyKS5nZXRWYWx1ZSgpOworICAgICAgICAgICAgaWYgKHN0YXJ0ICsgV09SRCArIGxlbmd0aCA+IGRhdGEubGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgc3dpdGNoKG9uVW5wYXJzZWFibGVEYXRhLmdldEtleSgpKSB7CisgICAgICAgICAgICAgICAgY2FzZSBVbnBhcnNlYWJsZUV4dHJhRmllbGQuVEhST1dfS0VZOgorICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWmlwRXhjZXB0aW9uKCJiYWQgZXh0cmEgZmllbGQgc3RhcnRpbmcgYXQgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgc3RhcnQgKyAiLiAgQmxvY2sgbGVuZ3RoIG9mICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGxlbmd0aCArICIgYnl0ZXMgZXhjZWVkcyByZW1haW5pbmciCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIGRhdGEgb2YgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgKGRhdGEubGVuZ3RoIC0gc3RhcnQgLSBXT1JEKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiBieXRlcy4iKTsKKyAgICAgICAgICAgICAgICBjYXNlIFVucGFyc2VhYmxlRXh0cmFGaWVsZC5SRUFEX0tFWToKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgVW5wYXJzZWFibGVFeHRyYUZpZWxkRGF0YSBmaWVsZCA9CisgICAgICAgICAgICAgICAgICAgICAgICBuZXcgVW5wYXJzZWFibGVFeHRyYUZpZWxkRGF0YSgpOworICAgICAgICAgICAgICAgICAgICBpZiAobG9jYWwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkLnBhcnNlRnJvbUxvY2FsRmlsZURhdGEoZGF0YSwgc3RhcnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEubGVuZ3RoIC0gc3RhcnQpOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgZmllbGQucGFyc2VGcm9tQ2VudHJhbERpcmVjdG9yeURhdGEoZGF0YSwgc3RhcnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhLmxlbmd0aCAtIHN0YXJ0KTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB2LmFkZChmaWVsZCk7CisgICAgICAgICAgICAgICAgICAgIC8vJEZBTEwtVEhST1VHSCQKKyAgICAgICAgICAgICAgICBjYXNlIFVucGFyc2VhYmxlRXh0cmFGaWVsZC5TS0lQX0tFWToKKyAgICAgICAgICAgICAgICAgICAgLy8gc2luY2Ugd2UgY2Fubm90IHBhcnNlIHRoZSBkYXRhIHdlIG11c3QgYXNzdW1lCisgICAgICAgICAgICAgICAgICAgIC8vIHRoZSBleHRyYSBmaWVsZCBjb25zdW1lcyB0aGUgd2hvbGUgcmVzdCBvZiB0aGUKKyAgICAgICAgICAgICAgICAgICAgLy8gYXZhaWxhYmxlIGRhdGEKKyAgICAgICAgICAgICAgICAgICAgYnJlYWsgTE9PUDsKKyAgICAgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWmlwRXhjZXB0aW9uKCJ1bmtub3duIFVucGFyc2VhYmxlRXh0cmFGaWVsZCBrZXk6ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIG9uVW5wYXJzZWFibGVEYXRhLmdldEtleSgpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGZpbmFsIFppcEV4dHJhRmllbGQgemUgPSBjcmVhdGVFeHRyYUZpZWxkKGhlYWRlcklkKTsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBpZiAobG9jYWwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHplLnBhcnNlRnJvbUxvY2FsRmlsZURhdGEoZGF0YSwgc3RhcnQgKyBXT1JELCBsZW5ndGgpOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgemUucGFyc2VGcm9tQ2VudHJhbERpcmVjdG9yeURhdGEoZGF0YSwgc3RhcnQgKyBXT1JELCBsZW5ndGgpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGFpb2JlKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IChaaXBFeGNlcHRpb24pIG5ldyBaaXBFeGNlcHRpb24oIkZhaWxlZCB0byBwYXJzZSBjb3JydXB0IFpJUCBleHRyYSBmaWVsZCBvZiB0eXBlICIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgSW50ZWdlci50b0hleFN0cmluZyhoZWFkZXJJZC5nZXRWYWx1ZSgpKSkuaW5pdENhdXNlKGFpb2JlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgdi5hZGQoemUpOworICAgICAgICAgICAgfSBjYXRjaCAoZmluYWwgSW5zdGFudGlhdGlvbkV4Y2VwdGlvbiB8IElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gaWUpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyAoWmlwRXhjZXB0aW9uKSBuZXcgWmlwRXhjZXB0aW9uKGllLmdldE1lc3NhZ2UoKSkuaW5pdENhdXNlKGllKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHN0YXJ0ICs9IGxlbmd0aCArIFdPUkQ7CisgICAgICAgIH0KKworICAgICAgICBmaW5hbCBaaXBFeHRyYUZpZWxkW10gcmVzdWx0ID0gbmV3IFppcEV4dHJhRmllbGRbdi5zaXplKCldOworICAgICAgICByZXR1cm4gdi50b0FycmF5KHJlc3VsdCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogTWVyZ2VzIHRoZSBsb2NhbCBmaWxlIGRhdGEgZmllbGRzIG9mIHRoZSBnaXZlbiBaaXBFeHRyYUZpZWxkcy4KKyAgICAgKiBAcGFyYW0gZGF0YSBhbiBhcnJheSBvZiBFeHRyYUZpbGVzCisgICAgICogQHJldHVybiBhbiBhcnJheSBvZiBieXRlcworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYnl0ZVtdIG1lcmdlTG9jYWxGaWxlRGF0YURhdGEoZmluYWwgWmlwRXh0cmFGaWVsZFtdIGRhdGEpIHsKKyAgICAgICAgZmluYWwgYm9vbGVhbiBsYXN0SXNVbnBhcnNlYWJsZUhvbGRlciA9IGRhdGEubGVuZ3RoID4gMAorICAgICAgICAgICAgJiYgZGF0YVtkYXRhLmxlbmd0aCAtIDFdIGluc3RhbmNlb2YgVW5wYXJzZWFibGVFeHRyYUZpZWxkRGF0YTsKKyAgICAgICAgZmluYWwgaW50IHJlZ3VsYXJFeHRyYUZpZWxkQ291bnQgPQorICAgICAgICAgICAgbGFzdElzVW5wYXJzZWFibGVIb2xkZXIgPyBkYXRhLmxlbmd0aCAtIDEgOiBkYXRhLmxlbmd0aDsKKworICAgICAgICBpbnQgc3VtID0gV09SRCAqIHJlZ3VsYXJFeHRyYUZpZWxkQ291bnQ7CisgICAgICAgIGZvciAoZmluYWwgWmlwRXh0cmFGaWVsZCBlbGVtZW50IDogZGF0YSkgeworICAgICAgICAgICAgc3VtICs9IGVsZW1lbnQuZ2V0TG9jYWxGaWxlRGF0YUxlbmd0aCgpLmdldFZhbHVlKCk7CisgICAgICAgIH0KKworICAgICAgICBmaW5hbCBieXRlW10gcmVzdWx0ID0gbmV3IGJ5dGVbc3VtXTsKKyAgICAgICAgaW50IHN0YXJ0ID0gMDsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZWd1bGFyRXh0cmFGaWVsZENvdW50OyBpKyspIHsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZGF0YVtpXS5nZXRIZWFkZXJJZCgpLmdldEJ5dGVzKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIHJlc3VsdCwgc3RhcnQsIDIpOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShkYXRhW2ldLmdldExvY2FsRmlsZURhdGFMZW5ndGgoKS5nZXRCeXRlcygpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCByZXN1bHQsIHN0YXJ0ICsgMiwgMik7CisgICAgICAgICAgICBzdGFydCArPSBXT1JEOworICAgICAgICAgICAgZmluYWwgYnl0ZVtdIGxvY2FsID0gZGF0YVtpXS5nZXRMb2NhbEZpbGVEYXRhRGF0YSgpOworICAgICAgICAgICAgaWYgKGxvY2FsICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGxvY2FsLCAwLCByZXN1bHQsIHN0YXJ0LCBsb2NhbC5sZW5ndGgpOworICAgICAgICAgICAgICAgIHN0YXJ0ICs9IGxvY2FsLmxlbmd0aDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAobGFzdElzVW5wYXJzZWFibGVIb2xkZXIpIHsKKyAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBsb2NhbCA9IGRhdGFbZGF0YS5sZW5ndGggLSAxXS5nZXRMb2NhbEZpbGVEYXRhRGF0YSgpOworICAgICAgICAgICAgaWYgKGxvY2FsICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGxvY2FsLCAwLCByZXN1bHQsIHN0YXJ0LCBsb2NhbC5sZW5ndGgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogTWVyZ2VzIHRoZSBjZW50cmFsIGRpcmVjdG9yeSBmaWVsZHMgb2YgdGhlIGdpdmVuIFppcEV4dHJhRmllbGRzLgorICAgICAqIEBwYXJhbSBkYXRhIGFuIGFycmF5IG9mIEV4dHJhRmllbGRzCisgICAgICogQHJldHVybiBhbiBhcnJheSBvZiBieXRlcworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYnl0ZVtdIG1lcmdlQ2VudHJhbERpcmVjdG9yeURhdGEoZmluYWwgWmlwRXh0cmFGaWVsZFtdIGRhdGEpIHsKKyAgICAgICAgZmluYWwgYm9vbGVhbiBsYXN0SXNVbnBhcnNlYWJsZUhvbGRlciA9IGRhdGEubGVuZ3RoID4gMAorICAgICAgICAgICAgJiYgZGF0YVtkYXRhLmxlbmd0aCAtIDFdIGluc3RhbmNlb2YgVW5wYXJzZWFibGVFeHRyYUZpZWxkRGF0YTsKKyAgICAgICAgZmluYWwgaW50IHJlZ3VsYXJFeHRyYUZpZWxkQ291bnQgPQorICAgICAgICAgICAgbGFzdElzVW5wYXJzZWFibGVIb2xkZXIgPyBkYXRhLmxlbmd0aCAtIDEgOiBkYXRhLmxlbmd0aDsKKworICAgICAgICBpbnQgc3VtID0gV09SRCAqIHJlZ3VsYXJFeHRyYUZpZWxkQ291bnQ7CisgICAgICAgIGZvciAoZmluYWwgWmlwRXh0cmFGaWVsZCBlbGVtZW50IDogZGF0YSkgeworICAgICAgICAgICAgc3VtICs9IGVsZW1lbnQuZ2V0Q2VudHJhbERpcmVjdG9yeUxlbmd0aCgpLmdldFZhbHVlKCk7CisgICAgICAgIH0KKyAgICAgICAgZmluYWwgYnl0ZVtdIHJlc3VsdCA9IG5ldyBieXRlW3N1bV07CisgICAgICAgIGludCBzdGFydCA9IDA7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVndWxhckV4dHJhRmllbGRDb3VudDsgaSsrKSB7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGRhdGFbaV0uZ2V0SGVhZGVySWQoKS5nZXRCeXRlcygpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCByZXN1bHQsIHN0YXJ0LCAyKTsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZGF0YVtpXS5nZXRDZW50cmFsRGlyZWN0b3J5TGVuZ3RoKCkuZ2V0Qnl0ZXMoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgcmVzdWx0LCBzdGFydCArIDIsIDIpOworICAgICAgICAgICAgc3RhcnQgKz0gV09SRDsKKyAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBsb2NhbCA9IGRhdGFbaV0uZ2V0Q2VudHJhbERpcmVjdG9yeURhdGEoKTsKKyAgICAgICAgICAgIGlmIChsb2NhbCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShsb2NhbCwgMCwgcmVzdWx0LCBzdGFydCwgbG9jYWwubGVuZ3RoKTsKKyAgICAgICAgICAgICAgICBzdGFydCArPSBsb2NhbC5sZW5ndGg7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKGxhc3RJc1VucGFyc2VhYmxlSG9sZGVyKSB7CisgICAgICAgICAgICBmaW5hbCBieXRlW10gbG9jYWwgPSBkYXRhW2RhdGEubGVuZ3RoIC0gMV0uZ2V0Q2VudHJhbERpcmVjdG9yeURhdGEoKTsKKyAgICAgICAgICAgIGlmIChsb2NhbCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShsb2NhbCwgMCwgcmVzdWx0LCBzdGFydCwgbG9jYWwubGVuZ3RoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqICJlbnVtIiBmb3IgdGhlIHBvc3NpYmxlIGFjdGlvbnMgdG8gdGFrZSBpZiB0aGUgZXh0cmEgZmllbGQKKyAgICAgKiBjYW5ub3QgYmUgcGFyc2VkLgorICAgICAqCisgICAgICogQHNpbmNlIDEuMQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVW5wYXJzZWFibGVFeHRyYUZpZWxkIHsKKyAgICAgICAgLyoqCisgICAgICAgICAqIEtleSBmb3IgInRocm93IGFuIGV4Y2VwdGlvbiIgYWN0aW9uLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVEhST1dfS0VZID0gMDsKKyAgICAgICAgLyoqCisgICAgICAgICAqIEtleSBmb3IgInNraXAiIGFjdGlvbi4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNLSVBfS0VZID0gMTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIEtleSBmb3IgInJlYWQiIGFjdGlvbi4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFQURfS0VZID0gMjsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhyb3cgYW4gZXhjZXB0aW9uIGlmIGZpZWxkIGNhbm5vdCBiZSBwYXJzZWQuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFVucGFyc2VhYmxlRXh0cmFGaWVsZCBUSFJPVworICAgICAgICAgICAgPSBuZXcgVW5wYXJzZWFibGVFeHRyYUZpZWxkKFRIUk9XX0tFWSk7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFNraXAgdGhlIGV4dHJhIGZpZWxkIGVudGlyZWx5IGFuZCBkb24ndCBtYWtlIGl0cyBkYXRhCisgICAgICAgICAqIGF2YWlsYWJsZSAtIGVmZmVjdGl2ZWx5IHJlbW92aW5nIHRoZSBleHRyYSBmaWVsZCBkYXRhLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbnBhcnNlYWJsZUV4dHJhRmllbGQgU0tJUAorICAgICAgICAgICAgPSBuZXcgVW5wYXJzZWFibGVFeHRyYUZpZWxkKFNLSVBfS0VZKTsKKworICAgICAgICAvKioKKyAgICAgICAgICogUmVhZCB0aGUgZXh0cmEgZmllbGQgZGF0YSBpbnRvIGFuIGluc3RhbmNlIG9mIHtAbGluaworICAgICAgICAgKiBVbnBhcnNlYWJsZUV4dHJhRmllbGREYXRhIFVucGFyc2VhYmxlRXh0cmFGaWVsZERhdGF9LgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbnBhcnNlYWJsZUV4dHJhRmllbGQgUkVBRAorICAgICAgICAgICAgPSBuZXcgVW5wYXJzZWFibGVFeHRyYUZpZWxkKFJFQURfS0VZKTsKKworICAgICAgICBwcml2YXRlIGZpbmFsIGludCBrZXk7CisKKyAgICAgICAgcHJpdmF0ZSBVbnBhcnNlYWJsZUV4dHJhRmllbGQoZmluYWwgaW50IGspIHsKKyAgICAgICAgICAgIGtleSA9IGs7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogS2V5IG9mIHRoZSBhY3Rpb24gdG8gdGFrZS4KKyAgICAgICAgICogQHJldHVybiB0aGUga2V5CisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgaW50IGdldEtleSgpIHsgcmV0dXJuIGtleTsgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvR2VuZXJhbFB1cnBvc2VCaXQuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvR2VuZXJhbFB1cnBvc2VCaXQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kZDM2M2FhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9HZW5lcmFsUHVycG9zZUJpdC5qYXZhCkBAIC0wLDAgKzEsMjQ1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwOworCisvKioKKyAqIFBhcnNlci9lbmNvZGVyIGZvciB0aGUgImdlbmVyYWwgcHVycG9zZSBiaXQiIGZpZWxkIGluIFpJUCdzIGxvY2FsCisgKiBmaWxlIGFuZCBjZW50cmFsIGRpcmVjdG9yeSBoZWFkZXJzLgorICoKKyAqIEBzaW5jZSAxLjEKKyAqIEBOb3RUaHJlYWRTYWZlCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBHZW5lcmFsUHVycG9zZUJpdCBpbXBsZW1lbnRzIENsb25lYWJsZSB7CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgdGhhdCB0aGUgZmlsZSBpcyBlbmNyeXB0ZWQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEVOQ1JZUFRJT05fRkxBRyA9IDEgPDwgMDsKKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB0aGUgc2l6ZSBvZiB0aGUgc2xpZGluZyBkaWN0aW9uYXJ5IHVzZWQgYnkgdGhlIGNvbXByZXNzaW9uIG1ldGhvZCA2IChpbXBsb2RpbmcpLgorICAgICAqIDx1bD4KKyAgICAgKiAgIDxsaT4wOiA0MDk2IGJ5dGVzPC9saT4KKyAgICAgKiAgIDxsaT4xOiA4MTkyIGJ5dGVzPC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBTTElESU5HX0RJQ1RJT05BUllfU0laRV9GTEFHID0gMSA8PCAxOworCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHRoZSBudW1iZXIgb2YgU2hhbm5vbi1GYW5vIHRyZWVzIHVzZWQgYnkgdGhlIGNvbXByZXNzaW9uIG1ldGhvZCA2IChpbXBsb2RpbmcpLgorICAgICAqIDx1bD4KKyAgICAgKiAgIDxsaT4wOiAyIHRyZWVzIChsZW5ndGhzLCBkaXN0YW5jZXMpPC9saT4KKyAgICAgKiAgIDxsaT4xOiAzIHRyZWVzIChsaXRlcmFscywgbGVuZ3RocywgZGlzdGFuY2VzKTwvbGk+CisgICAgICogPC91bD4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTlVNQkVSX09GX1NIQU5OT05fRkFOT19UUkVFU19GTEFHID0gMSA8PCAyOworCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHRoYXQgYSBkYXRhIGRlc2NyaXB0b3Igc3RvcmVkIGFmdGVyIHRoZSBmaWxlIGNvbnRlbnRzCisgICAgICogd2lsbCBob2xkIENSQyBhbmQgc2l6ZSBpbmZvcm1hdGlvbi4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgREFUQV9ERVNDUklQVE9SX0ZMQUcgPSAxIDw8IDM7CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgc3Ryb25nIGVuY3J5cHRpb24uCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFNUUk9OR19FTkNSWVBUSU9OX0ZMQUcgPSAxIDw8IDY7CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgdGhhdCBmaWxlbmFtZXMgYXJlIHdyaXR0ZW4gaW4gVVRGLTguCisgICAgICoKKyAgICAgKiA8cD5UaGUgb25seSByZWFzb24gdGhpcyBpcyBwdWJsaWMgaXMgdGhhdCB7QGxpbmsKKyAgICAgKiBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtI0VGU19GTEFHfSB3YXMgcHVibGljIGluIEFwYWNoZSBDb21tb25zCisgICAgICogQ29tcHJlc3MgMS4wIGFuZCB3ZSBuZWVkZWQgYSBzdWJzdGl0dXRlIGZvciBpdC48L3A+CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVUZUOF9OQU1FU19GTEFHID0gMSA8PCAxMTsKKworICAgIHByaXZhdGUgYm9vbGVhbiBsYW5ndWFnZUVuY29kaW5nRmxhZyA9IGZhbHNlOworICAgIHByaXZhdGUgYm9vbGVhbiBkYXRhRGVzY3JpcHRvckZsYWcgPSBmYWxzZTsKKyAgICBwcml2YXRlIGJvb2xlYW4gZW5jcnlwdGlvbkZsYWcgPSBmYWxzZTsKKyAgICBwcml2YXRlIGJvb2xlYW4gc3Ryb25nRW5jcnlwdGlvbkZsYWcgPSBmYWxzZTsKKyAgICBwcml2YXRlIGludCBzbGlkaW5nRGljdGlvbmFyeVNpemU7CisgICAgcHJpdmF0ZSBpbnQgbnVtYmVyT2ZTaGFubm9uRmFub1RyZWVzOworCisgICAgcHVibGljIEdlbmVyYWxQdXJwb3NlQml0KCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIHdoZXRoZXIgdGhlIGN1cnJlbnQgZW50cnkgdXNlcyBVVEY4IGZvciBmaWxlIG5hbWUgYW5kIGNvbW1lbnQuCisgICAgICogQHJldHVybiB3aGV0aGVyIHRoZSBjdXJyZW50IGVudHJ5IHVzZXMgVVRGOCBmb3IgZmlsZSBuYW1lIGFuZCBjb21tZW50LgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHVzZXNVVEY4Rm9yTmFtZXMoKSB7CisgICAgICAgIHJldHVybiBsYW5ndWFnZUVuY29kaW5nRmxhZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB3aGV0aGVyIHRoZSBjdXJyZW50IGVudHJ5IHdpbGwgdXNlIFVURjggZm9yIGZpbGUgbmFtZSBhbmQgY29tbWVudC4KKyAgICAgKiBAcGFyYW0gYiB3aGV0aGVyIHRoZSBjdXJyZW50IGVudHJ5IHdpbGwgdXNlIFVURjggZm9yIGZpbGUgbmFtZSBhbmQgY29tbWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1c2VVVEY4Rm9yTmFtZXMoZmluYWwgYm9vbGVhbiBiKSB7CisgICAgICAgIGxhbmd1YWdlRW5jb2RpbmdGbGFnID0gYjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB3aGV0aGVyIHRoZSBjdXJyZW50IGVudHJ5IHVzZXMgdGhlIGRhdGEgZGVzY3JpcHRvciB0byBzdG9yZSBDUkMKKyAgICAgKiBhbmQgc2l6ZSBpbmZvcm1hdGlvbi4KKyAgICAgKiBAcmV0dXJuIHdoZXRoZXIgdGhlIGN1cnJlbnQgZW50cnkgdXNlcyB0aGUgZGF0YSBkZXNjcmlwdG9yIHRvIHN0b3JlIENSQworICAgICAqIGFuZCBzaXplIGluZm9ybWF0aW9uCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gdXNlc0RhdGFEZXNjcmlwdG9yKCkgeworICAgICAgICByZXR1cm4gZGF0YURlc2NyaXB0b3JGbGFnOworICAgIH0KKworICAgIC8qKgorICAgICAqIHdoZXRoZXIgdGhlIGN1cnJlbnQgZW50cnkgd2lsbCB1c2UgdGhlIGRhdGEgZGVzY3JpcHRvciB0byBzdG9yZQorICAgICAqIENSQyBhbmQgc2l6ZSBpbmZvcm1hdGlvbi4KKyAgICAgKiBAcGFyYW0gYiB3aGV0aGVyIHRoZSBjdXJyZW50IGVudHJ5IHdpbGwgdXNlIHRoZSBkYXRhIGRlc2NyaXB0b3IgdG8gc3RvcmUKKyAgICAgKiBDUkMgYW5kIHNpemUgaW5mb3JtYXRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1c2VEYXRhRGVzY3JpcHRvcihmaW5hbCBib29sZWFuIGIpIHsKKyAgICAgICAgZGF0YURlc2NyaXB0b3JGbGFnID0gYjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB3aGV0aGVyIHRoZSBjdXJyZW50IGVudHJ5IGlzIGVuY3J5cHRlZC4KKyAgICAgKiBAcmV0dXJuIHdoZXRoZXIgdGhlIGN1cnJlbnQgZW50cnkgaXMgZW5jcnlwdGVkCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gdXNlc0VuY3J5cHRpb24oKSB7CisgICAgICAgIHJldHVybiBlbmNyeXB0aW9uRmxhZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB3aGV0aGVyIHRoZSBjdXJyZW50IGVudHJ5IHdpbGwgYmUgZW5jcnlwdGVkLgorICAgICAqIEBwYXJhbSBiIHdoZXRoZXIgdGhlIGN1cnJlbnQgZW50cnkgd2lsbCBiZSBlbmNyeXB0ZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1c2VFbmNyeXB0aW9uKGZpbmFsIGJvb2xlYW4gYikgeworICAgICAgICBlbmNyeXB0aW9uRmxhZyA9IGI7CisgICAgfQorCisgICAgLyoqCisgICAgICogd2hldGhlciB0aGUgY3VycmVudCBlbnRyeSBpcyBlbmNyeXB0ZWQgdXNpbmcgc3Ryb25nIGVuY3J5cHRpb24uCisgICAgICogQHJldHVybiB3aGV0aGVyIHRoZSBjdXJyZW50IGVudHJ5IGlzIGVuY3J5cHRlZCB1c2luZyBzdHJvbmcgZW5jcnlwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHVzZXNTdHJvbmdFbmNyeXB0aW9uKCkgeworICAgICAgICByZXR1cm4gZW5jcnlwdGlvbkZsYWcgJiYgc3Ryb25nRW5jcnlwdGlvbkZsYWc7CisgICAgfQorCisgICAgLyoqCisgICAgICogd2hldGhlciB0aGUgY3VycmVudCBlbnRyeSB3aWxsIGJlIGVuY3J5cHRlZCAgdXNpbmcgc3Ryb25nIGVuY3J5cHRpb24uCisgICAgICogQHBhcmFtIGIgd2hldGhlciB0aGUgY3VycmVudCBlbnRyeSB3aWxsIGJlIGVuY3J5cHRlZCAgdXNpbmcgc3Ryb25nIGVuY3J5cHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1c2VTdHJvbmdFbmNyeXB0aW9uKGZpbmFsIGJvb2xlYW4gYikgeworICAgICAgICBzdHJvbmdFbmNyeXB0aW9uRmxhZyA9IGI7CisgICAgICAgIGlmIChiKSB7CisgICAgICAgICAgICB1c2VFbmNyeXB0aW9uKHRydWUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc2xpZGluZyBkaWN0aW9uYXJ5IHNpemUgdXNlZCBieSB0aGUgY29tcHJlc3Npb24gbWV0aG9kIDYgKGltcGxvZGluZykuCisgICAgICovCisgICAgaW50IGdldFNsaWRpbmdEaWN0aW9uYXJ5U2l6ZSgpIHsKKyAgICAgICAgcmV0dXJuIHNsaWRpbmdEaWN0aW9uYXJ5U2l6ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgdHJlZXMgdXNlZCBieSB0aGUgY29tcHJlc3Npb24gbWV0aG9kIDYgKGltcGxvZGluZykuCisgICAgICovCisgICAgaW50IGdldE51bWJlck9mU2hhbm5vbkZhbm9UcmVlcygpIHsKKyAgICAgICAgcmV0dXJuIG51bWJlck9mU2hhbm5vbkZhbm9UcmVlczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFbmNvZGVzIHRoZSBzZXQgYml0cyBpbiBhIGZvcm0gc3VpdGFibGUgZm9yIFpJUCBhcmNoaXZlcy4KKyAgICAgKiBAcmV0dXJuIHRoZSBlbmNvZGVkIGdlbmVyYWwgcHVycG9zZSBiaXRzCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBlbmNvZGUoKSB7CisgICAgICAgIGZpbmFsIGJ5dGVbXSByZXN1bHQgPSBuZXcgYnl0ZVsyXTsKKyAgICAgICAgZW5jb2RlKHJlc3VsdCwgMCk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBFbmNvZGVzIHRoZSBzZXQgYml0cyBpbiBhIGZvcm0gc3VpdGFibGUgZm9yIFpJUCBhcmNoaXZlcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBidWYgdGhlIG91dHB1dCBidWZmZXIKKyAgICAgKiBAcGFyYW0gIG9mZnNldAorICAgICAqICAgICAgICAgVGhlIG9mZnNldCB3aXRoaW4gdGhlIG91dHB1dCBidWZmZXIgb2YgdGhlIGZpcnN0IGJ5dGUgdG8gYmUgd3JpdHRlbi4KKyAgICAgKiAgICAgICAgIG11c3QgYmUgbm9uLW5lZ2F0aXZlIGFuZCBubyBsYXJnZXIgdGhhbiA8dHQ+YnVmLmxlbmd0aC0yPC90dD4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBlbmNvZGUoZmluYWwgYnl0ZVtdIGJ1ZiwgZmluYWwgaW50IG9mZnNldCkgeworICAgICAgICAgICAgICAgIFppcFNob3J0LnB1dFNob3J0KChkYXRhRGVzY3JpcHRvckZsYWcgPyBEQVRBX0RFU0NSSVBUT1JfRkxBRyA6IDApCisgICAgICAgICAgICAgICAgICAgICAgICB8CisgICAgICAgICAgICAgICAgICAgICAgICAobGFuZ3VhZ2VFbmNvZGluZ0ZsYWcgPyBVRlQ4X05BTUVTX0ZMQUcgOiAwKQorICAgICAgICAgICAgICAgICAgICAgICAgfAorICAgICAgICAgICAgICAgICAgICAgICAgKGVuY3J5cHRpb25GbGFnID8gRU5DUllQVElPTl9GTEFHIDogMCkKKyAgICAgICAgICAgICAgICAgICAgICAgIHwKKyAgICAgICAgICAgICAgICAgICAgICAgIChzdHJvbmdFbmNyeXB0aW9uRmxhZyA/IFNUUk9OR19FTkNSWVBUSU9OX0ZMQUcgOiAwKQorICAgICAgICAgICAgICAgICAgICAgICAgLCBidWYsIG9mZnNldCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2VzIHRoZSBzdXBwb3J0ZWQgZmxhZ3MgZnJvbSB0aGUgZ2l2ZW4gYXJjaGl2ZSBkYXRhLgorICAgICAqCisgICAgICogQHBhcmFtIGRhdGEgbG9jYWwgZmlsZSBoZWFkZXIgb3IgYSBjZW50cmFsIGRpcmVjdG9yeSBlbnRyeS4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0IG9mZnNldCBhdCB3aGljaCB0aGUgZ2VuZXJhbCBwdXJwb3NlIGJpdCBzdGFydHMKKyAgICAgKiBAcmV0dXJuIHBhcnNlZCBmbGFncworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgR2VuZXJhbFB1cnBvc2VCaXQgcGFyc2UoZmluYWwgYnl0ZVtdIGRhdGEsIGZpbmFsIGludCBvZmZzZXQpIHsKKyAgICAgICAgZmluYWwgaW50IGdlbmVyYWxQdXJwb3NlRmxhZyA9IFppcFNob3J0LmdldFZhbHVlKGRhdGEsIG9mZnNldCk7CisgICAgICAgIGZpbmFsIEdlbmVyYWxQdXJwb3NlQml0IGIgPSBuZXcgR2VuZXJhbFB1cnBvc2VCaXQoKTsKKyAgICAgICAgYi51c2VEYXRhRGVzY3JpcHRvcigoZ2VuZXJhbFB1cnBvc2VGbGFnICYgREFUQV9ERVNDUklQVE9SX0ZMQUcpICE9IDApOworICAgICAgICBiLnVzZVVURjhGb3JOYW1lcygoZ2VuZXJhbFB1cnBvc2VGbGFnICYgVUZUOF9OQU1FU19GTEFHKSAhPSAwKTsKKyAgICAgICAgYi51c2VTdHJvbmdFbmNyeXB0aW9uKChnZW5lcmFsUHVycG9zZUZsYWcgJiBTVFJPTkdfRU5DUllQVElPTl9GTEFHKSAhPSAwKTsKKyAgICAgICAgYi51c2VFbmNyeXB0aW9uKChnZW5lcmFsUHVycG9zZUZsYWcgJiBFTkNSWVBUSU9OX0ZMQUcpICE9IDApOworICAgICAgICBiLnNsaWRpbmdEaWN0aW9uYXJ5U2l6ZSA9IChnZW5lcmFsUHVycG9zZUZsYWcgJiBTTElESU5HX0RJQ1RJT05BUllfU0laRV9GTEFHKSAhPSAwID8gODE5MiA6IDQwOTY7CisgICAgICAgIGIubnVtYmVyT2ZTaGFubm9uRmFub1RyZWVzID0gKGdlbmVyYWxQdXJwb3NlRmxhZyAmIE5VTUJFUl9PRl9TSEFOTk9OX0ZBTk9fVFJFRVNfRkxBRykgIT0gMCA/IDMgOiAyOworICAgICAgICByZXR1cm4gYjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICByZXR1cm4gMyAqICg3ICogKDEzICogKDE3ICogKGVuY3J5cHRpb25GbGFnID8gMSA6IDApCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAoc3Ryb25nRW5jcnlwdGlvbkZsYWcgPyAxIDogMCkpCisgICAgICAgICAgICAgICAgICAgICAgICAgKyAobGFuZ3VhZ2VFbmNvZGluZ0ZsYWcgPyAxIDogMCkpCisgICAgICAgICAgICAgICAgICAgICsgKGRhdGFEZXNjcmlwdG9yRmxhZyA/IDEgOiAwKSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIE9iamVjdCBvKSB7CisgICAgICAgIGlmICghKG8gaW5zdGFuY2VvZiBHZW5lcmFsUHVycG9zZUJpdCkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBmaW5hbCBHZW5lcmFsUHVycG9zZUJpdCBnID0gKEdlbmVyYWxQdXJwb3NlQml0KSBvOworICAgICAgICByZXR1cm4gZy5lbmNyeXB0aW9uRmxhZyA9PSBlbmNyeXB0aW9uRmxhZworICAgICAgICAgICAgJiYgZy5zdHJvbmdFbmNyeXB0aW9uRmxhZyA9PSBzdHJvbmdFbmNyeXB0aW9uRmxhZworICAgICAgICAgICAgJiYgZy5sYW5ndWFnZUVuY29kaW5nRmxhZyA9PSBsYW5ndWFnZUVuY29kaW5nRmxhZworICAgICAgICAgICAgJiYgZy5kYXRhRGVzY3JpcHRvckZsYWcgPT0gZGF0YURlc2NyaXB0b3JGbGFnOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIC8vIGltcG9zc2libGUKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJHZW5lcmFsUHVycG9zZUJpdCBpcyBub3QgQ2xvbmVhYmxlPyIsIGV4KTsgLy9OT1NPTkFSCisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL0luZmxhdGVySW5wdXRTdHJlYW1XaXRoU3RhdGlzdGljcy5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9JbmZsYXRlcklucHV0U3RyZWFtV2l0aFN0YXRpc3RpY3MuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iMTA1OTBmCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9JbmZsYXRlcklucHV0U3RyZWFtV2l0aFN0YXRpc3RpY3MuamF2YQpAQCAtMCwwICsxLDgzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXA7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuSW5wdXRTdHJlYW1TdGF0aXN0aWNzOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC56aXAuSW5mbGF0ZXI7CitpbXBvcnQgamF2YS51dGlsLnppcC5JbmZsYXRlcklucHV0U3RyZWFtOworCisvKioKKyAqIEhlbHBlciBjbGFzcyB0byBwcm92aWRlIHN0YXRpc3RpY3MKKyAqCisgKiBAc2luY2UgMS4xNworICovCisvKiBwYWNrYWdlICovIGNsYXNzIEluZmxhdGVySW5wdXRTdHJlYW1XaXRoU3RhdGlzdGljcyBleHRlbmRzIEluZmxhdGVySW5wdXRTdHJlYW0KKyAgICBpbXBsZW1lbnRzIElucHV0U3RyZWFtU3RhdGlzdGljcyB7CisgICAgcHJpdmF0ZSBsb25nIGNvbXByZXNzZWRDb3VudCA9IDA7CisgICAgcHJpdmF0ZSBsb25nIHVuY29tcHJlc3NlZENvdW50ID0gMDsKKworICAgIHB1YmxpYyBJbmZsYXRlcklucHV0U3RyZWFtV2l0aFN0YXRpc3RpY3MoSW5wdXRTdHJlYW0gaW4pIHsKKyAgICAgICAgc3VwZXIoaW4pOworICAgIH0KKworICAgIHB1YmxpYyBJbmZsYXRlcklucHV0U3RyZWFtV2l0aFN0YXRpc3RpY3MoSW5wdXRTdHJlYW0gaW4sIEluZmxhdGVyIGluZikgeworICAgICAgICBzdXBlcihpbiwgaW5mKTsKKyAgICB9CisKKyAgICBwdWJsaWMgSW5mbGF0ZXJJbnB1dFN0cmVhbVdpdGhTdGF0aXN0aWNzKElucHV0U3RyZWFtIGluLCBJbmZsYXRlciBpbmYsIGludCBzaXplKSB7CisgICAgICAgIHN1cGVyKGluLCBpbmYsIHNpemUpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIGZpbGwoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzdXBlci5maWxsKCk7CisgICAgICAgIGNvbXByZXNzZWRDb3VudCArPSBpbmYuZ2V0UmVtYWluaW5nKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCByZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgaW50IGIgPSBzdXBlci5yZWFkKCk7CisgICAgICAgIGlmIChiID4gLTEpIHsKKyAgICAgICAgICAgIHVuY29tcHJlc3NlZENvdW50Kys7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGI7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCByZWFkKGJ5dGVbXSBiLCBpbnQgb2ZmLCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBpbnQgYnl0ZXMgPSBzdXBlci5yZWFkKGIsIG9mZiwgbGVuKTsKKyAgICAgICAgaWYgKGJ5dGVzID4gLTEpIHsKKyAgICAgICAgICAgIHVuY29tcHJlc3NlZENvdW50ICs9IGJ5dGVzOworICAgICAgICB9CisgICAgICAgIHJldHVybiBieXRlczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgbG9uZyBnZXRDb21wcmVzc2VkQ291bnQoKSB7CisgICAgICAgIHJldHVybiBjb21wcmVzc2VkQ291bnQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGxvbmcgZ2V0VW5jb21wcmVzc2VkQ291bnQoKSB7CisgICAgICAgIHJldHVybiB1bmNvbXByZXNzZWRDb3VudDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL0phck1hcmtlci5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9KYXJNYXJrZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hZDEyZjM3Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9KYXJNYXJrZXIuamF2YQpAQCAtMCwwICsxLDEyMiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICoKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcDsKKworaW1wb3J0IGphdmEudXRpbC56aXAuWmlwRXhjZXB0aW9uOworCisvKioKKyAqIElmIHRoaXMgZXh0cmEgZmllbGQgaXMgYWRkZWQgYXMgdGhlIHZlcnkgZmlyc3QgZXh0cmEgZmllbGQgb2YgdGhlCisgKiBhcmNoaXZlLCBTb2xhcmlzIHdpbGwgY29uc2lkZXIgaXQgYW4gZXhlY3V0YWJsZSBqYXIgZmlsZS4KKyAqIEBJbW11dGFibGUKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIEphck1hcmtlciBpbXBsZW1lbnRzIFppcEV4dHJhRmllbGQgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgWmlwU2hvcnQgSUQgPSBuZXcgWmlwU2hvcnQoMHhDQUZFKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBaaXBTaG9ydCBOVUxMID0gbmV3IFppcFNob3J0KDApOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBOT19CWVRFUyA9IG5ldyBieXRlWzBdOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEphck1hcmtlciBERUZBVUxUID0gbmV3IEphck1hcmtlcigpOworCisgICAgLyoqIE5vLWFyZyBjb25zdHJ1Y3RvciAqLworICAgIHB1YmxpYyBKYXJNYXJrZXIoKSB7CisgICAgICAgIC8vIGVtcHR5CisgICAgfQorCisgICAgLyoqCisgICAgICogU2luY2UgSmFyTWFya2VyIGlzIHN0YXRlbGVzcyB3ZSBjYW4gYWx3YXlzIHVzZSB0aGUgc2FtZSBpbnN0YW5jZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBERUZBVUxUIGphcm1ha2VyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgSmFyTWFya2VyIGdldEluc3RhbmNlKCkgeworICAgICAgICByZXR1cm4gREVGQVVMVDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgSGVhZGVyLUlELgorICAgICAqIEByZXR1cm4gdGhlIGhlYWRlciBpZAorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBaaXBTaG9ydCBnZXRIZWFkZXJJZCgpIHsKKyAgICAgICAgcmV0dXJuIElEOworICAgIH0KKworICAgIC8qKgorICAgICAqIExlbmd0aCBvZiB0aGUgZXh0cmEgZmllbGQgaW4gdGhlIGxvY2FsIGZpbGUgZGF0YSAtIHdpdGhvdXQKKyAgICAgKiBIZWFkZXItSUQgb3IgbGVuZ3RoIHNwZWNpZmllci4KKyAgICAgKiBAcmV0dXJuIDAKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgWmlwU2hvcnQgZ2V0TG9jYWxGaWxlRGF0YUxlbmd0aCgpIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgLyoqCisgICAgICogTGVuZ3RoIG9mIHRoZSBleHRyYSBmaWVsZCBpbiB0aGUgY2VudHJhbCBkaXJlY3RvcnkgLSB3aXRob3V0CisgICAgICogSGVhZGVyLUlEIG9yIGxlbmd0aCBzcGVjaWZpZXIuCisgICAgICogQHJldHVybiAwCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFppcFNob3J0IGdldENlbnRyYWxEaXJlY3RvcnlMZW5ndGgoKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBhY3R1YWwgZGF0YSB0byBwdXQgaW50byBsb2NhbCBmaWxlIGRhdGEgLSB3aXRob3V0IEhlYWRlci1JRAorICAgICAqIG9yIGxlbmd0aCBzcGVjaWZpZXIuCisgICAgICogQHJldHVybiB0aGUgZGF0YQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBieXRlW10gZ2V0TG9jYWxGaWxlRGF0YURhdGEoKSB7CisgICAgICAgIHJldHVybiBOT19CWVRFUzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgYWN0dWFsIGRhdGEgdG8gcHV0IGNlbnRyYWwgZGlyZWN0b3J5IC0gd2l0aG91dCBIZWFkZXItSUQgb3IKKyAgICAgKiBsZW5ndGggc3BlY2lmaWVyLgorICAgICAqIEByZXR1cm4gdGhlIGRhdGEKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYnl0ZVtdIGdldENlbnRyYWxEaXJlY3RvcnlEYXRhKCkgeworICAgICAgICByZXR1cm4gTk9fQllURVM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUG9wdWxhdGUgZGF0YSBmcm9tIHRoaXMgYXJyYXkgYXMgaWYgaXQgd2FzIGluIGxvY2FsIGZpbGUgZGF0YS4KKyAgICAgKiBAcGFyYW0gZGF0YSBhbiBhcnJheSBvZiBieXRlcworICAgICAqIEBwYXJhbSBvZmZzZXQgdGhlIHN0YXJ0IG9mZnNldAorICAgICAqIEBwYXJhbSBsZW5ndGggdGhlIG51bWJlciBvZiBieXRlcyBpbiB0aGUgYXJyYXkgZnJvbSBvZmZzZXQKKyAgICAgKgorICAgICAqIEB0aHJvd3MgWmlwRXhjZXB0aW9uIG9uIGVycm9yCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcGFyc2VGcm9tTG9jYWxGaWxlRGF0YShmaW5hbCBieXRlW10gZGF0YSwgZmluYWwgaW50IG9mZnNldCwgZmluYWwgaW50IGxlbmd0aCkKKyAgICAgICAgdGhyb3dzIFppcEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChsZW5ndGggIT0gMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFppcEV4Y2VwdGlvbigiSmFyTWFya2VyIGRvZXNuJ3QgZXhwZWN0IGFueSBkYXRhIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEb2Vzbid0IGRvIGFueXRoaW5nIHNwZWNpYWwgc2luY2UgdGhpcyBjbGFzcyBhbHdheXMgdXNlcyB0aGUKKyAgICAgKiBzYW1lIGRhdGEgaW4gY2VudHJhbCBkaXJlY3RvcnkgYW5kIGxvY2FsIGZpbGUgZGF0YS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBwYXJzZUZyb21DZW50cmFsRGlyZWN0b3J5RGF0YShmaW5hbCBieXRlW10gYnVmZmVyLCBmaW5hbCBpbnQgb2Zmc2V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBsZW5ndGgpCisgICAgICAgIHRocm93cyBaaXBFeGNlcHRpb24geworICAgICAgICBwYXJzZUZyb21Mb2NhbEZpbGVEYXRhKGJ1ZmZlciwgb2Zmc2V0LCBsZW5ndGgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvTmlvWmlwRW5jb2RpbmcuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvTmlvWmlwRW5jb2RpbmcuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wYTc1ODFhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9OaW9aaXBFbmNvZGluZy5qYXZhCkBAIC0wLDAgKzEsMjE2IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLm5pby5DaGFyQnVmZmVyOworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldDsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXREZWNvZGVyOworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldEVuY29kZXI7CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5Db2RlclJlc3VsdDsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNvZGluZ0Vycm9yQWN0aW9uOworCisvKioKKyAqIEEgWmlwRW5jb2RpbmcsIHdoaWNoIHVzZXMgYSBqYXZhLm5pbyB7QGxpbmsKKyAqIGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldCBDaGFyc2V0fSB0byBlbmNvZGUgbmFtZXMuCisgKiA8cD5UaGUgbWV0aG9kcyBvZiB0aGlzIGNsYXNzIGFyZSByZWVudHJhbnQuPC9wPgorICogQEltbXV0YWJsZQorICovCitjbGFzcyBOaW9aaXBFbmNvZGluZyBpbXBsZW1lbnRzIFppcEVuY29kaW5nLCBDaGFyc2V0QWNjZXNzb3IgeworCisgICAgcHJpdmF0ZSBmaW5hbCBDaGFyc2V0IGNoYXJzZXQ7CisgICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIHVzZVJlcGxhY2VtZW50OworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXIgUkVQTEFDRU1FTlQgPSAnPyc7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIFJFUExBQ0VNRU5UX0JZVEVTID0geyAoYnl0ZSkgUkVQTEFDRU1FTlQgfTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUkVQTEFDRU1FTlRfU1RSSU5HID0gU3RyaW5nLnZhbHVlT2YoUkVQTEFDRU1FTlQpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXJbXSBIRVhfQ0hBUlMgPSBuZXcgY2hhcltdIHsKKyAgICAgICAgJzAnLCAnMScsICcyJywgJzMnLCAnNCcsICc1JywgJzYnLCAnNycsICc4JywgJzknLCAnQScsICdCJywgJ0MnLCAnRCcsICdFJywgJ0YnCisgICAgfTsKKworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGFuIE5pb1ppcEVuY29kaW5nIHVzaW5nIHRoZSBnaXZlbiBjaGFyc2V0LgorICAgICAqIEBwYXJhbSBjaGFyc2V0ICBUaGUgY2hhcmFjdGVyIHNldCB0byB1c2UuCisgICAgICogQHBhcmFtIHVzZVJlcGxhY2VtZW50IHNob3VsZCBpbnZhbGlkIGNoYXJhY3RlcnMgYmUgcmVwbGFjZWQsIG9yIHJlcG9ydGVkLgorICAgICAqLworICAgIE5pb1ppcEVuY29kaW5nKGZpbmFsIENoYXJzZXQgY2hhcnNldCwgYm9vbGVhbiB1c2VSZXBsYWNlbWVudCkgeworICAgICAgICB0aGlzLmNoYXJzZXQgPSBjaGFyc2V0OworICAgICAgICB0aGlzLnVzZVJlcGxhY2VtZW50ID0gdXNlUmVwbGFjZW1lbnQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIENoYXJzZXQgZ2V0Q2hhcnNldCgpIHsKKyAgICAgICAgcmV0dXJuIGNoYXJzZXQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSAgWmlwRW5jb2RpbmcjY2FuRW5jb2RlKGphdmEubGFuZy5TdHJpbmcpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gY2FuRW5jb2RlKGZpbmFsIFN0cmluZyBuYW1lKSB7CisgICAgICAgIGZpbmFsIENoYXJzZXRFbmNvZGVyIGVuYyA9IG5ld0VuY29kZXIoKTsKKworICAgICAgICByZXR1cm4gZW5jLmNhbkVuY29kZShuYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIFppcEVuY29kaW5nI2VuY29kZShqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCeXRlQnVmZmVyIGVuY29kZShmaW5hbCBTdHJpbmcgbmFtZSkgeworICAgICAgICBmaW5hbCBDaGFyc2V0RW5jb2RlciBlbmMgPSBuZXdFbmNvZGVyKCk7CisKKyAgICAgICAgZmluYWwgQ2hhckJ1ZmZlciBjYiA9IENoYXJCdWZmZXIud3JhcChuYW1lKTsKKyAgICAgICAgQ2hhckJ1ZmZlciB0bXAgPSBudWxsOworICAgICAgICBCeXRlQnVmZmVyIG91dCA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUoZXN0aW1hdGVJbml0aWFsQnVmZmVyU2l6ZShlbmMsIGNiLnJlbWFpbmluZygpKSk7CisKKyAgICAgICAgd2hpbGUgKGNiLnJlbWFpbmluZygpID4gMCkgeworICAgICAgICAgICAgZmluYWwgQ29kZXJSZXN1bHQgcmVzID0gZW5jLmVuY29kZShjYiwgb3V0LCBmYWxzZSk7CisKKyAgICAgICAgICAgIGlmIChyZXMuaXNVbm1hcHBhYmxlKCkgfHwgcmVzLmlzTWFsZm9ybWVkKCkpIHsKKworICAgICAgICAgICAgICAgIC8vIHdyaXRlIHRoZSB1bm1hcHBhYmxlIGNoYXJhY3RlcnMgaW4gdXRmLTE2CisgICAgICAgICAgICAgICAgLy8gcHNldWRvLVVSTCBlbmNvZGluZyBzdHlsZSB0byBCeXRlQnVmZmVyLgorCisgICAgICAgICAgICAgICAgaW50IHNwYWNlRm9yU3Vycm9nYXRlID0gZXN0aW1hdGVJbmNyZW1lbnRhbEVuY29kaW5nU2l6ZShlbmMsIDYgKiByZXMubGVuZ3RoKCkpOworICAgICAgICAgICAgICAgIGlmIChzcGFjZUZvclN1cnJvZ2F0ZSA+IG91dC5yZW1haW5pbmcoKSkgeworICAgICAgICAgICAgICAgICAgICAvLyBpZiB0aGUgZGVzdGluYXRpb24gYnVmZmVyIGlzbid0IG92ZXIgc2l6ZWQsIGFzc3VtZSB0aGF0IHRoZSBwcmVzZW5jZSBvZiBvbmUKKyAgICAgICAgICAgICAgICAgICAgLy8gdW5tYXBwYWJsZSBjaGFyYWN0ZXIgbWFrZXMgaXQgbGlrZWx5IHRoYXQgdGhlcmUgd2lsbCBiZSBtb3JlLiBGaW5kIGFsbCB0aGUKKyAgICAgICAgICAgICAgICAgICAgLy8gdW4tZW5jb2RlZCBjaGFyYWN0ZXJzIGFuZCBhbGxvY2F0ZSBzcGFjZSBiYXNlZCBvbiB0aG9zZSBlc3RpbWF0ZXMuCisgICAgICAgICAgICAgICAgICAgIGludCBjaGFyQ291bnQgPSAwOworICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gY2IucG9zaXRpb24oKSA7IGkgPCBjYi5saW1pdCgpOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNoYXJDb3VudCArPSAhZW5jLmNhbkVuY29kZShjYi5nZXQoaSkpID8gNiA6IDE7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgaW50IHRvdGFsRXh0cmFTcGFjZSA9IGVzdGltYXRlSW5jcmVtZW50YWxFbmNvZGluZ1NpemUoZW5jLCBjaGFyQ291bnQpOworICAgICAgICAgICAgICAgICAgICBvdXQgPSBaaXBFbmNvZGluZ0hlbHBlci5ncm93QnVmZmVyQnkob3V0LCB0b3RhbEV4dHJhU3BhY2UgLSBvdXQucmVtYWluaW5nKCkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAodG1wID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgdG1wID0gQ2hhckJ1ZmZlci5hbGxvY2F0ZSg2KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXMubGVuZ3RoKCk7ICsraSkgeworICAgICAgICAgICAgICAgICAgICBvdXQgPSBlbmNvZGVGdWxseShlbmMsIGVuY29kZVN1cnJvZ2F0ZSh0bXAsIGNiLmdldCgpKSwgb3V0KTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIH0gZWxzZSBpZiAocmVzLmlzT3ZlcmZsb3coKSkgeworICAgICAgICAgICAgICAgIGludCBpbmNyZW1lbnQgPSBlc3RpbWF0ZUluY3JlbWVudGFsRW5jb2RpbmdTaXplKGVuYywgY2IucmVtYWluaW5nKCkpOworICAgICAgICAgICAgICAgIG91dCA9IFppcEVuY29kaW5nSGVscGVyLmdyb3dCdWZmZXJCeShvdXQsIGluY3JlbWVudCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgLy8gdGVsbCB0aGUgZW5jb2RlciB3ZSBhcmUgZG9uZQorICAgICAgICBlbmMuZW5jb2RlKGNiLCBvdXQsIHRydWUpOworICAgICAgICAvLyBtYXkgaGF2ZSBjYXVzZWQgdW5kZXJmbG93LCBidXQgdGhhdCdzIGJlZW4gaWdub3JlZCB0cmFkaXRpb25hbGx5CisKKyAgICAgICAgb3V0LmxpbWl0KG91dC5wb3NpdGlvbigpKTsKKyAgICAgICAgb3V0LnJld2luZCgpOworICAgICAgICByZXR1cm4gb3V0OworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUKKyAgICAgKiBaaXBFbmNvZGluZyNkZWNvZGUoYnl0ZVtdKQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgZGVjb2RlKGZpbmFsIGJ5dGVbXSBkYXRhKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gbmV3RGVjb2RlcigpCisgICAgICAgICAgICAuZGVjb2RlKEJ5dGVCdWZmZXIud3JhcChkYXRhKSkudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBCeXRlQnVmZmVyIGVuY29kZUZ1bGx5KENoYXJzZXRFbmNvZGVyIGVuYywgQ2hhckJ1ZmZlciBjYiwgQnl0ZUJ1ZmZlciBvdXQpIHsKKyAgICAgICAgQnl0ZUJ1ZmZlciBvID0gb3V0OworICAgICAgICB3aGlsZSAoY2IuaGFzUmVtYWluaW5nKCkpIHsKKyAgICAgICAgICAgIENvZGVyUmVzdWx0IHJlc3VsdCA9IGVuYy5lbmNvZGUoY2IsIG8sIGZhbHNlKTsKKyAgICAgICAgICAgIGlmIChyZXN1bHQuaXNPdmVyZmxvdygpKSB7CisgICAgICAgICAgICAgICAgaW50IGluY3JlbWVudCA9IGVzdGltYXRlSW5jcmVtZW50YWxFbmNvZGluZ1NpemUoZW5jLCBjYi5yZW1haW5pbmcoKSk7CisgICAgICAgICAgICAgICAgbyA9IFppcEVuY29kaW5nSGVscGVyLmdyb3dCdWZmZXJCeShvLCBpbmNyZW1lbnQpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBvOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIENoYXJCdWZmZXIgZW5jb2RlU3Vycm9nYXRlKENoYXJCdWZmZXIgY2IsIGNoYXIgYykgeworICAgICAgICBjYi5wb3NpdGlvbigwKS5saW1pdCg2KTsKKyAgICAgICAgY2IucHV0KCclJyk7CisgICAgICAgIGNiLnB1dCgnVScpOworCisgICAgICAgIGNiLnB1dChIRVhfQ0hBUlNbKGMgPj4gMTIpICYgMHgwZl0pOworICAgICAgICBjYi5wdXQoSEVYX0NIQVJTWyhjID4+IDgpICYgMHgwZl0pOworICAgICAgICBjYi5wdXQoSEVYX0NIQVJTWyhjID4+IDQpICYgMHgwZl0pOworICAgICAgICBjYi5wdXQoSEVYX0NIQVJTW2MgJiAweDBmXSk7CisgICAgICAgIGNiLmZsaXAoKTsKKyAgICAgICAgcmV0dXJuIGNiOworICAgIH0KKworICAgIHByaXZhdGUgQ2hhcnNldEVuY29kZXIgbmV3RW5jb2RlcigpIHsKKyAgICAgICAgaWYgKHVzZVJlcGxhY2VtZW50KSB7CisgICAgICAgICAgICByZXR1cm4gY2hhcnNldC5uZXdFbmNvZGVyKCkKKyAgICAgICAgICAgICAgICAub25NYWxmb3JtZWRJbnB1dChDb2RpbmdFcnJvckFjdGlvbi5SRVBMQUNFKQorICAgICAgICAgICAgICAgIC5vblVubWFwcGFibGVDaGFyYWN0ZXIoQ29kaW5nRXJyb3JBY3Rpb24uUkVQTEFDRSkKKyAgICAgICAgICAgICAgICAucmVwbGFjZVdpdGgoUkVQTEFDRU1FTlRfQllURVMpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIGNoYXJzZXQubmV3RW5jb2RlcigpCisgICAgICAgICAgICAgICAgLm9uTWFsZm9ybWVkSW5wdXQoQ29kaW5nRXJyb3JBY3Rpb24uUkVQT1JUKQorICAgICAgICAgICAgICAgIC5vblVubWFwcGFibGVDaGFyYWN0ZXIoQ29kaW5nRXJyb3JBY3Rpb24uUkVQT1JUKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgQ2hhcnNldERlY29kZXIgbmV3RGVjb2RlcigpIHsKKyAgICAgICAgaWYgKCF1c2VSZXBsYWNlbWVudCkgeworICAgICAgICAgICAgcmV0dXJuIHRoaXMuY2hhcnNldC5uZXdEZWNvZGVyKCkKKyAgICAgICAgICAgICAgICAub25NYWxmb3JtZWRJbnB1dChDb2RpbmdFcnJvckFjdGlvbi5SRVBPUlQpCisgICAgICAgICAgICAgICAgLm9uVW5tYXBwYWJsZUNoYXJhY3RlcihDb2RpbmdFcnJvckFjdGlvbi5SRVBPUlQpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuICBjaGFyc2V0Lm5ld0RlY29kZXIoKQorICAgICAgICAgICAgICAgIC5vbk1hbGZvcm1lZElucHV0KENvZGluZ0Vycm9yQWN0aW9uLlJFUExBQ0UpCisgICAgICAgICAgICAgICAgLm9uVW5tYXBwYWJsZUNoYXJhY3RlcihDb2RpbmdFcnJvckFjdGlvbi5SRVBMQUNFKQorICAgICAgICAgICAgICAgIC5yZXBsYWNlV2l0aChSRVBMQUNFTUVOVF9TVFJJTkcpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRXN0aW1hdGUgdGhlIGluaXRpYWwgZW5jb2RlZCBzaXplIChpbiBieXRlcykgZm9yIGEgY2hhcmFjdGVyIGJ1ZmZlci4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgZXN0aW1hdGUgYXNzdW1lcyB0aGF0IG9uZSBjaGFyYWN0ZXIgY29uc3VtZXMgdXNlcyB0aGUgbWF4aW11bSBsZW5ndGggZW5jb2RpbmcsCisgICAgICogd2hpbHN0IHRoZSByZXN0IHVzZSBhbiBhdmVyYWdlIHNpemUgZW5jb2RpbmcuIFRoaXMgYWNjb3VudHMgZm9yIGFueSBCT00gZm9yIFVURi0xNiwgYXQKKyAgICAgKiB0aGUgZXhwZW5zZSBvZiBhIGNvdXBsZSBvZiBleHRyYSBieXRlcyBmb3IgVVRGLTggZW5jb2RlZCBBU0NJSS4KKyAgICAgKiA8L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gZW5jICAgICAgICBlbmNvZGVyIHRvIHVzZSBmb3IgZXN0aW1hdGVzCisgICAgICogQHBhcmFtIGNoYXJDaG91bnQgbnVtYmVyIG9mIGNoYXJhY3RlcnMgaW4gc3RyaW5nCisgICAgICogQHJldHVybiBlc3RpbWF0ZWQgc2l6ZSBpbiBieXRlcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBpbnQgZXN0aW1hdGVJbml0aWFsQnVmZmVyU2l6ZShDaGFyc2V0RW5jb2RlciBlbmMsIGludCBjaGFyQ2hvdW50KSB7CisgICAgICAgIGZsb2F0IGZpcnN0ID0gZW5jLm1heEJ5dGVzUGVyQ2hhcigpOworICAgICAgICBmbG9hdCByZXN0ID0gKGNoYXJDaG91bnQgLSAxKSAqIGVuYy5hdmVyYWdlQnl0ZXNQZXJDaGFyKCk7CisgICAgICAgIHJldHVybiAoaW50KSBNYXRoLmNlaWwoZmlyc3QgKyByZXN0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFc3RpbWF0ZSB0aGUgc2l6ZSBuZWVkZWQgZm9yIHJlbWFpbmluZyBjaGFyYWN0ZXJzCisgICAgICoKKyAgICAgKiBAcGFyYW0gZW5jICAgICAgIGVuY29kZXIgdG8gdXNlIGZvciBlc3RpbWF0ZXMKKyAgICAgKiBAcGFyYW0gY2hhckNvdW50IG51bWJlciBvZiBjaGFyYWN0ZXJzIHJlbWFpbmluZworICAgICAqIEByZXR1cm4gZXN0aW1hdGVkIHNpemUgaW4gYnl0ZXMuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IGVzdGltYXRlSW5jcmVtZW50YWxFbmNvZGluZ1NpemUoQ2hhcnNldEVuY29kZXIgZW5jLCBpbnQgY2hhckNvdW50KSB7CisgICAgICAgIHJldHVybiAoaW50KSBNYXRoLmNlaWwoY2hhckNvdW50ICogZW5jLmF2ZXJhZ2VCeXRlc1BlckNoYXIoKSk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1BLV2FyZUV4dHJhSGVhZGVyLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1BLV2FyZUV4dHJhSGVhZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzE3N2M4NwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvUEtXYXJlRXh0cmFIZWFkZXIuamF2YQpAQCAtMCwwICsxLDMwOCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwOworCitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5NYXA7CisKKy8qKgorICogQmFzZSBjbGFzcyBmb3IgYWxsIFBLV2FyZSBzdHJvbmcgY3J5cHRvIGV4dHJhIGhlYWRlcnMuCisgKgorICogPHA+VGhpcyBiYXNlIGNsYXNzIGFjdHMgYXMgYSBtYXJrZXIgc28geW91IGtub3cgeW91IGNhbiBpZ25vcmUgYWxsCisgKiBleHRyYSBmaWVsZHMgdGhhdCBleHRlbmQgdGhpcyBjbGFzcyBpZiB5b3UgYXJlIG5vdCBpbnRlcmVzdGVkIGluCisgKiB0aGUgbWV0YSBkYXRhIG9mIFBLV2FyZSBzdHJvbmcgZW5jcnlwdGlvbi48L3A+CisgKgorICogPGI+QWxnb3JpdGhtIElEczwvYj4gLSBpbnRlZ2VyIGlkZW50aWZpZXIgb2YgdGhlIGVuY3J5cHRpb24gYWxnb3JpdGhtIGZyb20KKyAqIHRoZSBmb2xsb3dpbmcgcmFuZ2UKKyAqCisgKiA8dWw+CisgKiA8bGk+MHg2NjAxIC0gREVTPC9saT4KKyAqIDxsaT4weDY2MDIgLSBSQzIgKHZlcnNpb24gbmVlZGVkIHRvIGV4dHJhY3QgJmx0OyA1LjIpPC9saT4KKyAqIDxsaT4weDY2MDMgLSAzREVTIDE2ODwvbGk+CisgKiA8bGk+MHg2NjA5IC0gM0RFUyAxMTI8L2xpPgorICogPGxpPjB4NjYwRSAtIEFFUyAxMjg8L2xpPgorICogPGxpPjB4NjYwRiAtIEFFUyAxOTI8L2xpPgorICogPGxpPjB4NjYxMCAtIEFFUyAyNTY8L2xpPgorICogPGxpPjB4NjcwMiAtIFJDMiAodmVyc2lvbiBuZWVkZWQgdG8gZXh0cmFjdCAmZ3Q7PSA1LjIpPC9saT4KKyAqIDxsaT4weDY3MjAgLSBCbG93ZmlzaDwvbGk+CisgKiA8bGk+MHg2NzIxIC0gVHdvZmlzaDwvbGk+CisgKiA8bGk+MHg2ODAxIC0gUkM0PC9saT4KKyAqIDxsaT4weEZGRkYgLSBVbmtub3duIGFsZ29yaXRobTwvbGk+CisgKiA8L3VsPgorICoKKyAqIDxiPkhhc2ggQWxnb3JpdGhtczwvYj4gLSBpbnRlZ2VyIGlkZW50aWZpZXIgb2YgdGhlIGhhc2ggYWxnb3JpdGhtIGZyb20gdGhlCisgKiBmb2xsb3dpbmcgcmFuZ2UKKyAqCisgKiA8dWw+CisgKiA8bGk+MHgwMDAwIC0gbm9uZTwvbGk+CisgKiA8bGk+MHgwMDAxIC0gQ1JDMzI8L2xpPgorICogPGxpPjB4ODAwMyAtIE1ENTwvbGk+CisgKiA8bGk+MHg4MDA0IC0gU0hBMTwvbGk+CisgKiA8bGk+MHg4MDA3IC0gUklQRU1EMTYwPC9saT4KKyAqIDxsaT4weDgwMEMgLSBTSEEyNTY8L2xpPgorICogPGxpPjB4ODAwRCAtIFNIQTM4NDwvbGk+CisgKiA8bGk+MHg4MDBFIC0gU0hBNTEyPC9saT4KKyAqIDwvdWw+CisgKgorICogQHNpbmNlIDEuMTEKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIFBLV2FyZUV4dHJhSGVhZGVyIGltcGxlbWVudHMgWmlwRXh0cmFGaWVsZCB7CisKKyAgICBwcml2YXRlIGZpbmFsIFppcFNob3J0IGhlYWRlcklkOworICAgIC8qKgorICAgICAqIEV4dHJhIGZpZWxkIGRhdGEgaW4gbG9jYWwgZmlsZSBkYXRhIC0gd2l0aG91dCBIZWFkZXItSUQgb3IgbGVuZ3RoCisgICAgICogc3BlY2lmaWVyLgorICAgICAqLworICAgIHByaXZhdGUgYnl0ZVtdIGxvY2FsRGF0YTsKKyAgICAvKioKKyAgICAgKiBFeHRyYSBmaWVsZCBkYXRhIGluIGNlbnRyYWwgZGlyZWN0b3J5IC0gd2l0aG91dCBIZWFkZXItSUQgb3IgbGVuZ3RoCisgICAgICogc3BlY2lmaWVyLgorICAgICAqLworICAgIHByaXZhdGUgYnl0ZVtdIGNlbnRyYWxEYXRhOworCisgICAgcHJvdGVjdGVkIFBLV2FyZUV4dHJhSGVhZGVyKGZpbmFsIFppcFNob3J0IGhlYWRlcklkKSB7CisgICAgICAgIHRoaXMuaGVhZGVySWQgPSBoZWFkZXJJZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIGhlYWRlciBpZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGhlYWRlciBpZAorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBaaXBTaG9ydCBnZXRIZWFkZXJJZCgpIHsKKyAgICAgICAgcmV0dXJuIGhlYWRlcklkOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgZXh0cmEgZmllbGQgZGF0YSBpbiB0aGUgbG9jYWwgZmlsZSBkYXRhIC0gd2l0aG91dCBIZWFkZXItSUQgb3IKKyAgICAgKiBsZW5ndGggc3BlY2lmaWVyLgorICAgICAqCisgICAgICogQHBhcmFtIGRhdGEKKyAgICAgKiAgICAgICAgICAgIHRoZSBmaWVsZCBkYXRhIHRvIHVzZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldExvY2FsRmlsZURhdGFEYXRhKGZpbmFsIGJ5dGVbXSBkYXRhKSB7CisgICAgICAgIGxvY2FsRGF0YSA9IFppcFV0aWwuY29weShkYXRhKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIGxlbmd0aCBvZiB0aGUgbG9jYWwgZGF0YS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGxlbmd0aCBvZiB0aGUgbG9jYWwgZGF0YQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBaaXBTaG9ydCBnZXRMb2NhbEZpbGVEYXRhTGVuZ3RoKCkgeworICAgICAgICByZXR1cm4gbmV3IFppcFNob3J0KGxvY2FsRGF0YSAhPSBudWxsID8gbG9jYWxEYXRhLmxlbmd0aCA6IDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgbG9jYWwgZGF0YS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGxvY2FsIGRhdGEKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYnl0ZVtdIGdldExvY2FsRmlsZURhdGFEYXRhKCkgeworICAgICAgICByZXR1cm4gWmlwVXRpbC5jb3B5KGxvY2FsRGF0YSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBleHRyYSBmaWVsZCBkYXRhIGluIGNlbnRyYWwgZGlyZWN0b3J5LgorICAgICAqCisgICAgICogQHBhcmFtIGRhdGEKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXRhIHRvIHVzZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldENlbnRyYWxEaXJlY3RvcnlEYXRhKGZpbmFsIGJ5dGVbXSBkYXRhKSB7CisgICAgICAgIGNlbnRyYWxEYXRhID0gWmlwVXRpbC5jb3B5KGRhdGEpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgY2VudHJhbCBkYXRhIGxlbmd0aC4gSWYgdGhlcmUgaXMgbm8gY2VudHJhbCBkYXRhLCBnZXQgdGhlIGxvY2FsCisgICAgICogZmlsZSBkYXRhIGxlbmd0aC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGNlbnRyYWwgZGF0YSBsZW5ndGgKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgWmlwU2hvcnQgZ2V0Q2VudHJhbERpcmVjdG9yeUxlbmd0aCgpIHsKKyAgICAgICAgaWYgKGNlbnRyYWxEYXRhICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgWmlwU2hvcnQoY2VudHJhbERhdGEubGVuZ3RoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZ2V0TG9jYWxGaWxlRGF0YUxlbmd0aCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgY2VudHJhbCBkYXRhLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY2VudHJhbCBkYXRhIGlmIHByZXNlbnQsIGVsc2UgcmV0dXJuIHRoZSBsb2NhbCBmaWxlIGRhdGEKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYnl0ZVtdIGdldENlbnRyYWxEaXJlY3RvcnlEYXRhKCkgeworICAgICAgICBpZiAoY2VudHJhbERhdGEgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIFppcFV0aWwuY29weShjZW50cmFsRGF0YSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGdldExvY2FsRmlsZURhdGFEYXRhKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHBhcmFtIGRhdGEKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBvZiBieXRlcy4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIGxvY2F0aW9uIGluIHRoZSBkYXRhIGFycmF5LgorICAgICAqIEBwYXJhbSBsZW5ndGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gdXNlIGluIHRoZSBkYXRhIGFycmF5LgorICAgICAqIEBzZWUgWmlwRXh0cmFGaWVsZCNwYXJzZUZyb21Mb2NhbEZpbGVEYXRhKGJ5dGVbXSwgaW50LCBpbnQpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcGFyc2VGcm9tTG9jYWxGaWxlRGF0YShmaW5hbCBieXRlW10gZGF0YSwgZmluYWwgaW50IG9mZnNldCwgZmluYWwgaW50IGxlbmd0aCkgeworICAgICAgICBmaW5hbCBieXRlW10gdG1wID0gbmV3IGJ5dGVbbGVuZ3RoXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShkYXRhLCBvZmZzZXQsIHRtcCwgMCwgbGVuZ3RoKTsKKyAgICAgICAgc2V0TG9jYWxGaWxlRGF0YURhdGEodG1wKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcGFyYW0gZGF0YQorICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IG9mIGJ5dGVzLgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzb3VyY2UgbG9jYXRpb24gaW4gdGhlIGRhdGEgYXJyYXkuCisgICAgICogQHBhcmFtIGxlbmd0aAorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBieXRlcyB0byB1c2UgaW4gdGhlIGRhdGEgYXJyYXkuCisgICAgICogQHNlZSBaaXBFeHRyYUZpZWxkI3BhcnNlRnJvbUNlbnRyYWxEaXJlY3RvcnlEYXRhKGJ5dGVbXSwgaW50LCBpbnQpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcGFyc2VGcm9tQ2VudHJhbERpcmVjdG9yeURhdGEoZmluYWwgYnl0ZVtdIGRhdGEsIGZpbmFsIGludCBvZmZzZXQsIGZpbmFsIGludCBsZW5ndGgpIHsKKyAgICAgICAgZmluYWwgYnl0ZVtdIHRtcCA9IG5ldyBieXRlW2xlbmd0aF07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZGF0YSwgb2Zmc2V0LCB0bXAsIDAsIGxlbmd0aCk7CisgICAgICAgIHNldENlbnRyYWxEaXJlY3RvcnlEYXRhKHRtcCk7CisgICAgICAgIGlmIChsb2NhbERhdGEgPT0gbnVsbCkgeworICAgICAgICAgICAgc2V0TG9jYWxGaWxlRGF0YURhdGEodG1wKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEVuY3J5cHRpb24gYWxnb3JpdGhtLgorICAgICAqCisgICAgICogQHNpbmNlIDEuMTEKKyAgICAgKi8KKyAgICBwdWJsaWMgZW51bSBFbmNyeXB0aW9uQWxnb3JpdGhtIHsKKyAgICAgICAgREVTKDB4NjYwMSksCisgICAgICAgIFJDMnByZTUyKDB4NjYwMiksCisgICAgICAgIFRyaXBsZURFUzE2OCgweDY2MDMpLAorICAgICAgICBUcmlwbGVERVMxOTIoMHg2NjA5KSwKKyAgICAgICAgQUVTMTI4KDB4NjYwRSksCisgICAgICAgIEFFUzE5MigweDY2MEYpLAorICAgICAgICBBRVMyNTYoMHg2NjEwKSwKKyAgICAgICAgUkMyKDB4NjcwMiksCisgICAgICAgIFJDNCgweDY4MDEpLAorICAgICAgICBVTktOT1dOKDB4RkZGRik7CisKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBpbnQgY29kZTsKKworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBNYXA8SW50ZWdlciwgRW5jcnlwdGlvbkFsZ29yaXRobT4gY29kZVRvRW51bTsKKworICAgICAgICBzdGF0aWMgeworICAgICAgICAgICAgZmluYWwgTWFwPEludGVnZXIsIEVuY3J5cHRpb25BbGdvcml0aG0+IGN0ZSA9IG5ldyBIYXNoTWFwPD4oKTsKKyAgICAgICAgICAgIGZvciAoZmluYWwgRW5jcnlwdGlvbkFsZ29yaXRobSBtZXRob2QgOiB2YWx1ZXMoKSkgeworICAgICAgICAgICAgICAgIGN0ZS5wdXQobWV0aG9kLmdldENvZGUoKSwgbWV0aG9kKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNvZGVUb0VudW0gPSBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVNYXAoY3RlKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBwcml2YXRlIGNvbnN0cnVjdG9yIGZvciBlbnVtIHN0eWxlIGNsYXNzLgorICAgICAgICAgKi8KKyAgICAgICAgRW5jcnlwdGlvbkFsZ29yaXRobShmaW5hbCBpbnQgY29kZSkgeworICAgICAgICAgICAgdGhpcy5jb2RlID0gY29kZTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiB0aGUgYWxnb3JpdGhtIGlkLgorICAgICAgICAgKgorICAgICAgICAgKiBAcmV0dXJuIHRoZSBQS1dhcmUgQWxnb3JpdGhtSWQKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBpbnQgZ2V0Q29kZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBjb2RlOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJldHVybnMgdGhlIEVuY3J5cHRpb25BbGdvcml0aG0gZm9yIHRoZSBnaXZlbiBjb2RlIG9yIG51bGwgaWYgdGhlCisgICAgICAgICAqIG1ldGhvZCBpcyBub3Qga25vd24uCisgICAgICAgICAqIEBwYXJhbSBjb2RlIHRoZSBjb2RlIG9mIHRoZSBhbGdvcml0aG0KKyAgICAgICAgICogQHJldHVybiB0aGUgRW5jcnlwdGlvbkFsZ29yaXRobSBmb3IgdGhlIGdpdmVuIGNvZGUgb3IgbnVsbAorICAgICAgICAgKiBpZiB0aGUgbWV0aG9kIGlzIG5vdCBrbm93bgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBFbmNyeXB0aW9uQWxnb3JpdGhtIGdldEFsZ29yaXRobUJ5Q29kZShmaW5hbCBpbnQgY29kZSkgeworICAgICAgICAgICAgcmV0dXJuIGNvZGVUb0VudW0uZ2V0KGNvZGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogSGFzaCBBbGdvcml0aG0KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjExCisgICAgICovCisgICAgcHVibGljIGVudW0gSGFzaEFsZ29yaXRobSB7CisgICAgICAgIE5PTkUoMCksCisgICAgICAgIENSQzMyKDEpLAorICAgICAgICBNRDUoMHg4MDAzKSwKKyAgICAgICAgU0hBMSgweDgwMDQpLAorICAgICAgICBSSVBFTkQxNjAoMHg4MDA3KSwKKyAgICAgICAgU0hBMjU2KDB4ODAwQyksCisgICAgICAgIFNIQTM4NCgweDgwMEQpLAorICAgICAgICBTSEE1MTIoMHg4MDBFKTsKKworICAgICAgICBwcml2YXRlIGZpbmFsIGludCBjb2RlOworCisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE1hcDxJbnRlZ2VyLCBIYXNoQWxnb3JpdGhtPiBjb2RlVG9FbnVtOworCisgICAgICAgIHN0YXRpYyB7CisgICAgICAgICAgICBmaW5hbCBNYXA8SW50ZWdlciwgSGFzaEFsZ29yaXRobT4gY3RlID0gbmV3IEhhc2hNYXA8PigpOworICAgICAgICAgICAgZm9yIChmaW5hbCBIYXNoQWxnb3JpdGhtIG1ldGhvZCA6IHZhbHVlcygpKSB7CisgICAgICAgICAgICAgICAgY3RlLnB1dChtZXRob2QuZ2V0Q29kZSgpLCBtZXRob2QpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgY29kZVRvRW51bSA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChjdGUpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIHByaXZhdGUgY29uc3RydWN0b3IgZm9yIGVudW0gc3R5bGUgY2xhc3MuCisgICAgICAgICAqLworICAgICAgICBIYXNoQWxnb3JpdGhtKGZpbmFsIGludCBjb2RlKSB7CisgICAgICAgICAgICB0aGlzLmNvZGUgPSBjb2RlOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIHRoZSBoYXNoIGFsZ29yaXRobSBJRC4KKyAgICAgICAgICoKKyAgICAgICAgICogQHJldHVybiB0aGUgUEtXYXJlIGhhc2hBbGcKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBpbnQgZ2V0Q29kZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBjb2RlOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJldHVybnMgdGhlIEhhc2hBbGdvcml0aG0gZm9yIHRoZSBnaXZlbiBjb2RlIG9yIG51bGwgaWYgdGhlIG1ldGhvZCBpcworICAgICAgICAgKiBub3Qga25vd24uCisgICAgICAgICAqIEBwYXJhbSBjb2RlIHRoZSBjb2RlIG9mIHRoZSBhbGdvcml0aG0KKyAgICAgICAgICogQHJldHVybiB0aGUgSGFzaEFsZ29yaXRobSBmb3IgdGhlIGdpdmVuIGNvZGUgb3IgbnVsbAorICAgICAgICAgKiBpZiB0aGUgbWV0aG9kIGlzIG5vdCBrbm93bgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBIYXNoQWxnb3JpdGhtIGdldEFsZ29yaXRobUJ5Q29kZShmaW5hbCBpbnQgY29kZSkgeworICAgICAgICAgICAgcmV0dXJuIGNvZGVUb0VudW0uZ2V0KGNvZGUpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9QYXJhbGxlbFNjYXR0ZXJaaXBDcmVhdG9yLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1BhcmFsbGVsU2NhdHRlclppcENyZWF0b3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hMzgxZDBhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9QYXJhbGxlbFNjYXR0ZXJaaXBDcmVhdG9yLmphdmEKQEAgLTAsMCArMSwyNzUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXA7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MucGFyYWxsZWwuRmlsZUJhc2VkU2NhdHRlckdhdGhlckJhY2tpbmdTdG9yZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MucGFyYWxsZWwuSW5wdXRTdHJlYW1TdXBwbGllcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MucGFyYWxsZWwuU2NhdHRlckdhdGhlckJhY2tpbmdTdG9yZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MucGFyYWxsZWwuU2NhdHRlckdhdGhlckJhY2tpbmdTdG9yZVN1cHBsaWVyOworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5DYWxsYWJsZTsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRpb25FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0b3JTZXJ2aWNlOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dG9yczsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5GdXR1cmU7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGltZVVuaXQ7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljLkF0b21pY0ludGVnZXI7CitpbXBvcnQgamF2YS51dGlsLnppcC5EZWZsYXRlcjsKKworaW1wb3J0IHN0YXRpYyBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuc3luY2hyb25pemVkTGlzdDsKK2ltcG9ydCBzdGF0aWMgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXAuWmlwQXJjaGl2ZUVudHJ5UmVxdWVzdC5jcmVhdGVaaXBBcmNoaXZlRW50cnlSZXF1ZXN0OworCisvKioKKyAqIENyZWF0ZXMgYSB6aXAgaW4gcGFyYWxsZWwgYnkgdXNpbmcgbXVsdGlwbGUgdGhyZWFkbG9jYWwge0BsaW5rIFNjYXR0ZXJaaXBPdXRwdXRTdHJlYW19IGluc3RhbmNlcy4KKyAqIDxwPgorICogTm90ZSB0aGF0IHRoaXMgY2xhc3MgZ2VuZXJhbGx5IG1ha2VzIG5vIGd1YXJhbnRlZXMgYWJvdXQgdGhlIG9yZGVyIG9mIHRoaW5ncyB3cml0dGVuIHRvCisgKiB0aGUgb3V0cHV0IGZpbGUuIFRoaW5ncyB0aGF0IG5lZWQgdG8gY29tZSBpbiBhIHNwZWNpZmljIG9yZGVyIChtYW5pZmVzdHMsIGRpcmVjdG9yaWVzKQorICogbXVzdCBiZSBoYW5kbGVkIGJ5IHRoZSBjbGllbnQgb2YgdGhpcyBjbGFzcywgdXN1YWxseSBieSB3cml0aW5nIHRoZXNlIHRoaW5ncyB0byB0aGUKKyAqIHtAbGluayBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtfSA8ZW0+YmVmb3JlPC9lbT4gY2FsbGluZyB7QGxpbmsgI3dyaXRlVG8gd3JpdGVUb30gb24gdGhpcyBjbGFzcy48L3A+CisgKiA8cD4KKyAqIFRoZSBjbGllbnQgY2FuIHN1cHBseSBhbiB7QGxpbmsgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0b3JTZXJ2aWNlfSwgYnV0IGZvciByZWFzb25zIG9mCisgKiBtZW1vcnkgbW9kZWwgY29uc2lzdGVuY3ksIHRoaXMgd2lsbCBiZSBzaHV0IGRvd24gYnkgdGhpcyBjbGFzcyBwcmlvciB0byBjb21wbGV0aW9uLgorICogPC9wPgorICogQHNpbmNlIDEuMTAKKyAqLworcHVibGljIGNsYXNzIFBhcmFsbGVsU2NhdHRlclppcENyZWF0b3IgeworICAgIHByaXZhdGUgZmluYWwgTGlzdDxTY2F0dGVyWmlwT3V0cHV0U3RyZWFtPiBzdHJlYW1zID0gc3luY2hyb25pemVkTGlzdChuZXcgQXJyYXlMaXN0PFNjYXR0ZXJaaXBPdXRwdXRTdHJlYW0+KCkpOworICAgIHByaXZhdGUgZmluYWwgRXhlY3V0b3JTZXJ2aWNlIGVzOworICAgIHByaXZhdGUgZmluYWwgU2NhdHRlckdhdGhlckJhY2tpbmdTdG9yZVN1cHBsaWVyIGJhY2tpbmdTdG9yZVN1cHBsaWVyOworICAgIHByaXZhdGUgZmluYWwgTGlzdDxGdXR1cmU8T2JqZWN0Pj4gZnV0dXJlcyA9IG5ldyBBcnJheUxpc3Q8PigpOworCisgICAgcHJpdmF0ZSBmaW5hbCBsb25nIHN0YXJ0ZWRBdCA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgIHByaXZhdGUgbG9uZyBjb21wcmVzc2lvbkRvbmVBdCA9IDA7CisgICAgcHJpdmF0ZSBsb25nIHNjYXR0ZXJEb25lQXQ7CisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBEZWZhdWx0QmFja2luZ1N0b3JlU3VwcGxpZXIgaW1wbGVtZW50cyBTY2F0dGVyR2F0aGVyQmFja2luZ1N0b3JlU3VwcGxpZXIgeworICAgICAgICBmaW5hbCBBdG9taWNJbnRlZ2VyIHN0b3JlTnVtID0gbmV3IEF0b21pY0ludGVnZXIoMCk7CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBTY2F0dGVyR2F0aGVyQmFja2luZ1N0b3JlIGdldCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBmaW5hbCBGaWxlIHRlbXBGaWxlID0gRmlsZS5jcmVhdGVUZW1wRmlsZSgicGFyYWxsZWxzY2F0dGVyIiwgIm4iICsgc3RvcmVOdW0uaW5jcmVtZW50QW5kR2V0KCkpOworICAgICAgICAgICAgcmV0dXJuIG5ldyBGaWxlQmFzZWRTY2F0dGVyR2F0aGVyQmFja2luZ1N0b3JlKHRlbXBGaWxlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgU2NhdHRlclppcE91dHB1dFN0cmVhbSBjcmVhdGVEZWZlcnJlZChmaW5hbCBTY2F0dGVyR2F0aGVyQmFja2luZ1N0b3JlU3VwcGxpZXIgc2NhdHRlckdhdGhlckJhY2tpbmdTdG9yZVN1cHBsaWVyKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgU2NhdHRlckdhdGhlckJhY2tpbmdTdG9yZSBicyA9IHNjYXR0ZXJHYXRoZXJCYWNraW5nU3RvcmVTdXBwbGllci5nZXQoKTsKKyAgICAgICAgLy8gbGlmZWN5Y2xlIGlzIGJvdW5kIHRvIHRoZSBTY2F0dGVyWmlwT3V0cHV0U3RyZWFtIHJldHVybmVkCisgICAgICAgIGZpbmFsIFN0cmVhbUNvbXByZXNzb3Igc2MgPSBTdHJlYW1Db21wcmVzc29yLmNyZWF0ZShEZWZsYXRlci5ERUZBVUxUX0NPTVBSRVNTSU9OLCBicyk7IC8vTk9TT05BUgorICAgICAgICByZXR1cm4gbmV3IFNjYXR0ZXJaaXBPdXRwdXRTdHJlYW0oYnMsIHNjKTsKKyAgICB9CisKKyAgICBwcml2YXRlIGZpbmFsIFRocmVhZExvY2FsPFNjYXR0ZXJaaXBPdXRwdXRTdHJlYW0+IHRsU2NhdHRlclN0cmVhbXMgPSBuZXcgVGhyZWFkTG9jYWw8U2NhdHRlclppcE91dHB1dFN0cmVhbT4oKSB7CisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgU2NhdHRlclppcE91dHB1dFN0cmVhbSBpbml0aWFsVmFsdWUoKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGZpbmFsIFNjYXR0ZXJaaXBPdXRwdXRTdHJlYW0gc2NhdHRlclN0cmVhbSA9IGNyZWF0ZURlZmVycmVkKGJhY2tpbmdTdG9yZVN1cHBsaWVyKTsKKyAgICAgICAgICAgICAgICBzdHJlYW1zLmFkZChzY2F0dGVyU3RyZWFtKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gc2NhdHRlclN0cmVhbTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKGZpbmFsIElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlKTsgLy9OT1NPTkFSCisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9OworCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgUGFyYWxsZWxTY2F0dGVyWmlwQ3JlYXRvciB3aXRoIGRlZmF1bHQgdGhyZWFkcywgd2hpY2ggaXMgc2V0IHRvIHRoZSBudW1iZXIgb2YgYXZhaWxhYmxlCisgICAgICogcHJvY2Vzc29ycywgYXMgZGVmaW5lZCBieSB7QGxpbmsgamF2YS5sYW5nLlJ1bnRpbWUjYXZhaWxhYmxlUHJvY2Vzc29yc30KKyAgICAgKi8KKyAgICBwdWJsaWMgUGFyYWxsZWxTY2F0dGVyWmlwQ3JlYXRvcigpIHsKKyAgICAgICAgdGhpcyhFeGVjdXRvcnMubmV3Rml4ZWRUaHJlYWRQb29sKFJ1bnRpbWUuZ2V0UnVudGltZSgpLmF2YWlsYWJsZVByb2Nlc3NvcnMoKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIFBhcmFsbGVsU2NhdHRlclppcENyZWF0b3IKKyAgICAgKgorICAgICAqIEBwYXJhbSBleGVjdXRvclNlcnZpY2UgVGhlIGV4ZWN1dG9yU2VydmljZSB0byB1c2UgZm9yIHBhcmFsbGVsIHNjaGVkdWxpbmcuIEZvciB0ZWNobmljYWwgcmVhc29ucywKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMgd2lsbCBiZSBzaHV0IGRvd24gYnkgdGhpcyBjbGFzcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgUGFyYWxsZWxTY2F0dGVyWmlwQ3JlYXRvcihmaW5hbCBFeGVjdXRvclNlcnZpY2UgZXhlY3V0b3JTZXJ2aWNlKSB7CisgICAgICAgIHRoaXMoZXhlY3V0b3JTZXJ2aWNlLCBuZXcgRGVmYXVsdEJhY2tpbmdTdG9yZVN1cHBsaWVyKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIFBhcmFsbGVsU2NhdHRlclppcENyZWF0b3IKKyAgICAgKgorICAgICAqIEBwYXJhbSBleGVjdXRvclNlcnZpY2UgVGhlIGV4ZWN1dG9yU2VydmljZSB0byB1c2UuIEZvciB0ZWNobmljYWwgcmVhc29ucywgdGhpcyB3aWxsIGJlIHNodXQgZG93bgorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgYnkgdGhpcyBjbGFzcy4KKyAgICAgKiBAcGFyYW0gYmFja2luZ1N0b3JlU3VwcGxpZXIgVGhlIHN1cHBsaWVyIG9mIGJhY2tpbmcgc3RvcmUgd2hpY2ggc2hhbGwgYmUgdXNlZAorICAgICAqLworICAgIHB1YmxpYyBQYXJhbGxlbFNjYXR0ZXJaaXBDcmVhdG9yKGZpbmFsIEV4ZWN1dG9yU2VydmljZSBleGVjdXRvclNlcnZpY2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgU2NhdHRlckdhdGhlckJhY2tpbmdTdG9yZVN1cHBsaWVyIGJhY2tpbmdTdG9yZVN1cHBsaWVyKSB7CisgICAgICAgIHRoaXMuYmFja2luZ1N0b3JlU3VwcGxpZXIgPSBiYWNraW5nU3RvcmVTdXBwbGllcjsKKyAgICAgICAgZXMgPSBleGVjdXRvclNlcnZpY2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkcyBhbiBhcmNoaXZlIGVudHJ5IHRvIHRoaXMgYXJjaGl2ZS4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIG1ldGhvZCBpcyBleHBlY3RlZCB0byBiZSBjYWxsZWQgZnJvbSBhIHNpbmdsZSBjbGllbnQgdGhyZWFkCisgICAgICogPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIHppcEFyY2hpdmVFbnRyeSBUaGUgZW50cnkgdG8gYWRkLgorICAgICAqIEBwYXJhbSBzb3VyY2UgICAgICAgICAgVGhlIHNvdXJjZSBpbnB1dCBzdHJlYW0gc3VwcGxpZXIKKyAgICAgKi8KKworICAgIHB1YmxpYyB2b2lkIGFkZEFyY2hpdmVFbnRyeShmaW5hbCBaaXBBcmNoaXZlRW50cnkgemlwQXJjaGl2ZUVudHJ5LCBmaW5hbCBJbnB1dFN0cmVhbVN1cHBsaWVyIHNvdXJjZSkgeworICAgICAgICBzdWJtaXQoY3JlYXRlQ2FsbGFibGUoemlwQXJjaGl2ZUVudHJ5LCBzb3VyY2UpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIGFuIGFyY2hpdmUgZW50cnkgdG8gdGhpcyBhcmNoaXZlLgorICAgICAqIDxwPgorICAgICAqIFRoaXMgbWV0aG9kIGlzIGV4cGVjdGVkIHRvIGJlIGNhbGxlZCBmcm9tIGEgc2luZ2xlIGNsaWVudCB0aHJlYWQKKyAgICAgKiA8L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gemlwQXJjaGl2ZUVudHJ5UmVxdWVzdFN1cHBsaWVyIFNob3VsZCBzdXBwbHkgdGhlIGVudHJ5IHRvIGJlIGFkZGVkLgorICAgICAqIEBzaW5jZSAxLjEzCisgICAgICovCisgICAgcHVibGljIHZvaWQgYWRkQXJjaGl2ZUVudHJ5KGZpbmFsIFppcEFyY2hpdmVFbnRyeVJlcXVlc3RTdXBwbGllciB6aXBBcmNoaXZlRW50cnlSZXF1ZXN0U3VwcGxpZXIpIHsKKyAgICAgICAgc3VibWl0KGNyZWF0ZUNhbGxhYmxlKHppcEFyY2hpdmVFbnRyeVJlcXVlc3RTdXBwbGllcikpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFN1Ym1pdCBhIGNhbGxhYmxlIGZvciBjb21wcmVzc2lvbi4KKyAgICAgKgorICAgICAqIEBzZWUgUGFyYWxsZWxTY2F0dGVyWmlwQ3JlYXRvciNjcmVhdGVDYWxsYWJsZSBmb3IgZGV0YWlscyBvZiBpZi93aGVuIHRvIHVzZSB0aGlzLgorICAgICAqCisgICAgICogQHBhcmFtIGNhbGxhYmxlIFRoZSBjYWxsYWJsZSB0byBydW4sIGNyZWF0ZWQgYnkge0BsaW5rICNjcmVhdGVDYWxsYWJsZSBjcmVhdGVDYWxsYWJsZX0sIHBvc3NpYmx5IHdyYXBwZWQgYnkgY2FsbGVyLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHN1Ym1pdChmaW5hbCBDYWxsYWJsZTxPYmplY3Q+IGNhbGxhYmxlKSB7CisgICAgICAgIGZ1dHVyZXMuYWRkKGVzLnN1Ym1pdChjYWxsYWJsZSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIGNhbGxhYmxlIHRoYXQgd2lsbCBjb21wcmVzcyB0aGUgZ2l2ZW4gYXJjaGl2ZSBlbnRyeS4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIGlzIGV4cGVjdGVkIHRvIGJlIGNhbGxlZCBmcm9tIGEgc2luZ2xlIGNsaWVudCB0aHJlYWQuPC9wPgorICAgICAqCisgICAgICogQ29uc2lkZXIgdXNpbmcge0BsaW5rICNhZGRBcmNoaXZlRW50cnkgYWRkQXJjaGl2ZUVudHJ5fSwgd2hpY2ggd3JhcHMgdGhpcyBtZXRob2QgYW5kIHtAbGluayAjc3VibWl0IHN1Ym1pdH0uCisgICAgICogVGhlIG1vc3QgY29tbW9uIHVzZSBjYXNlIGZvciB1c2luZyB7QGxpbmsgI2NyZWF0ZUNhbGxhYmxlIGNyZWF0ZUNhbGxhYmxlfSBhbmQge0BsaW5rICNzdWJtaXQgc3VibWl0fSBmcm9tIGEKKyAgICAgKiBjbGllbnQgaXMgaWYgeW91IHdhbnQgdG8gd3JhcCB0aGUgY2FsbGFibGUgaW4gc29tZXRoaW5nIHRoYXQgY2FuIGJlIHByaW9yaXRpemVkIGJ5IHRoZSBzdXBwbGllZAorICAgICAqIHtAbGluayBFeGVjdXRvclNlcnZpY2V9LCBmb3IgaW5zdGFuY2UgdG8gcHJvY2VzcyBsYXJnZSBvciBzbG93IGZpbGVzIGZpcnN0LgorICAgICAqIFNpbmNlIHRoZSBjcmVhdGlvbiBvZiB0aGUge0BsaW5rIEV4ZWN1dG9yU2VydmljZX0gaXMgaGFuZGxlZCBieSB0aGUgY2xpZW50LCBhbGwgb2YgdGhpcyBpcyB1cCB0byB0aGUgY2xpZW50LgorICAgICAqCisgICAgICogQHBhcmFtIHppcEFyY2hpdmVFbnRyeSBUaGUgZW50cnkgdG8gYWRkLgorICAgICAqIEBwYXJhbSBzb3VyY2UgICAgICAgICAgVGhlIHNvdXJjZSBpbnB1dCBzdHJlYW0gc3VwcGxpZXIKKyAgICAgKiBAcmV0dXJuIEEgY2FsbGFibGUgdGhhdCBzaG91bGQgc3Vic2VxdWVudGx5IHBhc3NlZCB0byAjc3VibWl0LCBwb3NzaWJseSBpbiBhIHdyYXBwZWQvYWRhcHRlZCBmcm9tLiBUaGUKKyAgICAgKiB2YWx1ZSBvZiB0aGlzIGNhbGxhYmxlIGlzIG5vdCB1c2VkLCBidXQgYW55IGV4Y2VwdGlvbnMgaGFwcGVuaW5nIGluc2lkZSB0aGUgY29tcHJlc3Npb24KKyAgICAgKiB3aWxsIGJlIHByb3BhZ2F0ZWQgdGhyb3VnaCB0aGUgY2FsbGFibGUuCisgICAgICovCisKKyAgICBwdWJsaWMgZmluYWwgQ2FsbGFibGU8T2JqZWN0PiBjcmVhdGVDYWxsYWJsZShmaW5hbCBaaXBBcmNoaXZlRW50cnkgemlwQXJjaGl2ZUVudHJ5LCBmaW5hbCBJbnB1dFN0cmVhbVN1cHBsaWVyIHNvdXJjZSkgeworICAgICAgICBmaW5hbCBpbnQgbWV0aG9kID0gemlwQXJjaGl2ZUVudHJ5LmdldE1ldGhvZCgpOworICAgICAgICBpZiAobWV0aG9kID09IFppcE1ldGhvZC5VTktOT1dOX0NPREUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIk1ldGhvZCBtdXN0IGJlIHNldCBvbiB6aXBBcmNoaXZlRW50cnk6ICIgKyB6aXBBcmNoaXZlRW50cnkpOworICAgICAgICB9CisgICAgICAgIGZpbmFsIFppcEFyY2hpdmVFbnRyeVJlcXVlc3QgemlwQXJjaGl2ZUVudHJ5UmVxdWVzdCA9IGNyZWF0ZVppcEFyY2hpdmVFbnRyeVJlcXVlc3QoemlwQXJjaGl2ZUVudHJ5LCBzb3VyY2UpOworICAgICAgICByZXR1cm4gbmV3IENhbGxhYmxlPE9iamVjdD4oKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgY2FsbCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAgICAgICAgIHRsU2NhdHRlclN0cmVhbXMuZ2V0KCkuYWRkQXJjaGl2ZUVudHJ5KHppcEFyY2hpdmVFbnRyeVJlcXVlc3QpOworICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfQorICAgICAgICB9OworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIGNhbGxhYmxlIHRoYXQgd2lsbCBjb21wcmVzcyBhcmNoaXZlIGVudHJ5IHN1cHBsaWVkIGJ5IHtAbGluayBaaXBBcmNoaXZlRW50cnlSZXF1ZXN0U3VwcGxpZXJ9LgorICAgICAqCisgICAgICogPHA+VGhpcyBtZXRob2QgaXMgZXhwZWN0ZWQgdG8gYmUgY2FsbGVkIGZyb20gYSBzaW5nbGUgY2xpZW50IHRocmVhZC48L3A+CisgICAgICoKKyAgICAgKiBUaGUgc2FtZSBhcyB7QGxpbmsgI2NyZWF0ZUNhbGxhYmxlKFppcEFyY2hpdmVFbnRyeSwgSW5wdXRTdHJlYW1TdXBwbGllcil9LCBidXQgdGhlIGFyY2hpdmUgZW50cnkKKyAgICAgKiB0byBiZSBhZGRlZCBpcyBzdXBwbGllZCBieSBhIHtAbGluayBaaXBBcmNoaXZlRW50cnlSZXF1ZXN0U3VwcGxpZXJ9LgorICAgICAqCisgICAgICogQHNlZSAjY3JlYXRlQ2FsbGFibGUoWmlwQXJjaGl2ZUVudHJ5LCBJbnB1dFN0cmVhbVN1cHBsaWVyKQorICAgICAqCisgICAgICogQHBhcmFtIHppcEFyY2hpdmVFbnRyeVJlcXVlc3RTdXBwbGllciBTaG91bGQgc3VwcGx5IHRoZSBlbnRyeSB0byBiZSBhZGRlZC4KKyAgICAgKiBAcmV0dXJuIEEgY2FsbGFibGUgdGhhdCBzaG91bGQgc3Vic2VxdWVudGx5IHBhc3NlZCB0byAjc3VibWl0LCBwb3NzaWJseSBpbiBhIHdyYXBwZWQvYWRhcHRlZCBmcm9tLiBUaGUKKyAgICAgKiB2YWx1ZSBvZiB0aGlzIGNhbGxhYmxlIGlzIG5vdCB1c2VkLCBidXQgYW55IGV4Y2VwdGlvbnMgaGFwcGVuaW5nIGluc2lkZSB0aGUgY29tcHJlc3Npb24KKyAgICAgKiB3aWxsIGJlIHByb3BhZ2F0ZWQgdGhyb3VnaCB0aGUgY2FsbGFibGUuCisgICAgICogQHNpbmNlIDEuMTMKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgQ2FsbGFibGU8T2JqZWN0PiBjcmVhdGVDYWxsYWJsZShmaW5hbCBaaXBBcmNoaXZlRW50cnlSZXF1ZXN0U3VwcGxpZXIgemlwQXJjaGl2ZUVudHJ5UmVxdWVzdFN1cHBsaWVyKSB7CisgICAgICAgIHJldHVybiBuZXcgQ2FsbGFibGU8T2JqZWN0PigpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIE9iamVjdCBjYWxsKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgdGxTY2F0dGVyU3RyZWFtcy5nZXQoKS5hZGRBcmNoaXZlRW50cnkoemlwQXJjaGl2ZUVudHJ5UmVxdWVzdFN1cHBsaWVyLmdldCgpKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZSB0aGUgY29udGVudHMgdGhpcyB0byB0aGUgdGFyZ2V0IHtAbGluayBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtfS4KKyAgICAgKiA8cD4KKyAgICAgKiBJdCBtYXkgYmUgYmVuZWZpY2lhbCB0byB3cml0ZSB0aGluZ3MgbGlrZSBkaXJlY3RvcmllcyBhbmQgbWFuaWZlc3QgZmlsZXMgdG8gdGhlIHRhcmdldFN0cmVhbQorICAgICAqIGJlZm9yZSBjYWxsaW5nIHRoaXMgbWV0aG9kLgorICAgICAqIDwvcD4KKyAgICAgKgorICAgICAqIDxwPkNhbGxpbmcgdGhpcyBtZXRob2Qgd2lsbCBzaHV0IGRvd24gdGhlIHtAbGluayBFeGVjdXRvclNlcnZpY2V9IHVzZWQgYnkgdGhpcyBjbGFzcy4gSWYgYW55IG9mIHRoZSB7QGxpbmsKKyAgICAgKiBDYWxsYWJsZX1zIHtAbGluayAjc3VibWl0fXRlZCB0byB0aGlzIGluc3RhbmNlIHRocm93cyBhbiBleGNlcHRpb24sIHRoZSBhcmNoaXZlIGNhbiBub3QgYmUgY3JlYXRlZCBwcm9wZXJseSBhbmQKKyAgICAgKiB0aGlzIG1ldGhvZCB3aWxsIHRocm93IGFuIGV4Y2VwdGlvbi48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gdGFyZ2V0U3RyZWFtIFRoZSB7QGxpbmsgWmlwQXJjaGl2ZU91dHB1dFN0cmVhbX0gdG8gcmVjZWl2ZSB0aGUgY29udGVudHMgb2YgdGhlIHNjYXR0ZXIgc3RyZWFtcworICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gICAgICAgICAgSWYgd3JpdGluZyBmYWlscworICAgICAqIEB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24gSWYgd2UgZ2V0IGludGVycnVwdGVkCisgICAgICogQHRocm93cyBFeGVjdXRpb25FeGNlcHRpb24gICBJZiBzb21ldGhpbmcgaGFwcGVucyBpbiB0aGUgcGFyYWxsZWwgZXhlY3V0aW9uCisgICAgICovCisgICAgcHVibGljIHZvaWQgd3JpdGVUbyhmaW5hbCBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtIHRhcmdldFN0cmVhbSkKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgSW50ZXJydXB0ZWRFeGNlcHRpb24sIEV4ZWN1dGlvbkV4Y2VwdGlvbiB7CisKKyAgICAgICAgLy8gTWFrZSBzdXJlIHdlIGNhdGNoIGFueSBleGNlcHRpb25zIGZyb20gcGFyYWxsZWwgcGhhc2UKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZvciAoZmluYWwgRnV0dXJlPD8+IGZ1dHVyZSA6IGZ1dHVyZXMpIHsKKyAgICAgICAgICAgICAgICBmdXR1cmUuZ2V0KCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBlcy5zaHV0ZG93bigpOworICAgICAgICB9CisKKyAgICAgICAgZXMuYXdhaXRUZXJtaW5hdGlvbigxMDAwICogNjBMLCBUaW1lVW5pdC5TRUNPTkRTKTsgIC8vID09IEluZmluaXR5LiBXZSByZWFsbHkgKm11c3QqIHdhaXQgZm9yIHRoaXMgdG8gY29tcGxldGUKKworICAgICAgICAvLyBJdCBpcyBpbXBvcnRhbnQgdGhhdCBhbGwgdGhyZWFkcyB0ZXJtaW5hdGUgYmVmb3JlIHdlIGdvIG9uLCBlbnN1cmUgaGFwcGVucy1iZWZvcmUgcmVsYXRpb25zaGlwCisgICAgICAgIGNvbXByZXNzaW9uRG9uZUF0ID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisKKyAgICAgICAgc3luY2hyb25pemVkIChzdHJlYW1zKSB7CisgICAgICAgICAgICBmb3IgKGZpbmFsIFNjYXR0ZXJaaXBPdXRwdXRTdHJlYW0gc2NhdHRlclN0cmVhbSA6IHN0cmVhbXMpIHsKKyAgICAgICAgICAgICAgICBzY2F0dGVyU3RyZWFtLndyaXRlVG8odGFyZ2V0U3RyZWFtKTsKKyAgICAgICAgICAgICAgICBzY2F0dGVyU3RyZWFtLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBzY2F0dGVyRG9uZUF0ID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG1lc3NhZ2UgZGVzY3JpYmluZyB0aGUgb3ZlcmFsbCBzdGF0aXN0aWNzIG9mIHRoZSBjb21wcmVzc2lvbiBydW4KKyAgICAgKgorICAgICAqIEByZXR1cm4gQSBzdHJpbmcKKyAgICAgKi8KKyAgICBwdWJsaWMgU2NhdHRlclN0YXRpc3RpY3MgZ2V0U3RhdGlzdGljc01lc3NhZ2UoKSB7CisgICAgICAgIHJldHVybiBuZXcgU2NhdHRlclN0YXRpc3RpY3MoY29tcHJlc3Npb25Eb25lQXQgLSBzdGFydGVkQXQsIHNjYXR0ZXJEb25lQXQgLSBjb21wcmVzc2lvbkRvbmVBdCk7CisgICAgfQorfQorCmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1Jlc291cmNlQWxpZ25tZW50RXh0cmFGaWVsZC5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9SZXNvdXJjZUFsaWdubWVudEV4dHJhRmllbGQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zZDA3NDFjCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9SZXNvdXJjZUFsaWdubWVudEV4dHJhRmllbGQuamF2YQpAQCAtMCwwICsxLDEzOCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwOworCisKK2ltcG9ydCBqYXZhLnV0aWwuemlwLlppcEV4Y2VwdGlvbjsKKworLyoqCisgKiBBbiBleHRyYSBmaWVsZCB3aG8ncyBzb2xlIHB1cnBvc2UgaXMgdG8gYWxpZ24gYW5kIHBhZCB0aGUgbG9jYWwgZmlsZSBoZWFkZXIKKyAqIHNvIHRoYXQgdGhlIGVudHJ5J3MgZGF0YSBzdGFydHMgYXQgYSBjZXJ0YWluIHBvc2l0aW9uLgorICoKKyAqIDxwPlRoZSBwYWRkaW5nIGNvbnRlbnQgb2YgdGhlIHBhZGRpbmcgaXMgaWdub3JlZCBhbmQgbm90IHJldGFpbmVkCisgKiB3aGVuIHJlYWRpbmcgYSBwYWRkaW5nIGZpZWxkLjwvcD4KKyAqCisgKiA8cD5UaGlzIGVuYWJsZXMgQ29tbW9ucyBDb21wcmVzcyB0byBjcmVhdGUgImFsaWduZWQiIGFyY2hpdmVzCisgKiBzaW1pbGFyIHRvIEFuZHJvaWQncyB6aXBhbGlnbiBjb21tYW5kIGxpbmUgdG9vbC48L3A+CisgKgorICogQHNpbmNlIDEuMTQKKyAqIEBzZWUgImh0dHBzOi8vZGV2ZWxvcGVyLmFuZHJvaWQuY29tL3N0dWRpby9jb21tYW5kLWxpbmUvemlwYWxpZ24uaHRtbCIKKyAqIEBzZWUgWmlwQXJjaGl2ZUVudHJ5I3NldEFsaWdubWVudAorICovCitwdWJsaWMgY2xhc3MgUmVzb3VyY2VBbGlnbm1lbnRFeHRyYUZpZWxkIGltcGxlbWVudHMgWmlwRXh0cmFGaWVsZCB7CisKKyAgICAvKioKKyAgICAgKiBFeHRyYSBmaWVsZCBpZCB1c2VkIGZvciBzdG9yaW5nIGFsaWdubWVudCBhbmQgcGFkZGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFppcFNob3J0IElEID0gbmV3IFppcFNob3J0KDB4YTExZSk7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCQVNFX1NJWkUgPSAyOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEFMTE9XX01FVEhPRF9NRVNTQUdFX0NIQU5HRV9GTEFHID0gMHg4MDAwOworCisgICAgcHJpdmF0ZSBzaG9ydCBhbGlnbm1lbnQ7CisKKyAgICBwcml2YXRlIGJvb2xlYW4gYWxsb3dNZXRob2RDaGFuZ2U7CisKKyAgICBwcml2YXRlIGludCBwYWRkaW5nID0gMDsKKworICAgIHB1YmxpYyBSZXNvdXJjZUFsaWdubWVudEV4dHJhRmllbGQoKSB7CisgICAgfQorCisgICAgcHVibGljIFJlc291cmNlQWxpZ25tZW50RXh0cmFGaWVsZChpbnQgYWxpZ25tZW50KSB7CisgICAgICAgIHRoaXMoYWxpZ25tZW50LCBmYWxzZSk7CisgICAgfQorCisgICAgcHVibGljIFJlc291cmNlQWxpZ25tZW50RXh0cmFGaWVsZChpbnQgYWxpZ25tZW50LCBib29sZWFuIGFsbG93TWV0aG9kQ2hhbmdlKSB7CisgICAgICAgIHRoaXMoYWxpZ25tZW50LCBhbGxvd01ldGhvZENoYW5nZSwgMCk7CisgICAgfQorCisgICAgcHVibGljIFJlc291cmNlQWxpZ25tZW50RXh0cmFGaWVsZChpbnQgYWxpZ25tZW50LCBib29sZWFuIGFsbG93TWV0aG9kQ2hhbmdlLCBpbnQgcGFkZGluZykgeworICAgICAgICBpZiAoYWxpZ25tZW50IDwgMCB8fCBhbGlnbm1lbnQgPiAweDdmZmYpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkFsaWdubWVudCBtdXN0IGJlIGJldHdlZW4gMCBhbmQgMHg3ZmZmLCB3YXM6ICIgKyBhbGlnbm1lbnQpOworICAgICAgICB9CisgICAgICAgIHRoaXMuYWxpZ25tZW50ID0gKHNob3J0KSBhbGlnbm1lbnQ7CisgICAgICAgIHRoaXMuYWxsb3dNZXRob2RDaGFuZ2UgPSBhbGxvd01ldGhvZENoYW5nZTsKKyAgICAgICAgdGhpcy5wYWRkaW5nID0gcGFkZGluZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHJlcXVlc3RlZCBhbGlnbm1lbnQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCisgICAgICogICAgICByZXF1ZXN0ZWQgYWxpZ25tZW50LgorICAgICAqLworICAgIHB1YmxpYyBzaG9ydCBnZXRBbGlnbm1lbnQoKSB7CisgICAgICAgIHJldHVybiBhbGlnbm1lbnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgbWV0aG9kIGNoYW5nZSBpcyBhbGxvd2VkIHdoZW4gcmUtY29tcHJlc3NpbmcgdGhlIHppcCBmaWxlLgorICAgICAqCisgICAgICogQHJldHVybgorICAgICAqICAgICAgdHJ1ZSBpZiBtZXRob2QgY2hhbmdlIGlzIGFsbG93ZWQsIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBhbGxvd01ldGhvZENoYW5nZSgpIHsKKyAgICAgICAgcmV0dXJuIGFsbG93TWV0aG9kQ2hhbmdlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBaaXBTaG9ydCBnZXRIZWFkZXJJZCgpIHsKKyAgICAgICAgcmV0dXJuIElEOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBaaXBTaG9ydCBnZXRMb2NhbEZpbGVEYXRhTGVuZ3RoKCkgeworICAgICAgICByZXR1cm4gbmV3IFppcFNob3J0KEJBU0VfU0laRSArIHBhZGRpbmcpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBaaXBTaG9ydCBnZXRDZW50cmFsRGlyZWN0b3J5TGVuZ3RoKCkgeworICAgICAgICByZXR1cm4gbmV3IFppcFNob3J0KEJBU0VfU0laRSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJ5dGVbXSBnZXRMb2NhbEZpbGVEYXRhRGF0YSgpIHsKKyAgICAgICAgYnl0ZVtdIGNvbnRlbnQgPSBuZXcgYnl0ZVtCQVNFX1NJWkUgKyBwYWRkaW5nXTsKKyAgICAgICAgWmlwU2hvcnQucHV0U2hvcnQoYWxpZ25tZW50IHwgKGFsbG93TWV0aG9kQ2hhbmdlID8gQUxMT1dfTUVUSE9EX01FU1NBR0VfQ0hBTkdFX0ZMQUcgOiAwKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudCwgMCk7CisgICAgICAgIHJldHVybiBjb250ZW50OworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBieXRlW10gZ2V0Q2VudHJhbERpcmVjdG9yeURhdGEoKSB7CisgICAgICAgIHJldHVybiBaaXBTaG9ydC5nZXRCeXRlcyhhbGlnbm1lbnQgfCAoYWxsb3dNZXRob2RDaGFuZ2UgPyBBTExPV19NRVRIT0RfTUVTU0FHRV9DSEFOR0VfRkxBRyA6IDApKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBwYXJzZUZyb21Mb2NhbEZpbGVEYXRhKGJ5dGVbXSBidWZmZXIsIGludCBvZmZzZXQsIGludCBsZW5ndGgpIHRocm93cyBaaXBFeGNlcHRpb24geworICAgICAgICBwYXJzZUZyb21DZW50cmFsRGlyZWN0b3J5RGF0YShidWZmZXIsIG9mZnNldCwgbGVuZ3RoKTsKKyAgICAgICAgdGhpcy5wYWRkaW5nID0gbGVuZ3RoIC0gQkFTRV9TSVpFOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHBhcnNlRnJvbUNlbnRyYWxEaXJlY3RvcnlEYXRhKGJ5dGVbXSBidWZmZXIsIGludCBvZmZzZXQsIGludCBsZW5ndGgpIHRocm93cyBaaXBFeGNlcHRpb24geworICAgICAgICBpZiAobGVuZ3RoIDwgQkFTRV9TSVpFKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgWmlwRXhjZXB0aW9uKCJUb28gc2hvcnQgY29udGVudCBmb3IgUmVzb3VyY2VBbGlnbm1lbnRFeHRyYUZpZWxkICgweGExMWUpOiAiICsgbGVuZ3RoKTsKKyAgICAgICAgfQorICAgICAgICBpbnQgYWxpZ25tZW50VmFsdWUgPSBaaXBTaG9ydC5nZXRWYWx1ZShidWZmZXIsIG9mZnNldCk7CisgICAgICAgIHRoaXMuYWxpZ25tZW50ID0gKHNob3J0KSAoYWxpZ25tZW50VmFsdWUgJiAoQUxMT1dfTUVUSE9EX01FU1NBR0VfQ0hBTkdFX0ZMQUcgLSAxKSk7CisgICAgICAgIHRoaXMuYWxsb3dNZXRob2RDaGFuZ2UgPSAoYWxpZ25tZW50VmFsdWUgJiBBTExPV19NRVRIT0RfTUVTU0FHRV9DSEFOR0VfRkxBRykgIT0gMDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1NjYXR0ZXJTdGF0aXN0aWNzLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1NjYXR0ZXJTdGF0aXN0aWNzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODNjNWJiNQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvU2NhdHRlclN0YXRpc3RpY3MuamF2YQpAQCAtMCwwICsxLDU2IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKyBwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwOworCisvKioKKyAqIFByb3ZpZGVzIGluZm9ybWF0aW9uIGFib3V0IGEgc2NhdHRlciBjb21wcmVzc2lvbiBydW4uCisgKgorICogQHNpbmNlIDEuMTAKKyAqLworcHVibGljIGNsYXNzIFNjYXR0ZXJTdGF0aXN0aWNzIHsKKyAgICBwcml2YXRlIGZpbmFsIGxvbmcgY29tcHJlc3Npb25FbGFwc2VkOworICAgIHByaXZhdGUgZmluYWwgbG9uZyBtZXJnaW5nRWxhcHNlZDsKKworICAgIFNjYXR0ZXJTdGF0aXN0aWNzKGZpbmFsIGxvbmcgY29tcHJlc3Npb25FbGFwc2VkLCBmaW5hbCBsb25nIG1lcmdpbmdFbGFwc2VkKSB7CisgICAgICAgIHRoaXMuY29tcHJlc3Npb25FbGFwc2VkID0gY29tcHJlc3Npb25FbGFwc2VkOworICAgICAgICB0aGlzLm1lcmdpbmdFbGFwc2VkID0gbWVyZ2luZ0VsYXBzZWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgZWxhcHNlZCBpbiB0aGUgcGFyYWxsZWwgY29tcHJlc3Npb24gcGhhc2UKKyAgICAgKiBAcmV0dXJuIFRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIGVsYXBzZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBnZXRDb21wcmVzc2lvbkVsYXBzZWQoKSB7CisgICAgICAgIHJldHVybiBjb21wcmVzc2lvbkVsYXBzZWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgZWxhcHNlZCBpbiBtZXJnaW5nIHRoZSByZXN1bHRzIG9mIHRoZSBwYXJhbGxlbCBjb21wcmVzc2lvbiwgdGhlIElPIHBoYXNlCisgICAgICogQHJldHVybiBUaGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBlbGFwc2VkCisgICAgICovCisgICAgcHVibGljIGxvbmcgZ2V0TWVyZ2luZ0VsYXBzZWQoKSB7CisgICAgICAgIHJldHVybiBtZXJnaW5nRWxhcHNlZDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICByZXR1cm4gImNvbXByZXNzaW9uRWxhcHNlZD0iICsgY29tcHJlc3Npb25FbGFwc2VkICsgIm1zLCBtZXJnaW5nRWxhcHNlZD0iICsgbWVyZ2luZ0VsYXBzZWQgKyAibXMiOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9TY2F0dGVyWmlwT3V0cHV0U3RyZWFtLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1NjYXR0ZXJaaXBPdXRwdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43MDAxYzg0Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9TY2F0dGVyWmlwT3V0cHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwxNTkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXA7CisKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5wYXJhbGxlbC5GaWxlQmFzZWRTY2F0dGVyR2F0aGVyQmFja2luZ1N0b3JlOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5wYXJhbGxlbC5TY2F0dGVyR2F0aGVyQmFja2luZ1N0b3JlOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5Cb3VuZGVkSW5wdXRTdHJlYW07CisKK2ltcG9ydCBqYXZhLmlvLkNsb3NlYWJsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlTm90Rm91bmRFeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5RdWV1ZTsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5Db25jdXJyZW50TGlua2VkUXVldWU7CitpbXBvcnQgamF2YS51dGlsLnppcC5EZWZsYXRlcjsKKworLyoqCisgKiBBIHppcCBvdXRwdXQgc3RyZWFtIHRoYXQgaXMgb3B0aW1pemVkIGZvciBtdWx0aS10aHJlYWRlZCBzY2F0dGVyL2dhdGhlciBjb25zdHJ1Y3Rpb24gb2YgemlwIGZpbGVzLgorICogPHA+CisgKiBUaGUgaW50ZXJuYWwgZGF0YSBmb3JtYXQgb2YgdGhlIGVudHJpZXMgdXNlZCBieSB0aGlzIGNsYXNzIGFyZSBlbnRpcmVseSBwcml2YXRlIHRvIHRoaXMgY2xhc3MKKyAqIGFuZCBhcmUgbm90IHBhcnQgb2YgYW55IHB1YmxpYyBhcGkgd2hhdHNvZXZlci4KKyAqIDwvcD4KKyAqIDxwPkl0IGlzIHBvc3NpYmxlIHRvIGV4dGVuZCB0aGlzIGNsYXNzIHRvIHN1cHBvcnQgZGlmZmVyZW50IGtpbmRzIG9mIGJhY2tpbmcgc3RvcmFnZSwgdGhlIGRlZmF1bHQKKyAqIGltcGxlbWVudGF0aW9uIG9ubHkgc3VwcG9ydHMgZmlsZS1iYXNlZCBiYWNraW5nLgorICogPC9wPgorICogVGhyZWFkIHNhZmV0eTogVGhpcyBjbGFzcyBzdXBwb3J0cyBtdWx0aXBsZSB0aHJlYWRzLiBCdXQgdGhlICJ3cml0ZVRvIiBtZXRob2QgbXVzdCBiZSBjYWxsZWQKKyAqIGJ5IHRoZSB0aHJlYWQgdGhhdCBvcmlnaW5hbGx5IGNyZWF0ZWQgdGhlIHtAbGluayBaaXBBcmNoaXZlRW50cnl9LgorICoKKyAqIEBzaW5jZSAxLjEwCisgKi8KK3B1YmxpYyBjbGFzcyBTY2F0dGVyWmlwT3V0cHV0U3RyZWFtIGltcGxlbWVudHMgQ2xvc2VhYmxlIHsKKyAgICBwcml2YXRlIGZpbmFsIFF1ZXVlPENvbXByZXNzZWRFbnRyeT4gaXRlbXMgPSBuZXcgQ29uY3VycmVudExpbmtlZFF1ZXVlPD4oKTsKKyAgICBwcml2YXRlIGZpbmFsIFNjYXR0ZXJHYXRoZXJCYWNraW5nU3RvcmUgYmFja2luZ1N0b3JlOworICAgIHByaXZhdGUgZmluYWwgU3RyZWFtQ29tcHJlc3NvciBzdHJlYW1Db21wcmVzc29yOworCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgQ29tcHJlc3NlZEVudHJ5IHsKKyAgICAgICAgZmluYWwgWmlwQXJjaGl2ZUVudHJ5UmVxdWVzdCB6aXBBcmNoaXZlRW50cnlSZXF1ZXN0OworICAgICAgICBmaW5hbCBsb25nIGNyYzsKKyAgICAgICAgZmluYWwgbG9uZyBjb21wcmVzc2VkU2l6ZTsKKyAgICAgICAgZmluYWwgbG9uZyBzaXplOworCisgICAgICAgIHB1YmxpYyBDb21wcmVzc2VkRW50cnkoZmluYWwgWmlwQXJjaGl2ZUVudHJ5UmVxdWVzdCB6aXBBcmNoaXZlRW50cnlSZXF1ZXN0LCBmaW5hbCBsb25nIGNyYywgZmluYWwgbG9uZyBjb21wcmVzc2VkU2l6ZSwgZmluYWwgbG9uZyBzaXplKSB7CisgICAgICAgICAgICB0aGlzLnppcEFyY2hpdmVFbnRyeVJlcXVlc3QgPSB6aXBBcmNoaXZlRW50cnlSZXF1ZXN0OworICAgICAgICAgICAgdGhpcy5jcmMgPSBjcmM7CisgICAgICAgICAgICB0aGlzLmNvbXByZXNzZWRTaXplID0gY29tcHJlc3NlZFNpemU7CisgICAgICAgICAgICB0aGlzLnNpemUgPSBzaXplOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFVwZGF0ZSB0aGUgb3JpZ2luYWwge0BsaW5rIFppcEFyY2hpdmVFbnRyeX0gd2l0aCBzaXplcy9jcmMKKyAgICAgICAgICogRG8gbm90IHVzZSB0aGlzIG1ldGhvZHMgZnJvbSB0aHJlYWRzIHRoYXQgZGlkIG5vdCBjcmVhdGUgdGhlIGluc3RhbmNlIGl0c2VsZiAhCisgICAgICAgICAqIEByZXR1cm4gdGhlIHppcEFyY2hpdmVFbnRyeSB0aGF0IGlzIGJhc2lzIGZvciB0aGlzIHJlcXVlc3QKKyAgICAgICAgICovCisKKyAgICAgICAgcHVibGljIFppcEFyY2hpdmVFbnRyeSB0cmFuc2ZlclRvQXJjaGl2ZUVudHJ5KCl7CisgICAgICAgICAgICBmaW5hbCBaaXBBcmNoaXZlRW50cnkgZW50cnkgPSB6aXBBcmNoaXZlRW50cnlSZXF1ZXN0LmdldFppcEFyY2hpdmVFbnRyeSgpOworICAgICAgICAgICAgZW50cnkuc2V0Q29tcHJlc3NlZFNpemUoY29tcHJlc3NlZFNpemUpOworICAgICAgICAgICAgZW50cnkuc2V0U2l6ZShzaXplKTsKKyAgICAgICAgICAgIGVudHJ5LnNldENyYyhjcmMpOworICAgICAgICAgICAgZW50cnkuc2V0TWV0aG9kKHppcEFyY2hpdmVFbnRyeVJlcXVlc3QuZ2V0TWV0aG9kKCkpOworICAgICAgICAgICAgcmV0dXJuIGVudHJ5OworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIFNjYXR0ZXJaaXBPdXRwdXRTdHJlYW0oZmluYWwgU2NhdHRlckdhdGhlckJhY2tpbmdTdG9yZSBiYWNraW5nU3RvcmUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyZWFtQ29tcHJlc3NvciBzdHJlYW1Db21wcmVzc29yKSB7CisgICAgICAgIHRoaXMuYmFja2luZ1N0b3JlID0gYmFja2luZ1N0b3JlOworICAgICAgICB0aGlzLnN0cmVhbUNvbXByZXNzb3IgPSBzdHJlYW1Db21wcmVzc29yOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZCBhbiBhcmNoaXZlIGVudHJ5IHRvIHRoaXMgc2NhdHRlciBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gemlwQXJjaGl2ZUVudHJ5UmVxdWVzdCBUaGUgZW50cnkgdG8gd3JpdGUuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiAgICBJZiB3cml0aW5nIGZhaWxzCisgICAgICovCisgICAgcHVibGljIHZvaWQgYWRkQXJjaGl2ZUVudHJ5KGZpbmFsIFppcEFyY2hpdmVFbnRyeVJlcXVlc3QgemlwQXJjaGl2ZUVudHJ5UmVxdWVzdCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IChmaW5hbCBJbnB1dFN0cmVhbSBwYXlsb2FkU3RyZWFtID0gemlwQXJjaGl2ZUVudHJ5UmVxdWVzdC5nZXRQYXlsb2FkU3RyZWFtKCkpIHsKKyAgICAgICAgICAgIHN0cmVhbUNvbXByZXNzb3IuZGVmbGF0ZShwYXlsb2FkU3RyZWFtLCB6aXBBcmNoaXZlRW50cnlSZXF1ZXN0LmdldE1ldGhvZCgpKTsKKyAgICAgICAgfQorICAgICAgICBpdGVtcy5hZGQobmV3IENvbXByZXNzZWRFbnRyeSh6aXBBcmNoaXZlRW50cnlSZXF1ZXN0LCBzdHJlYW1Db21wcmVzc29yLmdldENyYzMyKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbUNvbXByZXNzb3IuZ2V0Qnl0ZXNXcml0dGVuRm9yTGFzdEVudHJ5KCksIHN0cmVhbUNvbXByZXNzb3IuZ2V0Qnl0ZXNSZWFkKCkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZSB0aGUgY29udGVudHMgb2YgdGhpcyBzY2F0dGVyIHN0cmVhbSB0byBhIHRhcmdldCBhcmNoaXZlLgorICAgICAqCisgICAgICogQHBhcmFtIHRhcmdldCBUaGUgYXJjaGl2ZSB0byByZWNlaXZlIHRoZSBjb250ZW50cyBvZiB0aGlzIHtAbGluayBTY2F0dGVyWmlwT3V0cHV0U3RyZWFtfS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIElmIHdyaXRpbmcgZmFpbHMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGZpbmFsIFppcEFyY2hpdmVPdXRwdXRTdHJlYW0gdGFyZ2V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBiYWNraW5nU3RvcmUuY2xvc2VGb3JXcml0aW5nKCk7CisgICAgICAgIHRyeSAoZmluYWwgSW5wdXRTdHJlYW0gZGF0YSA9IGJhY2tpbmdTdG9yZS5nZXRJbnB1dFN0cmVhbSgpKSB7CisgICAgICAgICAgICBmb3IgKGZpbmFsIENvbXByZXNzZWRFbnRyeSBjb21wcmVzc2VkRW50cnkgOiBpdGVtcykgeworICAgICAgICAgICAgICAgIHRyeSAoZmluYWwgQm91bmRlZElucHV0U3RyZWFtIHJhd1N0cmVhbSA9IG5ldyBCb3VuZGVkSW5wdXRTdHJlYW0oZGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbXByZXNzZWRFbnRyeS5jb21wcmVzc2VkU2l6ZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgdGFyZ2V0LmFkZFJhd0FyY2hpdmVFbnRyeShjb21wcmVzc2VkRW50cnkudHJhbnNmZXJUb0FyY2hpdmVFbnRyeSgpLCByYXdTdHJlYW0pOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworCisgICAgLyoqCisgICAgICogQ2xvc2VzIHRoaXMgc3RyZWFtLCBmcmVlaW5nIGFsbCByZXNvdXJjZXMgaW52b2x2ZWQgaW4gdGhlIGNyZWF0aW9uIG9mIHRoaXMgc3RyZWFtLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gSWYgY2xvc2luZyBmYWlscworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJhY2tpbmdTdG9yZS5jbG9zZSgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgc3RyZWFtQ29tcHJlc3Nvci5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEge0BsaW5rIFNjYXR0ZXJaaXBPdXRwdXRTdHJlYW19IHdpdGggZGVmYXVsdCBjb21wcmVzc2lvbiBsZXZlbCB0aGF0IGlzIGJhY2tlZCBieSBhIGZpbGUKKyAgICAgKgorICAgICAqIEBwYXJhbSBmaWxlIFRoZSBmaWxlIHRvIG9mZmxvYWQgY29tcHJlc3NlZCBkYXRhIGludG8uCisgICAgICogQHJldHVybiBBIFNjYXR0ZXJaaXBPdXRwdXRTdHJlYW0gdGhhdCBpcyByZWFkeSBmb3IgdXNlLgorICAgICAqIEB0aHJvd3MgRmlsZU5vdEZvdW5kRXhjZXB0aW9uIGlmIHRoZSBmaWxlIGNhbm5vdCBiZSBmb3VuZAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU2NhdHRlclppcE91dHB1dFN0cmVhbSBmaWxlQmFzZWQoZmluYWwgRmlsZSBmaWxlKSB0aHJvd3MgRmlsZU5vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGZpbGVCYXNlZChmaWxlLCBEZWZsYXRlci5ERUZBVUxUX0NPTVBSRVNTSU9OKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSB7QGxpbmsgU2NhdHRlclppcE91dHB1dFN0cmVhbX0gdGhhdCBpcyBiYWNrZWQgYnkgYSBmaWxlCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmlsZSAgICAgICAgICAgICBUaGUgZmlsZSB0byBvZmZsb2FkIGNvbXByZXNzZWQgZGF0YSBpbnRvLgorICAgICAqIEBwYXJhbSBjb21wcmVzc2lvbkxldmVsIFRoZSBjb21wcmVzc2lvbiBsZXZlbCB0byB1c2UsIEBzZWUgI0RlZmxhdGVyCisgICAgICogQHJldHVybiBBICBTY2F0dGVyWmlwT3V0cHV0U3RyZWFtIHRoYXQgaXMgcmVhZHkgZm9yIHVzZS4KKyAgICAgKiBAdGhyb3dzIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiBpZiB0aGUgZmlsZSBjYW5ub3QgYmUgZm91bmQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFNjYXR0ZXJaaXBPdXRwdXRTdHJlYW0gZmlsZUJhc2VkKGZpbmFsIEZpbGUgZmlsZSwgZmluYWwgaW50IGNvbXByZXNzaW9uTGV2ZWwpIHRocm93cyBGaWxlTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICBmaW5hbCBTY2F0dGVyR2F0aGVyQmFja2luZ1N0b3JlIGJzID0gbmV3IEZpbGVCYXNlZFNjYXR0ZXJHYXRoZXJCYWNraW5nU3RvcmUoZmlsZSk7CisgICAgICAgIC8vIGxpZmVjeWNsZSBpcyBib3VuZCB0byB0aGUgU2NhdHRlclppcE91dHB1dFN0cmVhbSByZXR1cm5lZAorICAgICAgICBmaW5hbCBTdHJlYW1Db21wcmVzc29yIHNjID0gU3RyZWFtQ29tcHJlc3Nvci5jcmVhdGUoY29tcHJlc3Npb25MZXZlbCwgYnMpOyAvL05PU09OQVIKKyAgICAgICAgcmV0dXJuIG5ldyBTY2F0dGVyWmlwT3V0cHV0U3RyZWFtKGJzLCBzYyk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9TdHJlYW1Db21wcmVzc29yLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1N0cmVhbUNvbXByZXNzb3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZThkNjhiCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9TdHJlYW1Db21wcmVzc29yLmphdmEKQEAgLTAsMCArMSwzNDAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXA7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MucGFyYWxsZWwuU2NhdHRlckdhdGhlckJhY2tpbmdTdG9yZTsKKworaW1wb3J0IGphdmEuaW8uQ2xvc2VhYmxlOworaW1wb3J0IGphdmEuaW8uRGF0YU91dHB1dDsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5TZWVrYWJsZUJ5dGVDaGFubmVsOworaW1wb3J0IGphdmEudXRpbC56aXAuQ1JDMzI7CitpbXBvcnQgamF2YS51dGlsLnppcC5EZWZsYXRlcjsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLlppcEVudHJ5OworCisvKioKKyAqIEVuY2Fwc3VsYXRlcyBhIHtAbGluayBEZWZsYXRlcn0gYW5kIGNyYyBjYWxjdWxhdG9yLCBoYW5kbGluZyBtdWx0aXBsZSB0eXBlcyBvZiBvdXRwdXQgc3RyZWFtcy4KKyAqIEN1cnJlbnRseSB7QGxpbmsgamF2YS51dGlsLnppcC5aaXBFbnRyeSNERUZMQVRFRH0gYW5kIHtAbGluayBqYXZhLnV0aWwuemlwLlppcEVudHJ5I1NUT1JFRH0gYXJlIHRoZSBvbmx5CisgKiBzdXBwb3J0ZWQgY29tcHJlc3Npb24gbWV0aG9kcy4KKyAqCisgKiBAc2luY2UgMS4xMAorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgU3RyZWFtQ29tcHJlc3NvciBpbXBsZW1lbnRzIENsb3NlYWJsZSB7CisKKyAgICAvKgorICAgICAqIEFwcGFyZW50bHkgRGVmbGF0ZXIuc2V0SW5wdXQgZ2V0cyBzbG93ZWQgZG93biBhIGxvdCBvbiBTdW4gSlZNcworICAgICAqIHdoZW4gaXQgZ2V0cyBoYW5kZWQgYSByZWFsbHkgYmlnIGJ1ZmZlci4gIFNlZQorICAgICAqIGh0dHBzOi8vaXNzdWVzLmFwYWNoZS5vcmcvYnVnemlsbGEvc2hvd19idWcuY2dpP2lkPTQ1Mzk2CisgICAgICoKKyAgICAgKiBVc2luZyBhIGJ1ZmZlciBzaXplIG9mIDgga0IgcHJvdmVkIHRvIGJlIGEgZ29vZCBjb21wcm9taXNlCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IERFRkxBVEVSX0JMT0NLX1NJWkUgPSA4MTkyOworCisgICAgcHJpdmF0ZSBmaW5hbCBEZWZsYXRlciBkZWY7CisKKyAgICBwcml2YXRlIGZpbmFsIENSQzMyIGNyYyA9IG5ldyBDUkMzMigpOworCisgICAgcHJpdmF0ZSBsb25nIHdyaXR0ZW5Ub091dHB1dFN0cmVhbUZvckxhc3RFbnRyeSA9IDA7CisgICAgcHJpdmF0ZSBsb25nIHNvdXJjZVBheWxvYWRMZW5ndGggPSAwOworICAgIHByaXZhdGUgbG9uZyB0b3RhbFdyaXR0ZW5Ub091dHB1dFN0cmVhbSA9IDA7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQlVGRkVSX1NJWkUgPSA0MDk2OworICAgIHByaXZhdGUgZmluYWwgYnl0ZVtdIG91dHB1dEJ1ZmZlciA9IG5ldyBieXRlW0JVRkZFUl9TSVpFXTsKKyAgICBwcml2YXRlIGZpbmFsIGJ5dGVbXSByZWFkZXJCdWYgPSBuZXcgYnl0ZVtCVUZGRVJfU0laRV07CisKKyAgICBTdHJlYW1Db21wcmVzc29yKGZpbmFsIERlZmxhdGVyIGRlZmxhdGVyKSB7CisgICAgICAgIHRoaXMuZGVmID0gZGVmbGF0ZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgc3RyZWFtIGNvbXByZXNzb3Igd2l0aCB0aGUgZ2l2ZW4gY29tcHJlc3Npb24gbGV2ZWwuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3MgICAgICAgVGhlIHN0cmVhbSB0byByZWNlaXZlIG91dHB1dAorICAgICAqIEBwYXJhbSBkZWZsYXRlciBUaGUgZGVmbGF0ZXIgdG8gdXNlCisgICAgICogQHJldHVybiBBIHN0cmVhbSBjb21wcmVzc29yCisgICAgICovCisgICAgc3RhdGljIFN0cmVhbUNvbXByZXNzb3IgY3JlYXRlKGZpbmFsIE91dHB1dFN0cmVhbSBvcywgZmluYWwgRGVmbGF0ZXIgZGVmbGF0ZXIpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBPdXRwdXRTdHJlYW1Db21wcmVzc29yKGRlZmxhdGVyLCBvcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgc3RyZWFtIGNvbXByZXNzb3Igd2l0aCB0aGUgZGVmYXVsdCBjb21wcmVzc2lvbiBsZXZlbC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvcyBUaGUgc3RyZWFtIHRvIHJlY2VpdmUgb3V0cHV0CisgICAgICogQHJldHVybiBBIHN0cmVhbSBjb21wcmVzc29yCisgICAgICovCisgICAgc3RhdGljIFN0cmVhbUNvbXByZXNzb3IgY3JlYXRlKGZpbmFsIE91dHB1dFN0cmVhbSBvcykgeworICAgICAgICByZXR1cm4gY3JlYXRlKG9zLCBuZXcgRGVmbGF0ZXIoRGVmbGF0ZXIuREVGQVVMVF9DT01QUkVTU0lPTiwgdHJ1ZSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIHN0cmVhbSBjb21wcmVzc29yIHdpdGggdGhlIGdpdmVuIGNvbXByZXNzaW9uIGxldmVsLgorICAgICAqCisgICAgICogQHBhcmFtIG9zICAgICAgIFRoZSBEYXRhT3V0cHV0IHRvIHJlY2VpdmUgb3V0cHV0CisgICAgICogQHBhcmFtIGRlZmxhdGVyIFRoZSBkZWZsYXRlciB0byB1c2UgZm9yIHRoZSBjb21wcmVzc29yCisgICAgICogQHJldHVybiBBIHN0cmVhbSBjb21wcmVzc29yCisgICAgICovCisgICAgc3RhdGljIFN0cmVhbUNvbXByZXNzb3IgY3JlYXRlKGZpbmFsIERhdGFPdXRwdXQgb3MsIGZpbmFsIERlZmxhdGVyIGRlZmxhdGVyKSB7CisgICAgICAgIHJldHVybiBuZXcgRGF0YU91dHB1dENvbXByZXNzb3IoZGVmbGF0ZXIsIG9zKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBzdHJlYW0gY29tcHJlc3NvciB3aXRoIHRoZSBnaXZlbiBjb21wcmVzc2lvbiBsZXZlbC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvcyAgICAgICBUaGUgU2Vla2FibGVCeXRlQ2hhbm5lbCB0byByZWNlaXZlIG91dHB1dAorICAgICAqIEBwYXJhbSBkZWZsYXRlciBUaGUgZGVmbGF0ZXIgdG8gdXNlIGZvciB0aGUgY29tcHJlc3NvcgorICAgICAqIEByZXR1cm4gQSBzdHJlYW0gY29tcHJlc3NvcgorICAgICAqIEBzaW5jZSAxLjEzCisgICAgICovCisgICAgc3RhdGljIFN0cmVhbUNvbXByZXNzb3IgY3JlYXRlKGZpbmFsIFNlZWthYmxlQnl0ZUNoYW5uZWwgb3MsIGZpbmFsIERlZmxhdGVyIGRlZmxhdGVyKSB7CisgICAgICAgIHJldHVybiBuZXcgU2Vla2FibGVCeXRlQ2hhbm5lbENvbXByZXNzb3IoZGVmbGF0ZXIsIG9zKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBzdHJlYW0gY29tcHJlc3NvciB3aXRoIHRoZSBnaXZlbiBjb21wcmVzc2lvbiBsZXZlbC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb21wcmVzc2lvbkxldmVsIFRoZSB7QGxpbmsgRGVmbGF0ZXJ9ICBjb21wcmVzc2lvbiBsZXZlbAorICAgICAqIEBwYXJhbSBicyAgICAgICAgICAgICAgIFRoZSBTY2F0dGVyR2F0aGVyQmFja2luZ1N0b3JlIHRvIHJlY2VpdmUgb3V0cHV0CisgICAgICogQHJldHVybiBBIHN0cmVhbSBjb21wcmVzc29yCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJlYW1Db21wcmVzc29yIGNyZWF0ZShmaW5hbCBpbnQgY29tcHJlc3Npb25MZXZlbCwgZmluYWwgU2NhdHRlckdhdGhlckJhY2tpbmdTdG9yZSBicykgeworICAgICAgICBmaW5hbCBEZWZsYXRlciBkZWZsYXRlciA9IG5ldyBEZWZsYXRlcihjb21wcmVzc2lvbkxldmVsLCB0cnVlKTsKKyAgICAgICAgcmV0dXJuIG5ldyBTY2F0dGVyR2F0aGVyQmFja2luZ1N0b3JlQ29tcHJlc3NvcihkZWZsYXRlciwgYnMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIHN0cmVhbSBjb21wcmVzc29yIHdpdGggdGhlIGRlZmF1bHQgY29tcHJlc3Npb24gbGV2ZWwuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYnMgVGhlIFNjYXR0ZXJHYXRoZXJCYWNraW5nU3RvcmUgdG8gcmVjZWl2ZSBvdXRwdXQKKyAgICAgKiBAcmV0dXJuIEEgc3RyZWFtIGNvbXByZXNzb3IKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmVhbUNvbXByZXNzb3IgY3JlYXRlKGZpbmFsIFNjYXR0ZXJHYXRoZXJCYWNraW5nU3RvcmUgYnMpIHsKKyAgICAgICAgcmV0dXJuIGNyZWF0ZShEZWZsYXRlci5ERUZBVUxUX0NPTVBSRVNTSU9OLCBicyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIGNyYzMyIG9mIHRoZSBsYXN0IGRlZmxhdGVkIGZpbGUKKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGNyYzMyCisgICAgICovCisKKyAgICBwdWJsaWMgbG9uZyBnZXRDcmMzMigpIHsKKyAgICAgICAgcmV0dXJuIGNyYy5nZXRWYWx1ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgbnVtYmVyIG9mIGJ5dGVzIHJlYWQgZnJvbSB0aGUgc291cmNlIHN0cmVhbQorICAgICAqCisgICAgICogQHJldHVybiBUaGUgbnVtYmVyIG9mIGJ5dGVzIHJlYWQsIG5ldmVyIG5lZ2F0aXZlCisgICAgICovCisgICAgcHVibGljIGxvbmcgZ2V0Qnl0ZXNSZWFkKCkgeworICAgICAgICByZXR1cm4gc291cmNlUGF5bG9hZExlbmd0aDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgbnVtYmVyIG9mIGJ5dGVzIHdyaXR0ZW4gdG8gdGhlIG91dHB1dCBmb3IgdGhlIGxhc3QgZW50cnkKKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhlIG51bWJlciBvZiBieXRlcywgbmV2ZXIgbmVnYXRpdmUKKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBnZXRCeXRlc1dyaXR0ZW5Gb3JMYXN0RW50cnkoKSB7CisgICAgICAgIHJldHVybiB3cml0dGVuVG9PdXRwdXRTdHJlYW1Gb3JMYXN0RW50cnk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIHRvdGFsIG51bWJlciBvZiBieXRlcyB3cml0dGVuIHRvIHRoZSBvdXRwdXQgZm9yIGFsbCBmaWxlcworICAgICAqCisgICAgICogQHJldHVybiBUaGUgbnVtYmVyIG9mIGJ5dGVzLCBuZXZlciBuZWdhdGl2ZQorICAgICAqLworICAgIHB1YmxpYyBsb25nIGdldFRvdGFsQnl0ZXNXcml0dGVuKCkgeworICAgICAgICByZXR1cm4gdG90YWxXcml0dGVuVG9PdXRwdXRTdHJlYW07CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBEZWZsYXRlIHRoZSBnaXZlbiBzb3VyY2UgdXNpbmcgdGhlIHN1cHBsaWVkIGNvbXByZXNzaW9uIG1ldGhvZAorICAgICAqCisgICAgICogQHBhcmFtIHNvdXJjZSBUaGUgc291cmNlIHRvIGNvbXByZXNzCisgICAgICogQHBhcmFtIG1ldGhvZCBUaGUgI1ppcEFyY2hpdmVFbnRyeSBjb21wcmVzc2lvbiBtZXRob2QKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIFdoZW4gZmFpbHVyZXMgaGFwcGVuCisgICAgICovCisKKyAgICBwdWJsaWMgdm9pZCBkZWZsYXRlKGZpbmFsIElucHV0U3RyZWFtIHNvdXJjZSwgZmluYWwgaW50IG1ldGhvZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmVzZXQoKTsKKyAgICAgICAgaW50IGxlbmd0aDsKKworICAgICAgICB3aGlsZSAoKGxlbmd0aCA9IHNvdXJjZS5yZWFkKHJlYWRlckJ1ZiwgMCwgcmVhZGVyQnVmLmxlbmd0aCkpID49IDApIHsKKyAgICAgICAgICAgIHdyaXRlKHJlYWRlckJ1ZiwgMCwgbGVuZ3RoLCBtZXRob2QpOworICAgICAgICB9CisgICAgICAgIGlmIChtZXRob2QgPT0gWmlwRW50cnkuREVGTEFURUQpIHsKKyAgICAgICAgICAgIGZsdXNoRGVmbGF0ZXIoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyBieXRlcyB0byBaSVAgZW50cnkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYiAgICAgIHRoZSBieXRlIGFycmF5IHRvIHdyaXRlCisgICAgICogQHBhcmFtIG9mZnNldCB0aGUgc3RhcnQgcG9zaXRpb24gdG8gd3JpdGUgZnJvbQorICAgICAqIEBwYXJhbSBsZW5ndGggdGhlIG51bWJlciBvZiBieXRlcyB0byB3cml0ZQorICAgICAqIEBwYXJhbSBtZXRob2QgdGhlIGNvbXJwZXNzaW9uIG1ldGhvZCB0byB1c2UKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgd3JpdHRlbiB0byB0aGUgc3RyZWFtIHRoaXMgdGltZQorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gb24gZXJyb3IKKyAgICAgKi8KKyAgICBsb25nIHdyaXRlKGZpbmFsIGJ5dGVbXSBiLCBmaW5hbCBpbnQgb2Zmc2V0LCBmaW5hbCBpbnQgbGVuZ3RoLCBmaW5hbCBpbnQgbWV0aG9kKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBsb25nIGN1cnJlbnQgPSB3cml0dGVuVG9PdXRwdXRTdHJlYW1Gb3JMYXN0RW50cnk7CisgICAgICAgIGNyYy51cGRhdGUoYiwgb2Zmc2V0LCBsZW5ndGgpOworICAgICAgICBpZiAobWV0aG9kID09IFppcEVudHJ5LkRFRkxBVEVEKSB7CisgICAgICAgICAgICB3cml0ZURlZmxhdGVkKGIsIG9mZnNldCwgbGVuZ3RoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHdyaXRlQ291bnRlZChiLCBvZmZzZXQsIGxlbmd0aCk7CisgICAgICAgIH0KKyAgICAgICAgc291cmNlUGF5bG9hZExlbmd0aCArPSBsZW5ndGg7CisgICAgICAgIHJldHVybiB3cml0dGVuVG9PdXRwdXRTdHJlYW1Gb3JMYXN0RW50cnkgLSBjdXJyZW50OworICAgIH0KKworCisgICAgdm9pZCByZXNldCgpIHsKKyAgICAgICAgY3JjLnJlc2V0KCk7CisgICAgICAgIGRlZi5yZXNldCgpOworICAgICAgICBzb3VyY2VQYXlsb2FkTGVuZ3RoID0gMDsKKyAgICAgICAgd3JpdHRlblRvT3V0cHV0U3RyZWFtRm9yTGFzdEVudHJ5ID0gMDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGRlZi5lbmQoKTsKKyAgICB9CisKKyAgICB2b2lkIGZsdXNoRGVmbGF0ZXIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBkZWYuZmluaXNoKCk7CisgICAgICAgIHdoaWxlICghZGVmLmZpbmlzaGVkKCkpIHsKKyAgICAgICAgICAgIGRlZmxhdGUoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB3cml0ZURlZmxhdGVkKGZpbmFsIGJ5dGVbXSBiLCBmaW5hbCBpbnQgb2Zmc2V0LCBmaW5hbCBpbnQgbGVuZ3RoKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGxlbmd0aCA+IDAgJiYgIWRlZi5maW5pc2hlZCgpKSB7CisgICAgICAgICAgICBpZiAobGVuZ3RoIDw9IERFRkxBVEVSX0JMT0NLX1NJWkUpIHsKKyAgICAgICAgICAgICAgICBkZWYuc2V0SW5wdXQoYiwgb2Zmc2V0LCBsZW5ndGgpOworICAgICAgICAgICAgICAgIGRlZmxhdGVVbnRpbElucHV0SXNOZWVkZWQoKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZmluYWwgaW50IGZ1bGxibG9ja3MgPSBsZW5ndGggLyBERUZMQVRFUl9CTE9DS19TSVpFOworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZnVsbGJsb2NrczsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGRlZi5zZXRJbnB1dChiLCBvZmZzZXQgKyBpICogREVGTEFURVJfQkxPQ0tfU0laRSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBERUZMQVRFUl9CTE9DS19TSVpFKTsKKyAgICAgICAgICAgICAgICAgICAgZGVmbGF0ZVVudGlsSW5wdXRJc05lZWRlZCgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBmaW5hbCBpbnQgZG9uZSA9IGZ1bGxibG9ja3MgKiBERUZMQVRFUl9CTE9DS19TSVpFOworICAgICAgICAgICAgICAgIGlmIChkb25lIDwgbGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgICAgIGRlZi5zZXRJbnB1dChiLCBvZmZzZXQgKyBkb25lLCBsZW5ndGggLSBkb25lKTsKKyAgICAgICAgICAgICAgICAgICAgZGVmbGF0ZVVudGlsSW5wdXRJc05lZWRlZCgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBkZWZsYXRlVW50aWxJbnB1dElzTmVlZGVkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgd2hpbGUgKCFkZWYubmVlZHNJbnB1dCgpKSB7CisgICAgICAgICAgICBkZWZsYXRlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICB2b2lkIGRlZmxhdGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBpbnQgbGVuID0gZGVmLmRlZmxhdGUob3V0cHV0QnVmZmVyLCAwLCBvdXRwdXRCdWZmZXIubGVuZ3RoKTsKKyAgICAgICAgaWYgKGxlbiA+IDApIHsKKyAgICAgICAgICAgIHdyaXRlQ291bnRlZChvdXRwdXRCdWZmZXIsIDAsIGxlbik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB3cml0ZUNvdW50ZWQoZmluYWwgYnl0ZVtdIGRhdGEpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHdyaXRlQ291bnRlZChkYXRhLCAwLCBkYXRhLmxlbmd0aCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgd3JpdGVDb3VudGVkKGZpbmFsIGJ5dGVbXSBkYXRhLCBmaW5hbCBpbnQgb2Zmc2V0LCBmaW5hbCBpbnQgbGVuZ3RoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB3cml0ZU91dChkYXRhLCBvZmZzZXQsIGxlbmd0aCk7CisgICAgICAgIHdyaXR0ZW5Ub091dHB1dFN0cmVhbUZvckxhc3RFbnRyeSArPSBsZW5ndGg7CisgICAgICAgIHRvdGFsV3JpdHRlblRvT3V0cHV0U3RyZWFtICs9IGxlbmd0aDsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3Qgdm9pZCB3cml0ZU91dChieXRlW10gZGF0YSwgaW50IG9mZnNldCwgaW50IGxlbmd0aCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgU2NhdHRlckdhdGhlckJhY2tpbmdTdG9yZUNvbXByZXNzb3IgZXh0ZW5kcyBTdHJlYW1Db21wcmVzc29yIHsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBTY2F0dGVyR2F0aGVyQmFja2luZ1N0b3JlIGJzOworCisgICAgICAgIHB1YmxpYyBTY2F0dGVyR2F0aGVyQmFja2luZ1N0b3JlQ29tcHJlc3NvcihmaW5hbCBEZWZsYXRlciBkZWZsYXRlciwgZmluYWwgU2NhdHRlckdhdGhlckJhY2tpbmdTdG9yZSBicykgeworICAgICAgICAgICAgc3VwZXIoZGVmbGF0ZXIpOworICAgICAgICAgICAgdGhpcy5icyA9IGJzOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCBmaW5hbCB2b2lkIHdyaXRlT3V0KGZpbmFsIGJ5dGVbXSBkYXRhLCBmaW5hbCBpbnQgb2Zmc2V0LCBmaW5hbCBpbnQgbGVuZ3RoKQorICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBicy53cml0ZU91dChkYXRhLCBvZmZzZXQsIGxlbmd0aCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBPdXRwdXRTdHJlYW1Db21wcmVzc29yIGV4dGVuZHMgU3RyZWFtQ29tcHJlc3NvciB7CisgICAgICAgIHByaXZhdGUgZmluYWwgT3V0cHV0U3RyZWFtIG9zOworCisgICAgICAgIHB1YmxpYyBPdXRwdXRTdHJlYW1Db21wcmVzc29yKGZpbmFsIERlZmxhdGVyIGRlZmxhdGVyLCBmaW5hbCBPdXRwdXRTdHJlYW0gb3MpIHsKKyAgICAgICAgICAgIHN1cGVyKGRlZmxhdGVyKTsKKyAgICAgICAgICAgIHRoaXMub3MgPSBvczsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgZmluYWwgdm9pZCB3cml0ZU91dChmaW5hbCBieXRlW10gZGF0YSwgZmluYWwgaW50IG9mZnNldCwgZmluYWwgaW50IGxlbmd0aCkKKyAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgb3Mud3JpdGUoZGF0YSwgb2Zmc2V0LCBsZW5ndGgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRGF0YU91dHB1dENvbXByZXNzb3IgZXh0ZW5kcyBTdHJlYW1Db21wcmVzc29yIHsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBEYXRhT3V0cHV0IHJhZjsKKworICAgICAgICBwdWJsaWMgRGF0YU91dHB1dENvbXByZXNzb3IoZmluYWwgRGVmbGF0ZXIgZGVmbGF0ZXIsIGZpbmFsIERhdGFPdXRwdXQgcmFmKSB7CisgICAgICAgICAgICBzdXBlcihkZWZsYXRlcik7CisgICAgICAgICAgICB0aGlzLnJhZiA9IHJhZjsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgZmluYWwgdm9pZCB3cml0ZU91dChmaW5hbCBieXRlW10gZGF0YSwgZmluYWwgaW50IG9mZnNldCwgZmluYWwgaW50IGxlbmd0aCkKKyAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgcmFmLndyaXRlKGRhdGEsIG9mZnNldCwgbGVuZ3RoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFNlZWthYmxlQnl0ZUNoYW5uZWxDb21wcmVzc29yIGV4dGVuZHMgU3RyZWFtQ29tcHJlc3NvciB7CisgICAgICAgIHByaXZhdGUgZmluYWwgU2Vla2FibGVCeXRlQ2hhbm5lbCBjaGFubmVsOworCisgICAgICAgIHB1YmxpYyBTZWVrYWJsZUJ5dGVDaGFubmVsQ29tcHJlc3NvcihmaW5hbCBEZWZsYXRlciBkZWZsYXRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIFNlZWthYmxlQnl0ZUNoYW5uZWwgY2hhbm5lbCkgeworICAgICAgICAgICAgc3VwZXIoZGVmbGF0ZXIpOworICAgICAgICAgICAgdGhpcy5jaGFubmVsID0gY2hhbm5lbDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgZmluYWwgdm9pZCB3cml0ZU91dChmaW5hbCBieXRlW10gZGF0YSwgZmluYWwgaW50IG9mZnNldCwgZmluYWwgaW50IGxlbmd0aCkKKyAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgY2hhbm5lbC53cml0ZShCeXRlQnVmZmVyLndyYXAoZGF0YSwgb2Zmc2V0LCBsZW5ndGgpKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvVW5pY29kZUNvbW1lbnRFeHRyYUZpZWxkLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1VuaWNvZGVDb21tZW50RXh0cmFGaWVsZC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBiMGU4NGUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1VuaWNvZGVDb21tZW50RXh0cmFGaWVsZC5qYXZhCkBAIC0wLDAgKzEsNzAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcDsKKworLyoqCisgKiBJbmZvLVpJUCBVbmljb2RlIENvbW1lbnQgRXh0cmEgRmllbGQgKDB4NjM3NSk6CisgKgorICogPHA+U3RvcmVzIHRoZSBVVEYtOCB2ZXJzaW9uIG9mIHRoZSBmaWxlIGNvbW1lbnQgYXMgc3RvcmVkIGluIHRoZQorICogY2VudHJhbCBkaXJlY3RvcnkgaGVhZGVyLjwvcD4KKyAqCisgKiBAc2VlIDxhIGhyZWY9Imh0dHBzOi8vd3d3LnBrd2FyZS5jb20vZG9jdW1lbnRzL2Nhc2VzdHVkaWVzL0FQUE5PVEUuVFhUIj5QS1dBUkUKKyAqIEFQUE5PVEUuVFhULCBzZWN0aW9uIDQuNi44PC9hPgorICoKKyAqIEBOb3RUaHJlYWRTYWZlIHN1cGVyLWNsYXNzIGlzIG5vdCB0aHJlYWQtc2FmZQorICovCitwdWJsaWMgY2xhc3MgVW5pY29kZUNvbW1lbnRFeHRyYUZpZWxkIGV4dGVuZHMgQWJzdHJhY3RVbmljb2RlRXh0cmFGaWVsZCB7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFppcFNob3J0IFVDT01fSUQgPSBuZXcgWmlwU2hvcnQoMHg2Mzc1KTsKKworICAgIHB1YmxpYyBVbmljb2RlQ29tbWVudEV4dHJhRmllbGQgKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIEFzc2VtYmxlIGFzIHVuaWNvZGUgY29tbWVudCBleHRlbnNpb24gZnJvbSB0aGUgbmFtZSBnaXZlbiBhcworICAgICAqIHRleHQgYXMgd2VsbCBhcyB0aGUgZW5jb2RlZCBieXRlcyBhY3R1YWxseSB3cml0dGVuIHRvIHRoZSBhcmNoaXZlLgorICAgICAqCisgICAgICogQHBhcmFtIHRleHQgVGhlIGZpbGUgbmFtZQorICAgICAqIEBwYXJhbSBieXRlcyB0aGUgYnl0ZXMgYWN0dWFsbHkgd3JpdHRlbiB0byB0aGUgYXJjaGl2ZQorICAgICAqIEBwYXJhbSBvZmYgVGhlIG9mZnNldCBvZiB0aGUgZW5jb2RlZCBjb21tZW50IGluIDxjb2RlPmJ5dGVzPC9jb2RlPi4KKyAgICAgKiBAcGFyYW0gbGVuIFRoZSBsZW5ndGggb2YgdGhlIGVuY29kZWQgY29tbWVudCBvciBjb21tZW50IGluCisgICAgICogPGNvZGU+Ynl0ZXM8L2NvZGU+LgorICAgICAqLworICAgIHB1YmxpYyBVbmljb2RlQ29tbWVudEV4dHJhRmllbGQoZmluYWwgU3RyaW5nIHRleHQsIGZpbmFsIGJ5dGVbXSBieXRlcywgZmluYWwgaW50IG9mZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBsZW4pIHsKKyAgICAgICAgc3VwZXIodGV4dCwgYnl0ZXMsIG9mZiwgbGVuKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBc3NlbWJsZSBhcyB1bmljb2RlIGNvbW1lbnQgZXh0ZW5zaW9uIGZyb20gdGhlIGNvbW1lbnQgZ2l2ZW4gYXMKKyAgICAgKiB0ZXh0IGFzIHdlbGwgYXMgdGhlIGJ5dGVzIGFjdHVhbGx5IHdyaXR0ZW4gdG8gdGhlIGFyY2hpdmUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29tbWVudCBUaGUgZmlsZSBjb21tZW50CisgICAgICogQHBhcmFtIGJ5dGVzIHRoZSBieXRlcyBhY3R1YWxseSB3cml0dGVuIHRvIHRoZSBhcmNoaXZlCisgICAgICovCisgICAgcHVibGljIFVuaWNvZGVDb21tZW50RXh0cmFGaWVsZChmaW5hbCBTdHJpbmcgY29tbWVudCwgZmluYWwgYnl0ZVtdIGJ5dGVzKSB7CisgICAgICAgIHN1cGVyKGNvbW1lbnQsIGJ5dGVzKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgWmlwU2hvcnQgZ2V0SGVhZGVySWQoKSB7CisgICAgICAgIHJldHVybiBVQ09NX0lEOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9Vbmljb2RlUGF0aEV4dHJhRmllbGQuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvVW5pY29kZVBhdGhFeHRyYUZpZWxkLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTEwYzVhZAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvVW5pY29kZVBhdGhFeHRyYUZpZWxkLmphdmEKQEAgLTAsMCArMSw2OCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICoKKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwOworCisvKioKKyAqIEluZm8tWklQIFVuaWNvZGUgUGF0aCBFeHRyYSBGaWVsZCAoMHg3MDc1KToKKyAqCisgKiA8cD5TdG9yZXMgdGhlIFVURi04IHZlcnNpb24gb2YgdGhlIGZpbGUgbmFtZSBmaWVsZCBhcyBzdG9yZWQgaW4gdGhlCisgKiBsb2NhbCBoZWFkZXIgYW5kIGNlbnRyYWwgZGlyZWN0b3J5IGhlYWRlci48L3A+CisgKgorICogQHNlZSA8YSBocmVmPSJodHRwczovL3d3dy5wa3dhcmUuY29tL2RvY3VtZW50cy9jYXNlc3R1ZGllcy9BUFBOT1RFLlRYVCI+UEtXQVJFCisgKiBBUFBOT1RFLlRYVCwgc2VjdGlvbiA0LjYuOTwvYT4KKyAqCisgKiBATm90VGhyZWFkU2FmZSBzdXBlci1jbGFzcyBpcyBub3QgdGhyZWFkLXNhZmUKKyAqLworcHVibGljIGNsYXNzIFVuaWNvZGVQYXRoRXh0cmFGaWVsZCBleHRlbmRzIEFic3RyYWN0VW5pY29kZUV4dHJhRmllbGQgeworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBaaXBTaG9ydCBVUEFUSF9JRCA9IG5ldyBaaXBTaG9ydCgweDcwNzUpOworCisgICAgcHVibGljIFVuaWNvZGVQYXRoRXh0cmFGaWVsZCAoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXNzZW1ibGUgYXMgdW5pY29kZSBwYXRoIGV4dGVuc2lvbiBmcm9tIHRoZSBuYW1lIGdpdmVuIGFzCisgICAgICogdGV4dCBhcyB3ZWxsIGFzIHRoZSBlbmNvZGVkIGJ5dGVzIGFjdHVhbGx5IHdyaXR0ZW4gdG8gdGhlIGFyY2hpdmUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGV4dCBUaGUgZmlsZSBuYW1lCisgICAgICogQHBhcmFtIGJ5dGVzIHRoZSBieXRlcyBhY3R1YWxseSB3cml0dGVuIHRvIHRoZSBhcmNoaXZlCisgICAgICogQHBhcmFtIG9mZiBUaGUgb2Zmc2V0IG9mIHRoZSBlbmNvZGVkIGZpbGVuYW1lIGluIDxjb2RlPmJ5dGVzPC9jb2RlPi4KKyAgICAgKiBAcGFyYW0gbGVuIFRoZSBsZW5ndGggb2YgdGhlIGVuY29kZWQgZmlsZW5hbWUgb3IgY29tbWVudCBpbgorICAgICAqIDxjb2RlPmJ5dGVzPC9jb2RlPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgVW5pY29kZVBhdGhFeHRyYUZpZWxkKGZpbmFsIFN0cmluZyB0ZXh0LCBmaW5hbCBieXRlW10gYnl0ZXMsIGZpbmFsIGludCBvZmYsIGZpbmFsIGludCBsZW4pIHsKKyAgICAgICAgc3VwZXIodGV4dCwgYnl0ZXMsIG9mZiwgbGVuKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBc3NlbWJsZSBhcyB1bmljb2RlIHBhdGggZXh0ZW5zaW9uIGZyb20gdGhlIG5hbWUgZ2l2ZW4gYXMKKyAgICAgKiB0ZXh0IGFzIHdlbGwgYXMgdGhlIGVuY29kZWQgYnl0ZXMgYWN0dWFsbHkgd3JpdHRlbiB0byB0aGUgYXJjaGl2ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lIFRoZSBmaWxlIG5hbWUKKyAgICAgKiBAcGFyYW0gYnl0ZXMgdGhlIGJ5dGVzIGFjdHVhbGx5IHdyaXR0ZW4gdG8gdGhlIGFyY2hpdmUKKyAgICAgKi8KKyAgICBwdWJsaWMgVW5pY29kZVBhdGhFeHRyYUZpZWxkKGZpbmFsIFN0cmluZyBuYW1lLCBmaW5hbCBieXRlW10gYnl0ZXMpIHsKKyAgICAgICAgc3VwZXIobmFtZSwgYnl0ZXMpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBaaXBTaG9ydCBnZXRIZWFkZXJJZCgpIHsKKyAgICAgICAgcmV0dXJuIFVQQVRIX0lEOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvVW5peFN0YXQuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvVW5peFN0YXQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hMWIyMGJlCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9Vbml4U3RhdC5qYXZhCkBAIC0wLDAgKzEsNjggQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcDsKKworLyoqCisgKiBDb25zdGFudHMgZnJvbSBzdGF0Lmggb24gVW5peCBzeXN0ZW1zLgorICovCisvLyBDaGVja1N0eWxlOkludGVyZmFjZUlzVHlwZUNoZWNrIE9GRiAtIGJhY2t3YXJkIGNvbXBhdGlibGUKK3B1YmxpYyBpbnRlcmZhY2UgVW5peFN0YXQgeworCisgICAgLyoqCisgICAgICogQml0cyB1c2VkIGZvciBwZXJtaXNzaW9ucyAoYW5kIHN0aWNreSBiaXQpCisgICAgICovCisgICAgaW50IFBFUk1fTUFTSyA9IDA3Nzc3OworICAgIC8qKgorICAgICAqIEJpdHMgdXNlZCB0byBpbmRpY2F0ZSB0aGUgZmlsZXN5c3RlbSBvYmplY3QgdHlwZS4KKyAgICAgKiBAc2luY2UgMS4xNAorICAgICAqLworICAgIGludCBGSUxFX1RZUEVfRkxBRyA9IDAxNzAwMDA7CisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHN5bWJvbGljIGxpbmtzLgorICAgICAqLworICAgIGludCBMSU5LX0ZMQUcgPSAwMTIwMDAwOworICAgIC8qKgorICAgICAqIEluZGljYXRlcyBwbGFpbiBmaWxlcy4KKyAgICAgKi8KKyAgICBpbnQgRklMRV9GTEFHID0gMDEwMDAwMDsKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgZGlyZWN0b3JpZXMuCisgICAgICovCisgICAgaW50IERJUl9GTEFHID0gMDQwMDAwOworCisgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAgIC8vIHNvbWV3aGF0IGFyYml0cmFyeSBjaG9pY2VzIHRoYXQgYXJlIHF1aXRlIGNvbW1vbiBmb3Igc2hhcmVkCisgICAgLy8gaW5zdGFsbGF0aW9ucworICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgICAvKioKKyAgICAgKiBEZWZhdWx0IHBlcm1pc3Npb25zIGZvciBzeW1ib2xpYyBsaW5rcy4KKyAgICAgKi8KKyAgICBpbnQgREVGQVVMVF9MSU5LX1BFUk0gPSAwNzc3OworCisgICAgLyoqCisgICAgICogRGVmYXVsdCBwZXJtaXNzaW9ucyBmb3IgZGlyZWN0b3JpZXMuCisgICAgICovCisgICAgaW50IERFRkFVTFRfRElSX1BFUk0gPSAwNzU1OworCisgICAgLyoqCisgICAgICogRGVmYXVsdCBwZXJtaXNzaW9ucyBmb3IgcGxhaW4gZmlsZXMuCisgICAgICovCisgICAgaW50IERFRkFVTFRfRklMRV9QRVJNID0gMDY0NDsKK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvVW5wYXJzZWFibGVFeHRyYUZpZWxkRGF0YS5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9VbnBhcnNlYWJsZUV4dHJhRmllbGREYXRhLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDdkMjRkZgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvVW5wYXJzZWFibGVFeHRyYUZpZWxkRGF0YS5qYXZhCkBAIC0wLDAgKzEsMTIwIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXA7CisKKy8qKgorICogV3JhcHBlciBmb3IgZXh0cmEgZmllbGQgZGF0YSB0aGF0IGRvZXNuJ3QgY29uZm9ybSB0byB0aGUgcmVjb21tZW5kZWQgZm9ybWF0IG9mIGhlYWRlci10YWcgKyBzaXplICsgZGF0YS4KKyAqCisgKiA8cD5UaGUgaGVhZGVyLWlkIGlzIGFydGlmaWNpYWwgKGFuZCBub3QgbGlzdGVkIGFzIGEga25vd24gSUQgaW4gPGEKKyAqIGhyZWY9Imh0dHBzOi8vd3d3LnBrd2FyZS5jb20vZG9jdW1lbnRzL2Nhc2VzdHVkaWVzL0FQUE5PVEUuVFhUIj5BUFBOT1RFLlRYVDwvYT4pLiAgU2luY2UgaXQgaXNuJ3QgdXNlZCBhbnl3aGVyZQorICogZXhjZXB0IHRvIHNhdGlzZnkgdGhlIFppcEV4dHJhRmllbGQgY29udHJhY3QgaXQgc2hvdWxkbid0IG1hdHRlciBhbnl3YXkuPC9wPgorICoKKyAqIEBzaW5jZSAxLjEKKyAqIEBOb3RUaHJlYWRTYWZlCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBVbnBhcnNlYWJsZUV4dHJhRmllbGREYXRhIGltcGxlbWVudHMgWmlwRXh0cmFGaWVsZCB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgWmlwU2hvcnQgSEVBREVSX0lEID0gbmV3IFppcFNob3J0KDB4QUNDMSk7CisKKyAgICBwcml2YXRlIGJ5dGVbXSBsb2NhbEZpbGVEYXRhOworICAgIHByaXZhdGUgYnl0ZVtdIGNlbnRyYWxEaXJlY3RvcnlEYXRhOworCisgICAgLyoqCisgICAgICogVGhlIEhlYWRlci1JRC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBjb21wbGV0ZWx5IGFyYml0cmFyeSB2YWx1ZSB0aGF0IHNob3VsZCBiZSBpZ25vcmVkLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBaaXBTaG9ydCBnZXRIZWFkZXJJZCgpIHsKKyAgICAgICAgcmV0dXJuIEhFQURFUl9JRDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMZW5ndGggb2YgdGhlIGNvbXBsZXRlIGV4dHJhIGZpZWxkIGluIHRoZSBsb2NhbCBmaWxlIGRhdGEuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoZSBMb2NhbEZpbGVEYXRhTGVuZ3RoIHZhbHVlCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFppcFNob3J0IGdldExvY2FsRmlsZURhdGFMZW5ndGgoKSB7CisgICAgICAgIHJldHVybiBuZXcgWmlwU2hvcnQobG9jYWxGaWxlRGF0YSA9PSBudWxsID8gMCA6IGxvY2FsRmlsZURhdGEubGVuZ3RoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMZW5ndGggb2YgdGhlIGNvbXBsZXRlIGV4dHJhIGZpZWxkIGluIHRoZSBjZW50cmFsIGRpcmVjdG9yeS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhlIENlbnRyYWxEaXJlY3RvcnlMZW5ndGggdmFsdWUKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgWmlwU2hvcnQgZ2V0Q2VudHJhbERpcmVjdG9yeUxlbmd0aCgpIHsKKyAgICAgICAgcmV0dXJuIGNlbnRyYWxEaXJlY3RvcnlEYXRhID09IG51bGwKKyAgICAgICAgICAgID8gZ2V0TG9jYWxGaWxlRGF0YUxlbmd0aCgpCisgICAgICAgICAgICA6IG5ldyBaaXBTaG9ydChjZW50cmFsRGlyZWN0b3J5RGF0YS5sZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBhY3R1YWwgZGF0YSB0byBwdXQgaW50byBsb2NhbCBmaWxlIGRhdGEuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoZSBMb2NhbEZpbGVEYXRhRGF0YSB2YWx1ZQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBieXRlW10gZ2V0TG9jYWxGaWxlRGF0YURhdGEoKSB7CisgICAgICAgIHJldHVybiBaaXBVdGlsLmNvcHkobG9jYWxGaWxlRGF0YSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIGFjdHVhbCBkYXRhIHRvIHB1dCBpbnRvIGNlbnRyYWwgZGlyZWN0b3J5LgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgQ2VudHJhbERpcmVjdG9yeURhdGEgdmFsdWUKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYnl0ZVtdIGdldENlbnRyYWxEaXJlY3RvcnlEYXRhKCkgeworICAgICAgICByZXR1cm4gY2VudHJhbERpcmVjdG9yeURhdGEgPT0gbnVsbAorICAgICAgICAgICAgPyBnZXRMb2NhbEZpbGVEYXRhRGF0YSgpIDogWmlwVXRpbC5jb3B5KGNlbnRyYWxEaXJlY3RvcnlEYXRhKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQb3B1bGF0ZSBkYXRhIGZyb20gdGhpcyBhcnJheSBhcyBpZiBpdCB3YXMgaW4gbG9jYWwgZmlsZSBkYXRhLgorICAgICAqCisgICAgICogQHBhcmFtIGJ1ZmZlciB0aGUgYnVmZmVyIHRvIHJlYWQgZGF0YSBmcm9tCisgICAgICogQHBhcmFtIG9mZnNldCBvZmZzZXQgaW50byBidWZmZXIgdG8gcmVhZCBkYXRhCisgICAgICogQHBhcmFtIGxlbmd0aCB0aGUgbGVuZ3RoIG9mIGRhdGEKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBwYXJzZUZyb21Mb2NhbEZpbGVEYXRhKGZpbmFsIGJ5dGVbXSBidWZmZXIsIGZpbmFsIGludCBvZmZzZXQsIGZpbmFsIGludCBsZW5ndGgpIHsKKyAgICAgICAgbG9jYWxGaWxlRGF0YSA9IG5ldyBieXRlW2xlbmd0aF07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYnVmZmVyLCBvZmZzZXQsIGxvY2FsRmlsZURhdGEsIDAsIGxlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUG9wdWxhdGUgZGF0YSBmcm9tIHRoaXMgYXJyYXkgYXMgaWYgaXQgd2FzIGluIGNlbnRyYWwgZGlyZWN0b3J5IGRhdGEuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYnVmZmVyIHRoZSBidWZmZXIgdG8gcmVhZCBkYXRhIGZyb20KKyAgICAgKiBAcGFyYW0gb2Zmc2V0IG9mZnNldCBpbnRvIGJ1ZmZlciB0byByZWFkIGRhdGEKKyAgICAgKiBAcGFyYW0gbGVuZ3RoIHRoZSBsZW5ndGggb2YgZGF0YQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHBhcnNlRnJvbUNlbnRyYWxEaXJlY3RvcnlEYXRhKGZpbmFsIGJ5dGVbXSBidWZmZXIsIGZpbmFsIGludCBvZmZzZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGxlbmd0aCkgeworICAgICAgICBjZW50cmFsRGlyZWN0b3J5RGF0YSA9IG5ldyBieXRlW2xlbmd0aF07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYnVmZmVyLCBvZmZzZXQsIGNlbnRyYWxEaXJlY3RvcnlEYXRhLCAwLCBsZW5ndGgpOworICAgICAgICBpZiAobG9jYWxGaWxlRGF0YSA9PSBudWxsKSB7CisgICAgICAgICAgICBwYXJzZUZyb21Mb2NhbEZpbGVEYXRhKGJ1ZmZlciwgb2Zmc2V0LCBsZW5ndGgpOworICAgICAgICB9CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1VucmVjb2duaXplZEV4dHJhRmllbGQuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvVW5yZWNvZ25pemVkRXh0cmFGaWVsZC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY4ZWE4YjkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1VucmVjb2duaXplZEV4dHJhRmllbGQuamF2YQpAQCAtMCwwICsxLDE1NSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwOworCisvKioKKyAqIFNpbXBsZSBwbGFjZWhvbGRlciBmb3IgYWxsIHRob3NlIGV4dHJhIGZpZWxkcyB3ZSBkb24ndCB3YW50IHRvIGRlYWwKKyAqIHdpdGguCisgKgorICogPHA+QXNzdW1lcyBsb2NhbCBmaWxlIGRhdGEgYW5kIGNlbnRyYWwgZGlyZWN0b3J5IGVudHJpZXMgYXJlCisgKiBpZGVudGljYWwgLSB1bmxlc3MgdG9sZCB0aGUgb3Bwb3NpdGUuPC9wPgorICogQE5vdFRocmVhZFNhZmUKKyAqLworcHVibGljIGNsYXNzIFVucmVjb2duaXplZEV4dHJhRmllbGQgaW1wbGVtZW50cyBaaXBFeHRyYUZpZWxkIHsKKworICAgIC8qKgorICAgICAqIFRoZSBIZWFkZXItSUQuCisgICAgICovCisgICAgcHJpdmF0ZSBaaXBTaG9ydCBoZWFkZXJJZDsKKworICAgIC8qKgorICAgICAqIFNldCB0aGUgaGVhZGVyIGlkLgorICAgICAqIEBwYXJhbSBoZWFkZXJJZCB0aGUgaGVhZGVyIGlkIHRvIHVzZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEhlYWRlcklkKGZpbmFsIFppcFNob3J0IGhlYWRlcklkKSB7CisgICAgICAgIHRoaXMuaGVhZGVySWQgPSBoZWFkZXJJZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIGhlYWRlciBpZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBoZWFkZXIgaWQKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgWmlwU2hvcnQgZ2V0SGVhZGVySWQoKSB7CisgICAgICAgIHJldHVybiBoZWFkZXJJZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFeHRyYSBmaWVsZCBkYXRhIGluIGxvY2FsIGZpbGUgZGF0YSAtIHdpdGhvdXQKKyAgICAgKiBIZWFkZXItSUQgb3IgbGVuZ3RoIHNwZWNpZmllci4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJ5dGVbXSBsb2NhbERhdGE7CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIGV4dHJhIGZpZWxkIGRhdGEgaW4gdGhlIGxvY2FsIGZpbGUgZGF0YSAtCisgICAgICogd2l0aG91dCBIZWFkZXItSUQgb3IgbGVuZ3RoIHNwZWNpZmllci4KKyAgICAgKiBAcGFyYW0gZGF0YSB0aGUgZmllbGQgZGF0YSB0byB1c2UKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRMb2NhbEZpbGVEYXRhRGF0YShmaW5hbCBieXRlW10gZGF0YSkgeworICAgICAgICBsb2NhbERhdGEgPSBaaXBVdGlsLmNvcHkoZGF0YSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBsZW5ndGggb2YgdGhlIGxvY2FsIGRhdGEuCisgICAgICogQHJldHVybiB0aGUgbGVuZ3RoIG9mIHRoZSBsb2NhbCBkYXRhCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFppcFNob3J0IGdldExvY2FsRmlsZURhdGFMZW5ndGgoKSB7CisgICAgICAgIHJldHVybiBuZXcgWmlwU2hvcnQobG9jYWxEYXRhICE9IG51bGwgPyBsb2NhbERhdGEubGVuZ3RoIDogMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBsb2NhbCBkYXRhLgorICAgICAqIEByZXR1cm4gdGhlIGxvY2FsIGRhdGEKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYnl0ZVtdIGdldExvY2FsRmlsZURhdGFEYXRhKCkgeworICAgICAgICByZXR1cm4gWmlwVXRpbC5jb3B5KGxvY2FsRGF0YSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRXh0cmEgZmllbGQgZGF0YSBpbiBjZW50cmFsIGRpcmVjdG9yeSAtIHdpdGhvdXQKKyAgICAgKiBIZWFkZXItSUQgb3IgbGVuZ3RoIHNwZWNpZmllci4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJ5dGVbXSBjZW50cmFsRGF0YTsKKworICAgIC8qKgorICAgICAqIFNldCB0aGUgZXh0cmEgZmllbGQgZGF0YSBpbiBjZW50cmFsIGRpcmVjdG9yeS4KKyAgICAgKiBAcGFyYW0gZGF0YSB0aGUgZGF0YSB0byB1c2UKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRDZW50cmFsRGlyZWN0b3J5RGF0YShmaW5hbCBieXRlW10gZGF0YSkgeworICAgICAgICBjZW50cmFsRGF0YSA9IFppcFV0aWwuY29weShkYXRhKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIGNlbnRyYWwgZGF0YSBsZW5ndGguCisgICAgICogSWYgdGhlcmUgaXMgbm8gY2VudHJhbCBkYXRhLCBnZXQgdGhlIGxvY2FsIGZpbGUgZGF0YSBsZW5ndGguCisgICAgICogQHJldHVybiB0aGUgY2VudHJhbCBkYXRhIGxlbmd0aAorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBaaXBTaG9ydCBnZXRDZW50cmFsRGlyZWN0b3J5TGVuZ3RoKCkgeworICAgICAgICBpZiAoY2VudHJhbERhdGEgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBaaXBTaG9ydChjZW50cmFsRGF0YS5sZW5ndGgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBnZXRMb2NhbEZpbGVEYXRhTGVuZ3RoKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBjZW50cmFsIGRhdGEuCisgICAgICogQHJldHVybiB0aGUgY2VudHJhbCBkYXRhIGlmIHByZXNlbnQsIGVsc2UgcmV0dXJuIHRoZSBsb2NhbCBmaWxlIGRhdGEKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYnl0ZVtdIGdldENlbnRyYWxEaXJlY3RvcnlEYXRhKCkgeworICAgICAgICBpZiAoY2VudHJhbERhdGEgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIFppcFV0aWwuY29weShjZW50cmFsRGF0YSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGdldExvY2FsRmlsZURhdGFEYXRhKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHBhcmFtIGRhdGEgdGhlIGFycmF5IG9mIGJ5dGVzLgorICAgICAqIEBwYXJhbSBvZmZzZXQgdGhlIHNvdXJjZSBsb2NhdGlvbiBpbiB0aGUgZGF0YSBhcnJheS4KKyAgICAgKiBAcGFyYW0gbGVuZ3RoIHRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gdXNlIGluIHRoZSBkYXRhIGFycmF5LgorICAgICAqIEBzZWUgWmlwRXh0cmFGaWVsZCNwYXJzZUZyb21Mb2NhbEZpbGVEYXRhKGJ5dGVbXSwgaW50LCBpbnQpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcGFyc2VGcm9tTG9jYWxGaWxlRGF0YShmaW5hbCBieXRlW10gZGF0YSwgZmluYWwgaW50IG9mZnNldCwgZmluYWwgaW50IGxlbmd0aCkgeworICAgICAgICBmaW5hbCBieXRlW10gdG1wID0gbmV3IGJ5dGVbbGVuZ3RoXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShkYXRhLCBvZmZzZXQsIHRtcCwgMCwgbGVuZ3RoKTsKKyAgICAgICAgc2V0TG9jYWxGaWxlRGF0YURhdGEodG1wKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcGFyYW0gZGF0YSB0aGUgYXJyYXkgb2YgYnl0ZXMuCisgICAgICogQHBhcmFtIG9mZnNldCB0aGUgc291cmNlIGxvY2F0aW9uIGluIHRoZSBkYXRhIGFycmF5LgorICAgICAqIEBwYXJhbSBsZW5ndGggdGhlIG51bWJlciBvZiBieXRlcyB0byB1c2UgaW4gdGhlIGRhdGEgYXJyYXkuCisgICAgICogQHNlZSBaaXBFeHRyYUZpZWxkI3BhcnNlRnJvbUNlbnRyYWxEaXJlY3RvcnlEYXRhKGJ5dGVbXSwgaW50LCBpbnQpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcGFyc2VGcm9tQ2VudHJhbERpcmVjdG9yeURhdGEoZmluYWwgYnl0ZVtdIGRhdGEsIGZpbmFsIGludCBvZmZzZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGxlbmd0aCkgeworICAgICAgICBmaW5hbCBieXRlW10gdG1wID0gbmV3IGJ5dGVbbGVuZ3RoXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShkYXRhLCBvZmZzZXQsIHRtcCwgMCwgbGVuZ3RoKTsKKyAgICAgICAgc2V0Q2VudHJhbERpcmVjdG9yeURhdGEodG1wKTsKKyAgICAgICAgaWYgKGxvY2FsRGF0YSA9PSBudWxsKSB7CisgICAgICAgICAgICBzZXRMb2NhbEZpbGVEYXRhRGF0YSh0bXApOworICAgICAgICB9CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1Vuc2hyaW5raW5nSW5wdXRTdHJlYW0uamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvVW5zaHJpbmtpbmdJbnB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjExYzkwNGMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1Vuc2hyaW5raW5nSW5wdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDEyNyBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEubmlvLkJ5dGVPcmRlcjsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5sencuTFpXSW5wdXRTdHJlYW07CisKKy8qKgorICogSW5wdXQgc3RyZWFtIHRoYXQgZGVjb21wcmVzc2VzIFpJUCBtZXRob2QgMSAodW5zaHJpbmtpbmcpLiBBIHZhcmlhdGlvbiBvZiB0aGUgTFpXIGFsZ29yaXRobSwgd2l0aCBzb21lIHR3aXN0cy4KKyAqIEBOb3RUaHJlYWRTYWZlCisgKiBAc2luY2UgMS43CisgKi8KK2NsYXNzIFVuc2hyaW5raW5nSW5wdXRTdHJlYW0gZXh0ZW5kcyBMWldJbnB1dFN0cmVhbSB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE1BWF9DT0RFX1NJWkUgPSAxMzsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTUFYX1RBQkxFX1NJWkUgPSAxIDw8IE1BWF9DT0RFX1NJWkU7CisgICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuW10gaXNVc2VkOworCisgICAgLyoqCisgICAgICogSU9FeGNlcHRpb24gaXMgbm90IGFjdHVhbGx5IHRocm93biEKKyAgICAgKgorICAgICAqIEBwYXJhbSBpbnB1dFN0cmVhbQorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gSU9FeGNlcHRpb24gaXMgbm90IGFjdHVhbGx5IHRocm93biEKKyAgICAgKi8KKyAgICBwdWJsaWMgVW5zaHJpbmtpbmdJbnB1dFN0cmVhbShmaW5hbCBJbnB1dFN0cmVhbSBpbnB1dFN0cmVhbSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIoaW5wdXRTdHJlYW0sIEJ5dGVPcmRlci5MSVRUTEVfRU5ESUFOKTsKKyAgICAgICAgc2V0Q2xlYXJDb2RlKERFRkFVTFRfQ09ERV9TSVpFKTsKKyAgICAgICAgaW5pdGlhbGl6ZVRhYmxlcyhNQVhfQ09ERV9TSVpFKTsKKyAgICAgICAgaXNVc2VkID0gbmV3IGJvb2xlYW5bZ2V0UHJlZml4ZXNMZW5ndGgoKV07CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgKDEgPDwgOCk7IGkrKykgeworICAgICAgICAgICAgaXNVc2VkW2ldID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBzZXRUYWJsZVNpemUoZ2V0Q2xlYXJDb2RlKCkgKyAxKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgaW50IGFkZEVudHJ5KGZpbmFsIGludCBwcmV2aW91c0NvZGUsIGZpbmFsIGJ5dGUgY2hhcmFjdGVyKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgdGFibGVTaXplID0gZ2V0VGFibGVTaXplKCk7CisgICAgICAgIHdoaWxlICgodGFibGVTaXplIDwgTUFYX1RBQkxFX1NJWkUpICYmIGlzVXNlZFt0YWJsZVNpemVdKSB7CisgICAgICAgICAgICB0YWJsZVNpemUrKzsKKyAgICAgICAgfQorICAgICAgICBzZXRUYWJsZVNpemUodGFibGVTaXplKTsKKyAgICAgICAgZmluYWwgaW50IGlkeCA9IGFkZEVudHJ5KHByZXZpb3VzQ29kZSwgY2hhcmFjdGVyLCBNQVhfVEFCTEVfU0laRSk7CisgICAgICAgIGlmIChpZHggPj0gMCkgeworICAgICAgICAgICAgaXNVc2VkW2lkeF0gPSB0cnVlOworICAgICAgICB9CisgICAgICAgIHJldHVybiBpZHg7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHBhcnRpYWxDbGVhcigpIHsKKyAgICAgICAgZmluYWwgYm9vbGVhbltdIGlzUGFyZW50ID0gbmV3IGJvb2xlYW5bTUFYX1RBQkxFX1NJWkVdOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGlzVXNlZC5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgaWYgKGlzVXNlZFtpXSAmJiBnZXRQcmVmaXgoaSkgIT0gVU5VU0VEX1BSRUZJWCkgeworICAgICAgICAgICAgICAgIGlzUGFyZW50W2dldFByZWZpeChpKV0gPSB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSBnZXRDbGVhckNvZGUoKSArIDE7IGkgPCBpc1BhcmVudC5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgaWYgKCFpc1BhcmVudFtpXSkgeworICAgICAgICAgICAgICAgIGlzVXNlZFtpXSA9IGZhbHNlOworICAgICAgICAgICAgICAgIHNldFByZWZpeChpLCBVTlVTRURfUFJFRklYKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBpbnQgZGVjb21wcmVzc05leHRTeW1ib2woKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLworICAgICAgICAvLyAgICAgICAgICAgICAgICAgICB0YWJsZSBlbnRyeSAgICB0YWJsZSBlbnRyeQorICAgICAgICAvLyAgICAgICAgICAgICAgICAgIF9fX19fX19fX19fX18gICBfX19fXworICAgICAgICAvLyAgICB0YWJsZSBlbnRyeSAgLyAgICAgICAgICAgICBcIC8gICAgIFwKKyAgICAgICAgLy8gICAgX19fX19fX19fX19fLyAgICAgICAgICAgICAgIFwgICAgICAgXAorICAgICAgICAvLyAgIC8gICAgICAgICAgIC8gXCAgICAgICAgICAgICAvIFwgICAgICAgXAorICAgICAgICAvLyAgKy0tLSstLS0rLS0tKy0tLSstLS0rLS0tKy0tLSstLS0rLS0tKy0tLSsKKyAgICAgICAgLy8gIHwgLiB8IC4gfCAuIHwgLiB8IC4gfCAuIHwgLiB8IC4gfCAuIHwgLiB8CisgICAgICAgIC8vICArLS0tKy0tLSstLS0rLS0tKy0tLSstLS0rLS0tKy0tLSstLS0rLS0tKworICAgICAgICAvLyAgfDwtLS0tLS0tLS0+fDwtLS0tLS0tLS0tLS0tPnw8LS0tLS0+fDwtPnwKKyAgICAgICAgLy8gICAgIHN5bWJvbCAgICAgICAgc3ltYm9sICAgICAgc3ltYm9sICBzeW1ib2wKKyAgICAgICAgLy8KKyAgICAgICAgZmluYWwgaW50IGNvZGUgPSByZWFkTmV4dENvZGUoKTsKKyAgICAgICAgaWYgKGNvZGUgPCAwKSB7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0gZWxzZSBpZiAoY29kZSA9PSBnZXRDbGVhckNvZGUoKSkgeworICAgICAgICAgICAgZmluYWwgaW50IHN1YkNvZGUgPSByZWFkTmV4dENvZGUoKTsKKyAgICAgICAgICAgIGlmIChzdWJDb2RlIDwgMCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiVW5leHBlY3RlZCBFT0Y7Iik7CisgICAgICAgICAgICB9IGVsc2UgaWYgKHN1YkNvZGUgPT0gMSkgeworICAgICAgICAgICAgICAgIGlmIChnZXRDb2RlU2l6ZSgpIDwgTUFYX0NPREVfU0laRSkgeworICAgICAgICAgICAgICAgICAgICBpbmNyZW1lbnRDb2RlU2l6ZSgpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiQXR0ZW1wdCB0byBpbmNyZWFzZSBjb2RlIHNpemUgYmV5b25kIG1heGltdW0iKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgaWYgKHN1YkNvZGUgPT0gMikgeworICAgICAgICAgICAgICAgIHBhcnRpYWxDbGVhcigpOworICAgICAgICAgICAgICAgIHNldFRhYmxlU2l6ZShnZXRDbGVhckNvZGUoKSArIDEpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkludmFsaWQgY2xlYXIgY29kZSBzdWJjb2RlICIgKyBzdWJDb2RlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgYm9vbGVhbiBhZGRlZFVuZmluaXNoZWRFbnRyeSA9IGZhbHNlOworICAgICAgICAgICAgaW50IGVmZmVjdGl2ZUNvZGUgPSBjb2RlOworICAgICAgICAgICAgaWYgKCFpc1VzZWRbY29kZV0pIHsKKyAgICAgICAgICAgICAgICBlZmZlY3RpdmVDb2RlID0gYWRkUmVwZWF0T2ZQcmV2aW91c0NvZGUoKTsKKyAgICAgICAgICAgICAgICBhZGRlZFVuZmluaXNoZWRFbnRyeSA9IHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gZXhwYW5kQ29kZVRvT3V0cHV0U3RhY2soZWZmZWN0aXZlQ29kZSwgYWRkZWRVbmZpbmlzaGVkRW50cnkpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9VbnN1cHBvcnRlZFppcEZlYXR1cmVFeGNlcHRpb24uamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvVW5zdXBwb3J0ZWRaaXBGZWF0dXJlRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTkyZjljNwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvVW5zdXBwb3J0ZWRaaXBGZWF0dXJlRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSwxMzQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcDsKKworaW1wb3J0IGphdmEudXRpbC56aXAuWmlwRXhjZXB0aW9uOworCisvKioKKyAqIEV4Y2VwdGlvbiB0aHJvd24gd2hlbiBhdHRlbXB0aW5nIHRvIHJlYWQgb3Igd3JpdGUgZGF0YSBmb3IgYSB6aXAKKyAqIGVudHJ5IHRoYXQgdXNlcyBaSVAgZmVhdHVyZXMgbm90IHN1cHBvcnRlZCBieSB0aGlzIGxpYnJhcnkuCisgKiBAc2luY2UgMS4xCisgKi8KK3B1YmxpYyBjbGFzcyBVbnN1cHBvcnRlZFppcEZlYXR1cmVFeGNlcHRpb24gZXh0ZW5kcyBaaXBFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBmaW5hbCBGZWF0dXJlIHJlYXNvbjsKKyAgICBwcml2YXRlIHRyYW5zaWVudCBmaW5hbCBaaXBBcmNoaXZlRW50cnkgZW50cnk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMjAxNjEyMTlMOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBleGNlcHRpb24uCisgICAgICogQHBhcmFtIHJlYXNvbiB0aGUgZmVhdHVyZSB0aGF0IGlzIG5vdCBzdXBwb3J0ZWQKKyAgICAgKiBAcGFyYW0gZW50cnkgdGhlIGVudHJ5IHVzaW5nIHRoZSBmZWF0dXJlCisgICAgICovCisgICAgcHVibGljIFVuc3VwcG9ydGVkWmlwRmVhdHVyZUV4Y2VwdGlvbihmaW5hbCBGZWF0dXJlIHJlYXNvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIFppcEFyY2hpdmVFbnRyeSBlbnRyeSkgeworICAgICAgICBzdXBlcigidW5zdXBwb3J0ZWQgZmVhdHVyZSAiICsgcmVhc29uICsgICIgdXNlZCBpbiBlbnRyeSAiCisgICAgICAgICAgICAgICsgZW50cnkuZ2V0TmFtZSgpKTsKKyAgICAgICAgdGhpcy5yZWFzb24gPSByZWFzb247CisgICAgICAgIHRoaXMuZW50cnkgPSBlbnRyeTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIGV4Y2VwdGlvbiBmb3IgYXJjaGl2ZXMgdGhhdCB1c2UgYW4gdW5zdXBwb3J0ZWQKKyAgICAgKiBjb21wcmVzc2lvbiBhbGdvcml0aG0uCisgICAgICogQHBhcmFtIG1ldGhvZCB0aGUgbWV0aG9kIHRoYXQgaXMgbm90IHN1cHBvcnRlZAorICAgICAqIEBwYXJhbSBlbnRyeSB0aGUgZW50cnkgdXNpbmcgdGhlIGZlYXR1cmUKKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIFVuc3VwcG9ydGVkWmlwRmVhdHVyZUV4Y2VwdGlvbihmaW5hbCBaaXBNZXRob2QgbWV0aG9kLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgWmlwQXJjaGl2ZUVudHJ5IGVudHJ5KSB7CisgICAgICAgIHN1cGVyKCJ1bnN1cHBvcnRlZCBmZWF0dXJlIG1ldGhvZCAnIiArIG1ldGhvZC5uYW1lKCkKKyAgICAgICAgICAgICAgKyAgIicgdXNlZCBpbiBlbnRyeSAiICsgZW50cnkuZ2V0TmFtZSgpKTsKKyAgICAgICAgdGhpcy5yZWFzb24gPSBGZWF0dXJlLk1FVEhPRDsKKyAgICAgICAgdGhpcy5lbnRyeSA9IGVudHJ5OworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gZXhjZXB0aW9uIHdoZW4gdGhlIHdob2xlIGFyY2hpdmUgdXNlcyBhbiB1bnN1cHBvcnRlZAorICAgICAqIGZlYXR1cmUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVhc29uIHRoZSBmZWF0dXJlIHRoYXQgaXMgbm90IHN1cHBvcnRlZAorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgVW5zdXBwb3J0ZWRaaXBGZWF0dXJlRXhjZXB0aW9uKGZpbmFsIEZlYXR1cmUgcmVhc29uKSB7CisgICAgICAgIHN1cGVyKCJ1bnN1cHBvcnRlZCBmZWF0dXJlICIgKyByZWFzb24gKyAgIiB1c2VkIGluIGFyY2hpdmUuIik7CisgICAgICAgIHRoaXMucmVhc29uID0gcmVhc29uOworICAgICAgICB0aGlzLmVudHJ5ID0gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgdW5zdXBwb3J0ZWQgZmVhdHVyZSB0aGF0IGhhcyBiZWVuIHVzZWQuCisgICAgICogQHJldHVybiBUaGUgdW5zdXBwb3J0ZWQgZmVhdHVyZSB0aGF0IGhhcyBiZWVuIHVzZWQuCisgICAgICovCisgICAgcHVibGljIEZlYXR1cmUgZ2V0RmVhdHVyZSgpIHsKKyAgICAgICAgcmV0dXJuIHJlYXNvbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgZW50cnkgdXNpbmcgdGhlIHVuc3VwcG9ydGVkIGZlYXR1cmUuCisgICAgICogQHJldHVybiBUaGUgZW50cnkgdXNpbmcgdGhlIHVuc3VwcG9ydGVkIGZlYXR1cmUuCisgICAgICovCisgICAgcHVibGljIFppcEFyY2hpdmVFbnRyeSBnZXRFbnRyeSgpIHsKKyAgICAgICAgcmV0dXJuIGVudHJ5OworICAgIH0KKworICAgIC8qKgorICAgICAqIFpJUCBGZWF0dXJlcyB0aGF0IG1heSBvciBtYXkgbm90IGJlIHN1cHBvcnRlZC4KKyAgICAgKiBAc2luY2UgMS4xCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBGZWF0dXJlIGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworCisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDQxMTI1ODI5NDg3NzU0MjAzNTlMOworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIGVudHJ5IGlzIGVuY3J5cHRlZC4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRmVhdHVyZSBFTkNSWVBUSU9OID0gbmV3IEZlYXR1cmUoImVuY3J5cHRpb24iKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBlbnRyeSB1c2VkIGFuIHVuc3VwcG9ydGVkIGNvbXByZXNzaW9uIG1ldGhvZC4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRmVhdHVyZSBNRVRIT0QgPSBuZXcgRmVhdHVyZSgiY29tcHJlc3Npb24gbWV0aG9kIik7CisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgZW50cnkgdXNlcyBhIGRhdGEgZGVzY3JpcHRvci4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRmVhdHVyZSBEQVRBX0RFU0NSSVBUT1IgPSBuZXcgRmVhdHVyZSgiZGF0YSBkZXNjcmlwdG9yIik7CisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgYXJjaGl2ZSB1c2VzIHNwbGl0dGluZyBvciBzcGFubmluZy4KKyAgICAgICAgICogQHNpbmNlIDEuNQorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBGZWF0dXJlIFNQTElUVElORyA9IG5ldyBGZWF0dXJlKCJzcGxpdHRpbmciKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBhcmNoaXZlIGNvbnRhaW5zIGVudHJpZXMgd2l0aCB1bmtub3duIGNvbXByZXNzZWQgc2l6ZQorICAgICAgICAgKiBmb3IgYSBjb21wcmVzc2lvbiBtZXRob2QgdGhhdCBkb2Vzbid0IHN1cHBvcnQgZGV0ZWN0aW9uIG9mCisgICAgICAgICAqIHRoZSBlbmQgb2YgdGhlIGNvbXByZXNzZWQgc3RyZWFtLgorICAgICAgICAgKiBAc2luY2UgMS4xNgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBGZWF0dXJlIFVOS05PV05fQ09NUFJFU1NFRF9TSVpFID0gbmV3IEZlYXR1cmUoInVua25vd24gY29tcHJlc3NlZCBzaXplIik7CisKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgbmFtZTsKKworICAgICAgICBwcml2YXRlIEZlYXR1cmUoZmluYWwgU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgICAgIHJldHVybiBuYW1lOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9YMDAwQV9OVEZTLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1gwMDBBX05URlMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZGQ1YzMzCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9YMDAwQV9OVEZTLmphdmEKQEAgLTAsMCArMSwzOTQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXA7CisKK2ltcG9ydCBqYXZhLnV0aWwuRGF0ZTsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLlppcEV4Y2VwdGlvbjsKKworLyoqCisgKiBOVEZTIGV4dHJhIGZpZWxkIHRoYXQgd2FzIHRob3VnaHQgdG8gc3RvcmUgdmFyaW91cyBhdHRyaWJ1dGVzIGJ1dAorICogaW4gcmVhbGl0eSBvbmx5IHN0b3JlcyB0aW1lc3RhbXBzLgorICoKKyAqIDxwcmU+CisgKiAgICA0LjUuNSAtTlRGUyBFeHRyYSBGaWVsZCAoMHgwMDBhKToKKyAqCisgKiAgICAgICBUaGUgZm9sbG93aW5nIGlzIHRoZSBsYXlvdXQgb2YgdGhlIE5URlMgYXR0cmlidXRlcworICogICAgICAgImV4dHJhIiBibG9jay4gKE5vdGU6IEF0IHRoaXMgdGltZSB0aGUgTXRpbWUsIEF0aW1lCisgKiAgICAgICBhbmQgQ3RpbWUgdmFsdWVzIE1BWSBiZSB1c2VkIG9uIGFueSBXSU4zMiBzeXN0ZW0uKQorICoKKyAqICAgICAgIE5vdGU6IGFsbCBmaWVsZHMgc3RvcmVkIGluIEludGVsIGxvdy1ieXRlL2hpZ2gtYnl0ZSBvcmRlci4KKyAqCisgKiAgICAgICAgIFZhbHVlICAgICAgU2l6ZSAgICAgICBEZXNjcmlwdGlvbgorICogICAgICAgICAtLS0tLSAgICAgIC0tLS0gICAgICAgLS0tLS0tLS0tLS0KKyAqIChOVEZTKSAgMHgwMDBhICAgICAyIGJ5dGVzICAgIFRhZyBmb3IgdGhpcyAiZXh0cmEiIGJsb2NrIHR5cGUKKyAqICAgICAgICAgVFNpemUgICAgICAyIGJ5dGVzICAgIFNpemUgb2YgdGhlIHRvdGFsICJleHRyYSIgYmxvY2sKKyAqICAgICAgICAgUmVzZXJ2ZWQgICA0IGJ5dGVzICAgIFJlc2VydmVkIGZvciBmdXR1cmUgdXNlCisgKiAgICAgICAgIFRhZzEgICAgICAgMiBieXRlcyAgICBOVEZTIGF0dHJpYnV0ZSB0YWcgdmFsdWUgIzEKKyAqICAgICAgICAgU2l6ZTEgICAgICAyIGJ5dGVzICAgIFNpemUgb2YgYXR0cmlidXRlICMxLCBpbiBieXRlcworICogICAgICAgICAodmFyKSAgICAgIFNpemUxICAgICAgQXR0cmlidXRlICMxIGRhdGEKKyAqICAgICAgICAgIC4KKyAqICAgICAgICAgIC4KKyAqICAgICAgICAgIC4KKyAqICAgICAgICAgIFRhZ04gICAgICAgMiBieXRlcyAgICBOVEZTIGF0dHJpYnV0ZSB0YWcgdmFsdWUgI04KKyAqICAgICAgICAgIFNpemVOICAgICAgMiBieXRlcyAgICBTaXplIG9mIGF0dHJpYnV0ZSAjTiwgaW4gYnl0ZXMKKyAqICAgICAgICAgICh2YXIpICAgICAgU2l6ZU4gICAgICBBdHRyaWJ1dGUgI04gZGF0YQorICoKKyAqICAgICAgICBGb3IgTlRGUywgdmFsdWVzIGZvciBUYWcxIHRocm91Z2ggVGFnTiBhcmUgYXMgZm9sbG93czoKKyAqICAgICAgICAoY3VycmVudGx5IG9ubHkgb25lIHNldCBvZiBhdHRyaWJ1dGVzIGlzIGRlZmluZWQgZm9yIE5URlMpCisgKgorICogICAgICAgICAgVGFnICAgICAgICBTaXplICAgICAgIERlc2NyaXB0aW9uCisgKiAgICAgICAgICAtLS0tLSAgICAgIC0tLS0gICAgICAgLS0tLS0tLS0tLS0KKyAqICAgICAgICAgIDB4MDAwMSAgICAgMiBieXRlcyAgICBUYWcgZm9yIGF0dHJpYnV0ZSAjMQorICogICAgICAgICAgU2l6ZTEgICAgICAyIGJ5dGVzICAgIFNpemUgb2YgYXR0cmlidXRlICMxLCBpbiBieXRlcworICogICAgICAgICAgTXRpbWUgICAgICA4IGJ5dGVzICAgIEZpbGUgbGFzdCBtb2RpZmljYXRpb24gdGltZQorICogICAgICAgICAgQXRpbWUgICAgICA4IGJ5dGVzICAgIEZpbGUgbGFzdCBhY2Nlc3MgdGltZQorICogICAgICAgICAgQ3RpbWUgICAgICA4IGJ5dGVzICAgIEZpbGUgY3JlYXRpb24gdGltZQorICogPC9wcmU+CisgKgorICogQHNpbmNlIDEuMTEKKyAqIEBOb3RUaHJlYWRTYWZlCisgKi8KK3B1YmxpYyBjbGFzcyBYMDAwQV9OVEZTIGltcGxlbWVudHMgWmlwRXh0cmFGaWVsZCB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgWmlwU2hvcnQgSEVBREVSX0lEID0gbmV3IFppcFNob3J0KDB4MDAwYSk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgWmlwU2hvcnQgVElNRV9BVFRSX1RBRyA9IG5ldyBaaXBTaG9ydCgweDAwMDEpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFppcFNob3J0IFRJTUVfQVRUUl9TSVpFID0gbmV3IFppcFNob3J0KDMgKiA4KTsKKworICAgIHByaXZhdGUgWmlwRWlnaHRCeXRlSW50ZWdlciBtb2RpZnlUaW1lID0gWmlwRWlnaHRCeXRlSW50ZWdlci5aRVJPOworICAgIHByaXZhdGUgWmlwRWlnaHRCeXRlSW50ZWdlciBhY2Nlc3NUaW1lID0gWmlwRWlnaHRCeXRlSW50ZWdlci5aRVJPOworICAgIHByaXZhdGUgWmlwRWlnaHRCeXRlSW50ZWdlciBjcmVhdGVUaW1lID0gWmlwRWlnaHRCeXRlSW50ZWdlci5aRVJPOworCisgICAgLyoqCisgICAgICogVGhlIEhlYWRlci1JRC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIGZvciB0aGUgaGVhZGVyIGlkIGZvciB0aGlzIGV4dHJhZmllbGQKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgWmlwU2hvcnQgZ2V0SGVhZGVySWQoKSB7CisgICAgICAgIHJldHVybiBIRUFERVJfSUQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogTGVuZ3RoIG9mIHRoZSBleHRyYSBmaWVsZCBpbiB0aGUgbG9jYWwgZmlsZSBkYXRhIC0gd2l0aG91dAorICAgICAqIEhlYWRlci1JRCBvciBsZW5ndGggc3BlY2lmaWVyLgorICAgICAqCisgICAgICogQHJldHVybiBhIDxjb2RlPlppcFNob3J0PC9jb2RlPiBmb3IgdGhlIGxlbmd0aCBvZiB0aGUgZGF0YSBvZiB0aGlzIGV4dHJhIGZpZWxkCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFppcFNob3J0IGdldExvY2FsRmlsZURhdGFMZW5ndGgoKSB7CisgICAgICAgIHJldHVybiBuZXcgWmlwU2hvcnQoNCAvKiByZXNlcnZlZCAqLworICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgMiAvKiBUYWcjMSAqLworICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgMiAvKiBTaXplIzEgKi8KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICArIDMgKiA4IC8qIHRpbWUgdmFsdWVzICovKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMZW5ndGggb2YgdGhlIGV4dHJhIGZpZWxkIGluIHRoZSBsb2NhbCBmaWxlIGRhdGEgLSB3aXRob3V0CisgICAgICogSGVhZGVyLUlEIG9yIGxlbmd0aCBzcGVjaWZpZXIuCisgICAgICoKKyAgICAgKiA8cD5Gb3IgWDU0NTUgdGhlIGNlbnRyYWwgbGVuZ3RoIGlzIG9mdGVuIHNtYWxsZXIgdGhhbiB0aGUKKyAgICAgKiBsb2NhbCBsZW5ndGgsIGJlY2F1c2UgY2VudHJhbCBjYW5ub3QgY29udGFpbiBhY2Nlc3Mgb3IgY3JlYXRlCisgICAgICogdGltZXN0YW1wcy48L3A+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgPGNvZGU+WmlwU2hvcnQ8L2NvZGU+IGZvciB0aGUgbGVuZ3RoIG9mIHRoZSBkYXRhIG9mIHRoaXMgZXh0cmEgZmllbGQKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgWmlwU2hvcnQgZ2V0Q2VudHJhbERpcmVjdG9yeUxlbmd0aCgpIHsKKyAgICAgICAgcmV0dXJuIGdldExvY2FsRmlsZURhdGFMZW5ndGgoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgYWN0dWFsIGRhdGEgdG8gcHV0IGludG8gbG9jYWwgZmlsZSBkYXRhIC0gd2l0aG91dCBIZWFkZXItSUQKKyAgICAgKiBvciBsZW5ndGggc3BlY2lmaWVyLgorICAgICAqCisgICAgICogQHJldHVybiBnZXQgdGhlIGRhdGEKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYnl0ZVtdIGdldExvY2FsRmlsZURhdGFEYXRhKCkgeworICAgICAgICBmaW5hbCBieXRlW10gZGF0YSA9IG5ldyBieXRlW2dldExvY2FsRmlsZURhdGFMZW5ndGgoKS5nZXRWYWx1ZSgpXTsKKyAgICAgICAgaW50IHBvcyA9IDQ7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoVElNRV9BVFRSX1RBRy5nZXRCeXRlcygpLCAwLCBkYXRhLCBwb3MsIDIpOworICAgICAgICBwb3MgKz0gMjsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShUSU1FX0FUVFJfU0laRS5nZXRCeXRlcygpLCAwLCBkYXRhLCBwb3MsIDIpOworICAgICAgICBwb3MgKz0gMjsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShtb2RpZnlUaW1lLmdldEJ5dGVzKCksIDAsIGRhdGEsIHBvcywgOCk7CisgICAgICAgIHBvcyArPSA4OworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGFjY2Vzc1RpbWUuZ2V0Qnl0ZXMoKSwgMCwgZGF0YSwgcG9zLCA4KTsKKyAgICAgICAgcG9zICs9IDg7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoY3JlYXRlVGltZS5nZXRCeXRlcygpLCAwLCBkYXRhLCBwb3MsIDgpOworICAgICAgICByZXR1cm4gZGF0YTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgYWN0dWFsIGRhdGEgdG8gcHV0IGludG8gY2VudHJhbCBkaXJlY3RvcnkgZGF0YSAtIHdpdGhvdXQgSGVhZGVyLUlECisgICAgICogb3IgbGVuZ3RoIHNwZWNpZmllci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGNlbnRyYWwgZGlyZWN0b3J5IGRhdGEKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYnl0ZVtdIGdldENlbnRyYWxEaXJlY3RvcnlEYXRhKCkgeworICAgICAgICByZXR1cm4gZ2V0TG9jYWxGaWxlRGF0YURhdGEoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQb3B1bGF0ZSBkYXRhIGZyb20gdGhpcyBhcnJheSBhcyBpZiBpdCB3YXMgaW4gbG9jYWwgZmlsZSBkYXRhLgorICAgICAqCisgICAgICogQHBhcmFtIGRhdGEgICBhbiBhcnJheSBvZiBieXRlcworICAgICAqIEBwYXJhbSBvZmZzZXQgdGhlIHN0YXJ0IG9mZnNldAorICAgICAqIEBwYXJhbSBsZW5ndGggdGhlIG51bWJlciBvZiBieXRlcyBpbiB0aGUgYXJyYXkgZnJvbSBvZmZzZXQKKyAgICAgKiBAdGhyb3dzIGphdmEudXRpbC56aXAuWmlwRXhjZXB0aW9uIG9uIGVycm9yCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcGFyc2VGcm9tTG9jYWxGaWxlRGF0YSgKKyAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBkYXRhLCBpbnQgb2Zmc2V0LCBmaW5hbCBpbnQgbGVuZ3RoCisgICAgKSB0aHJvd3MgWmlwRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgaW50IGxlbiA9IG9mZnNldCArIGxlbmd0aDsKKworICAgICAgICAvLyBza2lwIHJlc2VydmVkCisgICAgICAgIG9mZnNldCArPSA0OworCisgICAgICAgIHdoaWxlIChvZmZzZXQgKyA0IDw9IGxlbikgeworICAgICAgICAgICAgZmluYWwgWmlwU2hvcnQgdGFnID0gbmV3IFppcFNob3J0KGRhdGEsIG9mZnNldCk7CisgICAgICAgICAgICBvZmZzZXQgKz0gMjsKKyAgICAgICAgICAgIGlmICh0YWcuZXF1YWxzKFRJTUVfQVRUUl9UQUcpKSB7CisgICAgICAgICAgICAgICAgcmVhZFRpbWVBdHRyKGRhdGEsIG9mZnNldCwgbGVuIC0gb2Zmc2V0KTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZpbmFsIFppcFNob3J0IHNpemUgPSBuZXcgWmlwU2hvcnQoZGF0YSwgb2Zmc2V0KTsKKyAgICAgICAgICAgIG9mZnNldCArPSAyICsgc2l6ZS5nZXRWYWx1ZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRG9lc24ndCBkbyBhbnl0aGluZyBzcGVjaWFsIHNpbmNlIHRoaXMgY2xhc3MgYWx3YXlzIHVzZXMgdGhlCisgICAgICogc2FtZSBwYXJzaW5nIGxvZ2ljIGZvciBib3RoIGNlbnRyYWwgZGlyZWN0b3J5IGFuZCBsb2NhbCBmaWxlIGRhdGEuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcGFyc2VGcm9tQ2VudHJhbERpcmVjdG9yeURhdGEoCisgICAgICAgICAgICBmaW5hbCBieXRlW10gYnVmZmVyLCBmaW5hbCBpbnQgb2Zmc2V0LCBmaW5hbCBpbnQgbGVuZ3RoCisgICAgKSB0aHJvd3MgWmlwRXhjZXB0aW9uIHsKKyAgICAgICAgcmVzZXQoKTsKKyAgICAgICAgcGFyc2VGcm9tTG9jYWxGaWxlRGF0YShidWZmZXIsIG9mZnNldCwgbGVuZ3RoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSAiRmlsZSBsYXN0IG1vZGlmaWNhdGlvbiB0aW1lIiBvZiB0aGlzIHppcCBlbnRyeSBhcworICAgICAqIGEgWmlwRWlnaHRCeXRlSW50ZWdlciBvYmplY3QsIG9yIHtAbGluaworICAgICAqIFppcEVpZ2h0Qnl0ZUludGVnZXIjWkVST30gaWYgbm8gc3VjaCB0aW1lc3RhbXAgZXhpc3RzIGluIHRoZQorICAgICAqIHppcCBlbnRyeS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gRmlsZSBsYXN0IG1vZGlmaWNhdGlvbiB0aW1lCisgICAgICovCisgICAgcHVibGljIFppcEVpZ2h0Qnl0ZUludGVnZXIgZ2V0TW9kaWZ5VGltZSgpIHsgcmV0dXJuIG1vZGlmeVRpbWU7IH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlICJGaWxlIGxhc3QgYWNjZXNzIHRpbWUiIG9mIHRoaXMgemlwIGVudHJ5IGFzIGEKKyAgICAgKiBaaXBFaWdodEJ5dGVJbnRlZ2VyIG9iamVjdCwgb3Ige0BsaW5rIFppcEVpZ2h0Qnl0ZUludGVnZXIjWkVST30KKyAgICAgKiBpZiBubyBzdWNoIHRpbWVzdGFtcCBleGlzdHMgaW4gdGhlIHppcCBlbnRyeS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gRmlsZSBsYXN0IGFjY2VzcyB0aW1lCisgICAgICovCisgICAgcHVibGljIFppcEVpZ2h0Qnl0ZUludGVnZXIgZ2V0QWNjZXNzVGltZSgpIHsgcmV0dXJuIGFjY2Vzc1RpbWU7IH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlICJGaWxlIGNyZWF0aW9uIHRpbWUiIG9mIHRoaXMgemlwIGVudHJ5IGFzIGEKKyAgICAgKiBaaXBFaWdodEJ5dGVJbnRlZ2VyIG9iamVjdCwgb3Ige0BsaW5rIFppcEVpZ2h0Qnl0ZUludGVnZXIjWkVST30KKyAgICAgKiBpZiBubyBzdWNoIHRpbWVzdGFtcCBleGlzdHMgaW4gdGhlIHppcCBlbnRyeS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gRmlsZSBjcmVhdGlvbiB0aW1lCisgICAgICovCisgICAgcHVibGljIFppcEVpZ2h0Qnl0ZUludGVnZXIgZ2V0Q3JlYXRlVGltZSgpIHsgcmV0dXJuIGNyZWF0ZVRpbWU7IH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG1vZGlmeSB0aW1lIGFzIGEgamF2YS51dGlsLkRhdGUKKyAgICAgKiBvZiB0aGlzIHppcCBlbnRyeSwgb3IgbnVsbCBpZiBubyBzdWNoIHRpbWVzdGFtcCBleGlzdHMgaW4gdGhlIHppcCBlbnRyeS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gbW9kaWZ5IHRpbWUgYXMgamF2YS51dGlsLkRhdGUgb3IgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGF0ZSBnZXRNb2RpZnlKYXZhVGltZSgpIHsKKyAgICAgICAgcmV0dXJuIHppcFRvRGF0ZShtb2RpZnlUaW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBhY2Nlc3MgdGltZSBhcyBhIGphdmEudXRpbC5EYXRlCisgICAgICogb2YgdGhpcyB6aXAgZW50cnksIG9yIG51bGwgaWYgbm8gc3VjaCB0aW1lc3RhbXAgZXhpc3RzIGluIHRoZSB6aXAgZW50cnkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFjY2VzcyB0aW1lIGFzIGphdmEudXRpbC5EYXRlIG9yIG51bGwuCisgICAgICovCisgICAgcHVibGljIERhdGUgZ2V0QWNjZXNzSmF2YVRpbWUoKSB7CisgICAgICAgIHJldHVybiB6aXBUb0RhdGUoYWNjZXNzVGltZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY3JlYXRlIHRpbWUgYXMgYSBhIGphdmEudXRpbC5EYXRlIG9mIHRoaXMgemlwCisgICAgICogZW50cnksIG9yIG51bGwgaWYgbm8gc3VjaCB0aW1lc3RhbXAgZXhpc3RzIGluIHRoZSB6aXAgZW50cnkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGNyZWF0ZSB0aW1lIGFzIGphdmEudXRpbC5EYXRlIG9yIG51bGwuCisgICAgICovCisgICAgcHVibGljIERhdGUgZ2V0Q3JlYXRlSmF2YVRpbWUoKSB7CisgICAgICAgIHJldHVybiB6aXBUb0RhdGUoY3JlYXRlVGltZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgRmlsZSBsYXN0IG1vZGlmaWNhdGlvbiB0aW1lIG9mIHRoaXMgemlwIGVudHJ5IHVzaW5nIGEKKyAgICAgKiBaaXBFaWdodEJ5dGVJbnRlZ2VyIG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0IFppcEVpZ2h0Qnl0ZUludGVnZXIgb2YgdGhlIG1vZGlmeSB0aW1lCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TW9kaWZ5VGltZShmaW5hbCBaaXBFaWdodEJ5dGVJbnRlZ2VyIHQpIHsKKyAgICAgICAgbW9kaWZ5VGltZSA9IHQgPT0gbnVsbCA/IFppcEVpZ2h0Qnl0ZUludGVnZXIuWkVSTyA6IHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgRmlsZSBsYXN0IGFjY2VzcyB0aW1lIG9mIHRoaXMgemlwIGVudHJ5IHVzaW5nIGEKKyAgICAgKiBaaXBFaWdodEJ5dGVJbnRlZ2VyIG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0IFppcEVpZ2h0Qnl0ZUludGVnZXIgb2YgdGhlIGFjY2VzcyB0aW1lCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0QWNjZXNzVGltZShmaW5hbCBaaXBFaWdodEJ5dGVJbnRlZ2VyIHQpIHsKKyAgICAgICAgYWNjZXNzVGltZSA9IHQgPT0gbnVsbCA/IFppcEVpZ2h0Qnl0ZUludGVnZXIuWkVSTyA6IHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgRmlsZSBjcmVhdGlvbiB0aW1lIG9mIHRoaXMgemlwIGVudHJ5IHVzaW5nIGEKKyAgICAgKiBaaXBFaWdodEJ5dGVJbnRlZ2VyIG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0IFppcEVpZ2h0Qnl0ZUludGVnZXIgb2YgdGhlIGNyZWF0ZSB0aW1lCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Q3JlYXRlVGltZShmaW5hbCBaaXBFaWdodEJ5dGVJbnRlZ2VyIHQpIHsKKyAgICAgICAgY3JlYXRlVGltZSA9IHQgPT0gbnVsbCA/IFppcEVpZ2h0Qnl0ZUludGVnZXIuWkVSTyA6IHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgbW9kaWZ5IHRpbWUgYXMgYSBqYXZhLnV0aWwuRGF0ZSBvZiB0aGlzIHppcCBlbnRyeS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkIG1vZGlmeSB0aW1lIGFzIGphdmEudXRpbC5EYXRlCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TW9kaWZ5SmF2YVRpbWUoZmluYWwgRGF0ZSBkKSB7IHNldE1vZGlmeVRpbWUoZGF0ZVRvWmlwKGQpKTsgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgYWNjZXNzIHRpbWUgYXMgYSBqYXZhLnV0aWwuRGF0ZQorICAgICAqIG9mIHRoaXMgemlwIGVudHJ5LgorICAgICAqCisgICAgICogQHBhcmFtIGQgYWNjZXNzIHRpbWUgYXMgamF2YS51dGlsLkRhdGUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRBY2Nlc3NKYXZhVGltZShmaW5hbCBEYXRlIGQpIHsgc2V0QWNjZXNzVGltZShkYXRlVG9aaXAoZCkpOyB9CisKKyAgICAvKioKKyAgICAgKiA8cD4KKyAgICAgKiBTZXRzIHRoZSBjcmVhdGUgdGltZSBhcyBhIGphdmEudXRpbC5EYXRlCisgICAgICogb2YgdGhpcyB6aXAgZW50cnkuICBTdXBwbGllZCB2YWx1ZSBpcyB0cnVuY2F0ZWQgdG8gcGVyLXNlY29uZAorICAgICAqIHByZWNpc2lvbiAobWlsbGlzZWNvbmRzIHplcm9lZC1vdXQpLgorICAgICAqIDwvcD48cD4KKyAgICAgKiBOb3RlOiB0aGUgc2V0dGVycyBmb3IgZmxhZ3MgYW5kIHRpbWVzdGFtcHMgYXJlIGRlY291cGxlZC4KKyAgICAgKiBFdmVuIGlmIHRoZSB0aW1lc3RhbXAgaXMgbm90LW51bGwsIGl0IHdpbGwgb25seSBiZSB3cml0dGVuCisgICAgICogb3V0IGlmIHRoZSBjb3JyZXNwb25kaW5nIGJpdCBpbiB0aGUgZmxhZ3MgaXMgYWxzbyBzZXQuCisgICAgICogPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGQgY3JlYXRlIHRpbWUgYXMgamF2YS51dGlsLkRhdGUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRDcmVhdGVKYXZhVGltZShmaW5hbCBEYXRlIGQpIHsgc2V0Q3JlYXRlVGltZShkYXRlVG9aaXAoZCkpOyB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgU3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgY2xhc3MgdXNlZnVsIGZvcgorICAgICAqIGRlYnVnZ2luZyBwdXJwb3Nlcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gQSBTdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBjbGFzcyB1c2VmdWwgZm9yCisgICAgICogICAgICAgICBkZWJ1Z2dpbmcgcHVycG9zZXMuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgZmluYWwgU3RyaW5nQnVpbGRlciBidWYgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICBidWYuYXBwZW5kKCIweDAwMEEgWmlwIEV4dHJhIEZpZWxkOiIpCisgICAgICAgICAgICAuYXBwZW5kKCIgTW9kaWZ5OlsiKS5hcHBlbmQoZ2V0TW9kaWZ5SmF2YVRpbWUoKSkuYXBwZW5kKCJdICIpCisgICAgICAgICAgICAuYXBwZW5kKCIgQWNjZXNzOlsiKS5hcHBlbmQoZ2V0QWNjZXNzSmF2YVRpbWUoKSkuYXBwZW5kKCJdICIpCisgICAgICAgICAgICAuYXBwZW5kKCIgQ3JlYXRlOlsiKS5hcHBlbmQoZ2V0Q3JlYXRlSmF2YVRpbWUoKSkuYXBwZW5kKCJdICIpOworICAgICAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIE9iamVjdCBvKSB7CisgICAgICAgIGlmIChvIGluc3RhbmNlb2YgWDAwMEFfTlRGUykgeworICAgICAgICAgICAgZmluYWwgWDAwMEFfTlRGUyB4ZiA9IChYMDAwQV9OVEZTKSBvOworCisgICAgICAgICAgICByZXR1cm4gKG1vZGlmeVRpbWUgPT0geGYubW9kaWZ5VGltZSB8fCAobW9kaWZ5VGltZSAhPSBudWxsICYmIG1vZGlmeVRpbWUuZXF1YWxzKHhmLm1vZGlmeVRpbWUpKSkgJiYKKyAgICAgICAgICAgICAgICAgICAgKGFjY2Vzc1RpbWUgPT0geGYuYWNjZXNzVGltZSB8fCAoYWNjZXNzVGltZSAhPSBudWxsICYmIGFjY2Vzc1RpbWUuZXF1YWxzKHhmLmFjY2Vzc1RpbWUpKSkgJiYKKyAgICAgICAgICAgICAgICAgICAgKGNyZWF0ZVRpbWUgPT0geGYuY3JlYXRlVGltZSB8fCAoY3JlYXRlVGltZSAhPSBudWxsICYmIGNyZWF0ZVRpbWUuZXF1YWxzKHhmLmNyZWF0ZVRpbWUpKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIGludCBoYyA9IC0xMjM7CisgICAgICAgIGlmIChtb2RpZnlUaW1lICE9IG51bGwpIHsKKyAgICAgICAgICAgIGhjIF49IG1vZGlmeVRpbWUuaGFzaENvZGUoKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoYWNjZXNzVGltZSAhPSBudWxsKSB7CisgICAgICAgICAgICAvLyBTaW5jZSBhY2Nlc3NUaW1lIGlzIG9mdGVuIHNhbWUgYXMgbW9kaWZ5VGltZSwKKyAgICAgICAgICAgIC8vIHRoaXMgcHJldmVudHMgdGhlbSBmcm9tIFhPUiBuZWdhdGluZyBlYWNoIG90aGVyLgorICAgICAgICAgICAgaGMgXj0gSW50ZWdlci5yb3RhdGVMZWZ0KGFjY2Vzc1RpbWUuaGFzaENvZGUoKSwgMTEpOworICAgICAgICB9CisgICAgICAgIGlmIChjcmVhdGVUaW1lICE9IG51bGwpIHsKKyAgICAgICAgICAgIGhjIF49IEludGVnZXIucm90YXRlTGVmdChjcmVhdGVUaW1lLmhhc2hDb2RlKCksIDIyKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaGM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVzZXQgc3RhdGUgYmFjayB0byBuZXdseSBjb25zdHJ1Y3RlZCBzdGF0ZS4gIEhlbHBzIHVzIG1ha2Ugc3VyZQorICAgICAqIHBhcnNlKCkgY2FsbHMgYWx3YXlzIGdlbmVyYXRlIGNsZWFuIHJlc3VsdHMuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHJlc2V0KCkgeworICAgICAgICB0aGlzLm1vZGlmeVRpbWUgPSBaaXBFaWdodEJ5dGVJbnRlZ2VyLlpFUk87CisgICAgICAgIHRoaXMuYWNjZXNzVGltZSA9IFppcEVpZ2h0Qnl0ZUludGVnZXIuWkVSTzsKKyAgICAgICAgdGhpcy5jcmVhdGVUaW1lID0gWmlwRWlnaHRCeXRlSW50ZWdlci5aRVJPOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByZWFkVGltZUF0dHIoZmluYWwgYnl0ZVtdIGRhdGEsIGludCBvZmZzZXQsIGZpbmFsIGludCBsZW5ndGgpIHsKKyAgICAgICAgaWYgKGxlbmd0aCA+PSAyICsgMyAqIDgpIHsKKyAgICAgICAgICAgIGZpbmFsIFppcFNob3J0IHRhZ1ZhbHVlTGVuZ3RoID0gbmV3IFppcFNob3J0KGRhdGEsIG9mZnNldCk7CisgICAgICAgICAgICBpZiAoVElNRV9BVFRSX1NJWkUuZXF1YWxzKHRhZ1ZhbHVlTGVuZ3RoKSkgeworICAgICAgICAgICAgICAgIG9mZnNldCArPSAyOworICAgICAgICAgICAgICAgIG1vZGlmeVRpbWUgPSBuZXcgWmlwRWlnaHRCeXRlSW50ZWdlcihkYXRhLCBvZmZzZXQpOworICAgICAgICAgICAgICAgIG9mZnNldCArPSA4OworICAgICAgICAgICAgICAgIGFjY2Vzc1RpbWUgPSBuZXcgWmlwRWlnaHRCeXRlSW50ZWdlcihkYXRhLCBvZmZzZXQpOworICAgICAgICAgICAgICAgIG9mZnNldCArPSA4OworICAgICAgICAgICAgICAgIGNyZWF0ZVRpbWUgPSBuZXcgWmlwRWlnaHRCeXRlSW50ZWdlcihkYXRhLCBvZmZzZXQpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLy8gaHR0cHM6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS93aW5kb3dzL2Rlc2t0b3AvbXM3MjQyOTAlMjh2PXZzLjg1JTI5LmFzcHgKKyAgICAvLyBBIGZpbGUgdGltZSBpcyBhIDY0LWJpdCB2YWx1ZSB0aGF0IHJlcHJlc2VudHMgdGhlIG51bWJlciBvZgorICAgIC8vIDEwMC1uYW5vc2Vjb25kIGludGVydmFscyB0aGF0IGhhdmUgZWxhcHNlZCBzaW5jZSAxMjowMAorICAgIC8vIEEuTS4gSmFudWFyeSAxLCAxNjAxIENvb3JkaW5hdGVkIFVuaXZlcnNhbCBUaW1lIChVVEMpLgorICAgIC8vIHRoaXMgaXMgdGhlIG9mZnNldCBvZiBXaW5kb3dzIHRpbWUgMCB0byBVbml4IGVwb2NoIGluIDEwMC1uYW5vc2Vjb25kIGludGVydmFscworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgRVBPQ0hfT0ZGU0VUID0gLTExNjQ0NDczNjAwMDAwMDAwMEw7CisKKyAgICBwcml2YXRlIHN0YXRpYyBaaXBFaWdodEJ5dGVJbnRlZ2VyIGRhdGVUb1ppcChmaW5hbCBEYXRlIGQpIHsKKyAgICAgICAgaWYgKGQgPT0gbnVsbCkgeyByZXR1cm4gbnVsbDsgfQorICAgICAgICByZXR1cm4gbmV3IFppcEVpZ2h0Qnl0ZUludGVnZXIoKGQuZ2V0VGltZSgpICogMTAwMDBMKSAtIEVQT0NIX09GRlNFVCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgRGF0ZSB6aXBUb0RhdGUoZmluYWwgWmlwRWlnaHRCeXRlSW50ZWdlciB6KSB7CisgICAgICAgIGlmICh6ID09IG51bGwgfHwgWmlwRWlnaHRCeXRlSW50ZWdlci5aRVJPLmVxdWFscyh6KSkgeyByZXR1cm4gbnVsbDsgfQorICAgICAgICBmaW5hbCBsb25nIGwgPSAoei5nZXRMb25nVmFsdWUoKSArIEVQT0NIX09GRlNFVCkgLyAxMDAwMEw7CisgICAgICAgIHJldHVybiBuZXcgRGF0ZShsKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvWDAwMTRfWDUwOUNlcnRpZmljYXRlcy5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9YMDAxNF9YNTA5Q2VydGlmaWNhdGVzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2JlNzg2MwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvWDAwMTRfWDUwOUNlcnRpZmljYXRlcy5qYXZhCkBAIC0wLDAgKzEsNDkgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcDsKKworLyoqCisgKiBQS0NTIzcgU3RvcmUgZm9yIFguNTA5IENlcnRpZmljYXRlcyAoMHgwMDE0KS4KKyAqCisgKiA8cD5UaGlzIGZpZWxkIE1VU1QgY29udGFpbiBpbmZvcm1hdGlvbiBhYm91dCBlYWNoIG9mIHRoZSBjZXJ0aWZpY2F0ZXMgZmlsZXMgbWF5CisgKiBiZSBzaWduZWQgd2l0aC4gV2hlbiB0aGUgQ2VudHJhbCBEaXJlY3RvcnkgRW5jcnlwdGlvbiBmZWF0dXJlIGlzIGVuYWJsZWQgZm9yCisgKiBhIFpJUCBmaWxlLCB0aGlzIHJlY29yZCB3aWxsIGFwcGVhciBpbiB0aGUgQXJjaGl2ZSBFeHRyYSBEYXRhIFJlY29yZCwKKyAqIG90aGVyd2lzZSBpdCB3aWxsIGFwcGVhciBpbiB0aGUgZmlyc3QgY2VudHJhbCBkaXJlY3RvcnkgcmVjb3JkIGFuZCB3aWxsIGJlCisgKiBpZ25vcmVkIGluIGFueSBvdGhlciByZWNvcmQuPC9wPgorICoKKyAqIDxwPk5vdGU6IGFsbCBmaWVsZHMgc3RvcmVkIGluIEludGVsIGxvdy1ieXRlL2hpZ2gtYnl0ZSBvcmRlci48L3A+CisgKgorICogPHByZT4KKyAqICAgICAgICAgVmFsdWUgICAgIFNpemUgICAgIERlc2NyaXB0aW9uCisgKiAgICAgICAgIC0tLS0tICAgICAtLS0tICAgICAtLS0tLS0tLS0tLQorICogKFN0b3JlKSAweDAwMTQgICAgMiBieXRlcyAgVGFnIGZvciB0aGlzICJleHRyYSIgYmxvY2sgdHlwZQorICogICAgICAgICBUU2l6ZSAgICAgMiBieXRlcyAgU2l6ZSBvZiB0aGUgc3RvcmUgZGF0YQorICogICAgICAgICBURGF0YSAgICAgVFNpemUgICAgRGF0YSBhYm91dCB0aGUgc3RvcmUKKyAqIDwvcHJlPgorICoKKyAqIEBOb3RUaHJlYWRTYWZlCisgKiBAc2luY2UgMS4xMQorICovCitwdWJsaWMgY2xhc3MgWDAwMTRfWDUwOUNlcnRpZmljYXRlcyBleHRlbmRzIFBLV2FyZUV4dHJhSGVhZGVyIHsKKworICAgIHB1YmxpYyBYMDAxNF9YNTA5Q2VydGlmaWNhdGVzKCkgeworICAgICAgICBzdXBlcihuZXcgWmlwU2hvcnQoMHgwMDE0KSk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1gwMDE1X0NlcnRpZmljYXRlSWRGb3JGaWxlLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1gwMDE1X0NlcnRpZmljYXRlSWRGb3JGaWxlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODliMzI3YgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvWDAwMTVfQ2VydGlmaWNhdGVJZEZvckZpbGUuamF2YQpAQCAtMCwwICsxLDc1IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXA7CisKKy8qKgorICogWC41MDkgQ2VydGlmaWNhdGUgSUQgYW5kIFNpZ25hdHVyZSBmb3IgaW5kaXZpZHVhbCBmaWxlICgweDAwMTUpLgorICoKKyAqIDxwPlRoaXMgZmllbGQgY29udGFpbnMgdGhlIGluZm9ybWF0aW9uIGFib3V0IHdoaWNoIGNlcnRpZmljYXRlIGluIHRoZSBQS0NTIzcKKyAqIHN0b3JlIHdhcyB1c2VkIHRvIHNpZ24gYSBwYXJ0aWN1bGFyIGZpbGUuIEl0IGFsc28gY29udGFpbnMgdGhlIHNpZ25hdHVyZQorICogZGF0YS4gVGhpcyBmaWVsZCBjYW4gYXBwZWFyIG11bHRpcGxlIHRpbWVzLCBidXQgY2FuIG9ubHkgYXBwZWFyIG9uY2UgcGVyCisgKiBjZXJ0aWZpY2F0ZS48L3A+CisgKgorICogPHA+Tm90ZTogYWxsIGZpZWxkcyBzdG9yZWQgaW4gSW50ZWwgbG93LWJ5dGUvaGlnaC1ieXRlIG9yZGVyLjwvcD4KKyAqCisgKiA8cHJlPgorICogICAgICAgICBWYWx1ZSAgICAgU2l6ZSAgICAgRGVzY3JpcHRpb24KKyAqICAgICAgICAgLS0tLS0gICAgIC0tLS0gICAgIC0tLS0tLS0tLS0tCisgKiAoQ0lEKSAgIDB4MDAxNSAgICAyIGJ5dGVzICBUYWcgZm9yIHRoaXMgImV4dHJhIiBibG9jayB0eXBlCisgKiAgICAgICAgIFRTaXplICAgICAyIGJ5dGVzICBTaXplIG9mIGRhdGEgdGhhdCBmb2xsb3dzCisgKiAgICAgICAgIFJDb3VudCAgICA0IGJ5dGVzICBOdW1iZXIgb2YgcmVjaXBpZW50cy4gKGluZmVycmVkKQorICogICAgICAgICBIYXNoQWxnICAgMiBieXRlcyAgSGFzaCBhbGdvcml0aG0gaWRlbnRpZmllci4gKGluZmVycmVkKQorICogICAgICAgICBURGF0YSAgICAgVFNpemUgICAgU2lnbmF0dXJlIERhdGEKKyAqIDwvcHJlPgorICoKKyAqIEBOb3RUaHJlYWRTYWZlCisgKiBAc2luY2UgMS4xMQorICovCitwdWJsaWMgY2xhc3MgWDAwMTVfQ2VydGlmaWNhdGVJZEZvckZpbGUgZXh0ZW5kcyBQS1dhcmVFeHRyYUhlYWRlciB7CisKKyAgICBwdWJsaWMgWDAwMTVfQ2VydGlmaWNhdGVJZEZvckZpbGUoKSB7CisgICAgICAgIHN1cGVyKG5ldyBaaXBTaG9ydCgweDAwMTUpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIGludCByY291bnQ7CisgICAgcHJpdmF0ZSBIYXNoQWxnb3JpdGhtIGhhc2hBbGc7CisKKyAgICAvKioKKyAgICAgKiBHZXQgcmVjb3JkIGNvdW50LgorICAgICAqIEByZXR1cm4gdGhlIHJlY29yZCBjb3VudAorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0UmVjb3JkQ291bnQoKSB7CisgICAgICAgIHJldHVybiByY291bnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IGhhc2ggYWxnb3JpdGhtLgorICAgICAqIEByZXR1cm4gdGhlIGhhc2ggYWxnb3JpdGhtCisgICAgICovCisgICAgcHVibGljIEhhc2hBbGdvcml0aG0gZ2V0SGFzaEFsZ29yaXRobSgpIHsKKyAgICAgICAgcmV0dXJuIGhhc2hBbGc7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcGFyc2VGcm9tQ2VudHJhbERpcmVjdG9yeURhdGEoZmluYWwgYnl0ZVtdIGRhdGEsIGZpbmFsIGludCBvZmZzZXQsIGZpbmFsIGludCBsZW5ndGgpIHsKKyAgICAgICAgc3VwZXIucGFyc2VGcm9tQ2VudHJhbERpcmVjdG9yeURhdGEoZGF0YSwgb2Zmc2V0LCBsZW5ndGgpOworICAgICAgICB0aGlzLnJjb3VudCA9IFppcFNob3J0LmdldFZhbHVlKGRhdGEsIG9mZnNldCk7CisgICAgICAgIHRoaXMuaGFzaEFsZyA9IEhhc2hBbGdvcml0aG0uZ2V0QWxnb3JpdGhtQnlDb2RlKFppcFNob3J0LmdldFZhbHVlKGRhdGEsIG9mZnNldCArIDIpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1gwMDE2X0NlcnRpZmljYXRlSWRGb3JDZW50cmFsRGlyZWN0b3J5LmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1gwMDE2X0NlcnRpZmljYXRlSWRGb3JDZW50cmFsRGlyZWN0b3J5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmFiMWU2MQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvWDAwMTZfQ2VydGlmaWNhdGVJZEZvckNlbnRyYWxEaXJlY3RvcnkuamF2YQpAQCAtMCwwICsxLDc1IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXA7CisKKy8qKgorICogWC41MDkgQ2VydGlmaWNhdGUgSUQgYW5kIFNpZ25hdHVyZSBmb3IgY2VudHJhbCBkaXJlY3RvcnkgKDB4MDAxNikuCisgKgorICogPHA+VGhpcyBmaWVsZCBjb250YWlucyB0aGUgaW5mb3JtYXRpb24gYWJvdXQgd2hpY2ggY2VydGlmaWNhdGUgaW4gdGhlIFBLQ1MjNworICogc3RvcmUgd2FzIHVzZWQgdG8gc2lnbiB0aGUgY2VudHJhbCBkaXJlY3Rvcnkgc3RydWN0dXJlLiBXaGVuIHRoZSBDZW50cmFsCisgKiBEaXJlY3RvcnkgRW5jcnlwdGlvbiBmZWF0dXJlIGlzIGVuYWJsZWQgZm9yIGEgWklQIGZpbGUsIHRoaXMgcmVjb3JkIHdpbGwKKyAqIGFwcGVhciBpbiB0aGUgQXJjaGl2ZSBFeHRyYSBEYXRhIFJlY29yZCwgb3RoZXJ3aXNlIGl0IHdpbGwgYXBwZWFyIGluIHRoZQorICogZmlyc3QgY2VudHJhbCBkaXJlY3RvcnkgcmVjb3JkLjwvcD4KKyAqCisgKiA8cD5Ob3RlOiBhbGwgZmllbGRzIHN0b3JlZCBpbiBJbnRlbCBsb3ctYnl0ZS9oaWdoLWJ5dGUgb3JkZXIuPC9wPgorICoKKyAqIDxwcmU+CisgKiAgICAgICAgIFZhbHVlICAgICBTaXplICAgICBEZXNjcmlwdGlvbgorICogICAgICAgICAtLS0tLSAgICAgLS0tLSAgICAgLS0tLS0tLS0tLS0KKyAqIChDRElEKSAgMHgwMDE2ICAgIDIgYnl0ZXMgIFRhZyBmb3IgdGhpcyAiZXh0cmEiIGJsb2NrIHR5cGUKKyAqICAgICAgICAgVFNpemUgICAgIDIgYnl0ZXMgIFNpemUgb2YgZGF0YSB0aGF0IGZvbGxvd3MKKyAqICAgICAgICAgUkNvdW50ICAgIDQgYnl0ZXMgIE51bWJlciBvZiByZWNpcGllbnRzLiAoaW5mZXJyZWQpCisgKiAgICAgICAgIEhhc2hBbGcgICAyIGJ5dGVzICBIYXNoIGFsZ29yaXRobSBpZGVudGlmaWVyLiAoaW5mZXJyZWQpCisgKiAgICAgICAgIFREYXRhICAgICBUU2l6ZSAgICBEYXRhCisgKiA8L3ByZT4KKyAqCisgKiBATm90VGhyZWFkU2FmZQorICogQHNpbmNlIDEuMTEKKyAqLworcHVibGljIGNsYXNzIFgwMDE2X0NlcnRpZmljYXRlSWRGb3JDZW50cmFsRGlyZWN0b3J5IGV4dGVuZHMgUEtXYXJlRXh0cmFIZWFkZXIgeworCisgICAgcHVibGljIFgwMDE2X0NlcnRpZmljYXRlSWRGb3JDZW50cmFsRGlyZWN0b3J5KCkgeworICAgICAgICBzdXBlcihuZXcgWmlwU2hvcnQoMHgwMDE2KSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnQgcmNvdW50OworICAgIHByaXZhdGUgSGFzaEFsZ29yaXRobSBoYXNoQWxnOworCisgICAgLyoqCisgICAgICogR2V0IHJlY29yZCBjb3VudC4KKyAgICAgKiBAcmV0dXJuIHRoZSByZWNvcmQgY291bnQKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFJlY29yZENvdW50KCkgeworICAgICAgICByZXR1cm4gcmNvdW50OworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCBoYXNoIGFsZ29yaXRobS4KKyAgICAgKiBAcmV0dXJuIHRoZSBoYXNoIGFsZ29yaXRobQorICAgICAqLworICAgIHB1YmxpYyBIYXNoQWxnb3JpdGhtIGdldEhhc2hBbGdvcml0aG0oKSB7CisgICAgICAgIHJldHVybiBoYXNoQWxnOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHBhcnNlRnJvbUNlbnRyYWxEaXJlY3RvcnlEYXRhKGZpbmFsIGJ5dGVbXSBkYXRhLCBmaW5hbCBpbnQgb2Zmc2V0LCBmaW5hbCBpbnQgbGVuZ3RoKSB7CisgICAgICAgIHRoaXMucmNvdW50ID0gWmlwU2hvcnQuZ2V0VmFsdWUoZGF0YSwgb2Zmc2V0KTsKKyAgICAgICAgdGhpcy5oYXNoQWxnID0gSGFzaEFsZ29yaXRobS5nZXRBbGdvcml0aG1CeUNvZGUoWmlwU2hvcnQuZ2V0VmFsdWUoZGF0YSwgb2Zmc2V0ICsgMikpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvWDAwMTdfU3Ryb25nRW5jcnlwdGlvbkhlYWRlci5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9YMDAxN19TdHJvbmdFbmNyeXB0aW9uSGVhZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWNjM2IyMgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvWDAwMTdfU3Ryb25nRW5jcnlwdGlvbkhlYWRlci5qYXZhCkBAIC0wLDAgKzEsMzgyIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXA7CisKKy8qKgorICogU3Ryb25nIEVuY3J5cHRpb24gSGVhZGVyICgweDAwMTcpLgorICoKKyAqIDxwPkNlcnRpZmljYXRlLWJhc2VkIGVuY3J5cHRpb246PC9wPgorICoKKyAqIDxwcmU+CisgKiBWYWx1ZSAgICAgU2l6ZSAgICAgRGVzY3JpcHRpb24KKyAqIC0tLS0tICAgICAtLS0tICAgICAtLS0tLS0tLS0tLQorICogMHgwMDE3ICAgIDIgYnl0ZXMgIFRhZyBmb3IgdGhpcyAiZXh0cmEiIGJsb2NrIHR5cGUKKyAqIFRTaXplICAgICAyIGJ5dGVzICBTaXplIG9mIGRhdGEgdGhhdCBmb2xsb3dzCisgKiBGb3JtYXQgICAgMiBieXRlcyAgRm9ybWF0IGRlZmluaXRpb24gZm9yIHRoaXMgcmVjb3JkCisgKiBBbGdJRCAgICAgMiBieXRlcyAgRW5jcnlwdGlvbiBhbGdvcml0aG0gaWRlbnRpZmllcgorICogQml0bGVuICAgIDIgYnl0ZXMgIEJpdCBsZW5ndGggb2YgZW5jcnlwdGlvbiBrZXkgKDMyLTQ0OCBiaXRzKQorICogRmxhZ3MgICAgIDIgYnl0ZXMgIFByb2Nlc3NpbmcgZmxhZ3MKKyAqIFJDb3VudCAgICA0IGJ5dGVzICBOdW1iZXIgb2YgcmVjaXBpZW50cy4KKyAqIEhhc2hBbGcgICAyIGJ5dGVzICBIYXNoIGFsZ29yaXRobSBpZGVudGlmaWVyCisgKiBIU2l6ZSAgICAgMiBieXRlcyAgSGFzaCBzaXplCisgKiBTUkxpc3QgICAgKHZhcikgICAgU2ltcGxlIGxpc3Qgb2YgcmVjaXBpZW50cyBoYXNoZWQgcHVibGljIGtleXMKKyAqCisgKiBGbGFncyAtICAgVGhpcyBkZWZpbmVzIHRoZSBwcm9jZXNzaW5nIGZsYWdzLgorICogPC9wcmU+CisgKgorICogICAgICAgICAgIDx1bD4KKyAqICAgICAgICAgICA8bGk+MHgwMDA3IC0gcmVzZXJ2ZWQgZm9yIGZ1dHVyZSB1c2UKKyAqICAgICAgICAgICA8bGk+MHgwMDBGIC0gcmVzZXJ2ZWQgZm9yIGZ1dHVyZSB1c2UKKyAqICAgICAgICAgICA8bGk+MHgwMTAwIC0gSW5kaWNhdGVzIG5vbi1PQUVQIGtleSB3cmFwcGluZyB3YXMgdXNlZC4gIElmIHRoaXMKKyAqICAgICAgICAgICAgICAgICAgICAgICAgdGhpcyBmaWVsZCBpcyBzZXQsIHRoZSB2ZXJzaW9uIG5lZWRlZCB0byBleHRyYWN0IG11c3QKKyAqICAgICAgICAgICAgICAgICAgICAgICAgYmUgYXQgbGVhc3QgNjEuICBUaGlzIG1lYW5zIE9BRVAga2V5IHdyYXBwaW5nIGlzIG5vdAorICogICAgICAgICAgICAgICAgICAgICAgICB1c2VkIHdoZW4gZ2VuZXJhdGluZyBhIE1hc3RlciBTZXNzaW9uIEtleSB1c2luZworICogICAgICAgICAgICAgICAgICAgICAgICBFcmREYXRhLgorICogICAgICAgICAgIDxsaT4weDQwMDAgLSBFcmREYXRhIG11c3QgYmUgZGVjcnlwdGVkIHVzaW5nIDNERVMtMTY4LCBvdGhlcndpc2UgdXNlIHRoZQorICogICAgICAgICAgICAgICAgICAgICAgICBzYW1lIGFsZ29yaXRobSB1c2VkIGZvciBlbmNyeXB0aW5nIHRoZSBmaWxlIGNvbnRlbnRzLgorICogICAgICAgICAgIDxsaT4weDgwMDAgLSByZXNlcnZlZCBmb3IgZnV0dXJlIHVzZQorICogICAgICAgICAgIDwvdWw+CisgKgorICogPHByZT4KKyAqIFJDb3VudCAtIFRoaXMgZGVmaW5lcyB0aGUgbnVtYmVyIGludGVuZGVkIHJlY2lwaWVudHMgd2hvc2UKKyAqICAgICAgICAgIHB1YmxpYyBrZXlzIHdlcmUgdXNlZCBmb3IgZW5jcnlwdGlvbi4gIFRoaXMgaWRlbnRpZmllcworICogICAgICAgICAgdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGUgU1JMaXN0LgorICoKKyAqICAgICAgICAgIHNlZSBhbHNvOiByZXNlcnZlZDEKKyAqCisgKiBIYXNoQWxnIC0gVGhpcyBkZWZpbmVzIHRoZSBoYXNoIGFsZ29yaXRobSB1c2VkIHRvIGNhbGN1bGF0ZQorICogICAgICAgICAgIHRoZSBwdWJsaWMga2V5IGhhc2ggb2YgZWFjaCBwdWJsaWMga2V5IHVzZWQKKyAqICAgICAgICAgICBmb3IgZW5jcnlwdGlvbi4gVGhpcyBmaWVsZCBjdXJyZW50bHkgc3VwcG9ydHMKKyAqICAgICAgICAgICBvbmx5IHRoZSBmb2xsb3dpbmcgdmFsdWUgZm9yIFNIQS0xCisgKgorICogICAgICAgICAgIDB4ODAwNCAtIFNIQTEKKyAqCisgKiBIU2l6ZSAtICAgVGhpcyBkZWZpbmVzIHRoZSBzaXplIG9mIGEgaGFzaGVkIHB1YmxpYyBrZXkuCisgKgorICogU1JMaXN0IC0gIFRoaXMgaXMgYSB2YXJpYWJsZSBsZW5ndGggbGlzdCBvZiB0aGUgaGFzaGVkCisgKiAgICAgICAgICAgcHVibGljIGtleXMgZm9yIGVhY2ggaW50ZW5kZWQgcmVjaXBpZW50LiAgRWFjaAorICogICAgICAgICAgIGVsZW1lbnQgaW4gdGhpcyBsaXN0IGlzIEhTaXplLiAgVGhlIHRvdGFsIHNpemUgb2YKKyAqICAgICAgICAgICBTUkxpc3QgaXMgZGV0ZXJtaW5lZCB1c2luZyBSQ291bnQgKiBIU2l6ZS4KKyAqIDwvcHJlPgorICoKKyAqIDxwPlBhc3N3b3JkLWJhc2VkIEV4dHJhIEZpZWxkIDB4MDAxNyBpbiBjZW50cmFsIGhlYWRlciBvbmx5LjwvcD4KKyAqCisgKiA8cHJlPgorICogVmFsdWUgICAgIFNpemUgICAgIERlc2NyaXB0aW9uCisgKiAtLS0tLSAgICAgLS0tLSAgICAgLS0tLS0tLS0tLS0KKyAqIDB4MDAxNyAgICAyIGJ5dGVzICBUYWcgZm9yIHRoaXMgImV4dHJhIiBibG9jayB0eXBlCisgKiBUU2l6ZSAgICAgMiBieXRlcyAgU2l6ZSBvZiBkYXRhIHRoYXQgZm9sbG93cworICogRm9ybWF0ICAgIDIgYnl0ZXMgIEZvcm1hdCBkZWZpbml0aW9uIGZvciB0aGlzIHJlY29yZAorICogQWxnSUQgICAgIDIgYnl0ZXMgIEVuY3J5cHRpb24gYWxnb3JpdGhtIGlkZW50aWZpZXIKKyAqIEJpdGxlbiAgICAyIGJ5dGVzICBCaXQgbGVuZ3RoIG9mIGVuY3J5cHRpb24ga2V5ICgzMi00NDggYml0cykKKyAqIEZsYWdzICAgICAyIGJ5dGVzICBQcm9jZXNzaW5nIGZsYWdzCisgKiAobW9yZT8pCisgKiA8L3ByZT4KKyAqCisgKiA8cD48Yj5Gb3JtYXQ8L2I+IC0gdGhlIGRhdGEgZm9ybWF0IGlkZW50aWZpZXIgZm9yIHRoaXMgcmVjb3JkLiBUaGUgb25seSB2YWx1ZQorICogYWxsb3dlZCBhdCB0aGlzIHRpbWUgaXMgdGhlIGludGVnZXIgdmFsdWUgMi48L3A+CisgKgorICogPHA+UGFzc3dvcmQtYmFzZWQgRXh0cmEgRmllbGQgMHgwMDE3IHByZWNlZGluZyBjb21wcmVzc2VkIGZpbGUgZGF0YS48L3A+CisgKgorICogPHByZT4KKyAqIFZhbHVlICAgICBTaXplICAgICBEZXNjcmlwdGlvbgorICogLS0tLS0gICAgIC0tLS0gICAgIC0tLS0tLS0tLS0tCisgKiAweDAwMTcgICAgMiBieXRlcyAgVGFnIGZvciB0aGlzICJleHRyYSIgYmxvY2sgdHlwZQorICogSVZTaXplICAgIDIgYnl0ZXMgIFNpemUgb2YgaW5pdGlhbGl6YXRpb24gdmVjdG9yIChJVikKKyAqIElWRGF0YSAgICBJVlNpemUgICBJbml0aWFsaXphdGlvbiB2ZWN0b3IgZm9yIHRoaXMgZmlsZQorICogU2l6ZSAgICAgIDQgYnl0ZXMgIFNpemUgb2YgcmVtYWluaW5nIGRlY3J5cHRpb24gaGVhZGVyIGRhdGEKKyAqIEZvcm1hdCAgICAyIGJ5dGVzICBGb3JtYXQgZGVmaW5pdGlvbiBmb3IgdGhpcyByZWNvcmQKKyAqIEFsZ0lEICAgICAyIGJ5dGVzICBFbmNyeXB0aW9uIGFsZ29yaXRobSBpZGVudGlmaWVyCisgKiBCaXRsZW4gICAgMiBieXRlcyAgQml0IGxlbmd0aCBvZiBlbmNyeXB0aW9uIGtleSAoMzItNDQ4IGJpdHMpCisgKiBGbGFncyAgICAgMiBieXRlcyAgUHJvY2Vzc2luZyBmbGFncworICogRXJkU2l6ZSAgIDIgYnl0ZXMgIFNpemUgb2YgRW5jcnlwdGVkIFJhbmRvbSBEYXRhCisgKiBFcmREYXRhICAgRXJkU2l6ZSAgRW5jcnlwdGVkIFJhbmRvbSBEYXRhCisgKiBSZXNlcnZlZDEgNCBieXRlcyAgUmVzZXJ2ZWQgY2VydGlmaWNhdGUgcHJvY2Vzc2luZyBkYXRhCisgKiBSZXNlcnZlZDIgKHZhcikgICAgUmVzZXJ2ZWQgZm9yIGNlcnRpZmljYXRlIHByb2Nlc3NpbmcgZGF0YQorICogVlNpemUgICAgIDIgYnl0ZXMgIFNpemUgb2YgcGFzc3dvcmQgdmFsaWRhdGlvbiBkYXRhCisgKiBWRGF0YSAgICAgVlNpemUtNCAgUGFzc3dvcmQgdmFsaWRhdGlvbiBkYXRhCisgKiBWQ1JDMzIgICAgNCBieXRlcyAgU3RhbmRhcmQgWklQIENSQzMyIG9mIHBhc3N3b3JkIHZhbGlkYXRpb24gZGF0YQorICoKKyAqIElWRGF0YSAtIFRoZSBzaXplIG9mIHRoZSBJViBzaG91bGQgbWF0Y2ggdGhlIGFsZ29yaXRobSBibG9jayBzaXplLgorICogICAgICAgICAgVGhlIElWRGF0YSBjYW4gYmUgY29tcGxldGVseSByYW5kb20gZGF0YS4gIElmIHRoZSBzaXplIG9mCisgKiAgICAgICAgICB0aGUgcmFuZG9tbHkgZ2VuZXJhdGVkIGRhdGEgZG9lcyBub3QgbWF0Y2ggdGhlIGJsb2NrIHNpemUKKyAqICAgICAgICAgIGl0IHNob3VsZCBiZSBjb21wbGVtZW50ZWQgd2l0aCB6ZXJvJ3Mgb3IgdHJ1bmNhdGVkIGFzCisgKiAgICAgICAgICBuZWNlc3NhcnkuICBJZiBJVlNpemUgaXMgMCx0aGVuIElWID0gQ1JDMzIgKyBVbmNvbXByZXNzZWQKKyAqICAgICAgICAgIEZpbGUgU2l6ZSAoYXMgYSA2NCBiaXQgbGl0dGxlLWVuZGlhbiwgdW5zaWduZWQgaW50ZWdlciB2YWx1ZSkuCisgKgorICogRm9ybWF0IC0gIHRoZSBkYXRhIGZvcm1hdCBpZGVudGlmaWVyIGZvciB0aGlzIHJlY29yZC4gIFRoZSBvbmx5CisgKiAgICAgICAgICAgdmFsdWUgYWxsb3dlZCBhdCB0aGlzIHRpbWUgaXMgdGhlIGludGVnZXIgdmFsdWUgMi4KKyAqCisgKiBFcmREYXRhIC0gRW5jcnlwdGVkIHJhbmRvbSBkYXRhIGlzIHVzZWQgdG8gc3RvcmUgcmFuZG9tIGRhdGEgdGhhdAorICogICAgICAgICAgIGlzIHVzZWQgdG8gZ2VuZXJhdGUgYSBmaWxlIHNlc3Npb24ga2V5IGZvciBlbmNyeXB0aW5nCisgKiAgICAgICAgICAgZWFjaCBmaWxlLiAgU0hBMSBpcyB1c2VkIHRvIGNhbGN1bGF0ZSBoYXNoIGRhdGEgdXNlZCB0bworICogICAgICAgICAgIGRlcml2ZSBrZXlzLiAgRmlsZSBzZXNzaW9uIGtleXMgYXJlIGRlcml2ZWQgZnJvbSBhIG1hc3RlcgorICogICAgICAgICAgIHNlc3Npb24ga2V5IGdlbmVyYXRlZCBmcm9tIHRoZSB1c2VyLXN1cHBsaWVkIHBhc3N3b3JkLgorICogICAgICAgICAgIElmIHRoZSBGbGFncyBmaWVsZCBpbiB0aGUgZGVjcnlwdGlvbiBoZWFkZXIgY29udGFpbnMKKyAqICAgICAgICAgICB0aGUgdmFsdWUgMHg0MDAwLCB0aGVuIHRoZSBFcmREYXRhIGZpZWxkIG11c3QgYmUKKyAqICAgICAgICAgICBkZWNyeXB0ZWQgdXNpbmcgM0RFUy4gSWYgdGhlIHZhbHVlIDB4NDAwMCBpcyBub3Qgc2V0LAorICogICAgICAgICAgIHRoZW4gdGhlIEVyZERhdGEgZmllbGQgbXVzdCBiZSBkZWNyeXB0ZWQgdXNpbmcgQWxnSWQuCisgKgorICogUmVzZXJ2ZWQxIC0gUmVzZXJ2ZWQgZm9yIGNlcnRpZmljYXRlIHByb2Nlc3NpbmcsIGlmIHZhbHVlIGlzCisgKiAgICAgICAgICAgemVybywgdGhlbiBSZXNlcnZlZDIgZGF0YSBpcyBhYnNlbnQuICBTZWUgdGhlIGV4cGxhbmF0aW9uCisgKiAgICAgICAgICAgdW5kZXIgdGhlIENlcnRpZmljYXRlIFByb2Nlc3NpbmcgTWV0aG9kIGZvciBkZXRhaWxzIG9uCisgKiAgICAgICAgICAgdGhpcyBkYXRhIHN0cnVjdHVyZS4KKyAqCisgKiBSZXNlcnZlZDIgLSBJZiBwcmVzZW50LCB0aGUgc2l6ZSBvZiB0aGUgUmVzZXJ2ZWQyIGRhdGEgc3RydWN0dXJlCisgKiAgICAgICAgICAgaXMgbG9jYXRlZCBieSBza2lwcGluZyB0aGUgZmlyc3QgNCBieXRlcyBvZiB0aGlzIGZpZWxkCisgKiAgICAgICAgICAgYW5kIHVzaW5nIHRoZSBuZXh0IDIgYnl0ZXMgYXMgdGhlIHJlbWFpbmluZyBzaXplLiAgU2VlCisgKiAgICAgICAgICAgdGhlIGV4cGxhbmF0aW9uIHVuZGVyIHRoZSBDZXJ0aWZpY2F0ZSBQcm9jZXNzaW5nIE1ldGhvZAorICogICAgICAgICAgIGZvciBkZXRhaWxzIG9uIHRoaXMgZGF0YSBzdHJ1Y3R1cmUuCisgKgorICogVlNpemUgLSBUaGlzIHNpemUgdmFsdWUgd2lsbCBhbHdheXMgaW5jbHVkZSB0aGUgNCBieXRlcyBvZiB0aGUKKyAqICAgICAgICAgVkNSQzMyIGRhdGEgYW5kIHdpbGwgYmUgZ3JlYXRlciB0aGFuIDQgYnl0ZXMuCisgKgorICogVkRhdGEgLSBSYW5kb20gZGF0YSBmb3IgcGFzc3dvcmQgdmFsaWRhdGlvbi4gIFRoaXMgZGF0YSBpcyBWU2l6ZQorICogICAgICAgICBpbiBsZW5ndGggYW5kIFZTaXplIG11c3QgYmUgYSBtdWx0aXBsZSBvZiB0aGUgZW5jcnlwdGlvbgorICogICAgICAgICBibG9jayBzaXplLiAgVkNSQzMyIGlzIGEgY2hlY2tzdW0gdmFsdWUgb2YgVkRhdGEuCisgKiAgICAgICAgIFZEYXRhIGFuZCBWQ1JDMzIgYXJlIHN0b3JlZCBlbmNyeXB0ZWQgYW5kIHN0YXJ0IHRoZQorICogICAgICAgICBzdHJlYW0gb2YgZW5jcnlwdGVkIGRhdGEgZm9yIGEgZmlsZS4KKyAqIDwvcHJlPgorICoKKyAqIDxwPlJlc2VydmVkMSAtIENlcnRpZmljYXRlIERlY3J5cHRpb24gSGVhZGVyIFJlc2VydmVkMSBEYXRhOjwvcD4KKyAqCisgKiA8cHJlPgorICogVmFsdWUgICAgIFNpemUgICAgIERlc2NyaXB0aW9uCisgKiAtLS0tLSAgICAgLS0tLSAgICAgLS0tLS0tLS0tLS0KKyAqIFJDb3VudCAgICA0IGJ5dGVzICBOdW1iZXIgb2YgcmVjaXBpZW50cy4KKyAqIDwvcHJlPgorICoKKyAqIDxwPlJDb3VudCAtIFRoaXMgZGVmaW5lcyB0aGUgbnVtYmVyIGludGVuZGVkIHJlY2lwaWVudHMgd2hvc2UgcHVibGljIGtleXMgd2VyZQorICogdXNlZCBmb3IgZW5jcnlwdGlvbi4gVGhpcyBkZWZpbmVzIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhlIFJFTGlzdCBmaWVsZAorICogZGVmaW5lZCBiZWxvdy48L3A+CisgKgorICogPHA+UmVzZXJ2ZWQyIC0gQ2VydGlmaWNhdGUgRGVjcnlwdGlvbiBIZWFkZXIgUmVzZXJ2ZWQyIERhdGEgU3RydWN0dXJlczo8L3A+CisgKgorICogPHByZT4KKyAqIFZhbHVlICAgICBTaXplICAgICBEZXNjcmlwdGlvbgorICogLS0tLS0gICAgIC0tLS0gICAgIC0tLS0tLS0tLS0tCisgKiBIYXNoQWxnICAgMiBieXRlcyAgSGFzaCBhbGdvcml0aG0gaWRlbnRpZmllcgorICogSFNpemUgICAgIDIgYnl0ZXMgIEhhc2ggc2l6ZQorICogUkVMaXN0ICAgICh2YXIpICAgIExpc3Qgb2YgcmVjaXBpZW50IGRhdGEgZWxlbWVudHMKKyAqCisgKiBIYXNoQWxnIC0gVGhpcyBkZWZpbmVzIHRoZSBoYXNoIGFsZ29yaXRobSB1c2VkIHRvIGNhbGN1bGF0ZQorICogICAgICAgICAgIHRoZSBwdWJsaWMga2V5IGhhc2ggb2YgZWFjaCBwdWJsaWMga2V5IHVzZWQKKyAqICAgICAgICAgICBmb3IgZW5jcnlwdGlvbi4gVGhpcyBmaWVsZCBjdXJyZW50bHkgc3VwcG9ydHMKKyAqICAgICAgICAgICBvbmx5IHRoZSBmb2xsb3dpbmcgdmFsdWUgZm9yIFNIQS0xCisgKgorICogICAgICAgICAgICAgICAweDgwMDQgLSBTSEExCisgKgorICogSFNpemUgLSAgIFRoaXMgZGVmaW5lcyB0aGUgc2l6ZSBvZiBhIGhhc2hlZCBwdWJsaWMga2V5CisgKiAgICAgICAgICAgZGVmaW5lZCBpbiBSRUhEYXRhLgorICoKKyAqIFJFTGlzdCAtICBUaGlzIGlzIGEgdmFyaWFibGUgbGVuZ3RoIG9mIGxpc3Qgb2YgcmVjaXBpZW50IGRhdGEuCisgKiAgICAgICAgICAgRWFjaCBlbGVtZW50IGluIHRoaXMgbGlzdCBjb25zaXN0cyBvZiBhIFJlY2lwaWVudAorICogICAgICAgICAgIEVsZW1lbnQgZGF0YSBzdHJ1Y3R1cmUgYXMgZm9sbG93czoKKyAqIDwvcHJlPgorICoKKyAqIDxwPlJlY2lwaWVudCBFbGVtZW50IChSRUxpc3QpIERhdGEgU3RydWN0dXJlOjwvcD4KKyAqCisgKiA8cHJlPgorICogVmFsdWUgICAgIFNpemUgICAgIERlc2NyaXB0aW9uCisgKiAtLS0tLSAgICAgLS0tLSAgICAgLS0tLS0tLS0tLS0KKyAqIFJFU2l6ZSAgICAyIGJ5dGVzICBTaXplIG9mIFJFSERhdGEgKyBSRUtEYXRhCisgKiBSRUhEYXRhICAgSFNpemUgICAgSGFzaCBvZiByZWNpcGllbnRzIHB1YmxpYyBrZXkKKyAqIFJFS0RhdGEgICAodmFyKSAgICBTaW1wbGUga2V5IGJsb2IKKyAqCisgKgorICogUkVTaXplIC0gIFRoaXMgZGVmaW5lcyB0aGUgc2l6ZSBvZiBhbiBpbmRpdmlkdWFsIFJFTGlzdAorICogICAgICAgICAgIGVsZW1lbnQuICBUaGlzIHZhbHVlIGlzIHRoZSBjb21iaW5lZCBzaXplIG9mIHRoZQorICogICAgICAgICAgIFJFSERhdGEgZmllbGQgKyBSRUtEYXRhIGZpZWxkLiAgUkVIRGF0YSBpcyBkZWZpbmVkIGJ5CisgKiAgICAgICAgICAgSFNpemUuICBSRUtEYXRhIGlzIHZhcmlhYmxlIGFuZCBjYW4gYmUgY2FsY3VsYXRlZAorICogICAgICAgICAgIGZvciBlYWNoIFJFTGlzdCBlbGVtZW50IHVzaW5nIFJFU2l6ZSBhbmQgSFNpemUuCisgKgorICogUkVIRGF0YSAtIEhhc2hlZCBwdWJsaWMga2V5IGZvciB0aGlzIHJlY2lwaWVudC4KKyAqCisgKiBSRUtEYXRhIC0gU2ltcGxlIEtleSBCbG9iLiAgVGhlIGZvcm1hdCBvZiB0aGlzIGRhdGEgc3RydWN0dXJlCisgKiAgICAgICAgICAgaXMgaWRlbnRpY2FsIHRvIHRoYXQgZGVmaW5lZCBpbiB0aGUgTWljcm9zb2Z0CisgKiAgICAgICAgICAgQ3J5cHRvQVBJIGFuZCBnZW5lcmF0ZWQgdXNpbmcgdGhlIENyeXB0RXhwb3J0S2V5KCkKKyAqICAgICAgICAgICBmdW5jdGlvbi4gIFRoZSB2ZXJzaW9uIG9mIHRoZSBTaW1wbGUgS2V5IEJsb2IKKyAqICAgICAgICAgICBzdXBwb3J0ZWQgYXQgdGhpcyB0aW1lIGlzIDB4MDIgYXMgZGVmaW5lZCBieQorICogICAgICAgICAgIE1pY3Jvc29mdC4KKyAqCisgKiAgICAgICAgICAgRm9yIG1vcmUgZGV0YWlscyBzZWUgaHR0cHM6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9hYTkyMDA1MS5hc3B4CisgKiA8L3ByZT4KKyAqCisgKiA8cD48Yj5GbGFnczwvYj4gLSBQcm9jZXNzaW5nIGZsYWdzIG5lZWRlZCBmb3IgZGVjcnlwdGlvbjwvcD4KKyAqCisgKiA8dWw+CisgKiA8bGk+MHgwMDAxIC0gUGFzc3dvcmQgaXMgcmVxdWlyZWQgdG8gZGVjcnlwdDwvbGk+CisgKiA8bGk+MHgwMDAyIC0gQ2VydGlmaWNhdGVzIG9ubHk8L2xpPgorICogPGxpPjB4MDAwMyAtIFBhc3N3b3JkIG9yIGNlcnRpZmljYXRlIHJlcXVpcmVkIHRvIGRlY3J5cHQ8L2xpPgorICogPGxpPjB4MDAwNyAtIHJlc2VydmVkIGZvciBmdXR1cmUgdXNlCisgKiA8bGk+MHgwMDBGIC0gcmVzZXJ2ZWQgZm9yIGZ1dHVyZSB1c2UKKyAqIDxsaT4weDAxMDAgLSBpbmRpY2F0ZXMgbm9uLU9BRVAga2V5IHdyYXBwaW5nIHdhcyB1c2VkLiBJZiB0aGlzIGZpZWxkIGlzIHNldAorICogdGhlIHZlcnNpb24gbmVlZGVkIHRvIGV4dHJhY3QgbXVzdCBiZSBhdCBsZWFzdCA2MS4gVGhpcyBtZWFucyBPQUVQIGtleQorICogd3JhcHBpbmcgaXMgbm90IHVzZWQgd2hlbiBnZW5lcmF0aW5nIGEgTWFzdGVyIFNlc3Npb24gS2V5IHVzaW5nIEVyZERhdGEuCisgKiA8bGk+MHg0MDAwIC0gRXJkRGF0YSBtdXN0IGJlIGRlY3J5cHRlZCB1c2luZyAzREVTLTE2OCwgb3RoZXJ3aXNlIHVzZSB0aGUgc2FtZQorICogYWxnb3JpdGhtIHVzZWQgZm9yIGVuY3J5cHRpbmcgdGhlIGZpbGUgY29udGVudHMuCisgKiA8bGk+MHg4MDAwIC0gcmVzZXJ2ZWQgZm9yIGZ1dHVyZSB1c2UuCisgKiA8L3VsPgorICoKKyAqIDxwPjxiPlNlZSB0aGUgc2VjdGlvbiBkZXNjcmliaW5nIHRoZSBTdHJvbmcgRW5jcnlwdGlvbiBTcGVjaWZpY2F0aW9uIGZvcgorICogZGV0YWlscy4gUmVmZXIgdG8gdGhlIHNlY3Rpb24gaW4gdGhpcyBkb2N1bWVudCBlbnRpdGxlZAorICogIkluY29ycG9yYXRpbmcgUEtXQVJFIFByb3ByaWV0YXJ5IFRlY2hub2xvZ3kgaW50byBZb3VyIFByb2R1Y3QiIGZvciBtb3JlCisgKiBpbmZvcm1hdGlvbi48L2I+PC9wPgorICoKKyAqIEBOb3RUaHJlYWRTYWZlCisgKiBAc2luY2UgMS4xMQorICovCitwdWJsaWMgY2xhc3MgWDAwMTdfU3Ryb25nRW5jcnlwdGlvbkhlYWRlciBleHRlbmRzIFBLV2FyZUV4dHJhSGVhZGVyIHsKKworICAgIHB1YmxpYyBYMDAxN19TdHJvbmdFbmNyeXB0aW9uSGVhZGVyKCkgeworICAgICAgICBzdXBlcihuZXcgWmlwU2hvcnQoMHgwMDE3KSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnQgZm9ybWF0OyAvLyBUT0RPIHdyaXR0ZW4gYnV0IG5vdCByZWFkCisgICAgcHJpdmF0ZSBFbmNyeXB0aW9uQWxnb3JpdGhtIGFsZ0lkOworICAgIHByaXZhdGUgaW50IGJpdGxlbjsgLy8gVE9ETyB3cml0dGVuIGJ1dCBub3QgcmVhZAorICAgIHByaXZhdGUgaW50IGZsYWdzOyAvLyBUT0RPIHdyaXR0ZW4gYnV0IG5vdCByZWFkCisgICAgcHJpdmF0ZSBsb25nIHJjb3VudDsKKyAgICBwcml2YXRlIEhhc2hBbGdvcml0aG0gaGFzaEFsZzsKKyAgICBwcml2YXRlIGludCBoYXNoU2l6ZTsKKworICAgIC8vIGVuY3J5cHRpb24gZGF0YQorICAgIHByaXZhdGUgYnl0ZSBpdkRhdGFbXTsKKyAgICBwcml2YXRlIGJ5dGUgZXJkRGF0YVtdOworCisgICAgLy8gZW5jcnlwdGlvbiBrZXkKKyAgICBwcml2YXRlIGJ5dGUgcmVjaXBpZW50S2V5SGFzaFtdOworICAgIHByaXZhdGUgYnl0ZSBrZXlCbG9iW107CisKKyAgICAvLyBwYXNzd29yZCB2ZXJpZmljYXRpb24gZGF0YQorICAgIHByaXZhdGUgYnl0ZSB2RGF0YVtdOworICAgIHByaXZhdGUgYnl0ZSB2Q1JDMzJbXTsKKworICAgIC8qKgorICAgICAqIEdldCByZWNvcmQgY291bnQuCisgICAgICogQHJldHVybiB0aGUgcmVjb3JkIGNvdW50CisgICAgICovCisgICAgcHVibGljIGxvbmcgZ2V0UmVjb3JkQ291bnQoKSB7CisgICAgICAgIHJldHVybiByY291bnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IGhhc2ggYWxnb3JpdGhtLgorICAgICAqIEByZXR1cm4gdGhlIGhhc2ggYWxnb3JpdGhtCisgICAgICovCisgICAgcHVibGljIEhhc2hBbGdvcml0aG0gZ2V0SGFzaEFsZ29yaXRobSgpIHsKKyAgICAgICAgcmV0dXJuIGhhc2hBbGc7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IGVuY3J5cHRpb24gYWxnb3JpdGhtLgorICAgICAqIEByZXR1cm4gdGhlIGVuY3J5cHRpb24gYWxnb3JpdGhtCisgICAgICovCisgICAgcHVibGljIEVuY3J5cHRpb25BbGdvcml0aG0gZ2V0RW5jcnlwdGlvbkFsZ29yaXRobSgpIHsKKyAgICAgICAgcmV0dXJuIGFsZ0lkOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlIGNlbnRyYWwgZGlyZWN0b3J5IGZvcm1hdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkYXRhIHRoZSBidWZmZXIgdG8gcmVhZCBkYXRhIGZyb20KKyAgICAgKiBAcGFyYW0gb2Zmc2V0IG9mZnNldCBpbnRvIGJ1ZmZlciB0byByZWFkIGRhdGEKKyAgICAgKiBAcGFyYW0gbGVuZ3RoIHRoZSBsZW5ndGggb2YgZGF0YQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHBhcnNlQ2VudHJhbERpcmVjdG9yeUZvcm1hdChmaW5hbCBieXRlW10gZGF0YSwgZmluYWwgaW50IG9mZnNldCwgZmluYWwgaW50IGxlbmd0aCkgeworICAgICAgICB0aGlzLmZvcm1hdCA9IFppcFNob3J0LmdldFZhbHVlKGRhdGEsIG9mZnNldCk7CisgICAgICAgIHRoaXMuYWxnSWQgPSBFbmNyeXB0aW9uQWxnb3JpdGhtLmdldEFsZ29yaXRobUJ5Q29kZShaaXBTaG9ydC5nZXRWYWx1ZShkYXRhLCBvZmZzZXQgKyAyKSk7CisgICAgICAgIHRoaXMuYml0bGVuID0gWmlwU2hvcnQuZ2V0VmFsdWUoZGF0YSwgb2Zmc2V0ICsgNCk7CisgICAgICAgIHRoaXMuZmxhZ3MgPSBaaXBTaG9ydC5nZXRWYWx1ZShkYXRhLCBvZmZzZXQgKyA2KTsKKyAgICAgICAgdGhpcy5yY291bnQgPSBaaXBMb25nLmdldFZhbHVlKGRhdGEsIG9mZnNldCArIDgpOworCisgICAgICAgIGlmIChyY291bnQgPiAwKSB7CisgICAgICAgICAgICB0aGlzLmhhc2hBbGcgPSBIYXNoQWxnb3JpdGhtLmdldEFsZ29yaXRobUJ5Q29kZShaaXBTaG9ydC5nZXRWYWx1ZShkYXRhLCBvZmZzZXQgKyAxMikpOworICAgICAgICAgICAgdGhpcy5oYXNoU2l6ZSA9IFppcFNob3J0LmdldFZhbHVlKGRhdGEsIG9mZnNldCArIDE0KTsKKyAgICAgICAgICAgIC8vIHNybGlzdC4uLiBoYXNoZWQgcHVibGljIGtleXMKKyAgICAgICAgICAgIGZvciAobG9uZyBpID0gMDsgaSA8IHRoaXMucmNvdW50OyBpKyspIHsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IHRoaXMuaGFzaFNpemU7IGorKykgeworICAgICAgICAgICAgICAgICAgICAvLyAgWmlwVXRpbC5zaWduZWRCeXRlVG9VbnNpZ25lZEludChkYXRhW29mZnNldCArIDE2ICsgKGkgKiB0aGlzLmhhc2hTaXplKSArIGpdKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2UgZmlsZSBoZWFkZXIgZm9ybWF0LgorICAgICAqCisgICAgICogPHA+KFBhc3N3b3JkIG9ubHk/KTwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkYXRhIHRoZSBidWZmZXIgdG8gcmVhZCBkYXRhIGZyb20KKyAgICAgKiBAcGFyYW0gb2Zmc2V0IG9mZnNldCBpbnRvIGJ1ZmZlciB0byByZWFkIGRhdGEKKyAgICAgKiBAcGFyYW0gbGVuZ3RoIHRoZSBsZW5ndGggb2YgZGF0YQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHBhcnNlRmlsZUZvcm1hdChmaW5hbCBieXRlW10gZGF0YSwgZmluYWwgaW50IG9mZnNldCwgZmluYWwgaW50IGxlbmd0aCkgeworICAgICAgICBmaW5hbCBpbnQgaXZTaXplID0gWmlwU2hvcnQuZ2V0VmFsdWUoZGF0YSwgb2Zmc2V0KTsKKyAgICAgICAgdGhpcy5pdkRhdGEgPSBuZXcgYnl0ZVtpdlNpemVdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGRhdGEsIG9mZnNldCArIDQsIHRoaXMuaXZEYXRhLCAwLCBpdlNpemUpOworCisgICAgICAgIHRoaXMuZm9ybWF0ID0gWmlwU2hvcnQuZ2V0VmFsdWUoZGF0YSwgb2Zmc2V0ICsgaXZTaXplICsgNik7CisgICAgICAgIHRoaXMuYWxnSWQgPSBFbmNyeXB0aW9uQWxnb3JpdGhtLmdldEFsZ29yaXRobUJ5Q29kZShaaXBTaG9ydC5nZXRWYWx1ZShkYXRhLCBvZmZzZXQgKyBpdlNpemUgKyA4KSk7CisgICAgICAgIHRoaXMuYml0bGVuID0gWmlwU2hvcnQuZ2V0VmFsdWUoZGF0YSwgb2Zmc2V0ICsgaXZTaXplICsgMTApOworICAgICAgICB0aGlzLmZsYWdzID0gWmlwU2hvcnQuZ2V0VmFsdWUoZGF0YSwgb2Zmc2V0ICsgaXZTaXplICsgMTIpOworCisgICAgICAgIGZpbmFsIGludCBlcmRTaXplID0gWmlwU2hvcnQuZ2V0VmFsdWUoZGF0YSwgb2Zmc2V0ICsgaXZTaXplICsgMTQpOworICAgICAgICB0aGlzLmVyZERhdGEgPSBuZXcgYnl0ZVtlcmRTaXplXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShkYXRhLCBvZmZzZXQgKyBpdlNpemUgKyAxNiwgdGhpcy5lcmREYXRhLCAwLCBlcmRTaXplKTsKKworICAgICAgICB0aGlzLnJjb3VudCA9IFppcExvbmcuZ2V0VmFsdWUoZGF0YSwgb2Zmc2V0ICsgaXZTaXplICsgMTYgKyBlcmRTaXplKTsKKyAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJyY291bnQ6ICIgKyByY291bnQpOworICAgICAgICBpZiAocmNvdW50ID09IDApIHsKKyAgICAgICAgICAgIGZpbmFsIGludCB2U2l6ZSA9IFppcFNob3J0LmdldFZhbHVlKGRhdGEsIG9mZnNldCArIGl2U2l6ZSArIDIwICsgZXJkU2l6ZSk7CisgICAgICAgICAgICB0aGlzLnZEYXRhID0gbmV3IGJ5dGVbdlNpemUgLSA0XTsKKyAgICAgICAgICAgIHRoaXMudkNSQzMyID0gbmV3IGJ5dGVbNF07CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGRhdGEsIG9mZnNldCArIGl2U2l6ZSArIDIyICsgZXJkU2l6ZSAsIHRoaXMudkRhdGEsIDAsIHZTaXplIC0gNCk7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGRhdGEsIG9mZnNldCArIGl2U2l6ZSArIDIyICsgZXJkU2l6ZSArIHZTaXplIC0gNCwgdkNSQzMyLCAwLCA0KTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRoaXMuaGFzaEFsZyA9IEhhc2hBbGdvcml0aG0uZ2V0QWxnb3JpdGhtQnlDb2RlKFppcFNob3J0LmdldFZhbHVlKGRhdGEsIG9mZnNldCArIGl2U2l6ZSArIDIwICsgZXJkU2l6ZSkpOworICAgICAgICAgICAgdGhpcy5oYXNoU2l6ZSA9IFppcFNob3J0LmdldFZhbHVlKGRhdGEsIG9mZnNldCArIGl2U2l6ZSArIDIyICsgZXJkU2l6ZSk7CisgICAgICAgICAgICBmaW5hbCBpbnQgcmVzaXplID0gWmlwU2hvcnQuZ2V0VmFsdWUoZGF0YSwgb2Zmc2V0ICsgaXZTaXplICsgMjQgKyBlcmRTaXplKTsKKyAgICAgICAgICAgIHRoaXMucmVjaXBpZW50S2V5SGFzaCA9IG5ldyBieXRlW3RoaXMuaGFzaFNpemVdOworICAgICAgICAgICAgdGhpcy5rZXlCbG9iID0gbmV3IGJ5dGVbcmVzaXplIC0gdGhpcy5oYXNoU2l6ZV07CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGRhdGEsIG9mZnNldCArIGl2U2l6ZSArIDI0ICsgZXJkU2l6ZSwgdGhpcy5yZWNpcGllbnRLZXlIYXNoLCAwLCB0aGlzLmhhc2hTaXplKTsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZGF0YSwgb2Zmc2V0ICsgaXZTaXplICsgMjQgKyBlcmRTaXplICsgdGhpcy5oYXNoU2l6ZSwgdGhpcy5rZXlCbG9iLCAwLCByZXNpemUgLSB0aGlzLmhhc2hTaXplKTsKKworICAgICAgICAgICAgZmluYWwgaW50IHZTaXplID0gWmlwU2hvcnQuZ2V0VmFsdWUoZGF0YSwgb2Zmc2V0ICsgaXZTaXplICsgMjYgKyBlcmRTaXplICsgcmVzaXplKTsKKyAgICAgICAgICAgIHRoaXMudkRhdGEgPSBuZXcgYnl0ZVt2U2l6ZSAtIDRdOworICAgICAgICAgICAgdGhpcy52Q1JDMzIgPSBuZXcgYnl0ZVs0XTsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZGF0YSwgb2Zmc2V0ICsgaXZTaXplICsgMjIgKyBlcmRTaXplICsgcmVzaXplLCB0aGlzLnZEYXRhLCAwLCB2U2l6ZSAtIDQpOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShkYXRhLCBvZmZzZXQgKyBpdlNpemUgKyAyMiArIGVyZFNpemUgKyByZXNpemUgKyB2U2l6ZSAtIDQsIHZDUkMzMiwgMCwgNCk7CisgICAgICAgIH0KKworICAgICAgICAvLyB2YWxpZGF0ZSB2YWx1ZXM/CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcGFyc2VGcm9tTG9jYWxGaWxlRGF0YShmaW5hbCBieXRlW10gZGF0YSwgZmluYWwgaW50IG9mZnNldCwgZmluYWwgaW50IGxlbmd0aCkgeworICAgICAgICBzdXBlci5wYXJzZUZyb21Mb2NhbEZpbGVEYXRhKGRhdGEsIG9mZnNldCwgbGVuZ3RoKTsKKyAgICAgICAgcGFyc2VGaWxlRm9ybWF0KGRhdGEsIG9mZnNldCwgbGVuZ3RoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBwYXJzZUZyb21DZW50cmFsRGlyZWN0b3J5RGF0YShmaW5hbCBieXRlW10gZGF0YSwgZmluYWwgaW50IG9mZnNldCwgZmluYWwgaW50IGxlbmd0aCkgeworICAgICAgICBzdXBlci5wYXJzZUZyb21DZW50cmFsRGlyZWN0b3J5RGF0YShkYXRhLCBvZmZzZXQsIGxlbmd0aCk7CisgICAgICAgIHBhcnNlQ2VudHJhbERpcmVjdG9yeUZvcm1hdChkYXRhLCBvZmZzZXQsIGxlbmd0aCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9YMDAxOV9FbmNyeXB0aW9uUmVjaXBpZW50Q2VydGlmaWNhdGVMaXN0LmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1gwMDE5X0VuY3J5cHRpb25SZWNpcGllbnRDZXJ0aWZpY2F0ZUxpc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MjU1MDc5Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9YMDAxOV9FbmNyeXB0aW9uUmVjaXBpZW50Q2VydGlmaWNhdGVMaXN0LmphdmEKQEAgLTAsMCArMSw1NyBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwOworCisvKioKKyAqIFBLQ1MjNyBFbmNyeXB0aW9uIFJlY2lwaWVudCBDZXJ0aWZpY2F0ZSBMaXN0ICgweDAwMTkpLgorICoKKyAqIDxwPlRoaXMgZmllbGQgTUFZIGNvbnRhaW4gaW5mb3JtYXRpb24gYWJvdXQgZWFjaCBvZiB0aGUgY2VydGlmaWNhdGVzIHVzZWQgaW4KKyAqIGVuY3J5cHRpb24gcHJvY2Vzc2luZyBhbmQgaXQgY2FuIGJlIHVzZWQgdG8gaWRlbnRpZnkgd2hvIGlzIGFsbG93ZWQgdG8KKyAqIGRlY3J5cHQgZW5jcnlwdGVkIGZpbGVzLiBUaGlzIGZpZWxkIHNob3VsZCBvbmx5IGFwcGVhciBpbiB0aGUgYXJjaGl2ZSBleHRyYQorICogZGF0YSByZWNvcmQuIFRoaXMgZmllbGQgaXMgbm90IHJlcXVpcmVkIGFuZCBzZXJ2ZXMgb25seSB0byBhaWQgYXJjaGl2ZQorICogbW9kaWZpY2F0aW9ucyBieSBwcmVzZXJ2aW5nIHB1YmxpYyBlbmNyeXB0aW9uIGtleSBkYXRhLiBJbmRpdmlkdWFsIHNlY3VyaXR5CisgKiByZXF1aXJlbWVudHMgbWF5IGRpY3RhdGUgdGhhdCB0aGlzIGRhdGEgYmUgb21pdHRlZCB0byBkZXRlciBpbmZvcm1hdGlvbgorICogZXhwb3N1cmUuPC9wPgorICoKKyAqIDxwPk5vdGU6IGFsbCBmaWVsZHMgc3RvcmVkIGluIEludGVsIGxvdy1ieXRlL2hpZ2gtYnl0ZSBvcmRlci48L3A+CisgKgorICogPHByZT4KKyAqICAgICAgICAgIFZhbHVlICAgICBTaXplICAgICBEZXNjcmlwdGlvbgorICogICAgICAgICAgLS0tLS0gICAgIC0tLS0gICAgIC0tLS0tLS0tLS0tCisgKiAoQ1N0b3JlKSAweDAwMTkgICAgMiBieXRlcyAgVGFnIGZvciB0aGlzICJleHRyYSIgYmxvY2sgdHlwZQorICogICAgICAgICAgVFNpemUgICAgIDIgYnl0ZXMgIFNpemUgb2YgdGhlIHN0b3JlIGRhdGEKKyAqICAgICAgICAgIFZlcnNpb24gICAyIGJ5dGVzICBGb3JtYXQgdmVyc2lvbiBudW1iZXIgLSBtdXN0IDB4MDAwMSBhdCB0aGlzIHRpbWUKKyAqICAgICAgICAgIENTdG9yZSAgICAodmFyKSAgICBQS0NTIzcgZGF0YSBibG9iCisgKiA8L3ByZT4KKyAqCisgKiA8cD48Yj5TZWUgdGhlIHNlY3Rpb24gZGVzY3JpYmluZyB0aGUgU3Ryb25nIEVuY3J5cHRpb24gU3BlY2lmaWNhdGlvbiBmb3IKKyAqIGRldGFpbHMuIFJlZmVyIHRvIHRoZSBzZWN0aW9uIGluIHRoaXMgZG9jdW1lbnQgZW50aXRsZWQKKyAqICJJbmNvcnBvcmF0aW5nIFBLV0FSRSBQcm9wcmlldGFyeSBUZWNobm9sb2d5IGludG8gWW91ciBQcm9kdWN0IiBmb3IgbW9yZQorICogaW5mb3JtYXRpb24uPC9iPjwvcD4KKyAqCisgKiBATm90VGhyZWFkU2FmZQorICogQHNpbmNlIDEuMTEKKyAqLworcHVibGljIGNsYXNzIFgwMDE5X0VuY3J5cHRpb25SZWNpcGllbnRDZXJ0aWZpY2F0ZUxpc3QgZXh0ZW5kcyBQS1dhcmVFeHRyYUhlYWRlciB7CisKKyAgICBwdWJsaWMgWDAwMTlfRW5jcnlwdGlvblJlY2lwaWVudENlcnRpZmljYXRlTGlzdCgpIHsKKyAgICAgICAgc3VwZXIobmV3IFppcFNob3J0KDB4MDAxOSkpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9YNTQ1NV9FeHRlbmRlZFRpbWVzdGFtcC5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9YNTQ1NV9FeHRlbmRlZFRpbWVzdGFtcC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI4NTkwYzIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1g1NDU1X0V4dGVuZGVkVGltZXN0YW1wLmphdmEKQEAgLTAsMCArMSw1OTkgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcDsKKworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworaW1wb3J0IGphdmEudXRpbC5EYXRlOworaW1wb3J0IGphdmEudXRpbC56aXAuWmlwRXhjZXB0aW9uOworCisvKioKKyAqIDxwPkFuIGV4dHJhIGZpZWxkIHRoYXQgc3RvcmVzIGFkZGl0aW9uYWwgZmlsZSBhbmQgZGlyZWN0b3J5IHRpbWVzdGFtcCBkYXRhCisgKiBmb3IgemlwIGVudHJpZXMuICAgRWFjaCB6aXAgZW50cnkgY2FuIGluY2x1ZGUgdXAgdG8gdGhyZWUgdGltZXN0YW1wcworICogKG1vZGlmeSwgYWNjZXNzLCBjcmVhdGUqKS4gIFRoZSB0aW1lc3RhbXBzIGFyZSBzdG9yZWQgYXMgMzIgYml0IHNpZ25lZAorICogaW50ZWdlcnMgcmVwcmVzZW50aW5nIHNlY29uZHMgc2luY2UgVU5JWCBlcG9jaCAoSmFuIDFzdCwgMTk3MCwgVVRDKS4KKyAqIFRoaXMgZmllbGQgaW1wcm92ZXMgb24gemlwJ3MgZGVmYXVsdCB0aW1lc3RhbXAgZ3JhbnVsYXJpdHksIHNpbmNlIGl0CisgKiBhbGxvd3Mgb25lIHRvIHN0b3JlIGFkZGl0aW9uYWwgdGltZXN0YW1wcywgYW5kLCBpbiBhZGRpdGlvbiwgdGhlIHRpbWVzdGFtcHMKKyAqIGFyZSBzdG9yZWQgdXNpbmcgcGVyLXNlY29uZCBncmFudWxhcml0eSAoemlwJ3MgZGVmYXVsdCBiZWhhdmlvdXIgY2FuIG9ubHkgc3RvcmUKKyAqIHRpbWVzdGFtcHMgdG8gdGhlIG5lYXJlc3QgPGVtPmV2ZW48L2VtPiBzZWNvbmQpLgorICogPC9wPjxwPgorICogVW5mb3J0dW5hdGVseSwgMzIgKHNpZ25lZCkgYml0cyBjYW4gb25seSBzdG9yZSBkYXRlcyB1cCB0byB0aGUgeWVhciAyMDM3LAorICogYW5kIHNvIHRoaXMgZXh0cmEgZmllbGQgd2lsbCBldmVudHVhbGx5IGJlIG9ic29sZXRlLiAgRW5qb3kgaXQgd2hpbGUgaXQgbGFzdHMhCisgKiA8L3A+CisgKiA8dWw+CisgKiA8bGk+PGI+bW9kaWZ5VGltZTo8L2I+CisgKiBtb3N0IHJlY2VudCB0aW1lIG9mIGZpbGUvZGlyZWN0b3J5IG1vZGlmaWNhdGlvbgorICogKG9yIGZpbGUvZGlyIGNyZWF0aW9uIGlmIHRoZSBlbnRyeSBoYXMgbm90IGJlZW4KKyAqIG1vZGlmaWVkIHNpbmNlIGl0IHdhcyBjcmVhdGVkKS4KKyAqIDwvbGk+CisgKiA8bGk+PGI+YWNjZXNzVGltZTo8L2I+CisgKiBtb3N0IHJlY2VudCB0aW1lIGZpbGUvZGlyZWN0b3J5IHdhcyBvcGVuZWQKKyAqIChlLmcuLCByZWFkIGZyb20gZGlzaykuICBNYW55IHBlb3BsZSBkaXNhYmxlCisgKiB0aGVpciBvcGVyYXRpbmcgc3lzdGVtcyBmcm9tIHVwZGF0aW5nIHRoaXMgdmFsdWUKKyAqIHVzaW5nIHRoZSBOT0FUSU1FIG1vdW50IG9wdGlvbiB0byBvcHRpbWl6ZSBkaXNrIGJlaGF2aW91ciwKKyAqIGFuZCB0aHVzIGl0J3Mgbm90IGFsd2F5cyByZWxpYWJsZS4gIEluIHRob3NlIGNhc2VzCisgKiBpdCdzIGFsd2F5cyBlcXVhbCB0byBtb2RpZnlUaW1lLgorICogPC9saT4KKyAqIDxsaT48Yj4qY3JlYXRlVGltZTo8L2I+CisgKiBtb2Rlcm4gbGludXggZmlsZSBzeXN0ZW1zIChlLmcuLCBleHQyIGFuZCBuZXdlcikKKyAqIGRvIG5vdCBhcHBlYXIgdG8gc3RvcmUgYSB2YWx1ZSBsaWtlIHRoaXMsIGFuZCBzbworICogaXQncyB1c3VhbGx5IG9taXR0ZWQgYWx0b2dldGhlciBpbiB0aGUgemlwIGV4dHJhCisgKiBmaWVsZC4gIFBlcmhhcHMgb3RoZXIgdW5peCBzeXN0ZW1zIHRyYWNrIHRoaXMuCisgKiA8L2xpPjwvdWw+CisgKiA8cD4KKyAqIFdlJ3JlIHVzaW5nIHRoZSBmaWVsZCBkZWZpbml0aW9uIGdpdmVuIGluIEluZm8tWmlwJ3Mgc291cmNlIGFyY2hpdmU6CisgKiB6aXAtMy4wLnRhci5nei9wcm9naW5mby9leHRyYWZsZC50eHQKKyAqIDwvcD4KKyAqIDxwcmU+CisgKiBWYWx1ZSAgICAgICAgIFNpemUgICAgICAgIERlc2NyaXB0aW9uCisgKiAtLS0tLSAgICAgICAgIC0tLS0gICAgICAgIC0tLS0tLS0tLS0tCisgKiAweDU0NTUgICAgICAgIFNob3J0ICAgICAgIHRhZyBmb3IgdGhpcyBleHRyYSBibG9jayB0eXBlICgiVVQiKQorICogVFNpemUgICAgICAgICBTaG9ydCAgICAgICB0b3RhbCBkYXRhIHNpemUgZm9yIHRoaXMgYmxvY2sKKyAqIEZsYWdzICAgICAgICAgQnl0ZSAgICAgICAgaW5mbyBiaXRzCisgKiAoTW9kVGltZSkgICAgIExvbmcgICAgICAgIHRpbWUgb2YgbGFzdCBtb2RpZmljYXRpb24gKFVUQy9HTVQpCisgKiAoQWNUaW1lKSAgICAgIExvbmcgICAgICAgIHRpbWUgb2YgbGFzdCBhY2Nlc3MgKFVUQy9HTVQpCisgKiAoQ3JUaW1lKSAgICAgIExvbmcgICAgICAgIHRpbWUgb2Ygb3JpZ2luYWwgY3JlYXRpb24gKFVUQy9HTVQpCisgKgorICogQ2VudHJhbC1oZWFkZXIgdmVyc2lvbjoKKyAqCisgKiBWYWx1ZSAgICAgICAgIFNpemUgICAgICAgIERlc2NyaXB0aW9uCisgKiAtLS0tLSAgICAgICAgIC0tLS0gICAgICAgIC0tLS0tLS0tLS0tCisgKiAweDU0NTUgICAgICAgIFNob3J0ICAgICAgIHRhZyBmb3IgdGhpcyBleHRyYSBibG9jayB0eXBlICgiVVQiKQorICogVFNpemUgICAgICAgICBTaG9ydCAgICAgICB0b3RhbCBkYXRhIHNpemUgZm9yIHRoaXMgYmxvY2sKKyAqIEZsYWdzICAgICAgICAgQnl0ZSAgICAgICAgaW5mbyBiaXRzIChyZWZlcnMgdG8gbG9jYWwgaGVhZGVyISkKKyAqIChNb2RUaW1lKSAgICAgTG9uZyAgICAgICAgdGltZSBvZiBsYXN0IG1vZGlmaWNhdGlvbiAoVVRDL0dNVCkKKyAqIDwvcHJlPgorICogQHNpbmNlIDEuNQorICovCitwdWJsaWMgY2xhc3MgWDU0NTVfRXh0ZW5kZWRUaW1lc3RhbXAgaW1wbGVtZW50cyBaaXBFeHRyYUZpZWxkLCBDbG9uZWFibGUsIFNlcmlhbGl6YWJsZSB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgWmlwU2hvcnQgSEVBREVSX0lEID0gbmV3IFppcFNob3J0KDB4NTQ1NSk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7CisKKyAgICAvKioKKyAgICAgKiBUaGUgYml0IHNldCBpbnNpZGUgdGhlIGZsYWdzIGJ5IHdoZW4gdGhlIGxhc3QgbW9kaWZpY2F0aW9uIHRpbWUKKyAgICAgKiBpcyBwcmVzZW50IGluIHRoaXMgZXh0cmEgZmllbGQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIE1PRElGWV9USU1FX0JJVCA9IDE7CisgICAgLyoqCisgICAgICogVGhlIGJpdCBzZXQgaW5zaWRlIHRoZSBmbGFncyBieSB3aGVuIHRoZSBsYXNyIGFjY2VzcyB0aW1lIGlzCisgICAgICogcHJlc2VudCBpbiB0aGlzIGV4dHJhIGZpZWxkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBBQ0NFU1NfVElNRV9CSVQgPSAyOworICAgIC8qKgorICAgICAqIFRoZSBiaXQgc2V0IGluc2lkZSB0aGUgZmxhZ3MgYnkgd2hlbiB0aGUgb3JpZ2luYWwgY3JlYXRpb24gdGltZQorICAgICAqIGlzIHByZXNlbnQgaW4gdGhpcyBleHRyYSBmaWVsZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgQ1JFQVRFX1RJTUVfQklUID0gNDsKKworICAgIC8vIFRoZSAzIGJvb2xlYW4gZmllbGRzIChiZWxvdykgY29tZSBmcm9tIHRoaXMgZmxhZ3MgYnl0ZS4gIFRoZSByZW1haW5pbmcgNSBiaXRzCisgICAgLy8gYXJlIGlnbm9yZWQgYWNjb3JkaW5nIHRvIHRoZSBjdXJyZW50IHZlcnNpb24gb2YgdGhlIHNwZWMgKERlY2VtYmVyIDIwMTIpLgorICAgIHByaXZhdGUgYnl0ZSBmbGFnczsKKworICAgIC8vIE5vdGU6IGV2ZW4gaWYgYml0MSBhbmQgYml0MiBhcmUgc2V0LCB0aGUgQ2VudHJhbCBkYXRhIHdpbGwgc3RpbGwgbm90IGNvbnRhaW4KKyAgICAvLyBhY2Nlc3MvY3JlYXRlIGZpZWxkczogIG9ubHkgbG9jYWwgZGF0YSBldmVyIGhvbGRzIHRob3NlISAgVGhpcyBjYXVzZXMKKyAgICAvLyBzb21lIG9mIG91ciBpbXBsZW1lbnRhdGlvbiB0byBsb29rIGEgbGl0dGxlIG9kZCwgd2l0aCBzZWVtaW5nbHkgc3B1cmlvdXMKKyAgICAvLyAhPSBudWxsIGFuZCBsZW5ndGggY2hlY2tzLgorICAgIHByaXZhdGUgYm9vbGVhbiBiaXQwX21vZGlmeVRpbWVQcmVzZW50OworICAgIHByaXZhdGUgYm9vbGVhbiBiaXQxX2FjY2Vzc1RpbWVQcmVzZW50OworICAgIHByaXZhdGUgYm9vbGVhbiBiaXQyX2NyZWF0ZVRpbWVQcmVzZW50OworCisgICAgcHJpdmF0ZSBaaXBMb25nIG1vZGlmeVRpbWU7CisgICAgcHJpdmF0ZSBaaXBMb25nIGFjY2Vzc1RpbWU7CisgICAgcHJpdmF0ZSBaaXBMb25nIGNyZWF0ZVRpbWU7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvciBmb3IgWDU0NTVfRXh0ZW5kZWRUaW1lc3RhbXAuCisgICAgICovCisgICAgcHVibGljIFg1NDU1X0V4dGVuZGVkVGltZXN0YW1wKCkge30KKworICAgIC8qKgorICAgICAqIFRoZSBIZWFkZXItSUQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBmb3IgdGhlIGhlYWRlciBpZCBmb3IgdGhpcyBleHRyYWZpZWxkCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFppcFNob3J0IGdldEhlYWRlcklkKCkgeworICAgICAgICByZXR1cm4gSEVBREVSX0lEOworICAgIH0KKworICAgIC8qKgorICAgICAqIExlbmd0aCBvZiB0aGUgZXh0cmEgZmllbGQgaW4gdGhlIGxvY2FsIGZpbGUgZGF0YSAtIHdpdGhvdXQKKyAgICAgKiBIZWFkZXItSUQgb3IgbGVuZ3RoIHNwZWNpZmllci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSA8Y29kZT5aaXBTaG9ydDwvY29kZT4gZm9yIHRoZSBsZW5ndGggb2YgdGhlIGRhdGEgb2YgdGhpcyBleHRyYSBmaWVsZAorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBaaXBTaG9ydCBnZXRMb2NhbEZpbGVEYXRhTGVuZ3RoKCkgeworICAgICAgICByZXR1cm4gbmV3IFppcFNob3J0KDEgKworICAgICAgICAgICAgICAgIChiaXQwX21vZGlmeVRpbWVQcmVzZW50ID8gNCA6IDApICsKKyAgICAgICAgICAgICAgICAoYml0MV9hY2Nlc3NUaW1lUHJlc2VudCAmJiBhY2Nlc3NUaW1lICE9IG51bGwgPyA0IDogMCkgKworICAgICAgICAgICAgICAgIChiaXQyX2NyZWF0ZVRpbWVQcmVzZW50ICYmIGNyZWF0ZVRpbWUgIT0gbnVsbCA/IDQgOiAwKQorICAgICAgICApOworICAgIH0KKworICAgIC8qKgorICAgICAqIExlbmd0aCBvZiB0aGUgZXh0cmEgZmllbGQgaW4gdGhlIGxvY2FsIGZpbGUgZGF0YSAtIHdpdGhvdXQKKyAgICAgKiBIZWFkZXItSUQgb3IgbGVuZ3RoIHNwZWNpZmllci4KKyAgICAgKgorICAgICAqIDxwPkZvciBYNTQ1NSB0aGUgY2VudHJhbCBsZW5ndGggaXMgb2Z0ZW4gc21hbGxlciB0aGFuIHRoZQorICAgICAqIGxvY2FsIGxlbmd0aCwgYmVjYXVzZSBjZW50cmFsIGNhbm5vdCBjb250YWluIGFjY2VzcyBvciBjcmVhdGUKKyAgICAgKiB0aW1lc3RhbXBzLjwvcD4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSA8Y29kZT5aaXBTaG9ydDwvY29kZT4gZm9yIHRoZSBsZW5ndGggb2YgdGhlIGRhdGEgb2YgdGhpcyBleHRyYSBmaWVsZAorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBaaXBTaG9ydCBnZXRDZW50cmFsRGlyZWN0b3J5TGVuZ3RoKCkgeworICAgICAgICByZXR1cm4gbmV3IFppcFNob3J0KDEgKworICAgICAgICAgICAgICAgIChiaXQwX21vZGlmeVRpbWVQcmVzZW50ID8gNCA6IDApCisgICAgICAgICk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIGFjdHVhbCBkYXRhIHRvIHB1dCBpbnRvIGxvY2FsIGZpbGUgZGF0YSAtIHdpdGhvdXQgSGVhZGVyLUlECisgICAgICogb3IgbGVuZ3RoIHNwZWNpZmllci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gZ2V0IHRoZSBkYXRhCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJ5dGVbXSBnZXRMb2NhbEZpbGVEYXRhRGF0YSgpIHsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGRhdGEgPSBuZXcgYnl0ZVtnZXRMb2NhbEZpbGVEYXRhTGVuZ3RoKCkuZ2V0VmFsdWUoKV07CisgICAgICAgIGludCBwb3MgPSAwOworICAgICAgICBkYXRhW3BvcysrXSA9IDA7CisgICAgICAgIGlmIChiaXQwX21vZGlmeVRpbWVQcmVzZW50KSB7CisgICAgICAgICAgICBkYXRhWzBdIHw9IE1PRElGWV9USU1FX0JJVDsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkobW9kaWZ5VGltZS5nZXRCeXRlcygpLCAwLCBkYXRhLCBwb3MsIDQpOworICAgICAgICAgICAgcG9zICs9IDQ7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGJpdDFfYWNjZXNzVGltZVByZXNlbnQgJiYgYWNjZXNzVGltZSAhPSBudWxsKSB7CisgICAgICAgICAgICBkYXRhWzBdIHw9IEFDQ0VTU19USU1FX0JJVDsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYWNjZXNzVGltZS5nZXRCeXRlcygpLCAwLCBkYXRhLCBwb3MsIDQpOworICAgICAgICAgICAgcG9zICs9IDQ7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGJpdDJfY3JlYXRlVGltZVByZXNlbnQgJiYgY3JlYXRlVGltZSAhPSBudWxsKSB7CisgICAgICAgICAgICBkYXRhWzBdIHw9IENSRUFURV9USU1FX0JJVDsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoY3JlYXRlVGltZS5nZXRCeXRlcygpLCAwLCBkYXRhLCBwb3MsIDQpOworICAgICAgICAgICAgcG9zICs9IDQ7IC8vIE5PU09OQVIgLSBhc3NpZ25tZW50IGFzIGRvY3VtZW50YXRpb24KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZGF0YTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgYWN0dWFsIGRhdGEgdG8gcHV0IGludG8gY2VudHJhbCBkaXJlY3RvcnkgZGF0YSAtIHdpdGhvdXQgSGVhZGVyLUlECisgICAgICogb3IgbGVuZ3RoIHNwZWNpZmllci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGNlbnRyYWwgZGlyZWN0b3J5IGRhdGEKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYnl0ZVtdIGdldENlbnRyYWxEaXJlY3RvcnlEYXRhKCkgeworICAgICAgICBmaW5hbCBieXRlW10gY2VudHJhbERhdGEgPSBuZXcgYnl0ZVtnZXRDZW50cmFsRGlyZWN0b3J5TGVuZ3RoKCkuZ2V0VmFsdWUoKV07CisgICAgICAgIGZpbmFsIGJ5dGVbXSBsb2NhbERhdGEgPSBnZXRMb2NhbEZpbGVEYXRhRGF0YSgpOworCisgICAgICAgIC8vIFRydW5jYXRlIG91dCBjcmVhdGUgJiBhY2Nlc3MgdGltZSAobGFzdCA4IGJ5dGVzKSBmcm9tCisgICAgICAgIC8vIHRoZSBjb3B5IG9mIHRoZSBsb2NhbCBkYXRhIHdlIG9idGFpbmVkOgorICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGxvY2FsRGF0YSwgMCwgY2VudHJhbERhdGEsIDAsIGNlbnRyYWxEYXRhLmxlbmd0aCk7CisgICAgICAgIHJldHVybiBjZW50cmFsRGF0YTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQb3B1bGF0ZSBkYXRhIGZyb20gdGhpcyBhcnJheSBhcyBpZiBpdCB3YXMgaW4gbG9jYWwgZmlsZSBkYXRhLgorICAgICAqCisgICAgICogQHBhcmFtIGRhdGEgICBhbiBhcnJheSBvZiBieXRlcworICAgICAqIEBwYXJhbSBvZmZzZXQgdGhlIHN0YXJ0IG9mZnNldAorICAgICAqIEBwYXJhbSBsZW5ndGggdGhlIG51bWJlciBvZiBieXRlcyBpbiB0aGUgYXJyYXkgZnJvbSBvZmZzZXQKKyAgICAgKiBAdGhyb3dzIGphdmEudXRpbC56aXAuWmlwRXhjZXB0aW9uIG9uIGVycm9yCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcGFyc2VGcm9tTG9jYWxGaWxlRGF0YSgKKyAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBkYXRhLCBpbnQgb2Zmc2V0LCBmaW5hbCBpbnQgbGVuZ3RoCisgICAgKSB0aHJvd3MgWmlwRXhjZXB0aW9uIHsKKyAgICAgICAgcmVzZXQoKTsKKyAgICAgICAgZmluYWwgaW50IGxlbiA9IG9mZnNldCArIGxlbmd0aDsKKyAgICAgICAgc2V0RmxhZ3MoZGF0YVtvZmZzZXQrK10pOworICAgICAgICBpZiAoYml0MF9tb2RpZnlUaW1lUHJlc2VudCkgeworICAgICAgICAgICAgbW9kaWZ5VGltZSA9IG5ldyBaaXBMb25nKGRhdGEsIG9mZnNldCk7CisgICAgICAgICAgICBvZmZzZXQgKz0gNDsKKyAgICAgICAgfQorCisgICAgICAgIC8vIE5vdGljZSB0aGUgZXh0cmEgbGVuZ3RoIGNoZWNrIGluIGNhc2Ugd2UgYXJlIHBhcnNpbmcgdGhlIHNob3J0ZXIKKyAgICAgICAgLy8gY2VudHJhbCBkYXRhIGZpZWxkIChmb3IgYm90aCBhY2Nlc3MgYW5kIGNyZWF0ZSB0aW1lc3RhbXBzKS4KKyAgICAgICAgaWYgKGJpdDFfYWNjZXNzVGltZVByZXNlbnQgJiYgb2Zmc2V0ICsgNCA8PSBsZW4pIHsKKyAgICAgICAgICAgIGFjY2Vzc1RpbWUgPSBuZXcgWmlwTG9uZyhkYXRhLCBvZmZzZXQpOworICAgICAgICAgICAgb2Zmc2V0ICs9IDQ7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGJpdDJfY3JlYXRlVGltZVByZXNlbnQgJiYgb2Zmc2V0ICsgNCA8PSBsZW4pIHsKKyAgICAgICAgICAgIGNyZWF0ZVRpbWUgPSBuZXcgWmlwTG9uZyhkYXRhLCBvZmZzZXQpOworICAgICAgICAgICAgb2Zmc2V0ICs9IDQ7IC8vIE5PU09OQVIgLSBhc3NpZ25tZW50IGFzIGRvY3VtZW50YXRpb24KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIERvZXNuJ3QgZG8gYW55dGhpbmcgc3BlY2lhbCBzaW5jZSB0aGlzIGNsYXNzIGFsd2F5cyB1c2VzIHRoZQorICAgICAqIHNhbWUgcGFyc2luZyBsb2dpYyBmb3IgYm90aCBjZW50cmFsIGRpcmVjdG9yeSBhbmQgbG9jYWwgZmlsZSBkYXRhLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHBhcnNlRnJvbUNlbnRyYWxEaXJlY3RvcnlEYXRhKAorICAgICAgICAgICAgZmluYWwgYnl0ZVtdIGJ1ZmZlciwgZmluYWwgaW50IG9mZnNldCwgZmluYWwgaW50IGxlbmd0aAorICAgICkgdGhyb3dzIFppcEV4Y2VwdGlvbiB7CisgICAgICAgIHJlc2V0KCk7CisgICAgICAgIHBhcnNlRnJvbUxvY2FsRmlsZURhdGEoYnVmZmVyLCBvZmZzZXQsIGxlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVzZXQgc3RhdGUgYmFjayB0byBuZXdseSBjb25zdHJ1Y3RlZCBzdGF0ZS4gIEhlbHBzIHVzIG1ha2Ugc3VyZQorICAgICAqIHBhcnNlKCkgY2FsbHMgYWx3YXlzIGdlbmVyYXRlIGNsZWFuIHJlc3VsdHMuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHJlc2V0KCkgeworICAgICAgICBzZXRGbGFncygoYnl0ZSkgMCk7CisgICAgICAgIHRoaXMubW9kaWZ5VGltZSA9IG51bGw7CisgICAgICAgIHRoaXMuYWNjZXNzVGltZSA9IG51bGw7CisgICAgICAgIHRoaXMuY3JlYXRlVGltZSA9IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyBmbGFncyBieXRlLiAgVGhlIGZsYWdzIGJ5dGUgdGVsbHMgdXMgd2hpY2ggb2YgdGhlCisgICAgICogdGhyZWUgZGF0ZXN0YW1wIGZpZWxkcyBhcmUgcHJlc2VudCBpbiB0aGUgZGF0YToKKyAgICAgKiA8cHJlPgorICAgICAqIGJpdDAgLSBtb2RpZnkgdGltZQorICAgICAqIGJpdDEgLSBhY2Nlc3MgdGltZQorICAgICAqIGJpdDIgLSBjcmVhdGUgdGltZQorICAgICAqIDwvcHJlPgorICAgICAqIE9ubHkgZmlyc3QgMyBiaXRzIG9mIGZsYWdzIGFyZSB1c2VkIGFjY29yZGluZyB0byB0aGUKKyAgICAgKiBsYXRlc3QgdmVyc2lvbiBvZiB0aGUgc3BlYyAoRGVjZW1iZXIgMjAxMikuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmxhZ3MgZmxhZ3MgYnl0ZSBpbmRpY2F0aW5nIHdoaWNoIG9mIHRoZQorICAgICAqICAgICAgICAgICAgICB0aHJlZSBkYXRlc3RhbXAgZmllbGRzIGFyZSBwcmVzZW50LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEZsYWdzKGZpbmFsIGJ5dGUgZmxhZ3MpIHsKKyAgICAgICAgdGhpcy5mbGFncyA9IGZsYWdzOworICAgICAgICB0aGlzLmJpdDBfbW9kaWZ5VGltZVByZXNlbnQgPSAoZmxhZ3MgJiBNT0RJRllfVElNRV9CSVQpID09IE1PRElGWV9USU1FX0JJVDsKKyAgICAgICAgdGhpcy5iaXQxX2FjY2Vzc1RpbWVQcmVzZW50ID0gKGZsYWdzICYgQUNDRVNTX1RJTUVfQklUKSA9PSBBQ0NFU1NfVElNRV9CSVQ7CisgICAgICAgIHRoaXMuYml0Ml9jcmVhdGVUaW1lUHJlc2VudCA9IChmbGFncyAmIENSRUFURV9USU1FX0JJVCkgPT0gQ1JFQVRFX1RJTUVfQklUOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgZmxhZ3MgYnl0ZS4gIFRoZSBmbGFncyBieXRlIHRlbGxzIHVzIHdoaWNoIG9mIHRoZQorICAgICAqIHRocmVlIGRhdGVzdGFtcCBmaWVsZHMgYXJlIHByZXNlbnQgaW4gdGhlIGRhdGE6CisgICAgICogPHByZT4KKyAgICAgKiBiaXQwIC0gbW9kaWZ5IHRpbWUKKyAgICAgKiBiaXQxIC0gYWNjZXNzIHRpbWUKKyAgICAgKiBiaXQyIC0gY3JlYXRlIHRpbWUKKyAgICAgKiA8L3ByZT4KKyAgICAgKiBPbmx5IGZpcnN0IDMgYml0cyBvZiBmbGFncyBhcmUgdXNlZCBhY2NvcmRpbmcgdG8gdGhlCisgICAgICogbGF0ZXN0IHZlcnNpb24gb2YgdGhlIHNwZWMgKERlY2VtYmVyIDIwMTIpLgorICAgICAqCisgICAgICogQHJldHVybiBmbGFncyBieXRlIGluZGljYXRpbmcgd2hpY2ggb2YgdGhlCisgICAgICogICAgICAgICB0aHJlZSBkYXRlc3RhbXAgZmllbGRzIGFyZSBwcmVzZW50LgorICAgICAqLworICAgIHB1YmxpYyBieXRlIGdldEZsYWdzKCkgeyByZXR1cm4gZmxhZ3M7IH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciBiaXQwIG9mIHRoZSBmbGFncyBieXRlIGlzIHNldCBvciBub3QsCisgICAgICogd2hpY2ggc2hvdWxkIGNvcnJlc3BvbmQgdG8gdGhlIHByZXNlbmNlIG9yIGFic2VuY2Ugb2YKKyAgICAgKiBhIG1vZGlmeSB0aW1lc3RhbXAgaW4gdGhpcyBwYXJ0aWN1bGFyIHppcCBlbnRyeS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBiaXQwIG9mIHRoZSBmbGFncyBieXRlIGlzIHNldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0JpdDBfbW9kaWZ5VGltZVByZXNlbnQoKSB7IHJldHVybiBiaXQwX21vZGlmeVRpbWVQcmVzZW50OyB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgYml0MSBvZiB0aGUgZmxhZ3MgYnl0ZSBpcyBzZXQgb3Igbm90LAorICAgICAqIHdoaWNoIHNob3VsZCBjb3JyZXNwb25kIHRvIHRoZSBwcmVzZW5jZSBvciBhYnNlbmNlIG9mCisgICAgICogYSAibGFzdCBhY2Nlc3MiIHRpbWVzdGFtcCBpbiB0aGlzIHBhcnRpY3VsYXIgemlwIGVudHJ5LgorICAgICAqCisgICAgICogQHJldHVybiB0cnVlIGlmIGJpdDEgb2YgdGhlIGZsYWdzIGJ5dGUgaXMgc2V0LgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzQml0MV9hY2Nlc3NUaW1lUHJlc2VudCgpIHsgcmV0dXJuIGJpdDFfYWNjZXNzVGltZVByZXNlbnQ7IH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciBiaXQyIG9mIHRoZSBmbGFncyBieXRlIGlzIHNldCBvciBub3QsCisgICAgICogd2hpY2ggc2hvdWxkIGNvcnJlc3BvbmQgdG8gdGhlIHByZXNlbmNlIG9yIGFic2VuY2Ugb2YKKyAgICAgKiBhIGNyZWF0ZSB0aW1lc3RhbXAgaW4gdGhpcyBwYXJ0aWN1bGFyIHppcCBlbnRyeS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBiaXQyIG9mIHRoZSBmbGFncyBieXRlIGlzIHNldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0JpdDJfY3JlYXRlVGltZVByZXNlbnQoKSB7IHJldHVybiBiaXQyX2NyZWF0ZVRpbWVQcmVzZW50OyB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBtb2RpZnkgdGltZSAoc2Vjb25kcyBzaW5jZSBlcG9jaCkgb2YgdGhpcyB6aXAgZW50cnkKKyAgICAgKiBhcyBhIFppcExvbmcgb2JqZWN0LCBvciBudWxsIGlmIG5vIHN1Y2ggdGltZXN0YW1wIGV4aXN0cyBpbiB0aGUKKyAgICAgKiB6aXAgZW50cnkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIG1vZGlmeSB0aW1lIChzZWNvbmRzIHNpbmNlIGVwb2NoKSBvciBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBaaXBMb25nIGdldE1vZGlmeVRpbWUoKSB7IHJldHVybiBtb2RpZnlUaW1lOyB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBhY2Nlc3MgdGltZSAoc2Vjb25kcyBzaW5jZSBlcG9jaCkgb2YgdGhpcyB6aXAgZW50cnkKKyAgICAgKiBhcyBhIFppcExvbmcgb2JqZWN0LCBvciBudWxsIGlmIG5vIHN1Y2ggdGltZXN0YW1wIGV4aXN0cyBpbiB0aGUKKyAgICAgKiB6aXAgZW50cnkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFjY2VzcyB0aW1lIChzZWNvbmRzIHNpbmNlIGVwb2NoKSBvciBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBaaXBMb25nIGdldEFjY2Vzc1RpbWUoKSB7IHJldHVybiBhY2Nlc3NUaW1lOyB9CisKKyAgICAvKioKKyAgICAgKiA8cD4KKyAgICAgKiBSZXR1cm5zIHRoZSBjcmVhdGUgdGltZSAoc2Vjb25kcyBzaW5jZSBlcG9jaCkgb2YgdGhpcyB6aXAgZW50cnkKKyAgICAgKiBhcyBhIFppcExvbmcgb2JqZWN0LCBvciBudWxsIGlmIG5vIHN1Y2ggdGltZXN0YW1wIGV4aXN0cyBpbiB0aGUKKyAgICAgKiB6aXAgZW50cnkuCisgICAgICogPC9wPjxwPgorICAgICAqIE5vdGU6IG1vZGVybiBsaW51eCBmaWxlIHN5c3RlbXMgKGUuZy4sIGV4dDIpCisgICAgICogZG8gbm90IGFwcGVhciB0byBzdG9yZSBhICJjcmVhdGUgdGltZSIgdmFsdWUsIGFuZCBzbworICAgICAqIGl0J3MgdXN1YWxseSBvbWl0dGVkIGFsdG9nZXRoZXIgaW4gdGhlIHppcCBleHRyYQorICAgICAqIGZpZWxkLiAgUGVyaGFwcyBvdGhlciB1bml4IHN5c3RlbXMgdHJhY2sgdGhpcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gY3JlYXRlIHRpbWUgKHNlY29uZHMgc2luY2UgZXBvY2gpIG9yIG51bGwuCisgICAgICovCisgICAgcHVibGljIFppcExvbmcgZ2V0Q3JlYXRlVGltZSgpIHsgcmV0dXJuIGNyZWF0ZVRpbWU7IH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG1vZGlmeSB0aW1lIGFzIGEgamF2YS51dGlsLkRhdGUKKyAgICAgKiBvZiB0aGlzIHppcCBlbnRyeSwgb3IgbnVsbCBpZiBubyBzdWNoIHRpbWVzdGFtcCBleGlzdHMgaW4gdGhlIHppcCBlbnRyeS4KKyAgICAgKiBUaGUgbWlsbGlzZWNvbmRzIGFyZSBhbHdheXMgemVyb2VkIG91dCwgc2luY2UgdGhlIHVuZGVybHlpbmcgZGF0YQorICAgICAqIG9mZmVycyBvbmx5IHBlci1zZWNvbmQgcHJlY2lzaW9uLgorICAgICAqCisgICAgICogQHJldHVybiBtb2RpZnkgdGltZSBhcyBqYXZhLnV0aWwuRGF0ZSBvciBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBEYXRlIGdldE1vZGlmeUphdmFUaW1lKCkgeworICAgICAgICByZXR1cm4gemlwTG9uZ1RvRGF0ZShtb2RpZnlUaW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBhY2Nlc3MgdGltZSBhcyBhIGphdmEudXRpbC5EYXRlCisgICAgICogb2YgdGhpcyB6aXAgZW50cnksIG9yIG51bGwgaWYgbm8gc3VjaCB0aW1lc3RhbXAgZXhpc3RzIGluIHRoZSB6aXAgZW50cnkuCisgICAgICogVGhlIG1pbGxpc2Vjb25kcyBhcmUgYWx3YXlzIHplcm9lZCBvdXQsIHNpbmNlIHRoZSB1bmRlcmx5aW5nIGRhdGEKKyAgICAgKiBvZmZlcnMgb25seSBwZXItc2Vjb25kIHByZWNpc2lvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYWNjZXNzIHRpbWUgYXMgamF2YS51dGlsLkRhdGUgb3IgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGF0ZSBnZXRBY2Nlc3NKYXZhVGltZSgpIHsKKyAgICAgICAgcmV0dXJuIHppcExvbmdUb0RhdGUoYWNjZXNzVGltZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+CisgICAgICogUmV0dXJucyB0aGUgY3JlYXRlIHRpbWUgYXMgYSBhIGphdmEudXRpbC5EYXRlCisgICAgICogb2YgdGhpcyB6aXAgZW50cnksIG9yIG51bGwgaWYgbm8gc3VjaCB0aW1lc3RhbXAgZXhpc3RzIGluIHRoZSB6aXAgZW50cnkuCisgICAgICogVGhlIG1pbGxpc2Vjb25kcyBhcmUgYWx3YXlzIHplcm9lZCBvdXQsIHNpbmNlIHRoZSB1bmRlcmx5aW5nIGRhdGEKKyAgICAgKiBvZmZlcnMgb25seSBwZXItc2Vjb25kIHByZWNpc2lvbi4KKyAgICAgKiA8L3A+PHA+CisgICAgICogTm90ZTogbW9kZXJuIGxpbnV4IGZpbGUgc3lzdGVtcyAoZS5nLiwgZXh0MikKKyAgICAgKiBkbyBub3QgYXBwZWFyIHRvIHN0b3JlIGEgImNyZWF0ZSB0aW1lIiB2YWx1ZSwgYW5kIHNvCisgICAgICogaXQncyB1c3VhbGx5IG9taXR0ZWQgYWx0b2dldGhlciBpbiB0aGUgemlwIGV4dHJhCisgICAgICogZmllbGQuICBQZXJoYXBzIG90aGVyIHVuaXggc3lzdGVtcyB0cmFjayB0aGlzLgorICAgICAqCisgICAgICogQHJldHVybiBjcmVhdGUgdGltZSBhcyBqYXZhLnV0aWwuRGF0ZSBvciBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBEYXRlIGdldENyZWF0ZUphdmFUaW1lKCkgeworICAgICAgICByZXR1cm4gemlwTG9uZ1RvRGF0ZShjcmVhdGVUaW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8cD4KKyAgICAgKiBTZXRzIHRoZSBtb2RpZnkgdGltZSAoc2Vjb25kcyBzaW5jZSBlcG9jaCkgb2YgdGhpcyB6aXAgZW50cnkKKyAgICAgKiB1c2luZyBhIFppcExvbmcgb2JqZWN0LgorICAgICAqIDwvcD48cD4KKyAgICAgKiBOb3RlOiB0aGUgc2V0dGVycyBmb3IgZmxhZ3MgYW5kIHRpbWVzdGFtcHMgYXJlIGRlY291cGxlZC4KKyAgICAgKiBFdmVuIGlmIHRoZSB0aW1lc3RhbXAgaXMgbm90LW51bGwsIGl0IHdpbGwgb25seSBiZSB3cml0dGVuCisgICAgICogb3V0IGlmIHRoZSBjb3JyZXNwb25kaW5nIGJpdCBpbiB0aGUgZmxhZ3MgaXMgYWxzbyBzZXQuCisgICAgICogPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGwgWmlwTG9uZyBvZiB0aGUgbW9kaWZ5IHRpbWUgKHNlY29uZHMgcGVyIGVwb2NoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE1vZGlmeVRpbWUoZmluYWwgWmlwTG9uZyBsKSB7CisgICAgICAgIGJpdDBfbW9kaWZ5VGltZVByZXNlbnQgPSBsICE9IG51bGw7CisgICAgICAgIGZsYWdzID0gKGJ5dGUpIChsICE9IG51bGwgPyAoZmxhZ3MgfCBNT0RJRllfVElNRV9CSVQpCisgICAgICAgICAgICAgICAgICAgICAgICA6IChmbGFncyAmIH5NT0RJRllfVElNRV9CSVQpKTsKKyAgICAgICAgdGhpcy5tb2RpZnlUaW1lID0gbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8cD4KKyAgICAgKiBTZXRzIHRoZSBhY2Nlc3MgdGltZSAoc2Vjb25kcyBzaW5jZSBlcG9jaCkgb2YgdGhpcyB6aXAgZW50cnkKKyAgICAgKiB1c2luZyBhIFppcExvbmcgb2JqZWN0CisgICAgICogPC9wPjxwPgorICAgICAqIE5vdGU6IHRoZSBzZXR0ZXJzIGZvciBmbGFncyBhbmQgdGltZXN0YW1wcyBhcmUgZGVjb3VwbGVkLgorICAgICAqIEV2ZW4gaWYgdGhlIHRpbWVzdGFtcCBpcyBub3QtbnVsbCwgaXQgd2lsbCBvbmx5IGJlIHdyaXR0ZW4KKyAgICAgKiBvdXQgaWYgdGhlIGNvcnJlc3BvbmRpbmcgYml0IGluIHRoZSBmbGFncyBpcyBhbHNvIHNldC4KKyAgICAgKiA8L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gbCBaaXBMb25nIG9mIHRoZSBhY2Nlc3MgdGltZSAoc2Vjb25kcyBwZXIgZXBvY2gpCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0QWNjZXNzVGltZShmaW5hbCBaaXBMb25nIGwpIHsKKyAgICAgICAgYml0MV9hY2Nlc3NUaW1lUHJlc2VudCA9IGwgIT0gbnVsbDsKKyAgICAgICAgZmxhZ3MgPSAoYnl0ZSkgKGwgIT0gbnVsbCA/IChmbGFncyB8IEFDQ0VTU19USU1FX0JJVCkKKyAgICAgICAgICAgICAgICAgICAgICAgIDogKGZsYWdzICYgfkFDQ0VTU19USU1FX0JJVCkpOworICAgICAgICB0aGlzLmFjY2Vzc1RpbWUgPSBsOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPgorICAgICAqIFNldHMgdGhlIGNyZWF0ZSB0aW1lIChzZWNvbmRzIHNpbmNlIGVwb2NoKSBvZiB0aGlzIHppcCBlbnRyeQorICAgICAqIHVzaW5nIGEgWmlwTG9uZyBvYmplY3QKKyAgICAgKiA8L3A+PHA+CisgICAgICogTm90ZTogdGhlIHNldHRlcnMgZm9yIGZsYWdzIGFuZCB0aW1lc3RhbXBzIGFyZSBkZWNvdXBsZWQuCisgICAgICogRXZlbiBpZiB0aGUgdGltZXN0YW1wIGlzIG5vdC1udWxsLCBpdCB3aWxsIG9ubHkgYmUgd3JpdHRlbgorICAgICAqIG91dCBpZiB0aGUgY29ycmVzcG9uZGluZyBiaXQgaW4gdGhlIGZsYWdzIGlzIGFsc28gc2V0LgorICAgICAqIDwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsIFppcExvbmcgb2YgdGhlIGNyZWF0ZSB0aW1lIChzZWNvbmRzIHBlciBlcG9jaCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRDcmVhdGVUaW1lKGZpbmFsIFppcExvbmcgbCkgeworICAgICAgICBiaXQyX2NyZWF0ZVRpbWVQcmVzZW50ID0gbCAhPSBudWxsOworICAgICAgICBmbGFncyA9IChieXRlKSAobCAhPSBudWxsID8gKGZsYWdzIHwgQ1JFQVRFX1RJTUVfQklUKQorICAgICAgICAgICAgICAgICAgICAgICAgOiAoZmxhZ3MgJiB+Q1JFQVRFX1RJTUVfQklUKSk7CisgICAgICAgIHRoaXMuY3JlYXRlVGltZSA9IGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+CisgICAgICogU2V0cyB0aGUgbW9kaWZ5IHRpbWUgYXMgYSBqYXZhLnV0aWwuRGF0ZQorICAgICAqIG9mIHRoaXMgemlwIGVudHJ5LiAgU3VwcGxpZWQgdmFsdWUgaXMgdHJ1bmNhdGVkIHRvIHBlci1zZWNvbmQKKyAgICAgKiBwcmVjaXNpb24gKG1pbGxpc2Vjb25kcyB6ZXJvZWQtb3V0KS4KKyAgICAgKiA8L3A+PHA+CisgICAgICogTm90ZTogdGhlIHNldHRlcnMgZm9yIGZsYWdzIGFuZCB0aW1lc3RhbXBzIGFyZSBkZWNvdXBsZWQuCisgICAgICogRXZlbiBpZiB0aGUgdGltZXN0YW1wIGlzIG5vdC1udWxsLCBpdCB3aWxsIG9ubHkgYmUgd3JpdHRlbgorICAgICAqIG91dCBpZiB0aGUgY29ycmVzcG9uZGluZyBiaXQgaW4gdGhlIGZsYWdzIGlzIGFsc28gc2V0LgorICAgICAqIDwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkIG1vZGlmeSB0aW1lIGFzIGphdmEudXRpbC5EYXRlCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TW9kaWZ5SmF2YVRpbWUoZmluYWwgRGF0ZSBkKSB7IHNldE1vZGlmeVRpbWUoZGF0ZVRvWmlwTG9uZyhkKSk7IH0KKworICAgIC8qKgorICAgICAqIDxwPgorICAgICAqIFNldHMgdGhlIGFjY2VzcyB0aW1lIGFzIGEgamF2YS51dGlsLkRhdGUKKyAgICAgKiBvZiB0aGlzIHppcCBlbnRyeS4gIFN1cHBsaWVkIHZhbHVlIGlzIHRydW5jYXRlZCB0byBwZXItc2Vjb25kCisgICAgICogcHJlY2lzaW9uIChtaWxsaXNlY29uZHMgemVyb2VkLW91dCkuCisgICAgICogPC9wPjxwPgorICAgICAqIE5vdGU6IHRoZSBzZXR0ZXJzIGZvciBmbGFncyBhbmQgdGltZXN0YW1wcyBhcmUgZGVjb3VwbGVkLgorICAgICAqIEV2ZW4gaWYgdGhlIHRpbWVzdGFtcCBpcyBub3QtbnVsbCwgaXQgd2lsbCBvbmx5IGJlIHdyaXR0ZW4KKyAgICAgKiBvdXQgaWYgdGhlIGNvcnJlc3BvbmRpbmcgYml0IGluIHRoZSBmbGFncyBpcyBhbHNvIHNldC4KKyAgICAgKiA8L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gZCBhY2Nlc3MgdGltZSBhcyBqYXZhLnV0aWwuRGF0ZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEFjY2Vzc0phdmFUaW1lKGZpbmFsIERhdGUgZCkgeyBzZXRBY2Nlc3NUaW1lKGRhdGVUb1ppcExvbmcoZCkpOyB9CisKKyAgICAvKioKKyAgICAgKiA8cD4KKyAgICAgKiBTZXRzIHRoZSBjcmVhdGUgdGltZSBhcyBhIGphdmEudXRpbC5EYXRlCisgICAgICogb2YgdGhpcyB6aXAgZW50cnkuICBTdXBwbGllZCB2YWx1ZSBpcyB0cnVuY2F0ZWQgdG8gcGVyLXNlY29uZAorICAgICAqIHByZWNpc2lvbiAobWlsbGlzZWNvbmRzIHplcm9lZC1vdXQpLgorICAgICAqIDwvcD48cD4KKyAgICAgKiBOb3RlOiB0aGUgc2V0dGVycyBmb3IgZmxhZ3MgYW5kIHRpbWVzdGFtcHMgYXJlIGRlY291cGxlZC4KKyAgICAgKiBFdmVuIGlmIHRoZSB0aW1lc3RhbXAgaXMgbm90LW51bGwsIGl0IHdpbGwgb25seSBiZSB3cml0dGVuCisgICAgICogb3V0IGlmIHRoZSBjb3JyZXNwb25kaW5nIGJpdCBpbiB0aGUgZmxhZ3MgaXMgYWxzbyBzZXQuCisgICAgICogPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGQgY3JlYXRlIHRpbWUgYXMgamF2YS51dGlsLkRhdGUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRDcmVhdGVKYXZhVGltZShmaW5hbCBEYXRlIGQpIHsgc2V0Q3JlYXRlVGltZShkYXRlVG9aaXBMb25nKGQpKTsgfQorCisgICAgLyoqCisgICAgICogVXRpbGl0eSBtZXRob2QgY29udmVydHMgamF2YS51dGlsLkRhdGUgKG1pbGxpc2Vjb25kcyBzaW5jZSBlcG9jaCkKKyAgICAgKiBpbnRvIGEgWmlwTG9uZyAoc2Vjb25kcyBzaW5jZSBlcG9jaCkuCisgICAgICogPHAvPgorICAgICAqIEFsc28gbWFrZXMgc3VyZSB0aGUgY29udmVydGVkIFppcExvbmcgaXMgbm90IHRvbyBiaWcgdG8gZml0CisgICAgICogaW4gMzIgdW5zaWduZWQgYml0cy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkIGphdmEudXRpbC5EYXRlIHRvIGNvbnZlcnQgdG8gWmlwTG9uZworICAgICAqIEByZXR1cm4gWmlwTG9uZworICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIFppcExvbmcgZGF0ZVRvWmlwTG9uZyhmaW5hbCBEYXRlIGQpIHsKKyAgICAgICAgaWYgKGQgPT0gbnVsbCkgeyByZXR1cm4gbnVsbDsgfQorCisgICAgICAgIHJldHVybiB1bml4VGltZVRvWmlwTG9uZyhkLmdldFRpbWUoKSAvIDEwMDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBTdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBjbGFzcyB1c2VmdWwgZm9yCisgICAgICogZGVidWdnaW5nIHB1cnBvc2VzLgorICAgICAqCisgICAgICogQHJldHVybiBBIFN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIGNsYXNzIHVzZWZ1bCBmb3IKKyAgICAgKiAgICAgICAgIGRlYnVnZ2luZyBwdXJwb3Nlcy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICBmaW5hbCBTdHJpbmdCdWlsZGVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgIGJ1Zi5hcHBlbmQoIjB4NTQ1NSBaaXAgRXh0cmEgRmllbGQ6IEZsYWdzPSIpOworICAgICAgICBidWYuYXBwZW5kKEludGVnZXIudG9CaW5hcnlTdHJpbmcoWmlwVXRpbC51bnNpZ25lZEludFRvU2lnbmVkQnl0ZShmbGFncykpKS5hcHBlbmQoIiAiKTsKKyAgICAgICAgaWYgKGJpdDBfbW9kaWZ5VGltZVByZXNlbnQgJiYgbW9kaWZ5VGltZSAhPSBudWxsKSB7CisgICAgICAgICAgICBmaW5hbCBEYXRlIG0gPSBnZXRNb2RpZnlKYXZhVGltZSgpOworICAgICAgICAgICAgYnVmLmFwcGVuZCgiIE1vZGlmeTpbIikuYXBwZW5kKG0pLmFwcGVuZCgiXSAiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoYml0MV9hY2Nlc3NUaW1lUHJlc2VudCAmJiBhY2Nlc3NUaW1lICE9IG51bGwpIHsKKyAgICAgICAgICAgIGZpbmFsIERhdGUgYSA9IGdldEFjY2Vzc0phdmFUaW1lKCk7CisgICAgICAgICAgICBidWYuYXBwZW5kKCIgQWNjZXNzOlsiKS5hcHBlbmQoYSkuYXBwZW5kKCJdICIpOworICAgICAgICB9CisgICAgICAgIGlmIChiaXQyX2NyZWF0ZVRpbWVQcmVzZW50ICYmIGNyZWF0ZVRpbWUgIT0gbnVsbCkgeworICAgICAgICAgICAgZmluYWwgRGF0ZSBjID0gZ2V0Q3JlYXRlSmF2YVRpbWUoKTsKKyAgICAgICAgICAgIGJ1Zi5hcHBlbmQoIiBDcmVhdGU6WyIpLmFwcGVuZChjKS5hcHBlbmQoIl0gIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGJ1Zi50b1N0cmluZygpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB0aHJvd3MgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgT2JqZWN0IG8pIHsKKyAgICAgICAgaWYgKG8gaW5zdGFuY2VvZiBYNTQ1NV9FeHRlbmRlZFRpbWVzdGFtcCkgeworICAgICAgICAgICAgZmluYWwgWDU0NTVfRXh0ZW5kZWRUaW1lc3RhbXAgeGYgPSAoWDU0NTVfRXh0ZW5kZWRUaW1lc3RhbXApIG87CisKKyAgICAgICAgICAgIC8vIFRoZSBaaXBMb25nPT1aaXBMb25nIGNsYXVzZXMgaGFuZGxlIHRoZSBjYXNlcyB3aGVyZSBib3RoIGFyZSBudWxsLgorICAgICAgICAgICAgLy8gYW5kIG9ubHkgbGFzdCAzIGJpdHMgb2YgZmxhZ3MgbWF0dGVyLgorICAgICAgICAgICAgcmV0dXJuICgoZmxhZ3MgJiAweDA3KSA9PSAoeGYuZmxhZ3MgJiAweDA3KSkgJiYKKyAgICAgICAgICAgICAgICAgICAgKG1vZGlmeVRpbWUgPT0geGYubW9kaWZ5VGltZSB8fCAobW9kaWZ5VGltZSAhPSBudWxsICYmIG1vZGlmeVRpbWUuZXF1YWxzKHhmLm1vZGlmeVRpbWUpKSkgJiYKKyAgICAgICAgICAgICAgICAgICAgKGFjY2Vzc1RpbWUgPT0geGYuYWNjZXNzVGltZSB8fCAoYWNjZXNzVGltZSAhPSBudWxsICYmIGFjY2Vzc1RpbWUuZXF1YWxzKHhmLmFjY2Vzc1RpbWUpKSkgJiYKKyAgICAgICAgICAgICAgICAgICAgKGNyZWF0ZVRpbWUgPT0geGYuY3JlYXRlVGltZSB8fCAoY3JlYXRlVGltZSAhPSBudWxsICYmIGNyZWF0ZVRpbWUuZXF1YWxzKHhmLmNyZWF0ZVRpbWUpKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIGludCBoYyA9ICgtMTIzICogKGZsYWdzICYgMHgwNykpOyAvLyBvbmx5IGxhc3QgMyBiaXRzIG9mIGZsYWdzIG1hdHRlcgorICAgICAgICBpZiAobW9kaWZ5VGltZSAhPSBudWxsKSB7CisgICAgICAgICAgICBoYyBePSBtb2RpZnlUaW1lLmhhc2hDb2RlKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGFjY2Vzc1RpbWUgIT0gbnVsbCkgeworICAgICAgICAgICAgLy8gU2luY2UgYWNjZXNzVGltZSBpcyBvZnRlbiBzYW1lIGFzIG1vZGlmeVRpbWUsCisgICAgICAgICAgICAvLyB0aGlzIHByZXZlbnRzIHRoZW0gZnJvbSBYT1IgbmVnYXRpbmcgZWFjaCBvdGhlci4KKyAgICAgICAgICAgIGhjIF49IEludGVnZXIucm90YXRlTGVmdChhY2Nlc3NUaW1lLmhhc2hDb2RlKCksIDExKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoY3JlYXRlVGltZSAhPSBudWxsKSB7CisgICAgICAgICAgICBoYyBePSBJbnRlZ2VyLnJvdGF0ZUxlZnQoY3JlYXRlVGltZS5oYXNoQ29kZSgpLCAyMik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGhjOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIERhdGUgemlwTG9uZ1RvRGF0ZShaaXBMb25nIHVuaXhUaW1lKSB7CisgICAgICAgIHJldHVybiB1bml4VGltZSAhPSBudWxsID8gbmV3IERhdGUodW5peFRpbWUuZ2V0SW50VmFsdWUoKSAqIDEwMDBMKSA6IG51bGw7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgWmlwTG9uZyB1bml4VGltZVRvWmlwTG9uZyhsb25nIGwpIHsKKyAgICAgICAgaWYgKGwgPCBJbnRlZ2VyLk1JTl9WQUxVRSB8fCBsID4gSW50ZWdlci5NQVhfVkFMVUUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlg1NDU1IHRpbWVzdGFtcHMgbXVzdCBmaXQgaW4gYSBzaWduZWQgMzIgYml0IGludGVnZXI6ICIgKyBsKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IFppcExvbmcobCk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1g3ODc1X05ld1VuaXguamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvWDc4NzVfTmV3VW5peC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE1NDBkYmEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1g3ODc1X05ld1VuaXguamF2YQpAQCAtMCwwICsxLDM2NSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwOworCitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CitpbXBvcnQgamF2YS5tYXRoLkJpZ0ludGVnZXI7CitpbXBvcnQgamF2YS51dGlsLnppcC5aaXBFeGNlcHRpb247CisKK2ltcG9ydCBzdGF0aWMgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXAuWmlwVXRpbC5yZXZlcnNlOworaW1wb3J0IHN0YXRpYyBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcC5aaXBVdGlsLnNpZ25lZEJ5dGVUb1Vuc2lnbmVkSW50OworaW1wb3J0IHN0YXRpYyBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcC5aaXBVdGlsLnVuc2lnbmVkSW50VG9TaWduZWRCeXRlOworCisvKioKKyAqIEFuIGV4dHJhIGZpZWxkIHRoYXQgc3RvcmVzIFVOSVggVUlEL0dJRCBkYXRhIChvd25lciAmYW1wOyBncm91cCBvd25lcnNoaXApIGZvciBhIGdpdmVuCisgKiB6aXAgZW50cnkuICBXZSdyZSB1c2luZyB0aGUgZmllbGQgZGVmaW5pdGlvbiBnaXZlbiBpbiBJbmZvLVppcCdzIHNvdXJjZSBhcmNoaXZlOgorICogemlwLTMuMC50YXIuZ3ovcHJvZ2luZm8vZXh0cmFmbGQudHh0CisgKgorICogPHByZT4KKyAqIExvY2FsLWhlYWRlciB2ZXJzaW9uOgorICoKKyAqIFZhbHVlICAgICAgICAgU2l6ZSAgICAgICAgRGVzY3JpcHRpb24KKyAqIC0tLS0tICAgICAgICAgLS0tLSAgICAgICAgLS0tLS0tLS0tLS0KKyAqIDB4Nzg3NSAgICAgICAgU2hvcnQgICAgICAgdGFnIGZvciB0aGlzIGV4dHJhIGJsb2NrIHR5cGUgKCJ1eCIpCisgKiBUU2l6ZSAgICAgICAgIFNob3J0ICAgICAgIHRvdGFsIGRhdGEgc2l6ZSBmb3IgdGhpcyBibG9jaworICogVmVyc2lvbiAgICAgICAxIGJ5dGUgICAgICB2ZXJzaW9uIG9mIHRoaXMgZXh0cmEgZmllbGQsIGN1cnJlbnRseSAxCisgKiBVSURTaXplICAgICAgIDEgYnl0ZSAgICAgIFNpemUgb2YgVUlEIGZpZWxkCisgKiBVSUQgICAgICAgICAgIFZhcmlhYmxlICAgIFVJRCBmb3IgdGhpcyBlbnRyeSAobGl0dGxlIGVuZGlhbikKKyAqIEdJRFNpemUgICAgICAgMSBieXRlICAgICAgU2l6ZSBvZiBHSUQgZmllbGQKKyAqIEdJRCAgICAgICAgICAgVmFyaWFibGUgICAgR0lEIGZvciB0aGlzIGVudHJ5IChsaXR0bGUgZW5kaWFuKQorICoKKyAqIENlbnRyYWwtaGVhZGVyIHZlcnNpb246CisgKgorICogVmFsdWUgICAgICAgICBTaXplICAgICAgICBEZXNjcmlwdGlvbgorICogLS0tLS0gICAgICAgICAtLS0tICAgICAgICAtLS0tLS0tLS0tLQorICogMHg3ODU1ICAgICAgICBTaG9ydCAgICAgICB0YWcgZm9yIHRoaXMgZXh0cmEgYmxvY2sgdHlwZSAoIlV4IikKKyAqIFRTaXplICAgICAgICAgU2hvcnQgICAgICAgdG90YWwgZGF0YSBzaXplIGZvciB0aGlzIGJsb2NrICgwKQorICogPC9wcmU+CisgKiBAc2luY2UgMS41CisgKi8KK3B1YmxpYyBjbGFzcyBYNzg3NV9OZXdVbml4IGltcGxlbWVudHMgWmlwRXh0cmFGaWVsZCwgQ2xvbmVhYmxlLCBTZXJpYWxpemFibGUgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFppcFNob3J0IEhFQURFUl9JRCA9IG5ldyBaaXBTaG9ydCgweDc4NzUpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFppcFNob3J0IFpFUk8gPSBuZXcgWmlwU2hvcnQoMCk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQmlnSW50ZWdlciBPTkVfVEhPVVNBTkQgPSBCaWdJbnRlZ2VyLnZhbHVlT2YoMTAwMCk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7CisKKyAgICBwcml2YXRlIGludCB2ZXJzaW9uID0gMTsgLy8gYWx3YXlzICcxJyBhY2NvcmRpbmcgdG8gY3VycmVudCBpbmZvLXppcCBzcGVjLgorCisgICAgLy8gQmlnSW50ZWdlciBoZWxwcyB1cyB3aXRoIGxpdHRsZS1lbmRpYW4gLyBiaWctZW5kaWFuIGNvbnZlcnNpb25zLgorICAgIC8vICh0aGFua3MgdG8gQmlnSW50ZWdlci50b0J5dGVBcnJheSgpIGFuZCBhIHJldmVyc2UoKSBtZXRob2Qgd2UgY3JlYXRlZCkuCisgICAgLy8gQWxzbywgdGhlIHNwZWMgdGhlb3JldGljYWxseSBhbGxvd3MgVUlEL0dJRCB1cCB0byAyNTUgYnl0ZXMgbG9uZyEKKyAgICAvLworICAgIC8vIE5PVEU6ICBlcXVhbHMoKSBhbmQgaGFzaENvZGUoKSBjdXJyZW50bHkgYXNzdW1lIHRoZXNlIGNhbiBuZXZlciBiZSBudWxsLgorICAgIHByaXZhdGUgQmlnSW50ZWdlciB1aWQ7CisgICAgcHJpdmF0ZSBCaWdJbnRlZ2VyIGdpZDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yIGZvciBYNzg3NV9OZXdVbml4LgorICAgICAqLworICAgIHB1YmxpYyBYNzg3NV9OZXdVbml4KCkgeworICAgICAgICByZXNldCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBIZWFkZXItSUQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBmb3IgdGhlIGhlYWRlciBpZCBmb3IgdGhpcyBleHRyYWZpZWxkCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFppcFNob3J0IGdldEhlYWRlcklkKCkgeworICAgICAgICByZXR1cm4gSEVBREVSX0lEOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIFVJRCBhcyBhIGxvbmcuICBVSUQgaXMgdHlwaWNhbGx5IGEgMzIgYml0IHVuc2lnbmVkCisgICAgICogdmFsdWUgb24gbW9zdCBVTklYIHN5c3RlbXMsIHNvIHdlIHJldHVybiBhIGxvbmcgdG8gYXZvaWQKKyAgICAgKiBpbnRlZ2VyIG92ZXJmbG93IGludG8gdGhlIG5lZ2F0aXZlcyBpbiBjYXNlIHZhbHVlcyBhYm92ZQorICAgICAqIGFuZCBpbmNsdWRpbmcgMl4zMSBhcmUgYmVpbmcgdXNlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIFVJRCB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBnZXRVSUQoKSB7IHJldHVybiBaaXBVdGlsLmJpZ1RvTG9uZyh1aWQpOyB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBHSUQgYXMgYSBsb25nLiAgR0lEIGlzIHR5cGljYWxseSBhIDMyIGJpdCB1bnNpZ25lZAorICAgICAqIHZhbHVlIG9uIG1vc3QgVU5JWCBzeXN0ZW1zLCBzbyB3ZSByZXR1cm4gYSBsb25nIHRvIGF2b2lkCisgICAgICogaW50ZWdlciBvdmVyZmxvdyBpbnRvIHRoZSBuZWdhdGl2ZXMgaW4gY2FzZSB2YWx1ZXMgYWJvdmUKKyAgICAgKiBhbmQgaW5jbHVkaW5nIDJeMzEgYXJlIGJlaW5nIHVzZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBHSUQgdmFsdWUuCisgICAgICovCisgICAgcHVibGljIGxvbmcgZ2V0R0lEKCkgeyByZXR1cm4gWmlwVXRpbC5iaWdUb0xvbmcoZ2lkKTsgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgVUlELgorICAgICAqCisgICAgICogQHBhcmFtIGwgVUlEIHZhbHVlIHRvIHNldCBvbiB0aGlzIGV4dHJhIGZpZWxkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFVJRChmaW5hbCBsb25nIGwpIHsKKyAgICAgICAgdGhpcy51aWQgPSBaaXBVdGlsLmxvbmdUb0JpZyhsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBHSUQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbCBHSUQgdmFsdWUgdG8gc2V0IG9uIHRoaXMgZXh0cmEgZmllbGQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0R0lEKGZpbmFsIGxvbmcgbCkgeworICAgICAgICB0aGlzLmdpZCA9IFppcFV0aWwubG9uZ1RvQmlnKGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIExlbmd0aCBvZiB0aGUgZXh0cmEgZmllbGQgaW4gdGhlIGxvY2FsIGZpbGUgZGF0YSAtIHdpdGhvdXQKKyAgICAgKiBIZWFkZXItSUQgb3IgbGVuZ3RoIHNwZWNpZmllci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSA8Y29kZT5aaXBTaG9ydDwvY29kZT4gZm9yIHRoZSBsZW5ndGggb2YgdGhlIGRhdGEgb2YgdGhpcyBleHRyYSBmaWVsZAorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBaaXBTaG9ydCBnZXRMb2NhbEZpbGVEYXRhTGVuZ3RoKCkgeworICAgICAgICBieXRlW10gYiA9IHRyaW1MZWFkaW5nWmVyb2VzRm9yY2VNaW5MZW5ndGgodWlkLnRvQnl0ZUFycmF5KCkpOworICAgICAgICBmaW5hbCBpbnQgdWlkU2l6ZSA9IGIgPT0gbnVsbCA/IDAgOiBiLmxlbmd0aDsKKyAgICAgICAgYiA9IHRyaW1MZWFkaW5nWmVyb2VzRm9yY2VNaW5MZW5ndGgoZ2lkLnRvQnl0ZUFycmF5KCkpOworICAgICAgICBmaW5hbCBpbnQgZ2lkU2l6ZSA9IGIgPT0gbnVsbCA/IDAgOiBiLmxlbmd0aDsKKworICAgICAgICAvLyBUaGUgMyBjb21lcyBmcm9tOiAgdmVyc2lvbj0xICsgdWlkc2l6ZT0xICsgZ2lkc2l6ZT0xCisgICAgICAgIHJldHVybiBuZXcgWmlwU2hvcnQoMyArIHVpZFNpemUgKyBnaWRTaXplKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMZW5ndGggb2YgdGhlIGV4dHJhIGZpZWxkIGluIHRoZSBjZW50cmFsIGRpcmVjdG9yeSBkYXRhIC0gd2l0aG91dAorICAgICAqIEhlYWRlci1JRCBvciBsZW5ndGggc3BlY2lmaWVyLgorICAgICAqCisgICAgICogQHJldHVybiBhIDxjb2RlPlppcFNob3J0PC9jb2RlPiBmb3IgdGhlIGxlbmd0aCBvZiB0aGUgZGF0YSBvZiB0aGlzIGV4dHJhIGZpZWxkCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFppcFNob3J0IGdldENlbnRyYWxEaXJlY3RvcnlMZW5ndGgoKSB7CisgICAgICAgIHJldHVybiBaRVJPOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBhY3R1YWwgZGF0YSB0byBwdXQgaW50byBsb2NhbCBmaWxlIGRhdGEgLSB3aXRob3V0IEhlYWRlci1JRAorICAgICAqIG9yIGxlbmd0aCBzcGVjaWZpZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGdldCB0aGUgZGF0YQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBieXRlW10gZ2V0TG9jYWxGaWxlRGF0YURhdGEoKSB7CisgICAgICAgIGJ5dGVbXSB1aWRCeXRlcyA9IHVpZC50b0J5dGVBcnJheSgpOworICAgICAgICBieXRlW10gZ2lkQnl0ZXMgPSBnaWQudG9CeXRlQXJyYXkoKTsKKworICAgICAgICAvLyBCaWdJbnRlZ2VyIG1pZ2h0IHByZXBlbmQgYSBsZWFkaW5nLXplcm8gdG8gZm9yY2UgYSBwb3NpdGl2ZSByZXByZXNlbnRhdGlvbgorICAgICAgICAvLyAoZS5nLiwgc28gdGhhdCB0aGUgc2lnbi1iaXQgaXMgc2V0IHRvIHplcm8pLiAgV2UgbmVlZCB0byByZW1vdmUgdGhhdAorICAgICAgICAvLyBiZWZvcmUgc2VuZGluZyB0aGUgbnVtYmVyIG92ZXIgdGhlIHdpcmUuCisgICAgICAgIHVpZEJ5dGVzID0gdHJpbUxlYWRpbmdaZXJvZXNGb3JjZU1pbkxlbmd0aCh1aWRCeXRlcyk7CisgICAgICAgIGludCB1aWRCeXRlc0xlbiA9IHVpZEJ5dGVzICE9IG51bGwgPyB1aWRCeXRlcy5sZW5ndGggOiAwOworICAgICAgICBnaWRCeXRlcyA9IHRyaW1MZWFkaW5nWmVyb2VzRm9yY2VNaW5MZW5ndGgoZ2lkQnl0ZXMpOworICAgICAgICBpbnQgZ2lkQnl0ZXNMZW4gPSBnaWRCeXRlcyAhPSBudWxsID8gZ2lkQnl0ZXMubGVuZ3RoIDogMDsKKworICAgICAgICAvLyBDb3VsZG4ndCBicmluZyBteXNlbGYgdG8ganVzdCBjYWxsIGdldExvY2FsRmlsZURhdGFMZW5ndGgoKSB3aGVuIHdlJ3ZlCisgICAgICAgIC8vIGFscmVhZHkgZ290IHRoZSBhcnJheXMgcmlnaHQgaGVyZS4gIFllYWgsIHllYWgsIEkga25vdywgcHJlbWF0dXJlCisgICAgICAgIC8vIG9wdGltaXphdGlvbiBpcyB0aGUgcm9vdCBvZiBhbGwuLi4KKyAgICAgICAgLy8KKyAgICAgICAgLy8gVGhlIDMgY29tZXMgZnJvbTogIHZlcnNpb249MSArIHVpZHNpemU9MSArIGdpZHNpemU9MQorICAgICAgICBmaW5hbCBieXRlW10gZGF0YSA9IG5ldyBieXRlWzMgKyB1aWRCeXRlc0xlbiArIGdpZEJ5dGVzTGVuXTsKKworICAgICAgICAvLyByZXZlcnNlKCkgc3dpdGNoZXMgYnl0ZSBhcnJheSBmcm9tIGJpZy1lbmRpYW4gdG8gbGl0dGxlLWVuZGlhbi4KKyAgICAgICAgaWYgKHVpZEJ5dGVzICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldmVyc2UodWlkQnl0ZXMpOworICAgICAgICB9CisgICAgICAgIGlmIChnaWRCeXRlcyAhPSBudWxsKSB7CisgICAgICAgICAgICByZXZlcnNlKGdpZEJ5dGVzKTsKKyAgICAgICAgfQorCisgICAgICAgIGludCBwb3MgPSAwOworICAgICAgICBkYXRhW3BvcysrXSA9IHVuc2lnbmVkSW50VG9TaWduZWRCeXRlKHZlcnNpb24pOworICAgICAgICBkYXRhW3BvcysrXSA9IHVuc2lnbmVkSW50VG9TaWduZWRCeXRlKHVpZEJ5dGVzTGVuKTsKKyAgICAgICAgaWYgKHVpZEJ5dGVzICE9IG51bGwpIHsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkodWlkQnl0ZXMsIDAsIGRhdGEsIHBvcywgdWlkQnl0ZXNMZW4pOworICAgICAgICB9CisgICAgICAgIHBvcyArPSB1aWRCeXRlc0xlbjsKKyAgICAgICAgZGF0YVtwb3MrK10gPSB1bnNpZ25lZEludFRvU2lnbmVkQnl0ZShnaWRCeXRlc0xlbik7CisgICAgICAgIGlmIChnaWRCeXRlcyAhPSBudWxsKSB7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGdpZEJ5dGVzLCAwLCBkYXRhLCBwb3MsIGdpZEJ5dGVzTGVuKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZGF0YTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgYWN0dWFsIGRhdGEgdG8gcHV0IGludG8gY2VudHJhbCBkaXJlY3RvcnkgZGF0YSAtIHdpdGhvdXQgSGVhZGVyLUlECisgICAgICogb3IgbGVuZ3RoIHNwZWNpZmllci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gZ2V0IHRoZSBkYXRhCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJ5dGVbXSBnZXRDZW50cmFsRGlyZWN0b3J5RGF0YSgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBieXRlWzBdOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBvcHVsYXRlIGRhdGEgZnJvbSB0aGlzIGFycmF5IGFzIGlmIGl0IHdhcyBpbiBsb2NhbCBmaWxlIGRhdGEuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGF0YSAgIGFuIGFycmF5IG9mIGJ5dGVzCisgICAgICogQHBhcmFtIG9mZnNldCB0aGUgc3RhcnQgb2Zmc2V0CisgICAgICogQHBhcmFtIGxlbmd0aCB0aGUgbnVtYmVyIG9mIGJ5dGVzIGluIHRoZSBhcnJheSBmcm9tIG9mZnNldAorICAgICAqIEB0aHJvd3MgamF2YS51dGlsLnppcC5aaXBFeGNlcHRpb24gb24gZXJyb3IKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBwYXJzZUZyb21Mb2NhbEZpbGVEYXRhKAorICAgICAgICAgICAgZmluYWwgYnl0ZVtdIGRhdGEsIGludCBvZmZzZXQsIGZpbmFsIGludCBsZW5ndGgKKyAgICApIHRocm93cyBaaXBFeGNlcHRpb24geworICAgICAgICByZXNldCgpOworICAgICAgICB0aGlzLnZlcnNpb24gPSBzaWduZWRCeXRlVG9VbnNpZ25lZEludChkYXRhW29mZnNldCsrXSk7CisgICAgICAgIGZpbmFsIGludCB1aWRTaXplID0gc2lnbmVkQnl0ZVRvVW5zaWduZWRJbnQoZGF0YVtvZmZzZXQrK10pOworICAgICAgICBmaW5hbCBieXRlW10gdWlkQnl0ZXMgPSBuZXcgYnl0ZVt1aWRTaXplXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShkYXRhLCBvZmZzZXQsIHVpZEJ5dGVzLCAwLCB1aWRTaXplKTsKKyAgICAgICAgb2Zmc2V0ICs9IHVpZFNpemU7CisgICAgICAgIHRoaXMudWlkID0gbmV3IEJpZ0ludGVnZXIoMSwgcmV2ZXJzZSh1aWRCeXRlcykpOyAvLyBzaWduLWJpdCBmb3JjZWQgcG9zaXRpdmUKKworICAgICAgICBmaW5hbCBpbnQgZ2lkU2l6ZSA9IHNpZ25lZEJ5dGVUb1Vuc2lnbmVkSW50KGRhdGFbb2Zmc2V0KytdKTsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGdpZEJ5dGVzID0gbmV3IGJ5dGVbZ2lkU2l6ZV07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZGF0YSwgb2Zmc2V0LCBnaWRCeXRlcywgMCwgZ2lkU2l6ZSk7CisgICAgICAgIHRoaXMuZ2lkID0gbmV3IEJpZ0ludGVnZXIoMSwgcmV2ZXJzZShnaWRCeXRlcykpOyAvLyBzaWduLWJpdCBmb3JjZWQgcG9zaXRpdmUKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEb2Vzbid0IGRvIGFueXRoaW5nIHNpbmNlIHRoaXMgY2xhc3MgZG9lc24ndCBzdG9yZSBhbnl0aGluZworICAgICAqIGluc2lkZSB0aGUgY2VudHJhbCBkaXJlY3RvcnkuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcGFyc2VGcm9tQ2VudHJhbERpcmVjdG9yeURhdGEoCisgICAgICAgICAgICBmaW5hbCBieXRlW10gYnVmZmVyLCBmaW5hbCBpbnQgb2Zmc2V0LCBmaW5hbCBpbnQgbGVuZ3RoCisgICAgKSB0aHJvd3MgWmlwRXhjZXB0aW9uIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXNldCBzdGF0ZSBiYWNrIHRvIG5ld2x5IGNvbnN0cnVjdGVkIHN0YXRlLiAgSGVscHMgdXMgbWFrZSBzdXJlCisgICAgICogcGFyc2UoKSBjYWxscyBhbHdheXMgZ2VuZXJhdGUgY2xlYW4gcmVzdWx0cy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcmVzZXQoKSB7CisgICAgICAgIC8vIFR5cGljYWwgVUlEL0dJRCBvZiB0aGUgZmlyc3Qgbm9uLXJvb3QgdXNlciBjcmVhdGVkIG9uIGEgdW5peCBzeXN0ZW0uCisgICAgICAgIHVpZCA9IE9ORV9USE9VU0FORDsKKyAgICAgICAgZ2lkID0gT05FX1RIT1VTQU5EOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBTdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBjbGFzcyB1c2VmdWwgZm9yCisgICAgICogZGVidWdnaW5nIHB1cnBvc2VzLgorICAgICAqCisgICAgICogQHJldHVybiBBIFN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIGNsYXNzIHVzZWZ1bCBmb3IKKyAgICAgKiAgICAgICAgIGRlYnVnZ2luZyBwdXJwb3Nlcy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICByZXR1cm4gIjB4Nzg3NSBaaXAgRXh0cmEgRmllbGQ6IFVJRD0iICsgdWlkICsgIiBHSUQ9IiArIGdpZDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIE9iamVjdCBvKSB7CisgICAgICAgIGlmIChvIGluc3RhbmNlb2YgWDc4NzVfTmV3VW5peCkgeworICAgICAgICAgICAgZmluYWwgWDc4NzVfTmV3VW5peCB4ZiA9IChYNzg3NV9OZXdVbml4KSBvOworICAgICAgICAgICAgLy8gV2UgYXNzdW1lIHVpZCBhbmQgZ2lkIGNhbiBuZXZlciBiZSBudWxsLgorICAgICAgICAgICAgcmV0dXJuIHZlcnNpb24gPT0geGYudmVyc2lvbiAmJiB1aWQuZXF1YWxzKHhmLnVpZCkgJiYgZ2lkLmVxdWFscyh4Zi5naWQpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICBpbnQgaGMgPSAtMTIzNDU2NyAqIHZlcnNpb247CisgICAgICAgIC8vIFNpbmNlIG1vc3QgVUlEJ3MgYW5kIEdJRCdzIGFyZSBiZWxvdyA2NSw1MzYsIHRoaXMgaXMgKGhvcGVmdWxseSEpCisgICAgICAgIC8vIGEgbmljZSB3YXkgdG8gbWFrZSBzdXJlIHR5cGljYWwgVUlEIGFuZCBHSUQgdmFsdWVzIGltcGFjdCB0aGUgaGFzaAorICAgICAgICAvLyBhcyBtdWNoIGFzIHBvc3NpYmxlLgorICAgICAgICBoYyBePSBJbnRlZ2VyLnJvdGF0ZUxlZnQodWlkLmhhc2hDb2RlKCksIDE2KTsKKyAgICAgICAgaGMgXj0gZ2lkLmhhc2hDb2RlKCk7CisgICAgICAgIHJldHVybiBoYzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBOb3QgcmVhbGx5IGZvciBleHRlcm5hbCB1c2FnZSwgYnV0IG1hcmtlZCAicGFja2FnZSIgdmlzaWJpbGl0eQorICAgICAqIHRvIGhlbHAgdXMgSlVuaXQgaXQuICAgVHJpbXMgYSBieXRlIGFycmF5IG9mIGxlYWRpbmcgemVyb2VzIHdoaWxlCisgICAgICogYWxzbyBlbmZvcmNpbmcgYSBtaW5pbXVtIGxlbmd0aCwgYW5kIHRodXMgaXQgcmVhbGx5IHRyaW1zIEFORCBwYWRzCisgICAgICogYXQgdGhlIHNhbWUgdGltZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheSBieXRlW10gYXJyYXkgdG8gdHJpbSAmIHBhZC4KKyAgICAgKiBAcmV0dXJuIHRyaW1tZWQgJiBwYWRkZWQgYnl0ZVtdIGFycmF5LgorICAgICAqLworICAgIHN0YXRpYyBieXRlW10gdHJpbUxlYWRpbmdaZXJvZXNGb3JjZU1pbkxlbmd0aChmaW5hbCBieXRlW10gYXJyYXkpIHsKKyAgICAgICAgaWYgKGFycmF5ID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBhcnJheTsKKyAgICAgICAgfQorCisgICAgICAgIGludCBwb3MgPSAwOworICAgICAgICBmb3IgKGZpbmFsIGJ5dGUgYiA6IGFycmF5KSB7CisgICAgICAgICAgICBpZiAoYiA9PSAwKSB7CisgICAgICAgICAgICAgICAgcG9zKys7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLyoKKworICAgICAgICBJIGFnb25pemVkIG92ZXIgbXkgY2hvaWNlIG9mIE1JTl9MRU5HVEg9MS4gIEhlcmUncyB0aGUgc2l0dWF0aW9uOgorICAgICAgICBJbmZvWmlwICh0aGUgdG9vbCBJIGFtIHVzaW5nIHRvIHRlc3QgaW50ZXJvcCkgYWx3YXlzIHNldHMgdGhlc2UKKyAgICAgICAgdG8gbGVuZ3RoPTQuICBBbmQgc28gYSBVSUQgb2YgMCAodHlwaWNhbGx5IHJvb3QpIGZvciBleGFtcGxlIGlzCisgICAgICAgIGVuY29kZWQgYXMgezQsMCwwLDAsMH0gKGxlbj00LCAzMiBiaXRzIG9mIHplcm8pLCB3aGVuIGl0IGNvdWxkIGp1c3QKKyAgICAgICAgYXMgZWFzaWx5IGJlIGVuY29kZWQgYXMgezEsMH0gKGxlbj0xLCA4IGJpdHMgb2YgemVybykgYWNjb3JkaW5nIHRvCisgICAgICAgIHRoZSBzcGVjLgorCisgICAgICAgIEluIHRoZSBlbmQgSSBkZWNpZGVkIG9uIE1JTl9MRU5HVEg9MSBmb3IgZm91ciByZWFzb25zOgorCisgICAgICAgIDEuKSAgV2UgYXJlIGFkaGVyaW5nIHRvIHRoZSBzcGVjIGFzIGZhciBhcyBJIGNhbiB0ZWxsLCBhbmQgc28KKyAgICAgICAgICAgICBhIGNvbnN1bWVyIHRoYXQgY2Fubm90IHBhcnNlIHRoaXMgaXMgYnJva2VuLgorCisgICAgICAgIDIuKSAgRnVuZGFtZW50YWxseSwgemlwIGZpbGVzIGFyZSBhYm91dCBzaHJpbmtpbmcgdGhpbmdzLCBzbworICAgICAgICAgICAgIGxldCdzIHNhdmUgYSBmZXcgYnl0ZXMgcGVyIGVudHJ5IHdoaWxlIHdlIGNhbi4KKworICAgICAgICAzLikgIE9mIGFsbCB0aGUgcGVvcGxlIGNyZWF0aW5nIHppcCBmaWxlcyB1c2luZyBjb21tb25zLQorICAgICAgICAgICAgIGNvbXByZXNzLCBob3cgbWFueSBjYXJlIGFib3V0IFVOSVggVUlEL0dJRCBhdHRyaWJ1dGVzCisgICAgICAgICAgICAgb2YgdGhlIGZpbGVzIHRoZXkgc3RvcmU/ICAgKGUuZy4sIEkgYW0gcHJvYmFibHkgdGhpbmtpbmcKKyAgICAgICAgICAgICB3YXkgdG9vIGhhcmQgYWJvdXQgdGhpcyBhbmQgbm8gb25lIGNhcmVzISkKKworICAgICAgICA0LikgIEluZm9aaXAncyB0b29sLCBldmVuIHRob3VnaCBpdCBjYXJlZnVsbHkgc3RvcmVzIGV2ZXJ5IFVJRC9HSUQKKyAgICAgICAgICAgICBmb3IgZXZlcnkgZmlsZSB6aXBwZWQgb24gYSB1bml4IG1hY2hpbmUgKGJ5IGRlZmF1bHQpIGN1cnJlbnRseQorICAgICAgICAgICAgIGFwcGVhcnMgdW5hYmxlIHRvIGV2ZXIgcmVzdG9yZSBVSUQvR0lELgorICAgICAgICAgICAgIHVuemlwIC1YIGhhcyBubyBlZmZlY3Qgb24gbXkgbWFjaGluZSwgZXZlbiB3aGVuIHJ1biBhcyByb290ISEhIQorCisgICAgICAgIEFuZCB0aHVzIGl0IGlzIGRlY2lkZWQ6ICBNSU5fTEVOR1RIPTEuCisKKyAgICAgICAgSWYgYW55b25lIHJ1bnMgaW50byBpbnRlcm9wIHByb2JsZW1zIGZyb20gdGhpcywgZmVlbCBmcmVlIHRvIHNldAorICAgICAgICBpdCB0byBNSU5fTEVOR1RIPTQgYXQgc29tZSBmdXR1cmUgdGltZSwgYW5kIHRoZW4gd2Ugd2lsbCBiZWhhdmUKKyAgICAgICAgZXhhY3RseSBsaWtlIEluZm9aaXAgKHJlcXVpcmVzIGNoYW5nZXMgdG8gdW5pdCB0ZXN0cywgdGhvdWdoKS4KKworICAgICAgICBBbmQgSSBhbSBzb3JyeSB0aGF0IHRoZSB0aW1lIHlvdSBzcGVudCByZWFkaW5nIHRoaXMgY29tbWVudCBpcyBub3cKKyAgICAgICAgZ29uZSBhbmQgeW91IGNhbiBuZXZlciBoYXZlIGl0IGJhY2suCisKKyAgICAgICAgKi8KKyAgICAgICAgZmluYWwgaW50IE1JTl9MRU5HVEggPSAxOworCisgICAgICAgIGZpbmFsIGJ5dGVbXSB0cmltbWVkQXJyYXkgPSBuZXcgYnl0ZVtNYXRoLm1heChNSU5fTEVOR1RILCBhcnJheS5sZW5ndGggLSBwb3MpXTsKKyAgICAgICAgZmluYWwgaW50IHN0YXJ0UG9zID0gdHJpbW1lZEFycmF5Lmxlbmd0aCAtIChhcnJheS5sZW5ndGggLSBwb3MpOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGFycmF5LCBwb3MsIHRyaW1tZWRBcnJheSwgc3RhcnRQb3MsIHRyaW1tZWRBcnJheS5sZW5ndGggLSBzdGFydFBvcyk7CisgICAgICAgIHJldHVybiB0cmltbWVkQXJyYXk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9aaXA2NEV4dGVuZGVkSW5mb3JtYXRpb25FeHRyYUZpZWxkLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1ppcDY0RXh0ZW5kZWRJbmZvcm1hdGlvbkV4dHJhRmllbGQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wNTc4ZTU4Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9aaXA2NEV4dGVuZGVkSW5mb3JtYXRpb25FeHRyYUZpZWxkLmphdmEKQEAgLTAsMCArMSwzNDAgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcDsKKworaW1wb3J0IGphdmEudXRpbC56aXAuWmlwRXhjZXB0aW9uOworCitpbXBvcnQgc3RhdGljIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwLlppcENvbnN0YW50cy5EV09SRDsKK2ltcG9ydCBzdGF0aWMgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXAuWmlwQ29uc3RhbnRzLldPUkQ7CisKKy8qKgorICogSG9sZHMgc2l6ZSBhbmQgb3RoZXIgZXh0ZW5kZWQgaW5mb3JtYXRpb24gZm9yIGVudHJpZXMgdGhhdCB1c2UgWmlwNjQKKyAqIGZlYXR1cmVzLgorICoKKyAqIDxwPkN1cnJlbnRseSBDb21tb25zIENvbXByZXNzIGRvZXNuJ3Qgc3VwcG9ydCBlbmNyeXB0aW5nIHRoZQorICogY2VudHJhbCBkaXJlY3Rvcnkgc28gdGhlIG5vdGUgaW4gQVBQTk9URS5UWFQgYWJvdXQgbWFza2luZyBkb2Vzbid0CisgKiBhcHBseS48L3A+CisgKgorICogPHA+VGhlIGltcGxlbWVudGF0aW9uIHJlbGllcyBvbiBkYXRhIGJlaW5nIHJlYWQgZnJvbSB0aGUgbG9jYWwgZmlsZQorICogaGVhZGVyIGFuZCBhc3N1bWVzIHRoYXQgYm90aCBzaXplIHZhbHVlcyBhcmUgYWx3YXlzIHByZXNlbnQuPC9wPgorICoKKyAqIEBzZWUgPGEgaHJlZj0iaHR0cHM6Ly93d3cucGt3YXJlLmNvbS9kb2N1bWVudHMvY2FzZXN0dWRpZXMvQVBQTk9URS5UWFQiPlBLV0FSRQorICogQVBQTk9URS5UWFQsIHNlY3Rpb24gNC41LjM8L2E+CisgKgorICogQHNpbmNlIDEuMgorICogQE5vdFRocmVhZFNhZmUKKyAqLworcHVibGljIGNsYXNzIFppcDY0RXh0ZW5kZWRJbmZvcm1hdGlvbkV4dHJhRmllbGQgaW1wbGVtZW50cyBaaXBFeHRyYUZpZWxkIHsKKworICAgIHN0YXRpYyBmaW5hbCBaaXBTaG9ydCBIRUFERVJfSUQgPSBuZXcgWmlwU2hvcnQoMHgwMDAxKTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBMRkhfTVVTVF9IQVZFX0JPVEhfU0laRVNfTVNHID0KKyAgICAgICAgIlppcDY0IGV4dGVuZGVkIGluZm9ybWF0aW9uIG11c3QgY29udGFpbiIKKyAgICAgICAgKyAiIGJvdGggc2l6ZSB2YWx1ZXMgaW4gdGhlIGxvY2FsIGZpbGUgaGVhZGVyLiI7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIEVNUFRZID0gbmV3IGJ5dGVbMF07CisKKyAgICBwcml2YXRlIFppcEVpZ2h0Qnl0ZUludGVnZXIgc2l6ZSwgY29tcHJlc3NlZFNpemUsIHJlbGF0aXZlSGVhZGVyT2Zmc2V0OworICAgIHByaXZhdGUgWmlwTG9uZyBkaXNrU3RhcnQ7CisKKyAgICAvKioKKyAgICAgKiBTdG9yZWQgaW4ge0BsaW5rICNwYXJzZUZyb21DZW50cmFsRGlyZWN0b3J5RGF0YQorICAgICAqIHBhcnNlRnJvbUNlbnRyYWxEaXJlY3RvcnlEYXRhfSBzbyBpdCBjYW4gYmUgcmV1c2VkIHdoZW4gWmlwRmlsZQorICAgICAqIGNhbGxzIHtAbGluayAjcmVwYXJzZUNlbnRyYWxEaXJlY3RvcnlEYXRhCisgICAgICogcmVwYXJzZUNlbnRyYWxEaXJlY3RvcnlEYXRhfS4KKyAgICAgKgorICAgICAqIDxwPk5vdCB1c2VkIGZvciBhbnl0aGluZyBlbHNlPC9wPgorICAgICAqCisgICAgICogQHNpbmNlIDEuMworICAgICAqLworICAgIHByaXZhdGUgYnl0ZVtdIHJhd0NlbnRyYWxEaXJlY3RvcnlEYXRhOworCisgICAgLyoqCisgICAgICogVGhpcyBjb25zdHJ1Y3RvciBzaG91bGQgb25seSBiZSB1c2VkIGJ5IHRoZSBjb2RlIHRoYXQgcmVhZHMKKyAgICAgKiBhcmNoaXZlcyBpbnNpZGUgb2YgQ29tbW9ucyBDb21wcmVzcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgWmlwNjRFeHRlbmRlZEluZm9ybWF0aW9uRXh0cmFGaWVsZCgpIHsgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBleHRyYSBmaWVsZCBiYXNlZCBvbiB0aGUgb3JpZ2luYWwgYW5kIGNvbXByZXNzZWQgc2l6ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzaXplIHRoZSBlbnRyeSdzIG9yaWdpbmFsIHNpemUKKyAgICAgKiBAcGFyYW0gY29tcHJlc3NlZFNpemUgdGhlIGVudHJ5J3MgY29tcHJlc3NlZCBzaXplCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBzaXplIG9yIGNvbXByZXNzZWRTaXplIGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgWmlwNjRFeHRlbmRlZEluZm9ybWF0aW9uRXh0cmFGaWVsZChmaW5hbCBaaXBFaWdodEJ5dGVJbnRlZ2VyIHNpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgWmlwRWlnaHRCeXRlSW50ZWdlciBjb21wcmVzc2VkU2l6ZSkgeworICAgICAgICB0aGlzKHNpemUsIGNvbXByZXNzZWRTaXplLCBudWxsLCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIGV4dHJhIGZpZWxkIGJhc2VkIG9uIGFsbCBmb3VyIHBvc3NpYmxlIHZhbHVlcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzaXplIHRoZSBlbnRyeSdzIG9yaWdpbmFsIHNpemUKKyAgICAgKiBAcGFyYW0gY29tcHJlc3NlZFNpemUgdGhlIGVudHJ5J3MgY29tcHJlc3NlZCBzaXplCisgICAgICogQHBhcmFtIHJlbGF0aXZlSGVhZGVyT2Zmc2V0IHRoZSBlbnRyeSdzIG9mZnNldAorICAgICAqIEBwYXJhbSBkaXNrU3RhcnQgdGhlIGRpc2sgc3RhcnQKKyAgICAgKgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHNpemUgb3IgY29tcHJlc3NlZFNpemUgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBaaXA2NEV4dGVuZGVkSW5mb3JtYXRpb25FeHRyYUZpZWxkKGZpbmFsIFppcEVpZ2h0Qnl0ZUludGVnZXIgc2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBaaXBFaWdodEJ5dGVJbnRlZ2VyIGNvbXByZXNzZWRTaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIFppcEVpZ2h0Qnl0ZUludGVnZXIgcmVsYXRpdmVIZWFkZXJPZmZzZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgWmlwTG9uZyBkaXNrU3RhcnQpIHsKKyAgICAgICAgdGhpcy5zaXplID0gc2l6ZTsKKyAgICAgICAgdGhpcy5jb21wcmVzc2VkU2l6ZSA9IGNvbXByZXNzZWRTaXplOworICAgICAgICB0aGlzLnJlbGF0aXZlSGVhZGVyT2Zmc2V0ID0gcmVsYXRpdmVIZWFkZXJPZmZzZXQ7CisgICAgICAgIHRoaXMuZGlza1N0YXJ0ID0gZGlza1N0YXJ0OworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBaaXBTaG9ydCBnZXRIZWFkZXJJZCgpIHsKKyAgICAgICAgcmV0dXJuIEhFQURFUl9JRDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgWmlwU2hvcnQgZ2V0TG9jYWxGaWxlRGF0YUxlbmd0aCgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBaaXBTaG9ydChzaXplICE9IG51bGwgPyAyICogRFdPUkQgOiAwKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgWmlwU2hvcnQgZ2V0Q2VudHJhbERpcmVjdG9yeUxlbmd0aCgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBaaXBTaG9ydCgoc2l6ZSAhPSBudWxsID8gRFdPUkQgOiAwKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgKGNvbXByZXNzZWRTaXplICE9IG51bGwgPyBEV09SRCA6IDApCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAocmVsYXRpdmVIZWFkZXJPZmZzZXQgIT0gbnVsbCA/IERXT1JEIDogMCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICArIChkaXNrU3RhcnQgIT0gbnVsbCA/IFdPUkQgOiAwKSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJ5dGVbXSBnZXRMb2NhbEZpbGVEYXRhRGF0YSgpIHsKKyAgICAgICAgaWYgKHNpemUgIT0gbnVsbCB8fCBjb21wcmVzc2VkU2l6ZSAhPSBudWxsKSB7CisgICAgICAgICAgICBpZiAoc2l6ZSA9PSBudWxsIHx8IGNvbXByZXNzZWRTaXplID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKExGSF9NVVNUX0hBVkVfQk9USF9TSVpFU19NU0cpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZmluYWwgYnl0ZVtdIGRhdGEgPSBuZXcgYnl0ZVsyICogRFdPUkRdOworICAgICAgICAgICAgYWRkU2l6ZXMoZGF0YSk7CisgICAgICAgICAgICByZXR1cm4gZGF0YTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gRU1QVFk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJ5dGVbXSBnZXRDZW50cmFsRGlyZWN0b3J5RGF0YSgpIHsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGRhdGEgPSBuZXcgYnl0ZVtnZXRDZW50cmFsRGlyZWN0b3J5TGVuZ3RoKCkuZ2V0VmFsdWUoKV07CisgICAgICAgIGludCBvZmYgPSBhZGRTaXplcyhkYXRhKTsKKyAgICAgICAgaWYgKHJlbGF0aXZlSGVhZGVyT2Zmc2V0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkocmVsYXRpdmVIZWFkZXJPZmZzZXQuZ2V0Qnl0ZXMoKSwgMCwgZGF0YSwgb2ZmLCBEV09SRCk7CisgICAgICAgICAgICBvZmYgKz0gRFdPUkQ7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGRpc2tTdGFydCAhPSBudWxsKSB7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGRpc2tTdGFydC5nZXRCeXRlcygpLCAwLCBkYXRhLCBvZmYsIFdPUkQpOworICAgICAgICAgICAgb2ZmICs9IFdPUkQ7IC8vIE5PU09OQVIgLSBhc3NpZ25tZW50IGFzIGRvY3VtZW50YXRpb24KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZGF0YTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBwYXJzZUZyb21Mb2NhbEZpbGVEYXRhKGZpbmFsIGJ5dGVbXSBidWZmZXIsIGludCBvZmZzZXQsIGZpbmFsIGludCBsZW5ndGgpCisgICAgICAgIHRocm93cyBaaXBFeGNlcHRpb24geworICAgICAgICBpZiAobGVuZ3RoID09IDApIHsKKyAgICAgICAgICAgIC8vIG5vIGxvY2FsIGZpbGUgZGF0YSBhdCBhbGwsIG1heSBoYXBwZW4gaWYgYW4gYXJjaGl2ZQorICAgICAgICAgICAgLy8gb25seSBob2xkcyBhIFpJUDY0IGV4dGVuZGVkIGluZm9ybWF0aW9uIGV4dHJhIGZpZWxkCisgICAgICAgICAgICAvLyBpbnNpZGUgdGhlIGNlbnRyYWwgZGlyZWN0b3J5IGJ1dCBub3QgaW5zaWRlIHRoZSBsb2NhbAorICAgICAgICAgICAgLy8gZmlsZSBoZWFkZXIKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBpZiAobGVuZ3RoIDwgMiAqIERXT1JEKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgWmlwRXhjZXB0aW9uKExGSF9NVVNUX0hBVkVfQk9USF9TSVpFU19NU0cpOworICAgICAgICB9CisgICAgICAgIHNpemUgPSBuZXcgWmlwRWlnaHRCeXRlSW50ZWdlcihidWZmZXIsIG9mZnNldCk7CisgICAgICAgIG9mZnNldCArPSBEV09SRDsKKyAgICAgICAgY29tcHJlc3NlZFNpemUgPSBuZXcgWmlwRWlnaHRCeXRlSW50ZWdlcihidWZmZXIsIG9mZnNldCk7CisgICAgICAgIG9mZnNldCArPSBEV09SRDsKKyAgICAgICAgaW50IHJlbWFpbmluZyA9IGxlbmd0aCAtIDIgKiBEV09SRDsKKyAgICAgICAgaWYgKHJlbWFpbmluZyA+PSBEV09SRCkgeworICAgICAgICAgICAgcmVsYXRpdmVIZWFkZXJPZmZzZXQgPSBuZXcgWmlwRWlnaHRCeXRlSW50ZWdlcihidWZmZXIsIG9mZnNldCk7CisgICAgICAgICAgICBvZmZzZXQgKz0gRFdPUkQ7CisgICAgICAgICAgICByZW1haW5pbmcgLT0gRFdPUkQ7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHJlbWFpbmluZyA+PSBXT1JEKSB7CisgICAgICAgICAgICBkaXNrU3RhcnQgPSBuZXcgWmlwTG9uZyhidWZmZXIsIG9mZnNldCk7CisgICAgICAgICAgICBvZmZzZXQgKz0gV09SRDsgLy8gTk9TT05BUiAtIGFzc2lnbm1lbnQgYXMgZG9jdW1lbnRhdGlvbgorICAgICAgICAgICAgcmVtYWluaW5nIC09IFdPUkQ7IC8vIE5PU09OQVIgLSBhc3NpZ25tZW50IGFzIGRvY3VtZW50YXRpb24KKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHBhcnNlRnJvbUNlbnRyYWxEaXJlY3RvcnlEYXRhKGZpbmFsIGJ5dGVbXSBidWZmZXIsIGludCBvZmZzZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGxlbmd0aCkKKyAgICAgICAgdGhyb3dzIFppcEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIHN0b3JlIGZvciBwcm9jZXNzaW5nIGluIHJlcGFyc2VDZW50cmFsRGlyZWN0b3J5RGF0YQorICAgICAgICByYXdDZW50cmFsRGlyZWN0b3J5RGF0YSA9IG5ldyBieXRlW2xlbmd0aF07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYnVmZmVyLCBvZmZzZXQsIHJhd0NlbnRyYWxEaXJlY3RvcnlEYXRhLCAwLCBsZW5ndGgpOworCisgICAgICAgIC8vIGlmIHRoZXJlIGlzIG5vIHNpemUgaW5mb3JtYXRpb24gaW4gaGVyZSwgd2UgYXJlIHNjcmV3ZWQgYW5kCisgICAgICAgIC8vIGNhbiBvbmx5IGhvcGUgdGhpbmdzIHdpbGwgZ2V0IHJlc29sdmVkIGJ5IExGSCBkYXRhIGxhdGVyCisgICAgICAgIC8vIEJ1dCB0aGVyZSBhcmUgc29tZSBjYXNlcyB0aGF0IGNhbiBiZSBkZXRlY3RlZAorICAgICAgICAvLyAqIGFsbCBkYXRhIGlzIHRoZXJlCisgICAgICAgIC8vICogbGVuZ3RoID09IDI0IC0+IGJvdGggc2l6ZXMgYW5kIG9mZnNldAorICAgICAgICAvLyAqIGxlbmd0aCAlIDggPT0gNCAtPiBhdCBsZWFzdCB3ZSBjYW4gaWRlbnRpZnkgdGhlIGRpc2tTdGFydCBmaWVsZAorICAgICAgICBpZiAobGVuZ3RoID49IDMgKiBEV09SRCArIFdPUkQpIHsKKyAgICAgICAgICAgIHBhcnNlRnJvbUxvY2FsRmlsZURhdGEoYnVmZmVyLCBvZmZzZXQsIGxlbmd0aCk7CisgICAgICAgIH0gZWxzZSBpZiAobGVuZ3RoID09IDMgKiBEV09SRCkgeworICAgICAgICAgICAgc2l6ZSA9IG5ldyBaaXBFaWdodEJ5dGVJbnRlZ2VyKGJ1ZmZlciwgb2Zmc2V0KTsKKyAgICAgICAgICAgIG9mZnNldCArPSBEV09SRDsKKyAgICAgICAgICAgIGNvbXByZXNzZWRTaXplID0gbmV3IFppcEVpZ2h0Qnl0ZUludGVnZXIoYnVmZmVyLCBvZmZzZXQpOworICAgICAgICAgICAgb2Zmc2V0ICs9IERXT1JEOworICAgICAgICAgICAgcmVsYXRpdmVIZWFkZXJPZmZzZXQgPSBuZXcgWmlwRWlnaHRCeXRlSW50ZWdlcihidWZmZXIsIG9mZnNldCk7CisgICAgICAgIH0gZWxzZSBpZiAobGVuZ3RoICUgRFdPUkQgPT0gV09SRCkgeworICAgICAgICAgICAgZGlza1N0YXJ0ID0gbmV3IFppcExvbmcoYnVmZmVyLCBvZmZzZXQgKyBsZW5ndGggLSBXT1JEKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlcyB0aGUgcmF3IGJ5dGVzIHJlYWQgZnJvbSB0aGUgY2VudHJhbCBkaXJlY3RvcnkgZXh0cmEKKyAgICAgKiBmaWVsZCB3aXRoIGtub3dsZWRnZSB3aGljaCBmaWVsZHMgYXJlIGV4cGVjdGVkIHRvIGJlIHRoZXJlLgorICAgICAqCisgICAgICogPHA+QWxsIGZvdXIgZmllbGRzIGluc2lkZSB0aGUgemlwNjQgZXh0ZW5kZWQgaW5mb3JtYXRpb24gZXh0cmEKKyAgICAgKiBmaWVsZCBhcmUgb3B0aW9uYWwgYW5kIG11c3Qgb25seSBiZSBwcmVzZW50IGlmIHRoZWlyIGNvcnJlc3BvbmRpbmcKKyAgICAgKiBlbnRyeSBpbnNpZGUgdGhlIGNlbnRyYWwgZGlyZWN0b3J5IGNvbnRhaW5zIHRoZSBjb3JyZWN0IG1hZ2ljCisgICAgICogdmFsdWUuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGhhc1VuY29tcHJlc3NlZFNpemUgZmxhZyB0byByZWFkIGZyb20gY2VudHJhbCBkaXJlY3RvcnkKKyAgICAgKiBAcGFyYW0gaGFzQ29tcHJlc3NlZFNpemUgZmxhZyB0byByZWFkIGZyb20gY2VudHJhbCBkaXJlY3RvcnkKKyAgICAgKiBAcGFyYW0gaGFzUmVsYXRpdmVIZWFkZXJPZmZzZXQgZmxhZyB0byByZWFkIGZyb20gY2VudHJhbCBkaXJlY3RvcnkKKyAgICAgKiBAcGFyYW0gaGFzRGlza1N0YXJ0IGZsYWcgdG8gcmVhZCBmcm9tIGNlbnRyYWwgZGlyZWN0b3J5CisgICAgICogQHRocm93cyBaaXBFeGNlcHRpb24gb24gZXJyb3IKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZXBhcnNlQ2VudHJhbERpcmVjdG9yeURhdGEoZmluYWwgYm9vbGVhbiBoYXNVbmNvbXByZXNzZWRTaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBib29sZWFuIGhhc0NvbXByZXNzZWRTaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBib29sZWFuIGhhc1JlbGF0aXZlSGVhZGVyT2Zmc2V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBib29sZWFuIGhhc0Rpc2tTdGFydCkKKyAgICAgICAgdGhyb3dzIFppcEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChyYXdDZW50cmFsRGlyZWN0b3J5RGF0YSAhPSBudWxsKSB7CisgICAgICAgICAgICBmaW5hbCBpbnQgZXhwZWN0ZWRMZW5ndGggPSAoaGFzVW5jb21wcmVzc2VkU2l6ZSA/IERXT1JEIDogMCkKKyAgICAgICAgICAgICAgICArIChoYXNDb21wcmVzc2VkU2l6ZSA/IERXT1JEIDogMCkKKyAgICAgICAgICAgICAgICArIChoYXNSZWxhdGl2ZUhlYWRlck9mZnNldCA/IERXT1JEIDogMCkKKyAgICAgICAgICAgICAgICArIChoYXNEaXNrU3RhcnQgPyBXT1JEIDogMCk7CisgICAgICAgICAgICBpZiAocmF3Q2VudHJhbERpcmVjdG9yeURhdGEubGVuZ3RoIDwgZXhwZWN0ZWRMZW5ndGgpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWmlwRXhjZXB0aW9uKCJjZW50cmFsIGRpcmVjdG9yeSB6aXA2NCBleHRlbmRlZCIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiBpbmZvcm1hdGlvbiBleHRyYSBmaWVsZCdzIGxlbmd0aCIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiBkb2Vzbid0IG1hdGNoIGNlbnRyYWwgZGlyZWN0b3J5IgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIGRhdGEuICBFeHBlY3RlZCBsZW5ndGggIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBleHBlY3RlZExlbmd0aCArICIgYnV0IGlzICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgcmF3Q2VudHJhbERpcmVjdG9yeURhdGEubGVuZ3RoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGludCBvZmZzZXQgPSAwOworICAgICAgICAgICAgaWYgKGhhc1VuY29tcHJlc3NlZFNpemUpIHsKKyAgICAgICAgICAgICAgICBzaXplID0gbmV3IFppcEVpZ2h0Qnl0ZUludGVnZXIocmF3Q2VudHJhbERpcmVjdG9yeURhdGEsIG9mZnNldCk7CisgICAgICAgICAgICAgICAgb2Zmc2V0ICs9IERXT1JEOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGhhc0NvbXByZXNzZWRTaXplKSB7CisgICAgICAgICAgICAgICAgY29tcHJlc3NlZFNpemUgPSBuZXcgWmlwRWlnaHRCeXRlSW50ZWdlcihyYXdDZW50cmFsRGlyZWN0b3J5RGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldCk7CisgICAgICAgICAgICAgICAgb2Zmc2V0ICs9IERXT1JEOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGhhc1JlbGF0aXZlSGVhZGVyT2Zmc2V0KSB7CisgICAgICAgICAgICAgICAgcmVsYXRpdmVIZWFkZXJPZmZzZXQgPQorICAgICAgICAgICAgICAgICAgICBuZXcgWmlwRWlnaHRCeXRlSW50ZWdlcihyYXdDZW50cmFsRGlyZWN0b3J5RGF0YSwgb2Zmc2V0KTsKKyAgICAgICAgICAgICAgICBvZmZzZXQgKz0gRFdPUkQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoaGFzRGlza1N0YXJ0KSB7CisgICAgICAgICAgICAgICAgZGlza1N0YXJ0ID0gbmV3IFppcExvbmcocmF3Q2VudHJhbERpcmVjdG9yeURhdGEsIG9mZnNldCk7CisgICAgICAgICAgICAgICAgb2Zmc2V0ICs9IFdPUkQ7IC8vIE5PU09OQVIgLSBhc3NpZ25tZW50IGFzIGRvY3VtZW50YXRpb24KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSB1bmNvbXByZXNzZWQgc2l6ZSBzdG9yZWQgaW4gdGhpcyBleHRyYSBmaWVsZC4KKyAgICAgKiBAcmV0dXJuIFRoZSB1bmNvbXByZXNzZWQgc2l6ZSBzdG9yZWQgaW4gdGhpcyBleHRyYSBmaWVsZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgWmlwRWlnaHRCeXRlSW50ZWdlciBnZXRTaXplKCkgeworICAgICAgICByZXR1cm4gc2l6ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgdW5jb21wcmVzc2VkIHNpemUgc3RvcmVkIGluIHRoaXMgZXh0cmEgZmllbGQuCisgICAgICogQHBhcmFtIHNpemUgVGhlIHVuY29tcHJlc3NlZCBzaXplIHN0b3JlZCBpbiB0aGlzIGV4dHJhIGZpZWxkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFNpemUoZmluYWwgWmlwRWlnaHRCeXRlSW50ZWdlciBzaXplKSB7CisgICAgICAgIHRoaXMuc2l6ZSA9IHNpemU7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIGNvbXByZXNzZWQgc2l6ZSBzdG9yZWQgaW4gdGhpcyBleHRyYSBmaWVsZC4KKyAgICAgKiBAcmV0dXJuIFRoZSBjb21wcmVzc2VkIHNpemUgc3RvcmVkIGluIHRoaXMgZXh0cmEgZmllbGQuCisgICAgICovCisgICAgcHVibGljIFppcEVpZ2h0Qnl0ZUludGVnZXIgZ2V0Q29tcHJlc3NlZFNpemUoKSB7CisgICAgICAgIHJldHVybiBjb21wcmVzc2VkU2l6ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgdW5jb21wcmVzc2VkIHNpemUgc3RvcmVkIGluIHRoaXMgZXh0cmEgZmllbGQuCisgICAgICogQHBhcmFtIGNvbXByZXNzZWRTaXplIFRoZSB1bmNvbXByZXNzZWQgc2l6ZSBzdG9yZWQgaW4gdGhpcyBleHRyYSBmaWVsZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRDb21wcmVzc2VkU2l6ZShmaW5hbCBaaXBFaWdodEJ5dGVJbnRlZ2VyIGNvbXByZXNzZWRTaXplKSB7CisgICAgICAgIHRoaXMuY29tcHJlc3NlZFNpemUgPSBjb21wcmVzc2VkU2l6ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgcmVsYXRpdmUgaGVhZGVyIG9mZnNldCBzdG9yZWQgaW4gdGhpcyBleHRyYSBmaWVsZC4KKyAgICAgKiBAcmV0dXJuIFRoZSByZWxhdGl2ZSBoZWFkZXIgb2Zmc2V0IHN0b3JlZCBpbiB0aGlzIGV4dHJhIGZpZWxkLgorICAgICAqLworICAgIHB1YmxpYyBaaXBFaWdodEJ5dGVJbnRlZ2VyIGdldFJlbGF0aXZlSGVhZGVyT2Zmc2V0KCkgeworICAgICAgICByZXR1cm4gcmVsYXRpdmVIZWFkZXJPZmZzZXQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIHJlbGF0aXZlIGhlYWRlciBvZmZzZXQgc3RvcmVkIGluIHRoaXMgZXh0cmEgZmllbGQuCisgICAgICogQHBhcmFtIHJobyBUaGUgcmVsYXRpdmUgaGVhZGVyIG9mZnNldCBzdG9yZWQgaW4gdGhpcyBleHRyYSBmaWVsZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRSZWxhdGl2ZUhlYWRlck9mZnNldChmaW5hbCBaaXBFaWdodEJ5dGVJbnRlZ2VyIHJobykgeworICAgICAgICByZWxhdGl2ZUhlYWRlck9mZnNldCA9IHJobzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgZGlzayBzdGFydCBudW1iZXIgc3RvcmVkIGluIHRoaXMgZXh0cmEgZmllbGQuCisgICAgICogQHJldHVybiBUaGUgZGlzayBzdGFydCBudW1iZXIgc3RvcmVkIGluIHRoaXMgZXh0cmEgZmllbGQuCisgICAgICovCisgICAgcHVibGljIFppcExvbmcgZ2V0RGlza1N0YXJ0TnVtYmVyKCkgeworICAgICAgICByZXR1cm4gZGlza1N0YXJ0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBkaXNrIHN0YXJ0IG51bWJlciBzdG9yZWQgaW4gdGhpcyBleHRyYSBmaWVsZC4KKyAgICAgKiBAcGFyYW0gZHMgVGhlIGRpc2sgc3RhcnQgbnVtYmVyIHN0b3JlZCBpbiB0aGlzIGV4dHJhIGZpZWxkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldERpc2tTdGFydE51bWJlcihmaW5hbCBaaXBMb25nIGRzKSB7CisgICAgICAgIGRpc2tTdGFydCA9IGRzOworICAgIH0KKworICAgIHByaXZhdGUgaW50IGFkZFNpemVzKGZpbmFsIGJ5dGVbXSBkYXRhKSB7CisgICAgICAgIGludCBvZmYgPSAwOworICAgICAgICBpZiAoc2l6ZSAhPSBudWxsKSB7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHNpemUuZ2V0Qnl0ZXMoKSwgMCwgZGF0YSwgMCwgRFdPUkQpOworICAgICAgICAgICAgb2ZmICs9IERXT1JEOworICAgICAgICB9CisgICAgICAgIGlmIChjb21wcmVzc2VkU2l6ZSAhPSBudWxsKSB7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGNvbXByZXNzZWRTaXplLmdldEJ5dGVzKCksIDAsIGRhdGEsIG9mZiwgRFdPUkQpOworICAgICAgICAgICAgb2ZmICs9IERXT1JEOworICAgICAgICB9CisgICAgICAgIHJldHVybiBvZmY7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9aaXA2NE1vZGUuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvWmlwNjRNb2RlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDA1MWU4OQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvWmlwNjRNb2RlLmphdmEKQEAgLTAsMCArMSw0NyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICoKKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwOworCisvKioKKyAqIFRoZSBkaWZmZXJlbnQgbW9kZXMge0BsaW5rIFppcEFyY2hpdmVPdXRwdXRTdHJlYW19IGNhbiBvcGVyYXRlIGluLgorICoKKyAqIEBzZWUgWmlwQXJjaGl2ZU91dHB1dFN0cmVhbSNzZXRVc2VaaXA2NAorICoKKyAqIEBzaW5jZSAxLjMKKyAqLworcHVibGljIGVudW0gWmlwNjRNb2RlIHsKKyAgICAvKioKKyAgICAgKiBVc2UgWmlwNjQgZXh0ZW5zaW9ucyBmb3IgYWxsIGVudHJpZXMsIGV2ZW4gaWYgaXQgaXMgY2xlYXIgaXQgaXMKKyAgICAgKiBub3QgcmVxdWlyZWQuCisgICAgICovCisgICAgQWx3YXlzLAorICAgIC8qKgorICAgICAqIERvbid0IHVzZSBaaXA2NCBleHRlbnNpb25zIGZvciBhbnkgZW50cmllcy4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgd2lsbCBjYXVzZSBhIHtAbGluayBaaXA2NFJlcXVpcmVkRXhjZXB0aW9ufSB0byBiZQorICAgICAqIHRocm93biBpZiB7QGxpbmsgWmlwQXJjaGl2ZU91dHB1dFN0cmVhbX0gZGV0ZWN0cyBpdCBuZWVkcyBaaXA2NAorICAgICAqIHN1cHBvcnQuPC9wPgorICAgICAqLworICAgIE5ldmVyLAorICAgIC8qKgorICAgICAqIFVzZSBaaXA2NCBleHRlbnNpb25zIGZvciBhbGwgZW50cmllcyB3aGVyZSB0aGV5IGFyZSByZXF1aXJlZCwKKyAgICAgKiBkb24ndCB1c2UgdGhlbSBmb3IgZW50cmllcyB0aGF0IGNsZWFybHkgZG9uJ3QgcmVxdWlyZSB0aGVtLgorICAgICAqLworICAgIEFzTmVlZGVkCit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1ppcDY0UmVxdWlyZWRFeGNlcHRpb24uamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvWmlwNjRSZXF1aXJlZEV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFlYzdlNzAKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1ppcDY0UmVxdWlyZWRFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDQ5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXA7CisKK2ltcG9ydCBqYXZhLnV0aWwuemlwLlppcEV4Y2VwdGlvbjsKKworLyoqCisgKiBFeGNlcHRpb24gdGhyb3duIHdoZW4gYXR0ZW1wdGluZyB0byB3cml0ZSBkYXRhIHRoYXQgcmVxdWlyZXMgWmlwNjQKKyAqIHN1cHBvcnQgdG8gYW4gYXJjaGl2ZSBhbmQge0BsaW5rIFppcEFyY2hpdmVPdXRwdXRTdHJlYW0jc2V0VXNlWmlwNjQKKyAqIFVzZVppcDY0fSBoYXMgYmVlbiBzZXQgdG8ge0BsaW5rIFppcDY0TW9kZSNOZXZlciBOZXZlcn0uCisgKiBAc2luY2UgMS4zCisgKi8KK3B1YmxpYyBjbGFzcyBaaXA2NFJlcXVpcmVkRXhjZXB0aW9uIGV4dGVuZHMgWmlwRXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDIwMTEwODA5TDsKKworICAgIC8qKgorICAgICAqIEhlbHBlciB0byBmb3JtYXQgImVudHJ5IHRvbyBiaWciIG1lc3NhZ2VzLgorICAgICAqLworICAgIHN0YXRpYyBTdHJpbmcgZ2V0RW50cnlUb29CaWdNZXNzYWdlKGZpbmFsIFppcEFyY2hpdmVFbnRyeSB6ZSkgeworICAgICAgICByZXR1cm4gemUuZ2V0TmFtZSgpICsgIidzIHNpemUgZXhjZWVkcyB0aGUgbGltaXQgb2YgNEdCeXRlLiI7CisgICAgfQorCisgICAgc3RhdGljIGZpbmFsIFN0cmluZyBBUkNISVZFX1RPT19CSUdfTUVTU0FHRSA9CisgICAgICAgICJhcmNoaXZlJ3Mgc2l6ZSBleGNlZWRzIHRoZSBsaW1pdCBvZiA0R0J5dGUuIjsKKworICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgVE9PX01BTllfRU5UUklFU19NRVNTQUdFID0KKyAgICAgICAgImFyY2hpdmUgY29udGFpbnMgbW9yZSB0aGFuIDY1NTM1IGVudHJpZXMuIjsKKworICAgIHB1YmxpYyBaaXA2NFJlcXVpcmVkRXhjZXB0aW9uKGZpbmFsIFN0cmluZyByZWFzb24pIHsKKyAgICAgICAgc3VwZXIocmVhc29uKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1ppcEFyY2hpdmVFbnRyeS5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9aaXBBcmNoaXZlRW50cnkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40YTA5ZWFjCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9aaXBBcmNoaXZlRW50cnkuamF2YQpAQCAtMCwwICsxLDEwMTYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXA7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLkFyY2hpdmVFbnRyeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLkVudHJ5U3RyZWFtT2Zmc2V0czsKKworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkRhdGU7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLnppcC5aaXBFeGNlcHRpb247CisKKy8qKgorICogRXh0ZW5zaW9uIHRoYXQgYWRkcyBiZXR0ZXIgaGFuZGxpbmcgb2YgZXh0cmEgZmllbGRzIGFuZCBwcm92aWRlcworICogYWNjZXNzIHRvIHRoZSBpbnRlcm5hbCBhbmQgZXh0ZXJuYWwgZmlsZSBhdHRyaWJ1dGVzLgorICoKKyAqIDxwPlRoZSBleHRyYSBkYXRhIGlzIGV4cGVjdGVkIHRvIGZvbGxvdyB0aGUgcmVjb21tZW5kYXRpb24gb2YKKyAqIDxhIGhyZWY9Imh0dHA6Ly93d3cucGt3YXJlLmNvbS9kb2N1bWVudHMvY2FzZXN0dWRpZXMvQVBQTk9URS5UWFQiPkFQUE5PVEUuVFhUPC9hPjo8L3A+CisgKiA8dWw+CisgKiAgIDxsaT50aGUgZXh0cmEgYnl0ZSBhcnJheSBjb25zaXN0cyBvZiBhIHNlcXVlbmNlIG9mIGV4dHJhIGZpZWxkczwvbGk+CisgKiAgIDxsaT5lYWNoIGV4dHJhIGZpZWxkcyBzdGFydHMgYnkgYSB0d28gYnl0ZSBoZWFkZXIgaWQgZm9sbG93ZWQgYnkKKyAqICAgYSB0d28gYnl0ZSBzZXF1ZW5jZSBob2xkaW5nIHRoZSBsZW5ndGggb2YgdGhlIHJlbWFpbmRlciBvZgorICogICBkYXRhLjwvbGk+CisgKiA8L3VsPgorICoKKyAqIDxwPkFueSBleHRyYSBkYXRhIHRoYXQgY2Fubm90IGJlIHBhcnNlZCBieSB0aGUgcnVsZXMgYWJvdmUgd2lsbCBiZQorICogY29uc3VtZWQgYXMgInVucGFyc2VhYmxlIiBleHRyYSBkYXRhIGFuZCB0cmVhdGVkIGRpZmZlcmVudGx5IGJ5IHRoZQorICogbWV0aG9kcyBvZiB0aGlzIGNsYXNzLiAgVmVyc2lvbnMgcHJpb3IgdG8gQXBhY2hlIENvbW1vbnMgQ29tcHJlc3MKKyAqIDEuMSB3b3VsZCBoYXZlIHRocm93biBhbiBleGNlcHRpb24gaWYgYW55IGF0dGVtcHQgd2FzIG1hZGUgdG8gcmVhZAorICogb3Igd3JpdGUgZXh0cmEgZGF0YSBub3QgY29uZm9ybWluZyB0byB0aGUgcmVjb21tZW5kYXRpb24uPC9wPgorICoKKyAqIEBOb3RUaHJlYWRTYWZlCisgKi8KK3B1YmxpYyBjbGFzcyBaaXBBcmNoaXZlRW50cnkgZXh0ZW5kcyBqYXZhLnV0aWwuemlwLlppcEVudHJ5CisgICAgaW1wbGVtZW50cyBBcmNoaXZlRW50cnksIEVudHJ5U3RyZWFtT2Zmc2V0cworeworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUExBVEZPUk1fVU5JWCA9IDM7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUExBVEZPUk1fRkFUICA9IDA7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ1JDX1VOS05PV04gPSAtMTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgU0hPUlRfTUFTSyA9IDB4RkZGRjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgU0hPUlRfU0hJRlQgPSAxNjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gRU1QVFkgPSBuZXcgYnl0ZVswXTsKKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyBob3cgdGhlIG5hbWUgb2YgdGhpcyBlbnRyeSBoYXMgYmVlbiBkZXRlcm1pbmVkLgorICAgICAqIEBzaW5jZSAxLjE2CisgICAgICovCisgICAgcHVibGljIGVudW0gTmFtZVNvdXJjZSB7CisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgbmFtZSBoYXMgYmVlbiByZWFkIGZyb20gdGhlIGFyY2hpdmUgdXNpbmcgdGhlIGVuY29kaW5nCisgICAgICAgICAqIG9mIHRoZSBhcmNoaXZlIHNwZWNpZmllZCB3aGVuIGNyZWF0aW5nIHRoZSB7QGxpbmsKKyAgICAgICAgICogWmlwQXJjaGl2ZUlucHV0U3RyZWFtfSBvciB7QGxpbmsgWmlwRmlsZX0gKGRlZmF1bHRzIHRvIHRoZQorICAgICAgICAgKiBwbGF0Zm9ybSdzIGRlZmF1bHQgZW5jb2RpbmcpLgorICAgICAgICAgKi8KKyAgICAgICAgTkFNRSwKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBuYW1lIGhhcyBiZWVuIHJlYWQgZnJvbSB0aGUgYXJjaGl2ZSBhbmQgdGhlIGFyY2hpdmUKKyAgICAgICAgICogc3BlY2lmaWVkIHRoZSBFRlMgZmxhZyB3aGljaCBpbmRpY2F0ZXMgdGhlIG5hbWUgaGFzIGJlZW4KKyAgICAgICAgICogZW5jb2RlZCBhcyBVVEYtOC4KKyAgICAgICAgICovCisgICAgICAgIE5BTUVfV0lUSF9FRlNfRkxBRywKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBuYW1lIGhhcyBiZWVuIHJlYWQgZnJvbSBhbiB7QGxpbmsgVW5pY29kZVBhdGhFeHRyYUZpZWxkCisgICAgICAgICAqIFVuaWNvZGUgRXh0cmEgRmllbGR9LgorICAgICAgICAgKi8KKyAgICAgICAgVU5JQ09ERV9FWFRSQV9GSUVMRAorICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyBob3cgdGhlIGNvbW1lbnQgb2YgdGhpcyBlbnRyeSBoYXMgYmVlbiBkZXRlcm1pbmVkLgorICAgICAqIEBzaW5jZSAxLjE2CisgICAgICovCisgICAgcHVibGljIGVudW0gQ29tbWVudFNvdXJjZSB7CisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgY29tbWVudCBoYXMgYmVlbiByZWFkIGZyb20gdGhlIGFyY2hpdmUgdXNpbmcgdGhlIGVuY29kaW5nCisgICAgICAgICAqIG9mIHRoZSBhcmNoaXZlIHNwZWNpZmllZCB3aGVuIGNyZWF0aW5nIHRoZSB7QGxpbmsKKyAgICAgICAgICogWmlwQXJjaGl2ZUlucHV0U3RyZWFtfSBvciB7QGxpbmsgWmlwRmlsZX0gKGRlZmF1bHRzIHRvIHRoZQorICAgICAgICAgKiBwbGF0Zm9ybSdzIGRlZmF1bHQgZW5jb2RpbmcpLgorICAgICAgICAgKi8KKyAgICAgICAgQ09NTUVOVCwKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBjb21tZW50IGhhcyBiZWVuIHJlYWQgZnJvbSBhbiB7QGxpbmsgVW5pY29kZUNvbW1lbnRFeHRyYUZpZWxkCisgICAgICAgICAqIFVuaWNvZGUgRXh0cmEgRmllbGR9LgorICAgICAgICAgKi8KKyAgICAgICAgVU5JQ09ERV9FWFRSQV9GSUVMRAorICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSB7QGxpbmsgamF2YS51dGlsLnppcC5aaXBFbnRyeX0gYmFzZSBjbGFzcyBvbmx5IHN1cHBvcnRzCisgICAgICogdGhlIGNvbXByZXNzaW9uIG1ldGhvZHMgU1RPUkVEIGFuZCBERUZMQVRFRC4gV2Ugb3ZlcnJpZGUgdGhlCisgICAgICogZmllbGQgc28gdGhhdCBhbnkgY29tcHJlc3Npb24gbWV0aG9kcyBjYW4gYmUgdXNlZC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgZGVmYXVsdCB2YWx1ZSAtMSBtZWFucyB0aGF0IHRoZSBtZXRob2QgaGFzIG5vdCBiZWVuIHNwZWNpZmllZC4KKyAgICAgKgorICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cHM6Ly9pc3N1ZXMuYXBhY2hlLm9yZy9qaXJhL2Jyb3dzZS9DT01QUkVTUy05MyIKKyAgICAgKiAgICAgICAgPkNPTVBSRVNTLTkzPC9hPgorICAgICAqLworICAgIHByaXZhdGUgaW50IG1ldGhvZCA9IFppcE1ldGhvZC5VTktOT1dOX0NPREU7CisKKyAgICAvKioKKyAgICAgKiBUaGUge0BsaW5rIGphdmEudXRpbC56aXAuWmlwRW50cnkjc2V0U2l6ZX0gbWV0aG9kIGluIHRoZSBiYXNlCisgICAgICogY2xhc3MgdGhyb3dzIGFuIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgc2l6ZSBpcyBiaWdnZXIKKyAgICAgKiB0aGFuIDJHQiBmb3IgSmF2YSB2ZXJzaW9ucyAmbHQ7IDcgYW5kIGV2ZW4gaW4gSmF2YSA3KyBpZiB0aGUKKyAgICAgKiBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhLnV0aWwuemlwIGRvZXNuJ3Qgc3VwcG9ydCBaaXA2NCBpdHNlbGYKKyAgICAgKiAoaXQgaXMgYW4gb3B0aW9uYWwgZmVhdHVyZSkuCisgICAgICoKKyAgICAgKiA8cD5XZSBuZWVkIHRvIGtlZXAgb3VyIG93biBzaXplIGluZm9ybWF0aW9uIGZvciBaaXA2NCBzdXBwb3J0LjwvcD4KKyAgICAgKi8KKyAgICBwcml2YXRlIGxvbmcgc2l6ZSA9IFNJWkVfVU5LTk9XTjsKKworICAgIHByaXZhdGUgaW50IGludGVybmFsQXR0cmlidXRlcyA9IDA7CisgICAgcHJpdmF0ZSBpbnQgdmVyc2lvblJlcXVpcmVkOworICAgIHByaXZhdGUgaW50IHZlcnNpb25NYWRlQnk7CisgICAgcHJpdmF0ZSBpbnQgcGxhdGZvcm0gPSBQTEFURk9STV9GQVQ7CisgICAgcHJpdmF0ZSBpbnQgcmF3RmxhZzsKKyAgICBwcml2YXRlIGxvbmcgZXh0ZXJuYWxBdHRyaWJ1dGVzID0gMDsKKyAgICBwcml2YXRlIGludCBhbGlnbm1lbnQgPSAwOworICAgIHByaXZhdGUgWmlwRXh0cmFGaWVsZFtdIGV4dHJhRmllbGRzOworICAgIHByaXZhdGUgVW5wYXJzZWFibGVFeHRyYUZpZWxkRGF0YSB1bnBhcnNlYWJsZUV4dHJhID0gbnVsbDsKKyAgICBwcml2YXRlIFN0cmluZyBuYW1lID0gbnVsbDsKKyAgICBwcml2YXRlIGJ5dGVbXSByYXdOYW1lID0gbnVsbDsKKyAgICBwcml2YXRlIEdlbmVyYWxQdXJwb3NlQml0IGdwYiA9IG5ldyBHZW5lcmFsUHVycG9zZUJpdCgpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFppcEV4dHJhRmllbGRbXSBub0V4dHJhRmllbGRzID0gbmV3IFppcEV4dHJhRmllbGRbMF07CisgICAgcHJpdmF0ZSBsb25nIGxvY2FsSGVhZGVyT2Zmc2V0ID0gT0ZGU0VUX1VOS05PV047CisgICAgcHJpdmF0ZSBsb25nIGRhdGFPZmZzZXQgPSBPRkZTRVRfVU5LTk9XTjsKKyAgICBwcml2YXRlIGJvb2xlYW4gaXNTdHJlYW1Db250aWd1b3VzID0gZmFsc2U7CisgICAgcHJpdmF0ZSBOYW1lU291cmNlIG5hbWVTb3VyY2UgPSBOYW1lU291cmNlLk5BTUU7CisgICAgcHJpdmF0ZSBDb21tZW50U291cmNlIGNvbW1lbnRTb3VyY2UgPSBDb21tZW50U291cmNlLkNPTU1FTlQ7CisKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgemlwIGVudHJ5IHdpdGggdGhlIHNwZWNpZmllZCBuYW1lLgorICAgICAqCisgICAgICogPHA+QXNzdW1lcyB0aGUgZW50cnkgcmVwcmVzZW50cyBhIGRpcmVjdG9yeSBpZiBhbmQgb25seSBpZiB0aGUKKyAgICAgKiBuYW1lIGVuZHMgd2l0aCBhIGZvcndhcmQgc2xhc2ggIi8iLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lIHRoZSBuYW1lIG9mIHRoZSBlbnRyeQorICAgICAqLworICAgIHB1YmxpYyBaaXBBcmNoaXZlRW50cnkoZmluYWwgU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgc3VwZXIobmFtZSk7CisgICAgICAgIHNldE5hbWUobmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB6aXAgZW50cnkgd2l0aCBmaWVsZHMgdGFrZW4gZnJvbSB0aGUgc3BlY2lmaWVkIHppcCBlbnRyeS4KKyAgICAgKgorICAgICAqIDxwPkFzc3VtZXMgdGhlIGVudHJ5IHJlcHJlc2VudHMgYSBkaXJlY3RvcnkgaWYgYW5kIG9ubHkgaWYgdGhlCisgICAgICogbmFtZSBlbmRzIHdpdGggYSBmb3J3YXJkIHNsYXNoICIvIi48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gZW50cnkgdGhlIGVudHJ5IHRvIGdldCBmaWVsZHMgZnJvbQorICAgICAqIEB0aHJvd3MgWmlwRXhjZXB0aW9uIG9uIGVycm9yCisgICAgICovCisgICAgcHVibGljIFppcEFyY2hpdmVFbnRyeShmaW5hbCBqYXZhLnV0aWwuemlwLlppcEVudHJ5IGVudHJ5KSB0aHJvd3MgWmlwRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIoZW50cnkpOworICAgICAgICBzZXROYW1lKGVudHJ5LmdldE5hbWUoKSk7CisgICAgICAgIGZpbmFsIGJ5dGVbXSBleHRyYSA9IGVudHJ5LmdldEV4dHJhKCk7CisgICAgICAgIGlmIChleHRyYSAhPSBudWxsKSB7CisgICAgICAgICAgICBzZXRFeHRyYUZpZWxkcyhFeHRyYUZpZWxkVXRpbHMucGFyc2UoZXh0cmEsIHRydWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXh0cmFGaWVsZFV0aWxzCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLlVucGFyc2VhYmxlRXh0cmFGaWVsZC5SRUFEKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvLyBpbml0aWFsaXplcyBleHRyYSBkYXRhIHRvIGFuIGVtcHR5IGJ5dGUgYXJyYXkKKyAgICAgICAgICAgIHNldEV4dHJhKCk7CisgICAgICAgIH0KKyAgICAgICAgc2V0TWV0aG9kKGVudHJ5LmdldE1ldGhvZCgpKTsKKyAgICAgICAgdGhpcy5zaXplID0gZW50cnkuZ2V0U2l6ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgemlwIGVudHJ5IHdpdGggZmllbGRzIHRha2VuIGZyb20gdGhlIHNwZWNpZmllZCB6aXAgZW50cnkuCisgICAgICoKKyAgICAgKiA8cD5Bc3N1bWVzIHRoZSBlbnRyeSByZXByZXNlbnRzIGEgZGlyZWN0b3J5IGlmIGFuZCBvbmx5IGlmIHRoZQorICAgICAqIG5hbWUgZW5kcyB3aXRoIGEgZm9yd2FyZCBzbGFzaCAiLyIuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGVudHJ5IHRoZSBlbnRyeSB0byBnZXQgZmllbGRzIGZyb20KKyAgICAgKiBAdGhyb3dzIFppcEV4Y2VwdGlvbiBvbiBlcnJvcgorICAgICAqLworICAgIHB1YmxpYyBaaXBBcmNoaXZlRW50cnkoZmluYWwgWmlwQXJjaGl2ZUVudHJ5IGVudHJ5KSB0aHJvd3MgWmlwRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcygoamF2YS51dGlsLnppcC5aaXBFbnRyeSkgZW50cnkpOworICAgICAgICBzZXRJbnRlcm5hbEF0dHJpYnV0ZXMoZW50cnkuZ2V0SW50ZXJuYWxBdHRyaWJ1dGVzKCkpOworICAgICAgICBzZXRFeHRlcm5hbEF0dHJpYnV0ZXMoZW50cnkuZ2V0RXh0ZXJuYWxBdHRyaWJ1dGVzKCkpOworICAgICAgICBzZXRFeHRyYUZpZWxkcyhnZXRBbGxFeHRyYUZpZWxkc05vQ29weSgpKTsKKyAgICAgICAgc2V0UGxhdGZvcm0oZW50cnkuZ2V0UGxhdGZvcm0oKSk7CisgICAgICAgIGZpbmFsIEdlbmVyYWxQdXJwb3NlQml0IG90aGVyID0gZW50cnkuZ2V0R2VuZXJhbFB1cnBvc2VCaXQoKTsKKyAgICAgICAgc2V0R2VuZXJhbFB1cnBvc2VCaXQob3RoZXIgPT0gbnVsbCA/IG51bGwgOgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoR2VuZXJhbFB1cnBvc2VCaXQpIG90aGVyLmNsb25lKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqLworICAgIHByb3RlY3RlZCBaaXBBcmNoaXZlRW50cnkoKSB7CisgICAgICAgIHRoaXMoIiIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgemlwIGVudHJ5IHRha2luZyBzb21lIGluZm9ybWF0aW9uIGZyb20gdGhlIGdpdmVuCisgICAgICogZmlsZSBhbmQgdXNpbmcgdGhlIHByb3ZpZGVkIG5hbWUuCisgICAgICoKKyAgICAgKiA8cD5UaGUgbmFtZSB3aWxsIGJlIGFkanVzdGVkIHRvIGVuZCB3aXRoIGEgZm9yd2FyZCBzbGFzaCAiLyIgaWYKKyAgICAgKiB0aGUgZmlsZSBpcyBhIGRpcmVjdG9yeS4gIElmIHRoZSBmaWxlIGlzIG5vdCBhIGRpcmVjdG9yeSBhCisgICAgICogcG90ZW50aWFsIHRyYWlsaW5nIGZvcndhcmQgc2xhc2ggd2lsbCBiZSBzdHJpcHBlZCBmcm9tIHRoZQorICAgICAqIGVudHJ5IG5hbWUuPC9wPgorICAgICAqIEBwYXJhbSBpbnB1dEZpbGUgZmlsZSB0byBjcmVhdGUgdGhlIGVudHJ5IGZyb20KKyAgICAgKiBAcGFyYW0gZW50cnlOYW1lIG5hbWUgb2YgdGhlIGVudHJ5CisgICAgICovCisgICAgcHVibGljIFppcEFyY2hpdmVFbnRyeShmaW5hbCBGaWxlIGlucHV0RmlsZSwgZmluYWwgU3RyaW5nIGVudHJ5TmFtZSkgeworICAgICAgICB0aGlzKGlucHV0RmlsZS5pc0RpcmVjdG9yeSgpICYmICFlbnRyeU5hbWUuZW5kc1dpdGgoIi8iKSA/CisgICAgICAgICAgICAgZW50cnlOYW1lICsgIi8iIDogZW50cnlOYW1lKTsKKyAgICAgICAgaWYgKGlucHV0RmlsZS5pc0ZpbGUoKSl7CisgICAgICAgICAgICBzZXRTaXplKGlucHV0RmlsZS5sZW5ndGgoKSk7CisgICAgICAgIH0KKyAgICAgICAgc2V0VGltZShpbnB1dEZpbGUubGFzdE1vZGlmaWVkKCkpOworICAgICAgICAvLyBUT0RPIGFyZSB0aGVyZSBhbnkgb3RoZXIgZmllbGRzIHdlIGNhbiBzZXQgaGVyZT8KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBPdmVyd3JpdGUgY2xvbmUuCisgICAgICogQHJldHVybiBhIGNsb25lZCBjb3B5IG9mIHRoaXMgWmlwQXJjaGl2ZUVudHJ5CisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE9iamVjdCBjbG9uZSgpIHsKKyAgICAgICAgZmluYWwgWmlwQXJjaGl2ZUVudHJ5IGUgPSAoWmlwQXJjaGl2ZUVudHJ5KSBzdXBlci5jbG9uZSgpOworCisgICAgICAgIGUuc2V0SW50ZXJuYWxBdHRyaWJ1dGVzKGdldEludGVybmFsQXR0cmlidXRlcygpKTsKKyAgICAgICAgZS5zZXRFeHRlcm5hbEF0dHJpYnV0ZXMoZ2V0RXh0ZXJuYWxBdHRyaWJ1dGVzKCkpOworICAgICAgICBlLnNldEV4dHJhRmllbGRzKGdldEFsbEV4dHJhRmllbGRzTm9Db3B5KCkpOworICAgICAgICByZXR1cm4gZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjb21wcmVzc2lvbiBtZXRob2Qgb2YgdGhpcyBlbnRyeSwgb3IgLTEgaWYgdGhlCisgICAgICogY29tcHJlc3Npb24gbWV0aG9kIGhhcyBub3QgYmVlbiBzcGVjaWZpZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGNvbXByZXNzaW9uIG1ldGhvZAorICAgICAqCisgICAgICogQHNpbmNlIDEuMQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0TWV0aG9kKCkgeworICAgICAgICByZXR1cm4gbWV0aG9kOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGNvbXByZXNzaW9uIG1ldGhvZCBvZiB0aGlzIGVudHJ5LgorICAgICAqCisgICAgICogQHBhcmFtIG1ldGhvZCBjb21wcmVzc2lvbiBtZXRob2QKKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjEKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRNZXRob2QoZmluYWwgaW50IG1ldGhvZCkgeworICAgICAgICBpZiAobWV0aG9kIDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgIlpJUCBjb21wcmVzc2lvbiBtZXRob2QgY2FuIG5vdCBiZSBuZWdhdGl2ZTogIiArIG1ldGhvZCk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5tZXRob2QgPSBtZXRob2Q7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0cmlldmVzIHRoZSBpbnRlcm5hbCBmaWxlIGF0dHJpYnV0ZXMuCisgICAgICoKKyAgICAgKiA8cD48Yj5Ob3RlPC9iPjoge0BsaW5rIFppcEFyY2hpdmVJbnB1dFN0cmVhbX0gaXMgdW5hYmxlIHRvIGZpbGwKKyAgICAgKiB0aGlzIGZpZWxkLCB5b3UgbXVzdCB1c2Uge0BsaW5rIFppcEZpbGV9IGlmIHlvdSB3YW50IHRvIHJlYWQKKyAgICAgKiBlbnRyaWVzIHVzaW5nIHRoaXMgYXR0cmlidXRlLjwvcD4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGludGVybmFsIGZpbGUgYXR0cmlidXRlcworICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0SW50ZXJuYWxBdHRyaWJ1dGVzKCkgeworICAgICAgICByZXR1cm4gaW50ZXJuYWxBdHRyaWJ1dGVzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGludGVybmFsIGZpbGUgYXR0cmlidXRlcy4KKyAgICAgKiBAcGFyYW0gdmFsdWUgYW4gPGNvZGU+aW50PC9jb2RlPiB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEludGVybmFsQXR0cmlidXRlcyhmaW5hbCBpbnQgdmFsdWUpIHsKKyAgICAgICAgaW50ZXJuYWxBdHRyaWJ1dGVzID0gdmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0cmlldmVzIHRoZSBleHRlcm5hbCBmaWxlIGF0dHJpYnV0ZXMuCisgICAgICoKKyAgICAgKiA8cD48Yj5Ob3RlPC9iPjoge0BsaW5rIFppcEFyY2hpdmVJbnB1dFN0cmVhbX0gaXMgdW5hYmxlIHRvIGZpbGwKKyAgICAgKiB0aGlzIGZpZWxkLCB5b3UgbXVzdCB1c2Uge0BsaW5rIFppcEZpbGV9IGlmIHlvdSB3YW50IHRvIHJlYWQKKyAgICAgKiBlbnRyaWVzIHVzaW5nIHRoaXMgYXR0cmlidXRlLjwvcD4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGV4dGVybmFsIGZpbGUgYXR0cmlidXRlcworICAgICAqLworICAgIHB1YmxpYyBsb25nIGdldEV4dGVybmFsQXR0cmlidXRlcygpIHsKKyAgICAgICAgcmV0dXJuIGV4dGVybmFsQXR0cmlidXRlczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBleHRlcm5hbCBmaWxlIGF0dHJpYnV0ZXMuCisgICAgICogQHBhcmFtIHZhbHVlIGFuIDxjb2RlPmxvbmc8L2NvZGU+IHZhbHVlCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RXh0ZXJuYWxBdHRyaWJ1dGVzKGZpbmFsIGxvbmcgdmFsdWUpIHsKKyAgICAgICAgZXh0ZXJuYWxBdHRyaWJ1dGVzID0gdmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyBVbml4IHBlcm1pc3Npb25zIGluIGEgd2F5IHRoYXQgaXMgdW5kZXJzdG9vZCBieSBJbmZvLVppcCdzCisgICAgICogdW56aXAgY29tbWFuZC4KKyAgICAgKiBAcGFyYW0gbW9kZSBhbiA8Y29kZT5pbnQ8L2NvZGU+IHZhbHVlCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0VW5peE1vZGUoZmluYWwgaW50IG1vZGUpIHsKKyAgICAgICAgLy8gQ2hlY2tTdHlsZTpNYWdpY051bWJlckNoZWNrIE9GRiAtIG5vIHBvaW50CisgICAgICAgIHNldEV4dGVybmFsQXR0cmlidXRlcygobW9kZSA8PCBTSE9SVF9TSElGVCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE1TLURPUyByZWFkLW9ubHkgYXR0cmlidXRlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICgobW9kZSAmIDAyMDApID09IDAgPyAxIDogMCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE1TLURPUyBkaXJlY3RvcnkgZmxhZworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAoaXNEaXJlY3RvcnkoKSA/IDB4MTAgOiAwKSk7CisgICAgICAgIC8vIENoZWNrU3R5bGU6TWFnaWNOdW1iZXJDaGVjayBPTgorICAgICAgICBwbGF0Zm9ybSA9IFBMQVRGT1JNX1VOSVg7CisgICAgfQorCisgICAgLyoqCisgICAgICogVW5peCBwZXJtaXNzaW9uLgorICAgICAqIEByZXR1cm4gdGhlIHVuaXggcGVybWlzc2lvbnMKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFVuaXhNb2RlKCkgeworICAgICAgICByZXR1cm4gcGxhdGZvcm0gIT0gUExBVEZPUk1fVU5JWCA/IDAgOgorICAgICAgICAgICAgKGludCkgKChnZXRFeHRlcm5hbEF0dHJpYnV0ZXMoKSA+PiBTSE9SVF9TSElGVCkgJiBTSE9SVF9NQVNLKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBlbnRyeSByZXByZXNlbnRzIGEgdW5peCBzeW1saW5rLAorICAgICAqIGluIHdoaWNoIGNhc2UgdGhlIGVudHJ5J3MgY29udGVudCBjb250YWlucyB0aGUgdGFyZ2V0IHBhdGgKKyAgICAgKiBmb3IgdGhlIHN5bWxpbmsuCisgICAgICoKKyAgICAgKiBAc2luY2UgMS41CisgICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBlbnRyeSByZXByZXNlbnRzIGEgdW5peCBzeW1saW5rLCBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNVbml4U3ltbGluaygpIHsKKyAgICAgICAgcmV0dXJuIChnZXRVbml4TW9kZSgpICYgVW5peFN0YXQuRklMRV9UWVBFX0ZMQUcpID09IFVuaXhTdGF0LkxJTktfRkxBRzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQbGF0Zm9ybSBzcGVjaWZpY2F0aW9uIHRvIHB1dCBpbnRvIHRoZSAmcXVvdDt2ZXJzaW9uIG1hZGUKKyAgICAgKiBieSZxdW90OyBwYXJ0IG9mIHRoZSBjZW50cmFsIGZpbGUgaGVhZGVyLgorICAgICAqCisgICAgICogQHJldHVybiBQTEFURk9STV9GQVQgdW5sZXNzIHtAbGluayAjc2V0VW5peE1vZGUgc2V0VW5peE1vZGV9CisgICAgICogaGFzIGJlZW4gY2FsbGVkLCBpbiB3aGljaCBjYXNlIFBMQVRGT1JNX1VOSVggd2lsbCBiZSByZXR1cm5lZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFBsYXRmb3JtKCkgeworICAgICAgICByZXR1cm4gcGxhdGZvcm07CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBwbGF0Zm9ybSAoVU5JWCBvciBGQVQpLgorICAgICAqIEBwYXJhbSBwbGF0Zm9ybSBhbiA8Y29kZT5pbnQ8L2NvZGU+IHZhbHVlIC0gMCBpcyBGQVQsIDMgaXMgVU5JWAorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHNldFBsYXRmb3JtKGZpbmFsIGludCBwbGF0Zm9ybSkgeworICAgICAgICB0aGlzLnBsYXRmb3JtID0gcGxhdGZvcm07CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBjdXJyZW50bHkgY29uZmlndXJlZCBhbGlnbm1lbnQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCisgICAgICogICAgICBhbGlnbm1lbnQgZm9yIHRoaXMgZW50cnkuCisgICAgICogQHNpbmNlIDEuMTQKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IGdldEFsaWdubWVudCgpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMuYWxpZ25tZW50OworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgYWxpZ25tZW50IGZvciB0aGlzIGVudHJ5LgorICAgICAqCisgICAgICogQHBhcmFtIGFsaWdubWVudAorICAgICAqICAgICAgcmVxdWVzdGVkIGFsaWdubWVudCwgMCBmb3IgZGVmYXVsdC4KKyAgICAgKiBAc2luY2UgMS4xNAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEFsaWdubWVudChpbnQgYWxpZ25tZW50KSB7CisgICAgICAgIGlmICgoYWxpZ25tZW50ICYgKGFsaWdubWVudCAtIDEpKSAhPSAwIHx8IGFsaWdubWVudCA+IDB4ZmZmZikgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSW52YWxpZCB2YWx1ZSBmb3IgYWxpZ25tZW50LCBtdXN0IGJlIHBvd2VyIG9mIHR3byBhbmQgbm8gYmlnZ2VyIHRoYW4gIgorICAgICAgICAgICAgICAgICsgMHhmZmZmICsgIiBidXQgaXMgIiArIGFsaWdubWVudCk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5hbGlnbm1lbnQgPSBhbGlnbm1lbnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVwbGFjZXMgYWxsIGN1cnJlbnRseSBhdHRhY2hlZCBleHRyYSBmaWVsZHMgd2l0aCB0aGUgbmV3IGFycmF5LgorICAgICAqIEBwYXJhbSBmaWVsZHMgYW4gYXJyYXkgb2YgZXh0cmEgZmllbGRzCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RXh0cmFGaWVsZHMoZmluYWwgWmlwRXh0cmFGaWVsZFtdIGZpZWxkcykgeworICAgICAgICBmaW5hbCBMaXN0PFppcEV4dHJhRmllbGQ+IG5ld0ZpZWxkcyA9IG5ldyBBcnJheUxpc3Q8PigpOworICAgICAgICBmb3IgKGZpbmFsIFppcEV4dHJhRmllbGQgZmllbGQgOiBmaWVsZHMpIHsKKyAgICAgICAgICAgIGlmIChmaWVsZCBpbnN0YW5jZW9mIFVucGFyc2VhYmxlRXh0cmFGaWVsZERhdGEpIHsKKyAgICAgICAgICAgICAgICB1bnBhcnNlYWJsZUV4dHJhID0gKFVucGFyc2VhYmxlRXh0cmFGaWVsZERhdGEpIGZpZWxkOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBuZXdGaWVsZHMuYWRkKCBmaWVsZCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgZXh0cmFGaWVsZHMgPSBuZXdGaWVsZHMudG9BcnJheShuZXcgWmlwRXh0cmFGaWVsZFtuZXdGaWVsZHMuc2l6ZSgpXSk7CisgICAgICAgIHNldEV4dHJhKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0cmlldmVzIGFsbCBleHRyYSBmaWVsZHMgdGhhdCBoYXZlIGJlZW4gcGFyc2VkIHN1Y2Nlc3NmdWxseS4KKyAgICAgKgorICAgICAqIDxwPjxiPk5vdGU8L2I+OiBUaGUgc2V0IG9mIGV4dHJhIGZpZWxkcyBtYXkgYmUgaW5jb21wbGV0ZSB3aGVuCisgICAgICoge0BsaW5rIFppcEFyY2hpdmVJbnB1dFN0cmVhbX0gaGFzIGJlZW4gdXNlZCBhcyBzb21lIGV4dHJhCisgICAgICogZmllbGRzIHVzZSB0aGUgY2VudHJhbCBkaXJlY3RvcnkgdG8gc3RvcmUgYWRkaXRpb25hbAorICAgICAqIGluZm9ybWF0aW9uLjwvcD4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gYXJyYXkgb2YgdGhlIGV4dHJhIGZpZWxkcworICAgICAqLworICAgIHB1YmxpYyBaaXBFeHRyYUZpZWxkW10gZ2V0RXh0cmFGaWVsZHMoKSB7CisgICAgICAgIHJldHVybiBnZXRQYXJzZWFibGVFeHRyYUZpZWxkcygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHJpZXZlcyBleHRyYSBmaWVsZHMuCisgICAgICogQHBhcmFtIGluY2x1ZGVVbnBhcnNlYWJsZSB3aGV0aGVyIHRvIGFsc28gcmV0dXJuIHVucGFyc2VhYmxlCisgICAgICogZXh0cmEgZmllbGRzIGFzIHtAbGluayBVbnBhcnNlYWJsZUV4dHJhRmllbGREYXRhfSBpZiBzdWNoIGRhdGEKKyAgICAgKiBleGlzdHMuCisgICAgICogQHJldHVybiBhbiBhcnJheSBvZiB0aGUgZXh0cmEgZmllbGRzCisgICAgICoKKyAgICAgKiBAc2luY2UgMS4xCisgICAgICovCisgICAgcHVibGljIFppcEV4dHJhRmllbGRbXSBnZXRFeHRyYUZpZWxkcyhmaW5hbCBib29sZWFuIGluY2x1ZGVVbnBhcnNlYWJsZSkgeworICAgICAgICByZXR1cm4gaW5jbHVkZVVucGFyc2VhYmxlID8KKyAgICAgICAgICAgICAgICBnZXRBbGxFeHRyYUZpZWxkcygpIDoKKyAgICAgICAgICAgICAgICBnZXRQYXJzZWFibGVFeHRyYUZpZWxkcygpOworICAgIH0KKworICAgIHByaXZhdGUgWmlwRXh0cmFGaWVsZFtdIGdldFBhcnNlYWJsZUV4dHJhRmllbGRzTm9Db3B5KCkgeworICAgICAgICBpZiAoZXh0cmFGaWVsZHMgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG5vRXh0cmFGaWVsZHM7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGV4dHJhRmllbGRzOworICAgIH0KKworICAgIHByaXZhdGUgWmlwRXh0cmFGaWVsZFtdIGdldFBhcnNlYWJsZUV4dHJhRmllbGRzKCkgeworICAgICAgICBmaW5hbCBaaXBFeHRyYUZpZWxkW10gcGFyc2VhYmxlRXh0cmFGaWVsZHMgPSBnZXRQYXJzZWFibGVFeHRyYUZpZWxkc05vQ29weSgpOworICAgICAgICByZXR1cm4gKHBhcnNlYWJsZUV4dHJhRmllbGRzID09IGV4dHJhRmllbGRzKSA/IGNvcHlPZihwYXJzZWFibGVFeHRyYUZpZWxkcykgOiBwYXJzZWFibGVFeHRyYUZpZWxkczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgYWxsIGV4dHJhIGZpZWxkcywgaW5jbHVkaW5nIHVucGFyc2VhYmxlIG9uZXMuCisgICAgICogQHJldHVybiBBbiBhcnJheSBvZiBhbGwgZXh0cmEgZmllbGRzLiBOb3QgbmVjZXNzYXJpbHkgYSBjb3B5IG9mIGludGVybmFsIGRhdGEgc3RydWN0dXJlcywgaGVuY2UgcHJpdmF0ZSBtZXRob2QKKyAgICAgKi8KKyAgICBwcml2YXRlIFppcEV4dHJhRmllbGRbXSBnZXRBbGxFeHRyYUZpZWxkc05vQ29weSgpIHsKKyAgICAgICAgaWYgKGV4dHJhRmllbGRzID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBnZXRVbnBhcnNlYWJsZU9ubHkoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdW5wYXJzZWFibGVFeHRyYSAhPSBudWxsID8gZ2V0TWVyZ2VkRmllbGRzKCkgOiBleHRyYUZpZWxkczsKKyAgICB9CisKKyAgICBwcml2YXRlIFppcEV4dHJhRmllbGRbXSBjb3B5T2YoZmluYWwgWmlwRXh0cmFGaWVsZFtdIHNyYyl7CisgICAgICAgIHJldHVybiBjb3B5T2Yoc3JjLCBzcmMubGVuZ3RoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIFppcEV4dHJhRmllbGRbXSBjb3B5T2YoZmluYWwgWmlwRXh0cmFGaWVsZFtdIHNyYywgZmluYWwgaW50IGxlbmd0aCkgeworICAgICAgICBmaW5hbCBaaXBFeHRyYUZpZWxkW10gY3B5ID0gbmV3IFppcEV4dHJhRmllbGRbbGVuZ3RoXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShzcmMsIDAsIGNweSwgMCwgTWF0aC5taW4oc3JjLmxlbmd0aCwgbGVuZ3RoKSk7CisgICAgICAgIHJldHVybiBjcHk7CisgICAgfQorCisgICAgcHJpdmF0ZSBaaXBFeHRyYUZpZWxkW10gZ2V0TWVyZ2VkRmllbGRzKCkgeworICAgICAgICBmaW5hbCBaaXBFeHRyYUZpZWxkW10gemlwRXh0cmFGaWVsZHMgPSBjb3B5T2YoZXh0cmFGaWVsZHMsIGV4dHJhRmllbGRzLmxlbmd0aCArIDEpOworICAgICAgICB6aXBFeHRyYUZpZWxkc1tleHRyYUZpZWxkcy5sZW5ndGhdID0gdW5wYXJzZWFibGVFeHRyYTsKKyAgICAgICAgcmV0dXJuIHppcEV4dHJhRmllbGRzOworICAgIH0KKworICAgIHByaXZhdGUgWmlwRXh0cmFGaWVsZFtdIGdldFVucGFyc2VhYmxlT25seSgpIHsKKyAgICAgICAgcmV0dXJuIHVucGFyc2VhYmxlRXh0cmEgPT0gbnVsbCA/IG5vRXh0cmFGaWVsZHMgOiBuZXcgWmlwRXh0cmFGaWVsZFtdIHsgdW5wYXJzZWFibGVFeHRyYSB9OworICAgIH0KKworICAgIHByaXZhdGUgWmlwRXh0cmFGaWVsZFtdIGdldEFsbEV4dHJhRmllbGRzKCkgeworICAgICAgICBmaW5hbCBaaXBFeHRyYUZpZWxkW10gYWxsRXh0cmFGaWVsZHNOb0NvcHkgPSBnZXRBbGxFeHRyYUZpZWxkc05vQ29weSgpOworICAgICAgICByZXR1cm4gKGFsbEV4dHJhRmllbGRzTm9Db3B5ID09IGV4dHJhRmllbGRzKSA/IGNvcHlPZiggYWxsRXh0cmFGaWVsZHNOb0NvcHkpIDogYWxsRXh0cmFGaWVsZHNOb0NvcHk7CisgICAgfQorICAgIC8qKgorICAgICAqIEFkZHMgYW4gZXh0cmEgZmllbGQgLSByZXBsYWNpbmcgYW4gYWxyZWFkeSBwcmVzZW50IGV4dHJhIGZpZWxkCisgICAgICogb2YgdGhlIHNhbWUgdHlwZS4KKyAgICAgKgorICAgICAqIDxwPklmIG5vIGV4dHJhIGZpZWxkIG9mIHRoZSBzYW1lIHR5cGUgZXhpc3RzLCB0aGUgZmllbGQgd2lsbCBiZQorICAgICAqIGFkZGVkIGFzIGxhc3QgZmllbGQuPC9wPgorICAgICAqIEBwYXJhbSB6ZSBhbiBleHRyYSBmaWVsZAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFkZEV4dHJhRmllbGQoZmluYWwgWmlwRXh0cmFGaWVsZCB6ZSkgeworICAgICAgICBpZiAoemUgaW5zdGFuY2VvZiBVbnBhcnNlYWJsZUV4dHJhRmllbGREYXRhKSB7CisgICAgICAgICAgICB1bnBhcnNlYWJsZUV4dHJhID0gKFVucGFyc2VhYmxlRXh0cmFGaWVsZERhdGEpIHplOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaWYgKGV4dHJhRmllbGRzID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBleHRyYUZpZWxkcyA9IG5ldyBaaXBFeHRyYUZpZWxkW117IHplfTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgaWYgKGdldEV4dHJhRmllbGQoemUuZ2V0SGVhZGVySWQoKSkhPSBudWxsKXsKKyAgICAgICAgICAgICAgICAgICAgcmVtb3ZlRXh0cmFGaWVsZCh6ZS5nZXRIZWFkZXJJZCgpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZmluYWwgWmlwRXh0cmFGaWVsZFtdIHppcEV4dHJhRmllbGRzID0gY29weU9mKGV4dHJhRmllbGRzLCBleHRyYUZpZWxkcy5sZW5ndGggKyAxKTsKKyAgICAgICAgICAgICAgICB6aXBFeHRyYUZpZWxkc1t6aXBFeHRyYUZpZWxkcy5sZW5ndGggLTFdID0gemU7CisgICAgICAgICAgICAgICAgZXh0cmFGaWVsZHMgPSB6aXBFeHRyYUZpZWxkczsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBzZXRFeHRyYSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgYW4gZXh0cmEgZmllbGQgLSByZXBsYWNpbmcgYW4gYWxyZWFkeSBwcmVzZW50IGV4dHJhIGZpZWxkCisgICAgICogb2YgdGhlIHNhbWUgdHlwZS4KKyAgICAgKgorICAgICAqIDxwPlRoZSBuZXcgZXh0cmEgZmllbGQgd2lsbCBiZSB0aGUgZmlyc3Qgb25lLjwvcD4KKyAgICAgKiBAcGFyYW0gemUgYW4gZXh0cmEgZmllbGQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGRBc0ZpcnN0RXh0cmFGaWVsZChmaW5hbCBaaXBFeHRyYUZpZWxkIHplKSB7CisgICAgICAgIGlmICh6ZSBpbnN0YW5jZW9mIFVucGFyc2VhYmxlRXh0cmFGaWVsZERhdGEpIHsKKyAgICAgICAgICAgIHVucGFyc2VhYmxlRXh0cmEgPSAoVW5wYXJzZWFibGVFeHRyYUZpZWxkRGF0YSkgemU7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpZiAoZ2V0RXh0cmFGaWVsZCh6ZS5nZXRIZWFkZXJJZCgpKSAhPSBudWxsKXsKKyAgICAgICAgICAgICAgICByZW1vdmVFeHRyYUZpZWxkKHplLmdldEhlYWRlcklkKCkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZmluYWwgWmlwRXh0cmFGaWVsZFtdIGNvcHkgPSBleHRyYUZpZWxkczsKKyAgICAgICAgICAgIGZpbmFsIGludCBuZXdMZW4gPSBleHRyYUZpZWxkcyAhPSBudWxsID8gZXh0cmFGaWVsZHMubGVuZ3RoICsgMTogMTsKKyAgICAgICAgICAgIGV4dHJhRmllbGRzID0gbmV3IFppcEV4dHJhRmllbGRbbmV3TGVuXTsKKyAgICAgICAgICAgIGV4dHJhRmllbGRzWzBdID0gemU7CisgICAgICAgICAgICBpZiAoY29weSAhPSBudWxsKXsKKyAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGNvcHksIDAsIGV4dHJhRmllbGRzLCAxLCBleHRyYUZpZWxkcy5sZW5ndGggLSAxKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBzZXRFeHRyYSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZSBhbiBleHRyYSBmaWVsZC4KKyAgICAgKiBAcGFyYW0gdHlwZSB0aGUgdHlwZSBvZiBleHRyYSBmaWVsZCB0byByZW1vdmUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZW1vdmVFeHRyYUZpZWxkKGZpbmFsIFppcFNob3J0IHR5cGUpIHsKKyAgICAgICAgaWYgKGV4dHJhRmllbGRzID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLnV0aWwuTm9TdWNoRWxlbWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgZmluYWwgTGlzdDxaaXBFeHRyYUZpZWxkPiBuZXdSZXN1bHQgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKyAgICAgICAgZm9yIChmaW5hbCBaaXBFeHRyYUZpZWxkIGV4dHJhRmllbGQgOiBleHRyYUZpZWxkcykgeworICAgICAgICAgICAgaWYgKCF0eXBlLmVxdWFscyhleHRyYUZpZWxkLmdldEhlYWRlcklkKCkpKXsKKyAgICAgICAgICAgICAgICBuZXdSZXN1bHQuYWRkKCBleHRyYUZpZWxkKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoZXh0cmFGaWVsZHMubGVuZ3RoID09IG5ld1Jlc3VsdC5zaXplKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLnV0aWwuTm9TdWNoRWxlbWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGV4dHJhRmllbGRzID0gbmV3UmVzdWx0LnRvQXJyYXkobmV3IFppcEV4dHJhRmllbGRbbmV3UmVzdWx0LnNpemUoKV0pOworICAgICAgICBzZXRFeHRyYSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgdW5wYXJzZWFibGUgZXh0cmEgZmllbGQgZGF0YS4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjEKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZW1vdmVVbnBhcnNlYWJsZUV4dHJhRmllbGREYXRhKCkgeworICAgICAgICBpZiAodW5wYXJzZWFibGVFeHRyYSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgamF2YS51dGlsLk5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICB1bnBhcnNlYWJsZUV4dHJhID0gbnVsbDsKKyAgICAgICAgc2V0RXh0cmEoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMb29rcyB1cCBhbiBleHRyYSBmaWVsZCBieSBpdHMgaGVhZGVyIGlkLgorICAgICAqCisgICAgICogQHBhcmFtIHR5cGUgdGhlIGhlYWRlciBpZAorICAgICAqIEByZXR1cm4gbnVsbCBpZiBubyBzdWNoIGZpZWxkIGV4aXN0cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgWmlwRXh0cmFGaWVsZCBnZXRFeHRyYUZpZWxkKGZpbmFsIFppcFNob3J0IHR5cGUpIHsKKyAgICAgICAgaWYgKGV4dHJhRmllbGRzICE9IG51bGwpIHsKKyAgICAgICAgICAgIGZvciAoZmluYWwgWmlwRXh0cmFGaWVsZCBleHRyYUZpZWxkIDogZXh0cmFGaWVsZHMpIHsKKyAgICAgICAgICAgICAgICBpZiAodHlwZS5lcXVhbHMoZXh0cmFGaWVsZC5nZXRIZWFkZXJJZCgpKSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gZXh0cmFGaWVsZDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogTG9va3MgdXAgZXh0cmEgZmllbGQgZGF0YSB0aGF0IGNvdWxkbid0IGJlIHBhcnNlZCBjb3JyZWN0bHkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIG51bGwgaWYgbm8gc3VjaCBmaWVsZCBleGlzdHMuCisgICAgICoKKyAgICAgKiBAc2luY2UgMS4xCisgICAgICovCisgICAgcHVibGljIFVucGFyc2VhYmxlRXh0cmFGaWVsZERhdGEgZ2V0VW5wYXJzZWFibGVFeHRyYUZpZWxkRGF0YSgpIHsKKyAgICAgICAgcmV0dXJuIHVucGFyc2VhYmxlRXh0cmE7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2VzIHRoZSBnaXZlbiBieXRlcyBhcyBleHRyYSBmaWVsZCBkYXRhIGFuZCBjb25zdW1lcyBhbnkKKyAgICAgKiB1bnBhcnNlYWJsZSBkYXRhIGFzIGFuIHtAbGluayBVbnBhcnNlYWJsZUV4dHJhRmllbGREYXRhfQorICAgICAqIGluc3RhbmNlLgorICAgICAqIEBwYXJhbSBleHRyYSBhbiBhcnJheSBvZiBieXRlcyB0byBiZSBwYXJzZWQgaW50byBleHRyYSBmaWVsZHMKKyAgICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gaWYgdGhlIGJ5dGVzIGNhbm5vdCBiZSBwYXJzZWQKKyAgICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gb24gZXJyb3IKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRFeHRyYShmaW5hbCBieXRlW10gZXh0cmEpIHRocm93cyBSdW50aW1lRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZpbmFsIFppcEV4dHJhRmllbGRbXSBsb2NhbCA9CisgICAgICAgICAgICAgICAgRXh0cmFGaWVsZFV0aWxzLnBhcnNlKGV4dHJhLCB0cnVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFeHRyYUZpZWxkVXRpbHMuVW5wYXJzZWFibGVFeHRyYUZpZWxkLlJFQUQpOworICAgICAgICAgICAgbWVyZ2VFeHRyYUZpZWxkcyhsb2NhbCwgdHJ1ZSk7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIFppcEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBhY3R1YWxseSB0aGlzIGlzIG5vdCBwb3NzaWJsZSBhcyBvZiBDb21tb25zIENvbXByZXNzIDEuMQorICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIkVycm9yIHBhcnNpbmcgZXh0cmEgZmllbGRzIGZvciBlbnRyeTogIiAvL05PU09OQVIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgZ2V0TmFtZSgpICsgIiAtICIgKyBlLmdldE1lc3NhZ2UoKSwgZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVbmZvcnR1bmF0ZWx5IHtAbGluayBqYXZhLnV0aWwuemlwLlppcE91dHB1dFN0cmVhbQorICAgICAqIGphdmEudXRpbC56aXAuWmlwT3V0cHV0U3RyZWFtfSBzZWVtcyB0byBhY2Nlc3MgdGhlIGV4dHJhIGRhdGEKKyAgICAgKiBkaXJlY3RseSwgc28gb3ZlcnJpZGluZyBnZXRFeHRyYSBkb2Vzbid0IGhlbHAgLSB3ZSBuZWVkIHRvCisgICAgICogbW9kaWZ5IHN1cGVyJ3MgZGF0YSBkaXJlY3RseS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRFeHRyYSgpIHsKKyAgICAgICAgc3VwZXIuc2V0RXh0cmEoRXh0cmFGaWVsZFV0aWxzLm1lcmdlTG9jYWxGaWxlRGF0YURhdGEoZ2V0QWxsRXh0cmFGaWVsZHNOb0NvcHkoKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGNlbnRyYWwgZGlyZWN0b3J5IHBhcnQgb2YgZXh0cmEgZmllbGRzLgorICAgICAqIEBwYXJhbSBiIGFuIGFycmF5IG9mIGJ5dGVzIHRvIGJlIHBhcnNlZCBpbnRvIGV4dHJhIGZpZWxkcworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldENlbnRyYWxEaXJlY3RvcnlFeHRyYShmaW5hbCBieXRlW10gYikgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmluYWwgWmlwRXh0cmFGaWVsZFtdIGNlbnRyYWwgPQorICAgICAgICAgICAgICAgIEV4dHJhRmllbGRVdGlscy5wYXJzZShiLCBmYWxzZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXh0cmFGaWVsZFV0aWxzLlVucGFyc2VhYmxlRXh0cmFGaWVsZC5SRUFEKTsKKyAgICAgICAgICAgIG1lcmdlRXh0cmFGaWVsZHMoY2VudHJhbCwgZmFsc2UpOworICAgICAgICB9IGNhdGNoIChmaW5hbCBaaXBFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZS5nZXRNZXNzYWdlKCksIGUpOyAvL05PU09OQVIKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHJpZXZlcyB0aGUgZXh0cmEgZGF0YSBmb3IgdGhlIGxvY2FsIGZpbGUgZGF0YS4KKyAgICAgKiBAcmV0dXJuIHRoZSBleHRyYSBkYXRhIGZvciBsb2NhbCBmaWxlCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXRMb2NhbEZpbGVEYXRhRXh0cmEoKSB7CisgICAgICAgIGZpbmFsIGJ5dGVbXSBleHRyYSA9IGdldEV4dHJhKCk7CisgICAgICAgIHJldHVybiBleHRyYSAhPSBudWxsID8gZXh0cmEgOiBFTVBUWTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXRyaWV2ZXMgdGhlIGV4dHJhIGRhdGEgZm9yIHRoZSBjZW50cmFsIGRpcmVjdG9yeS4KKyAgICAgKiBAcmV0dXJuIHRoZSBjZW50cmFsIGRpcmVjdG9yeSBleHRyYSBkYXRhCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXRDZW50cmFsRGlyZWN0b3J5RXh0cmEoKSB7CisgICAgICAgIHJldHVybiBFeHRyYUZpZWxkVXRpbHMubWVyZ2VDZW50cmFsRGlyZWN0b3J5RGF0YShnZXRBbGxFeHRyYUZpZWxkc05vQ29weSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIG5hbWUgb2YgdGhlIGVudHJ5LgorICAgICAqCisgICAgICogPHA+VGhpcyBtZXRob2QgcmV0dXJucyB0aGUgcmF3IG5hbWUgYXMgaXQgaXMgc3RvcmVkIGluc2lkZSBvZiB0aGUgYXJjaGl2ZS48L3A+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBlbnRyeSBuYW1lCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgeworICAgICAgICByZXR1cm4gbmFtZSA9PSBudWxsID8gc3VwZXIuZ2V0TmFtZSgpIDogbmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJcyB0aGlzIGVudHJ5IGEgZGlyZWN0b3J5PworICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgZW50cnkgaXMgYSBkaXJlY3RvcnkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0RpcmVjdG9yeSgpIHsKKyAgICAgICAgcmV0dXJuIGdldE5hbWUoKS5lbmRzV2l0aCgiLyIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgbmFtZSBvZiB0aGUgZW50cnkuCisgICAgICogQHBhcmFtIG5hbWUgdGhlIG5hbWUgdG8gdXNlCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0TmFtZShTdHJpbmcgbmFtZSkgeworICAgICAgICBpZiAobmFtZSAhPSBudWxsICYmIGdldFBsYXRmb3JtKCkgPT0gUExBVEZPUk1fRkFUCisgICAgICAgICAgICAmJiAhbmFtZS5jb250YWlucygiLyIpKSB7CisgICAgICAgICAgICBuYW1lID0gbmFtZS5yZXBsYWNlKCdcXCcsICcvJyk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB1bmNvbXByZXNzZWQgc2l6ZSBvZiB0aGUgZW50cnkgZGF0YS4KKyAgICAgKgorICAgICAqIDxwPjxiPk5vdGU8L2I+OiB7QGxpbmsgWmlwQXJjaGl2ZUlucHV0U3RyZWFtfSBtYXkgY3JlYXRlCisgICAgICogZW50cmllcyB0aGF0IHJldHVybiB7QGxpbmsgI1NJWkVfVU5LTk9XTiBTSVpFX1VOS05PV059IGFzIGxvbmcKKyAgICAgKiBhcyB0aGUgZW50cnkgaGFzbid0IGJlZW4gcmVhZCBjb21wbGV0ZWx5LjwvcD4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGVudHJ5IHNpemUKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgbG9uZyBnZXRTaXplKCkgeworICAgICAgICByZXR1cm4gc2l6ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB1bmNvbXByZXNzZWQgc2l6ZSBvZiB0aGUgZW50cnkgZGF0YS4KKyAgICAgKiBAcGFyYW0gc2l6ZSB0aGUgdW5jb21wcmVzc2VkIHNpemUgaW4gYnl0ZXMKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIHNpemUgaXMgbGVzcworICAgICAqICAgICAgICAgICAgdGhhbiAwCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0U2l6ZShmaW5hbCBsb25nIHNpemUpIHsKKyAgICAgICAgaWYgKHNpemUgPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJpbnZhbGlkIGVudHJ5IHNpemUiKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLnNpemUgPSBzaXplOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIG5hbWUgdXNpbmcgdGhlIHJhdyBieXRlcyBhbmQgdGhlIHN0cmluZyBjcmVhdGVkIGZyb20KKyAgICAgKiBpdCBieSBndWVzc2luZyBvciB1c2luZyB0aGUgY29uZmlndXJlZCBlbmNvZGluZy4KKyAgICAgKiBAcGFyYW0gbmFtZSB0aGUgbmFtZSB0byB1c2UgY3JlYXRlZCBmcm9tIHRoZSByYXcgYnl0ZXMgdXNpbmcKKyAgICAgKiB0aGUgZ3Vlc3NlZCBvciBjb25maWd1cmVkIGVuY29kaW5nCisgICAgICogQHBhcmFtIHJhd05hbWUgdGhlIGJ5dGVzIG9yaWdpbmFsbHkgcmVhZCBhcyBuYW1lIGZyb20gdGhlCisgICAgICogYXJjaGl2ZQorICAgICAqIEBzaW5jZSAxLjIKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXROYW1lKGZpbmFsIFN0cmluZyBuYW1lLCBmaW5hbCBieXRlW10gcmF3TmFtZSkgeworICAgICAgICBzZXROYW1lKG5hbWUpOworICAgICAgICB0aGlzLnJhd05hbWUgPSByYXdOYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHJhdyBieXRlcyB0aGF0IG1hZGUgdXAgdGhlIG5hbWUgYmVmb3JlIGl0IGhhcyBiZWVuCisgICAgICogY29udmVydGVkIHVzaW5nIHRoZSBjb25maWd1cmVkIG9yIGd1ZXNzZWQgZW5jb2RpbmcuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCB3aWxsIHJldHVybiBudWxsIGlmIHRoaXMgaW5zdGFuY2UgaGFzIG5vdCBiZWVuCisgICAgICogcmVhZCBmcm9tIGFuIGFyY2hpdmUuPC9wPgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcmF3IG5hbWUgYnl0ZXMKKyAgICAgKiBAc2luY2UgMS4yCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXRSYXdOYW1lKCkgeworICAgICAgICBpZiAocmF3TmFtZSAhPSBudWxsKSB7CisgICAgICAgICAgICBmaW5hbCBieXRlW10gYiA9IG5ldyBieXRlW3Jhd05hbWUubGVuZ3RoXTsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkocmF3TmFtZSwgMCwgYiwgMCwgcmF3TmFtZS5sZW5ndGgpOworICAgICAgICAgICAgcmV0dXJuIGI7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHJvdGVjdGVkIGxvbmcgZ2V0TG9jYWxIZWFkZXJPZmZzZXQoKSB7CisgICAgICAgIHJldHVybiB0aGlzLmxvY2FsSGVhZGVyT2Zmc2V0OworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHNldExvY2FsSGVhZGVyT2Zmc2V0KGxvbmcgbG9jYWxIZWFkZXJPZmZzZXQpIHsKKyAgICAgICAgdGhpcy5sb2NhbEhlYWRlck9mZnNldCA9IGxvY2FsSGVhZGVyT2Zmc2V0OworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBsb25nIGdldERhdGFPZmZzZXQoKSB7CisgICAgICAgIHJldHVybiBkYXRhT2Zmc2V0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGRhdGEgb2Zmc2V0LgorICAgICAqCisgICAgICogQHBhcmFtIGRhdGFPZmZzZXQKKyAgICAgKiAgICAgIG5ldyB2YWx1ZSBvZiBkYXRhIG9mZnNldC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXREYXRhT2Zmc2V0KGxvbmcgZGF0YU9mZnNldCkgeworICAgICAgICB0aGlzLmRhdGFPZmZzZXQgPSBkYXRhT2Zmc2V0OworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGlzU3RyZWFtQ29udGlndW91cygpIHsKKyAgICAgICAgcmV0dXJuIGlzU3RyZWFtQ29udGlndW91czsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRTdHJlYW1Db250aWd1b3VzKGJvb2xlYW4gaXNTdHJlYW1Db250aWd1b3VzKSB7CisgICAgICAgIHRoaXMuaXNTdHJlYW1Db250aWd1b3VzID0gaXNTdHJlYW1Db250aWd1b3VzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgaGFzaENvZGUgb2YgdGhlIGVudHJ5LgorICAgICAqIFRoaXMgdXNlcyB0aGUgbmFtZSBhcyB0aGUgaGFzaGNvZGUuCisgICAgICogQHJldHVybiBhIGhhc2hjb2RlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIC8vIHRoaXMgbWV0aG9kIGhhcyBzZXZlcmUgY29uc2VxdWVuY2VzIG9uIHBlcmZvcm1hbmNlLiBXZSBjYW5ub3QgcmVseQorICAgICAgICAvLyBvbiB0aGUgc3VwZXIuaGFzaENvZGUoKSBtZXRob2Qgc2luY2Ugc3VwZXIuZ2V0TmFtZSgpIGFsd2F5cyByZXR1cm4KKyAgICAgICAgLy8gdGhlIGVtcHR5IHN0cmluZyBpbiB0aGUgY3VycmVudCBpbXBsZW1lbnRpb24gKHRoZXJlJ3Mgbm8gc2V0dGVyKQorICAgICAgICAvLyBzbyBpdCBpcyBiYXNpY2FsbHkgZHJhaW5pbmcgdGhlIHBlcmZvcm1hbmNlIG9mIGEgaGFzaG1hcCBsb29rdXAKKyAgICAgICAgcmV0dXJuIGdldE5hbWUoKS5oYXNoQ29kZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSAiZ2VuZXJhbCBwdXJwb3NlIGJpdCIgZmllbGQuCisgICAgICogQHJldHVybiB0aGUgZ2VuZXJhbCBwdXJwb3NlIGJpdAorICAgICAqIEBzaW5jZSAxLjEKKyAgICAgKi8KKyAgICBwdWJsaWMgR2VuZXJhbFB1cnBvc2VCaXQgZ2V0R2VuZXJhbFB1cnBvc2VCaXQoKSB7CisgICAgICAgIHJldHVybiBncGI7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlICJnZW5lcmFsIHB1cnBvc2UgYml0IiBmaWVsZC4KKyAgICAgKiBAcGFyYW0gYiB0aGUgZ2VuZXJhbCBwdXJwb3NlIGJpdAorICAgICAqIEBzaW5jZSAxLjEKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRHZW5lcmFsUHVycG9zZUJpdChmaW5hbCBHZW5lcmFsUHVycG9zZUJpdCBiKSB7CisgICAgICAgIGdwYiA9IGI7CisgICAgfQorCisgICAgLyoqCisgICAgICogSWYgdGhlcmUgYXJlIG5vIGV4dHJhIGZpZWxkcywgdXNlIHRoZSBnaXZlbiBmaWVsZHMgYXMgbmV3IGV4dHJhCisgICAgICogZGF0YSAtIG90aGVyd2lzZSBtZXJnZSB0aGUgZmllbGRzIGFzc3VtaW5nIHRoZSBleGlzdGluZyBmaWVsZHMKKyAgICAgKiBhbmQgdGhlIG5ldyBmaWVsZHMgc3RlbSBmcm9tIGRpZmZlcmVudCBsb2NhdGlvbnMgaW5zaWRlIHRoZQorICAgICAqIGFyY2hpdmUuCisgICAgICogQHBhcmFtIGYgdGhlIGV4dHJhIGZpZWxkcyB0byBtZXJnZQorICAgICAqIEBwYXJhbSBsb2NhbCB3aGV0aGVyIHRoZSBuZXcgZmllbGRzIG9yaWdpbmF0ZSBmcm9tIGxvY2FsIGRhdGEKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgbWVyZ2VFeHRyYUZpZWxkcyhmaW5hbCBaaXBFeHRyYUZpZWxkW10gZiwgZmluYWwgYm9vbGVhbiBsb2NhbCkKKyAgICAgICAgdGhyb3dzIFppcEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChleHRyYUZpZWxkcyA9PSBudWxsKSB7CisgICAgICAgICAgICBzZXRFeHRyYUZpZWxkcyhmKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGZvciAoZmluYWwgWmlwRXh0cmFGaWVsZCBlbGVtZW50IDogZikgeworICAgICAgICAgICAgICAgIFppcEV4dHJhRmllbGQgZXhpc3Rpbmc7CisgICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQgaW5zdGFuY2VvZiBVbnBhcnNlYWJsZUV4dHJhRmllbGREYXRhKSB7CisgICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nID0gdW5wYXJzZWFibGVFeHRyYTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBleGlzdGluZyA9IGdldEV4dHJhRmllbGQoZWxlbWVudC5nZXRIZWFkZXJJZCgpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKGV4aXN0aW5nID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgYWRkRXh0cmFGaWVsZChlbGVtZW50KTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBpZiAobG9jYWwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBiID0gZWxlbWVudC5nZXRMb2NhbEZpbGVEYXRhRGF0YSgpOworICAgICAgICAgICAgICAgICAgICAgICAgZXhpc3RpbmcucGFyc2VGcm9tTG9jYWxGaWxlRGF0YShiLCAwLCBiLmxlbmd0aCk7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBieXRlW10gYiA9IGVsZW1lbnQuZ2V0Q2VudHJhbERpcmVjdG9yeURhdGEoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nLnBhcnNlRnJvbUNlbnRyYWxEaXJlY3RvcnlEYXRhKGIsIDAsIGIubGVuZ3RoKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHNldEV4dHJhKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcmFwcyB7QGxpbmsgamF2YS51dGlsLnppcC5aaXBFbnRyeSNnZXRUaW1lfSB3aXRoIGEge0BsaW5rIERhdGV9IGFzIHRoZQorICAgICAqIGVudHJ5J3MgbGFzdCBtb2RpZmllZCBkYXRlLgorICAgICAqCisgICAgICogPHA+Q2hhbmdlcyB0byB0aGUgaW1wbGVtZW50YXRpb24gb2Yge0BsaW5rIGphdmEudXRpbC56aXAuWmlwRW50cnkjZ2V0VGltZX0KKyAgICAgKiBsZWFrIHRocm91Z2ggYW5kIHRoZSByZXR1cm5lZCB2YWx1ZSBtYXkgZGVwZW5kIG9uIHlvdXIgbG9jYWwKKyAgICAgKiB0aW1lIHpvbmUgYXMgd2VsbCBhcyB5b3VyIHZlcnNpb24gb2YgSmF2YS48L3A+CisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIERhdGUgZ2V0TGFzdE1vZGlmaWVkRGF0ZSgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBEYXRlKGdldFRpbWUoKSk7CisgICAgfQorCisgICAgLyogKG5vbi1KYXZhZG9jKQorICAgICAqIEBzZWUgamF2YS5sYW5nLk9iamVjdCNlcXVhbHMoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgT2JqZWN0IG9iaikgeworICAgICAgICBpZiAodGhpcyA9PSBvYmopIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmIChvYmogPT0gbnVsbCB8fCBnZXRDbGFzcygpICE9IG9iai5nZXRDbGFzcygpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgZmluYWwgWmlwQXJjaGl2ZUVudHJ5IG90aGVyID0gKFppcEFyY2hpdmVFbnRyeSkgb2JqOworICAgICAgICBmaW5hbCBTdHJpbmcgbXlOYW1lID0gZ2V0TmFtZSgpOworICAgICAgICBmaW5hbCBTdHJpbmcgb3RoZXJOYW1lID0gb3RoZXIuZ2V0TmFtZSgpOworICAgICAgICBpZiAobXlOYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIGlmIChvdGhlck5hbWUgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIGlmICghbXlOYW1lLmVxdWFscyhvdGhlck5hbWUpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nIG15Q29tbWVudCA9IGdldENvbW1lbnQoKTsKKyAgICAgICAgU3RyaW5nIG90aGVyQ29tbWVudCA9IG90aGVyLmdldENvbW1lbnQoKTsKKyAgICAgICAgaWYgKG15Q29tbWVudCA9PSBudWxsKSB7CisgICAgICAgICAgICBteUNvbW1lbnQgPSAiIjsKKyAgICAgICAgfQorICAgICAgICBpZiAob3RoZXJDb21tZW50ID09IG51bGwpIHsKKyAgICAgICAgICAgIG90aGVyQ29tbWVudCA9ICIiOworICAgICAgICB9CisgICAgICAgIHJldHVybiBnZXRUaW1lKCkgPT0gb3RoZXIuZ2V0VGltZSgpCisgICAgICAgICAgICAmJiBteUNvbW1lbnQuZXF1YWxzKG90aGVyQ29tbWVudCkKKyAgICAgICAgICAgICYmIGdldEludGVybmFsQXR0cmlidXRlcygpID09IG90aGVyLmdldEludGVybmFsQXR0cmlidXRlcygpCisgICAgICAgICAgICAmJiBnZXRQbGF0Zm9ybSgpID09IG90aGVyLmdldFBsYXRmb3JtKCkKKyAgICAgICAgICAgICYmIGdldEV4dGVybmFsQXR0cmlidXRlcygpID09IG90aGVyLmdldEV4dGVybmFsQXR0cmlidXRlcygpCisgICAgICAgICAgICAmJiBnZXRNZXRob2QoKSA9PSBvdGhlci5nZXRNZXRob2QoKQorICAgICAgICAgICAgJiYgZ2V0U2l6ZSgpID09IG90aGVyLmdldFNpemUoKQorICAgICAgICAgICAgJiYgZ2V0Q3JjKCkgPT0gb3RoZXIuZ2V0Q3JjKCkKKyAgICAgICAgICAgICYmIGdldENvbXByZXNzZWRTaXplKCkgPT0gb3RoZXIuZ2V0Q29tcHJlc3NlZFNpemUoKQorICAgICAgICAgICAgJiYgQXJyYXlzLmVxdWFscyhnZXRDZW50cmFsRGlyZWN0b3J5RXh0cmEoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3RoZXIuZ2V0Q2VudHJhbERpcmVjdG9yeUV4dHJhKCkpCisgICAgICAgICAgICAmJiBBcnJheXMuZXF1YWxzKGdldExvY2FsRmlsZURhdGFFeHRyYSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdGhlci5nZXRMb2NhbEZpbGVEYXRhRXh0cmEoKSkKKyAgICAgICAgICAgICYmIGxvY2FsSGVhZGVyT2Zmc2V0ID09IG90aGVyLmxvY2FsSGVhZGVyT2Zmc2V0CisgICAgICAgICAgICAmJiBkYXRhT2Zmc2V0ID09IG90aGVyLmRhdGFPZmZzZXQKKyAgICAgICAgICAgICYmIGdwYi5lcXVhbHMob3RoZXIuZ3BiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSAidmVyc2lvbiBtYWRlIGJ5IiBmaWVsZC4KKyAgICAgKiBAcGFyYW0gdmVyc2lvbk1hZGVCeSAidmVyc2lvbiBtYWRlIGJ5IiBmaWVsZAorICAgICAqIEBzaW5jZSAxLjExCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0VmVyc2lvbk1hZGVCeShmaW5hbCBpbnQgdmVyc2lvbk1hZGVCeSkgeworICAgICAgICB0aGlzLnZlcnNpb25NYWRlQnkgPSB2ZXJzaW9uTWFkZUJ5OworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlICJ2ZXJzaW9uIHJlcXVpcmVkIHRvIGV4cGFuZCIgZmllbGQuCisgICAgICogQHBhcmFtIHZlcnNpb25SZXF1aXJlZCAidmVyc2lvbiByZXF1aXJlZCB0byBleHBhbmQiIGZpZWxkCisgICAgICogQHNpbmNlIDEuMTEKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRWZXJzaW9uUmVxdWlyZWQoZmluYWwgaW50IHZlcnNpb25SZXF1aXJlZCkgeworICAgICAgICB0aGlzLnZlcnNpb25SZXF1aXJlZCA9IHZlcnNpb25SZXF1aXJlZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgInZlcnNpb24gcmVxdWlyZWQgdG8gZXhwYW5kIiBmaWVsZC4KKyAgICAgKiBAcmV0dXJuICJ2ZXJzaW9uIHJlcXVpcmVkIHRvIGV4cGFuZCIgZmllbGQKKyAgICAgKiBAc2luY2UgMS4xMQorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0VmVyc2lvblJlcXVpcmVkKCkgeworICAgICAgICByZXR1cm4gdmVyc2lvblJlcXVpcmVkOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSAidmVyc2lvbiBtYWRlIGJ5IiBmaWVsZC4KKyAgICAgKiBAcmV0dXJuICJ2ZXJzaW9uIG1hZGUgYnkiIGZpZWxkCisgICAgICogQHNpbmNlIDEuMTEKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFZlcnNpb25NYWRlQnkoKSB7CisgICAgICAgIHJldHVybiB2ZXJzaW9uTWFkZUJ5OworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBjb250ZW50IG9mIHRoZSBmbGFncyBmaWVsZC4KKyAgICAgKiBAcmV0dXJuIGNvbnRlbnQgb2YgdGhlIGZsYWdzIGZpZWxkCisgICAgICogQHNpbmNlIDEuMTEKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFJhd0ZsYWcoKSB7CisgICAgICAgIHJldHVybiByYXdGbGFnOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGNvbnRlbnQgb2YgdGhlIGZsYWdzIGZpZWxkLgorICAgICAqIEBwYXJhbSByYXdGbGFnIGNvbnRlbnQgb2YgdGhlIGZsYWdzIGZpZWxkCisgICAgICogQHNpbmNlIDEuMTEKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRSYXdGbGFnKGZpbmFsIGludCByYXdGbGFnKSB7CisgICAgICAgIHRoaXMucmF3RmxhZyA9IHJhd0ZsYWc7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIHNvdXJjZSBvZiB0aGUgbmFtZSBmaWVsZCB2YWx1ZS4KKyAgICAgKiBAcmV0dXJuIHNvdXJjZSBvZiB0aGUgbmFtZSBmaWVsZCB2YWx1ZQorICAgICAqIEBzaW5jZSAxLjE2CisgICAgICovCisgICAgcHVibGljIE5hbWVTb3VyY2UgZ2V0TmFtZVNvdXJjZSgpIHsKKyAgICAgICAgcmV0dXJuIG5hbWVTb3VyY2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgc291cmNlIG9mIHRoZSBuYW1lIGZpZWxkIHZhbHVlLgorICAgICAqIEBwYXJhbSBuYW1lU291cmNlIHNvdXJjZSBvZiB0aGUgbmFtZSBmaWVsZCB2YWx1ZQorICAgICAqIEBzaW5jZSAxLjE2CisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TmFtZVNvdXJjZShOYW1lU291cmNlIG5hbWVTb3VyY2UpIHsKKyAgICAgICAgdGhpcy5uYW1lU291cmNlID0gbmFtZVNvdXJjZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgc291cmNlIG9mIHRoZSBjb21tZW50IGZpZWxkIHZhbHVlLgorICAgICAqIEByZXR1cm4gc291cmNlIG9mIHRoZSBjb21tZW50IGZpZWxkIHZhbHVlCisgICAgICogQHNpbmNlIDEuMTYKKyAgICAgKi8KKyAgICBwdWJsaWMgQ29tbWVudFNvdXJjZSBnZXRDb21tZW50U291cmNlKCkgeworICAgICAgICByZXR1cm4gY29tbWVudFNvdXJjZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBzb3VyY2Ugb2YgdGhlIGNvbW1lbnQgZmllbGQgdmFsdWUuCisgICAgICogQHBhcmFtIGNvbW1lbnRTb3VyY2Ugc291cmNlIG9mIHRoZSBjb21tZW50IGZpZWxkIHZhbHVlCisgICAgICogQHNpbmNlIDEuMTYKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRDb21tZW50U291cmNlKENvbW1lbnRTb3VyY2UgY29tbWVudFNvdXJjZSkgeworICAgICAgICB0aGlzLmNvbW1lbnRTb3VyY2UgPSBjb21tZW50U291cmNlOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9aaXBBcmNoaXZlRW50cnlQcmVkaWNhdGUuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvWmlwQXJjaGl2ZUVudHJ5UHJlZGljYXRlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTcxMjJiOQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvWmlwQXJjaGl2ZUVudHJ5UHJlZGljYXRlLmphdmEKQEAgLTAsMCArMSwzNCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICoKKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwOworCisvKioKKyAqICBBIHByZWRpY2F0ZSB0byB0ZXN0IGlmIGEgI1ppcEFyY2hpdmVFbnRyeSBtYXRjaGVzIGEgY3JpdGVyaWEuCisgKiAgU29tZSBkYXkgdGhpcyBjYW4gZXh0ZW5kIGphdmEudXRpbC5mdW5jdGlvbi5QcmVkaWNhdGUKKyAqCisgKiAgQHNpbmNlIDEuMTAKKyAqLworcHVibGljIGludGVyZmFjZSBaaXBBcmNoaXZlRW50cnlQcmVkaWNhdGUgeworICAgIC8qKgorICAgICAqIEluZGljYXRlIGlmIHRoZSBnaXZlbiBlbnRyeSBzaG91bGQgYmUgaW5jbHVkZWQgaW4gdGhlIG9wZXJhdGlvbgorICAgICAqIEBwYXJhbSB6aXBBcmNoaXZlRW50cnkgdGhlIGVudHJ5IHRvIHRlc3QKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGVudHJ5IHNob3VsZCBiZSBpbmNsdWRlZAorICAgICAqLworICAgIGJvb2xlYW4gdGVzdChaaXBBcmNoaXZlRW50cnkgemlwQXJjaGl2ZUVudHJ5KTsKK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvWmlwQXJjaGl2ZUVudHJ5UmVxdWVzdC5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9aaXBBcmNoaXZlRW50cnlSZXF1ZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWMxM2Y3ZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvWmlwQXJjaGl2ZUVudHJ5UmVxdWVzdC5qYXZhCkBAIC0wLDAgKzEsODEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXA7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MucGFyYWxsZWwuSW5wdXRTdHJlYW1TdXBwbGllcjsKKworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CisKKy8qKgorICogQSBUaHJlYWQtc2FmZSByZXByZXNlbnRhdGlvbiBvZiBhIFppcEFyY2hpdmVFbnRyeSB0aGF0IGlzIHVzZWQgdG8gYWRkIGVudHJpZXMgdG8gcGFyYWxsZWwgYXJjaGl2ZXMuCisgKgorICogQHNpbmNlIDEuMTAKKyAqLworcHVibGljIGNsYXNzIFppcEFyY2hpdmVFbnRyeVJlcXVlc3QgeworICAgIC8qCisgICAgIFRoZSB6aXBBcmNoaXZlRW50cnkgaXMgbm90IHRocmVhZCBzYWZlLCBhbmQgY2Fubm90IGJlIHNhZmVseSBhY2Nlc3NlZCBieSB0aGUgZ2V0dGVycyBvZiB0aGlzIGNsYXNzLgorICAgICBJdCBpcyBzYWZlbHkgYWNjZXNzaWJsZSBkdXJpbmcgdGhlIGNvbnN0cnVjdGlvbiBwYXJ0IG9mIHRoaXMgY2xhc3MgYW5kIGFsc28gYWZ0ZXIgdGhlCisgICAgIHRocmVhZCBwb29scyBoYXZlIGJlZW4gc2h1dCBkb3duLgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgWmlwQXJjaGl2ZUVudHJ5IHppcEFyY2hpdmVFbnRyeTsKKyAgICBwcml2YXRlIGZpbmFsIElucHV0U3RyZWFtU3VwcGxpZXIgcGF5bG9hZFN1cHBsaWVyOworICAgIHByaXZhdGUgZmluYWwgaW50IG1ldGhvZDsKKworCisgICAgcHJpdmF0ZSBaaXBBcmNoaXZlRW50cnlSZXF1ZXN0KGZpbmFsIFppcEFyY2hpdmVFbnRyeSB6aXBBcmNoaXZlRW50cnksIGZpbmFsIElucHV0U3RyZWFtU3VwcGxpZXIgcGF5bG9hZFN1cHBsaWVyKSB7CisgICAgICAgIC8vIHRoaXMgY29uc3RydWN0b3IgaGFzICJzYWZlIiBhY2Nlc3MgdG8gYWxsIG1lbWJlciB2YXJpYWJsZXMgb24gemlwQXJjaGl2ZUVudHJ5CisgICAgICAgIHRoaXMuemlwQXJjaGl2ZUVudHJ5ID0gemlwQXJjaGl2ZUVudHJ5OworICAgICAgICB0aGlzLnBheWxvYWRTdXBwbGllciA9IHBheWxvYWRTdXBwbGllcjsKKyAgICAgICAgdGhpcy5tZXRob2QgPSB6aXBBcmNoaXZlRW50cnkuZ2V0TWV0aG9kKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgWmlwQXJjaGl2ZUVudHJ5UmVxdWVzdAorICAgICAqIEBwYXJhbSB6aXBBcmNoaXZlRW50cnkgVGhlIGVudHJ5IHRvIHVzZQorICAgICAqIEBwYXJhbSBwYXlsb2FkU3VwcGxpZXIgVGhlIHBheWxvYWQgdGhhdCB3aWxsIGJlIGFkZGVkIHRvIHRoZSB6aXAgZW50cnkuCisgICAgICogQHJldHVybiBUaGUgbmV3bHkgY3JlYXRlZCByZXF1ZXN0CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBaaXBBcmNoaXZlRW50cnlSZXF1ZXN0IGNyZWF0ZVppcEFyY2hpdmVFbnRyeVJlcXVlc3QoZmluYWwgWmlwQXJjaGl2ZUVudHJ5IHppcEFyY2hpdmVFbnRyeSwgZmluYWwgSW5wdXRTdHJlYW1TdXBwbGllciBwYXlsb2FkU3VwcGxpZXIpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBaaXBBcmNoaXZlRW50cnlSZXF1ZXN0KHppcEFyY2hpdmVFbnRyeSwgcGF5bG9hZFN1cHBsaWVyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgcGF5bGFvZCB0aGF0IHdpbGwgYmUgYWRkZWQgdG8gdGhpcyB6aXAgZW50cnkKKyAgICAgKiBAcmV0dXJuIFRoZSBpbnB1dCBzdHJlYW0uCisgICAgICovCisgICAgcHVibGljIElucHV0U3RyZWFtIGdldFBheWxvYWRTdHJlYW0oKSB7CisgICAgICAgIHJldHVybiBwYXlsb2FkU3VwcGxpZXIuZ2V0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIGNvbXByZXNzaW9uIG1ldGhvZCB0byB1c2UKKyAgICAgKiBAcmV0dXJuIFRoZSBjb21wcmVzc2lvbiBtZXRob2QgdG8gdXNlCisgICAgICovCisgICAgcHVibGljIGludCBnZXRNZXRob2QoKXsKKyAgICAgICByZXR1cm4gbWV0aG9kOworICAgIH0KKworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdW5kZXJseWluZyBlbnRyeS4gRG8gbm90IHVzZSB0aGlzIG1ldGhvZHMgZnJvbSB0aHJlYWRzIHRoYXQgZGlkIG5vdCBjcmVhdGUgdGhlIGluc3RhbmNlIGl0c2VsZiAhCisgICAgICogQHJldHVybiB0aGUgemlwZUFyY2hpdmVFbnRyeSB0aGF0IGlzIGJhc2lzIGZvciB0aGlzIHJlcXVlc3QKKyAgICAgKi8KKyAgICBaaXBBcmNoaXZlRW50cnkgZ2V0WmlwQXJjaGl2ZUVudHJ5KCkgeworICAgICAgICByZXR1cm4gemlwQXJjaGl2ZUVudHJ5OworICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvWmlwQXJjaGl2ZUVudHJ5UmVxdWVzdFN1cHBsaWVyLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1ppcEFyY2hpdmVFbnRyeVJlcXVlc3RTdXBwbGllci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM2YWM5NTcKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1ppcEFyY2hpdmVFbnRyeVJlcXVlc3RTdXBwbGllci5qYXZhCkBAIC0wLDAgKzEsMzYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXA7CisKKy8qKgorICogU3VwcGxpZXMge0BsaW5rIFppcEFyY2hpdmVFbnRyeVJlcXVlc3R9LgorICoKKyAqIEltcGxlbWVudGF0aW9ucyBhcmUgcmVxdWlyZWQgdG8gc3VwcG9ydCB0aHJlYWQtaGFuZG92ZXIuIFdoaWxlIGFuIGluc3RhbmNlIHdpbGwKKyAqIG5vdCBiZSBhY2Nlc3NlZCBjb25jdXJyZW50bHkgYnkgbXVsdGlwbGUgdGhyZWFkcywgaXQgd2lsbCBiZSBjYWxsZWQgYnkKKyAqIGEgZGlmZmVyZW50IHRocmVhZCB0aGFuIGl0IHdhcyBjcmVhdGVkIG9uLgorICoKKyAqIEBzaW5jZSAxLjEzCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgWmlwQXJjaGl2ZUVudHJ5UmVxdWVzdFN1cHBsaWVyIHsKKworICAgIC8qKgorICAgICAqIFN1cHBseSBhIHtAbGluayBaaXBBcmNoaXZlRW50cnlSZXF1ZXN0fSB0byBiZSBhZGRlZCB0byBhIHBhcmFsbGVsIGFyY2hpdmUuCisgICAgICogQHJldHVybiBUaGUge0BsaW5rIFppcEFyY2hpdmVFbnRyeVJlcXVlc3R9IGluc3RhbmNlLiBTaG91bGQgbmV2ZXIgYmUgbnVsbC4KKyAgICAgKi8KKyAgICBaaXBBcmNoaXZlRW50cnlSZXF1ZXN0IGdldCgpOworfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9aaXBBcmNoaXZlSW5wdXRTdHJlYW0uamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvWmlwQXJjaGl2ZUlucHV0U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTk2ZTQwMgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvWmlwQXJjaGl2ZUlucHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwxMjc4IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXA7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRU9GRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlB1c2hiYWNrSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5tYXRoLkJpZ0ludGVnZXI7CitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC56aXAuQ1JDMzI7CitpbXBvcnQgamF2YS51dGlsLnppcC5EYXRhRm9ybWF0RXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC56aXAuSW5mbGF0ZXI7CitpbXBvcnQgamF2YS51dGlsLnppcC5aaXBFbnRyeTsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLlppcEV4Y2VwdGlvbjsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZUVudHJ5OworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZUlucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5iemlwMi5CWmlwMkNvbXByZXNzb3JJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuZGVmbGF0ZTY0LkRlZmxhdGU2NENvbXByZXNzb3JJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuQXJjaGl2ZVV0aWxzOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5JT1V0aWxzOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5JbnB1dFN0cmVhbVN0YXRpc3RpY3M7CisKK2ltcG9ydCBzdGF0aWMgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXAuWmlwQ29uc3RhbnRzLkRXT1JEOworaW1wb3J0IHN0YXRpYyBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcC5aaXBDb25zdGFudHMuU0hPUlQ7CitpbXBvcnQgc3RhdGljIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwLlppcENvbnN0YW50cy5XT1JEOworaW1wb3J0IHN0YXRpYyBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcC5aaXBDb25zdGFudHMuWklQNjRfTUFHSUM7CisKKy8qKgorICogSW1wbGVtZW50cyBhbiBpbnB1dCBzdHJlYW0gdGhhdCBjYW4gcmVhZCBaaXAgYXJjaGl2ZXMuCisgKgorICogPHA+QXMgb2YgQXBhY2hlIENvbW1vbnMgQ29tcHJlc3MgaXQgdHJhbnNwYXJlbnRseSBzdXBwb3J0cyBaaXA2NAorICogZXh0ZW5zaW9ucyBhbmQgdGh1cyBpbmRpdmlkdWFsIGVudHJpZXMgYW5kIGFyY2hpdmVzIGxhcmdlciB0aGFuIDQKKyAqIEdCIG9yIHdpdGggbW9yZSB0aGFuIDY1NTM2IGVudHJpZXMuPC9wPgorICoKKyAqIDxwPlRoZSB7QGxpbmsgWmlwRmlsZX0gY2xhc3MgaXMgcHJlZmVycmVkIHdoZW4gcmVhZGluZyBmcm9tIGZpbGVzCisgKiBhcyB7QGxpbmsgWmlwQXJjaGl2ZUlucHV0U3RyZWFtfSBpcyBsaW1pdGVkIGJ5IG5vdCBiZWluZyBhYmxlIHRvCisgKiByZWFkIHRoZSBjZW50cmFsIGRpcmVjdG9yeSBoZWFkZXIgYmVmb3JlIHJldHVybmluZyBlbnRyaWVzLiAgSW4KKyAqIHBhcnRpY3VsYXIge0BsaW5rIFppcEFyY2hpdmVJbnB1dFN0cmVhbX08L3A+CisgKgorICogPHVsPgorICoKKyAqICA8bGk+bWF5IHJldHVybiBlbnRyaWVzIHRoYXQgYXJlIG5vdCBwYXJ0IG9mIHRoZSBjZW50cmFsIGRpcmVjdG9yeQorICogIGF0IGFsbCBhbmQgc2hvdWxkbid0IGJlIGNvbnNpZGVyZWQgcGFydCBvZiB0aGUgYXJjaGl2ZS48L2xpPgorICoKKyAqICA8bGk+bWF5IHJldHVybiBzZXZlcmFsIGVudHJpZXMgd2l0aCB0aGUgc2FtZSBuYW1lLjwvbGk+CisgKgorICogIDxsaT53aWxsIG5vdCByZXR1cm4gaW50ZXJuYWwgb3IgZXh0ZXJuYWwgYXR0cmlidXRlcy48L2xpPgorICoKKyAqICA8bGk+bWF5IHJldHVybiBpbmNvbXBsZXRlIGV4dHJhIGZpZWxkIGRhdGEuPC9saT4KKyAqCisgKiAgPGxpPm1heSByZXR1cm4gdW5rbm93biBzaXplcyBhbmQgQ1JDIHZhbHVlcyBmb3IgZW50cmllcyB1bnRpbCB0aGUKKyAqICBuZXh0IGVudHJ5IGhhcyBiZWVuIHJlYWNoZWQgaWYgdGhlIGFyY2hpdmUgdXNlcyB0aGUgZGF0YQorICogIGRlc2NyaXB0b3IgZmVhdHVyZS48L2xpPgorICoKKyAqIDwvdWw+CisgKgorICogQHNlZSBaaXBGaWxlCisgKiBATm90VGhyZWFkU2FmZQorICovCitwdWJsaWMgY2xhc3MgWmlwQXJjaGl2ZUlucHV0U3RyZWFtIGV4dGVuZHMgQXJjaGl2ZUlucHV0U3RyZWFtIGltcGxlbWVudHMgSW5wdXRTdHJlYW1TdGF0aXN0aWNzIHsKKworICAgIC8qKiBUaGUgemlwIGVuY29kaW5nIHRvIHVzZSBmb3IgZmlsZW5hbWVzIGFuZCB0aGUgZmlsZSBjb21tZW50LiAqLworICAgIHByaXZhdGUgZmluYWwgWmlwRW5jb2RpbmcgemlwRW5jb2Rpbmc7CisKKyAgICAvLyB0aGUgcHJvdmlkZWQgZW5jb2RpbmcgKGZvciB1bml0IHRlc3RzKQorICAgIGZpbmFsIFN0cmluZyBlbmNvZGluZzsKKworICAgIC8qKiBXaGV0aGVyIHRvIGxvb2sgZm9yIGFuZCB1c2UgVW5pY29kZSBleHRyYSBmaWVsZHMuICovCisgICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIHVzZVVuaWNvZGVFeHRyYUZpZWxkczsKKworICAgIC8qKiBXcmFwcGVkIHN0cmVhbSwgd2lsbCBhbHdheXMgYmUgYSBQdXNoYmFja0lucHV0U3RyZWFtLiAqLworICAgIHByaXZhdGUgZmluYWwgSW5wdXRTdHJlYW0gaW47CisKKyAgICAvKiogSW5mbGF0ZXIgdXNlZCBmb3IgYWxsIGRlZmxhdGVkIGVudHJpZXMuICovCisgICAgcHJpdmF0ZSBmaW5hbCBJbmZsYXRlciBpbmYgPSBuZXcgSW5mbGF0ZXIodHJ1ZSk7CisKKyAgICAvKiogQnVmZmVyIHVzZWQgdG8gcmVhZCBmcm9tIHRoZSB3cmFwcGVkIHN0cmVhbS4gKi8KKyAgICBwcml2YXRlIGZpbmFsIEJ5dGVCdWZmZXIgYnVmID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZShaaXBBcmNoaXZlT3V0cHV0U3RyZWFtLkJVRkZFUl9TSVpFKTsKKworICAgIC8qKiBUaGUgZW50cnkgdGhhdCBpcyBjdXJyZW50bHkgYmVpbmcgcmVhZC4gKi8KKyAgICBwcml2YXRlIEN1cnJlbnRFbnRyeSBjdXJyZW50ID0gbnVsbDsKKworICAgIC8qKiBXaGV0aGVyIHRoZSBzdHJlYW0gaGFzIGJlZW4gY2xvc2VkLiAqLworICAgIHByaXZhdGUgYm9vbGVhbiBjbG9zZWQgPSBmYWxzZTsKKworICAgIC8qKiBXaGV0aGVyIHRoZSBzdHJlYW0gaGFzIHJlYWNoZWQgdGhlIGNlbnRyYWwgZGlyZWN0b3J5IC0gYW5kIHRodXMgZm91bmQgYWxsIGVudHJpZXMuICovCisgICAgcHJpdmF0ZSBib29sZWFuIGhpdENlbnRyYWxEaXJlY3RvcnkgPSBmYWxzZTsKKworICAgIC8qKgorICAgICAqIFdoZW4gcmVhZGluZyBhIHN0b3JlZCBlbnRyeSB0aGF0IHVzZXMgdGhlIGRhdGEgZGVzY3JpcHRvciB0aGlzCisgICAgICogc3RyZWFtIGhhcyB0byByZWFkIHRoZSBmdWxsIGVudHJ5IGFuZCBjYWNoZXMgaXQuICBUaGlzIGlzIHRoZQorICAgICAqIGNhY2hlLgorICAgICAqLworICAgIHByaXZhdGUgQnl0ZUFycmF5SW5wdXRTdHJlYW0gbGFzdFN0b3JlZEVudHJ5ID0gbnVsbDsKKworICAgIC8qKiBXaGV0aGVyIHRoZSBzdHJlYW0gd2lsbCB0cnkgdG8gcmVhZCBTVE9SRUQgZW50cmllcyB0aGF0IHVzZSBhIGRhdGEgZGVzY3JpcHRvci4gKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gYWxsb3dTdG9yZWRFbnRyaWVzV2l0aERhdGFEZXNjcmlwdG9yID0gZmFsc2U7CisKKyAgICAvKiogQ291bnQgZGVjb21wcmVzc2VkIGJ5dGVzIGZvciBjdXJyZW50IGVudHJ5ICovCisgICAgcHJpdmF0ZSBsb25nIHVuY29tcHJlc3NlZENvdW50ID0gMDsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBMRkhfTEVOID0gMzA7CisgICAgLyoKKyAgICAgIGxvY2FsIGZpbGUgaGVhZGVyIHNpZ25hdHVyZSAgICAgV09SRAorICAgICAgdmVyc2lvbiBuZWVkZWQgdG8gZXh0cmFjdCAgICAgICBTSE9SVAorICAgICAgZ2VuZXJhbCBwdXJwb3NlIGJpdCBmbGFnICAgICAgICBTSE9SVAorICAgICAgY29tcHJlc3Npb24gbWV0aG9kICAgICAgICAgICAgICBTSE9SVAorICAgICAgbGFzdCBtb2QgZmlsZSB0aW1lICAgICAgICAgICAgICBTSE9SVAorICAgICAgbGFzdCBtb2QgZmlsZSBkYXRlICAgICAgICAgICAgICBTSE9SVAorICAgICAgY3JjLTMyICAgICAgICAgICAgICAgICAgICAgICAgICBXT1JECisgICAgICBjb21wcmVzc2VkIHNpemUgICAgICAgICAgICAgICAgIFdPUkQKKyAgICAgIHVuY29tcHJlc3NlZCBzaXplICAgICAgICAgICAgICAgV09SRAorICAgICAgZmlsZSBuYW1lIGxlbmd0aCAgICAgICAgICAgICAgICBTSE9SVAorICAgICAgZXh0cmEgZmllbGQgbGVuZ3RoICAgICAgICAgICAgICBTSE9SVAorICAgICovCisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQ0ZIX0xFTiA9IDQ2OworICAgIC8qCisgICAgICAgIGNlbnRyYWwgZmlsZSBoZWFkZXIgc2lnbmF0dXJlICAgV09SRAorICAgICAgICB2ZXJzaW9uIG1hZGUgYnkgICAgICAgICAgICAgICAgIFNIT1JUCisgICAgICAgIHZlcnNpb24gbmVlZGVkIHRvIGV4dHJhY3QgICAgICAgU0hPUlQKKyAgICAgICAgZ2VuZXJhbCBwdXJwb3NlIGJpdCBmbGFnICAgICAgICBTSE9SVAorICAgICAgICBjb21wcmVzc2lvbiBtZXRob2QgICAgICAgICAgICAgIFNIT1JUCisgICAgICAgIGxhc3QgbW9kIGZpbGUgdGltZSAgICAgICAgICAgICAgU0hPUlQKKyAgICAgICAgbGFzdCBtb2QgZmlsZSBkYXRlICAgICAgICAgICAgICBTSE9SVAorICAgICAgICBjcmMtMzIgICAgICAgICAgICAgICAgICAgICAgICAgIFdPUkQKKyAgICAgICAgY29tcHJlc3NlZCBzaXplICAgICAgICAgICAgICAgICBXT1JECisgICAgICAgIHVuY29tcHJlc3NlZCBzaXplICAgICAgICAgICAgICAgV09SRAorICAgICAgICBmaWxlIG5hbWUgbGVuZ3RoICAgICAgICAgICAgICAgIFNIT1JUCisgICAgICAgIGV4dHJhIGZpZWxkIGxlbmd0aCAgICAgICAgICAgICAgU0hPUlQKKyAgICAgICAgZmlsZSBjb21tZW50IGxlbmd0aCAgICAgICAgICAgICBTSE9SVAorICAgICAgICBkaXNrIG51bWJlciBzdGFydCAgICAgICAgICAgICAgIFNIT1JUCisgICAgICAgIGludGVybmFsIGZpbGUgYXR0cmlidXRlcyAgICAgICAgU0hPUlQKKyAgICAgICAgZXh0ZXJuYWwgZmlsZSBhdHRyaWJ1dGVzICAgICAgICBXT1JECisgICAgICAgIHJlbGF0aXZlIG9mZnNldCBvZiBsb2NhbCBoZWFkZXIgV09SRAorICAgICovCisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIFRXT19FWFBfMzIgPSBaSVA2NF9NQUdJQyArIDE7CisKKyAgICAvLyBjYWNoZWQgYnVmZmVycyAtIG11c3Qgb25seSBiZSB1c2VkIGxvY2FsbHkgaW4gdGhlIGNsYXNzIChDT01QUkVTUy0xNzIgLSByZWR1Y2UgZ2FyYmFnZSBjb2xsZWN0aW9uKQorICAgIHByaXZhdGUgZmluYWwgYnl0ZVtdIGxmaEJ1ZiA9IG5ldyBieXRlW0xGSF9MRU5dOworICAgIHByaXZhdGUgZmluYWwgYnl0ZVtdIHNraXBCdWYgPSBuZXcgYnl0ZVsxMDI0XTsKKyAgICBwcml2YXRlIGZpbmFsIGJ5dGVbXSBzaG9ydEJ1ZiA9IG5ldyBieXRlW1NIT1JUXTsKKyAgICBwcml2YXRlIGZpbmFsIGJ5dGVbXSB3b3JkQnVmID0gbmV3IGJ5dGVbV09SRF07CisgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10gdHdvRHdvcmRCdWYgPSBuZXcgYnl0ZVsyICogRFdPUkRdOworCisgICAgcHJpdmF0ZSBpbnQgZW50cmllc1JlYWQgPSAwOworCisgICAgLyoqCisgICAgICogQ3JlYXRlIGFuIGluc3RhbmNlIHVzaW5nIFVURi04IGVuY29kaW5nCisgICAgICogQHBhcmFtIGlucHV0U3RyZWFtIHRoZSBzdHJlYW0gdG8gd3JhcAorICAgICAqLworICAgIHB1YmxpYyBaaXBBcmNoaXZlSW5wdXRTdHJlYW0oZmluYWwgSW5wdXRTdHJlYW0gaW5wdXRTdHJlYW0pIHsKKyAgICAgICAgdGhpcyhpbnB1dFN0cmVhbSwgWmlwRW5jb2RpbmdIZWxwZXIuVVRGOCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlIGFuIGluc3RhbmNlIHVzaW5nIHRoZSBzcGVjaWZpZWQgZW5jb2RpbmcKKyAgICAgKiBAcGFyYW0gaW5wdXRTdHJlYW0gdGhlIHN0cmVhbSB0byB3cmFwCisgICAgICogQHBhcmFtIGVuY29kaW5nIHRoZSBlbmNvZGluZyB0byB1c2UgZm9yIGZpbGUgbmFtZXMsIHVzZSBudWxsCisgICAgICogZm9yIHRoZSBwbGF0Zm9ybSdzIGRlZmF1bHQgZW5jb2RpbmcKKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIFppcEFyY2hpdmVJbnB1dFN0cmVhbShmaW5hbCBJbnB1dFN0cmVhbSBpbnB1dFN0cmVhbSwgZmluYWwgU3RyaW5nIGVuY29kaW5nKSB7CisgICAgICAgIHRoaXMoaW5wdXRTdHJlYW0sIGVuY29kaW5nLCB0cnVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYW4gaW5zdGFuY2UgdXNpbmcgdGhlIHNwZWNpZmllZCBlbmNvZGluZworICAgICAqIEBwYXJhbSBpbnB1dFN0cmVhbSB0aGUgc3RyZWFtIHRvIHdyYXAKKyAgICAgKiBAcGFyYW0gZW5jb2RpbmcgdGhlIGVuY29kaW5nIHRvIHVzZSBmb3IgZmlsZSBuYW1lcywgdXNlIG51bGwKKyAgICAgKiBmb3IgdGhlIHBsYXRmb3JtJ3MgZGVmYXVsdCBlbmNvZGluZworICAgICAqIEBwYXJhbSB1c2VVbmljb2RlRXh0cmFGaWVsZHMgd2hldGhlciB0byB1c2UgSW5mb1pJUCBVbmljb2RlCisgICAgICogRXh0cmEgRmllbGRzIChpZiBwcmVzZW50KSB0byBzZXQgdGhlIGZpbGUgbmFtZXMuCisgICAgICovCisgICAgcHVibGljIFppcEFyY2hpdmVJbnB1dFN0cmVhbShmaW5hbCBJbnB1dFN0cmVhbSBpbnB1dFN0cmVhbSwgZmluYWwgU3RyaW5nIGVuY29kaW5nLCBmaW5hbCBib29sZWFuIHVzZVVuaWNvZGVFeHRyYUZpZWxkcykgeworICAgICAgICB0aGlzKGlucHV0U3RyZWFtLCBlbmNvZGluZywgdXNlVW5pY29kZUV4dHJhRmllbGRzLCBmYWxzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlIGFuIGluc3RhbmNlIHVzaW5nIHRoZSBzcGVjaWZpZWQgZW5jb2RpbmcKKyAgICAgKiBAcGFyYW0gaW5wdXRTdHJlYW0gdGhlIHN0cmVhbSB0byB3cmFwCisgICAgICogQHBhcmFtIGVuY29kaW5nIHRoZSBlbmNvZGluZyB0byB1c2UgZm9yIGZpbGUgbmFtZXMsIHVzZSBudWxsCisgICAgICogZm9yIHRoZSBwbGF0Zm9ybSdzIGRlZmF1bHQgZW5jb2RpbmcKKyAgICAgKiBAcGFyYW0gdXNlVW5pY29kZUV4dHJhRmllbGRzIHdoZXRoZXIgdG8gdXNlIEluZm9aSVAgVW5pY29kZQorICAgICAqIEV4dHJhIEZpZWxkcyAoaWYgcHJlc2VudCkgdG8gc2V0IHRoZSBmaWxlIG5hbWVzLgorICAgICAqIEBwYXJhbSBhbGxvd1N0b3JlZEVudHJpZXNXaXRoRGF0YURlc2NyaXB0b3Igd2hldGhlciB0aGUgc3RyZWFtCisgICAgICogd2lsbCB0cnkgdG8gcmVhZCBTVE9SRUQgZW50cmllcyB0aGF0IHVzZSBhIGRhdGEgZGVzY3JpcHRvcgorICAgICAqIEBzaW5jZSAxLjEKKyAgICAgKi8KKyAgICBwdWJsaWMgWmlwQXJjaGl2ZUlucHV0U3RyZWFtKGZpbmFsIElucHV0U3RyZWFtIGlucHV0U3RyZWFtLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIGVuY29kaW5nLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgYm9vbGVhbiB1c2VVbmljb2RlRXh0cmFGaWVsZHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBib29sZWFuIGFsbG93U3RvcmVkRW50cmllc1dpdGhEYXRhRGVzY3JpcHRvcikgeworICAgICAgICB0aGlzLmVuY29kaW5nID0gZW5jb2Rpbmc7CisgICAgICAgIHppcEVuY29kaW5nID0gWmlwRW5jb2RpbmdIZWxwZXIuZ2V0WmlwRW5jb2RpbmcoZW5jb2RpbmcpOworICAgICAgICB0aGlzLnVzZVVuaWNvZGVFeHRyYUZpZWxkcyA9IHVzZVVuaWNvZGVFeHRyYUZpZWxkczsKKyAgICAgICAgaW4gPSBuZXcgUHVzaGJhY2tJbnB1dFN0cmVhbShpbnB1dFN0cmVhbSwgYnVmLmNhcGFjaXR5KCkpOworICAgICAgICB0aGlzLmFsbG93U3RvcmVkRW50cmllc1dpdGhEYXRhRGVzY3JpcHRvciA9CisgICAgICAgICAgICBhbGxvd1N0b3JlZEVudHJpZXNXaXRoRGF0YURlc2NyaXB0b3I7CisgICAgICAgIC8vIGhhdmVuJ3QgcmVhZCBhbnl0aGluZyBzbyBmYXIKKyAgICAgICAgYnVmLmxpbWl0KDApOworICAgIH0KKworICAgIHB1YmxpYyBaaXBBcmNoaXZlRW50cnkgZ2V0TmV4dFppcEVudHJ5KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdW5jb21wcmVzc2VkQ291bnQgPSAwOworCisgICAgICAgIGJvb2xlYW4gZmlyc3RFbnRyeSA9IHRydWU7CisgICAgICAgIGlmIChjbG9zZWQgfHwgaGl0Q2VudHJhbERpcmVjdG9yeSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGN1cnJlbnQgIT0gbnVsbCkgeworICAgICAgICAgICAgY2xvc2VFbnRyeSgpOworICAgICAgICAgICAgZmlyc3RFbnRyeSA9IGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgbG9uZyBjdXJyZW50SGVhZGVyT2Zmc2V0ID0gZ2V0Qnl0ZXNSZWFkKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAoZmlyc3RFbnRyeSkgeworICAgICAgICAgICAgICAgIC8vIHNwbGl0IGFyY2hpdmVzIGhhdmUgYSBzcGVjaWFsIHNpZ25hdHVyZSBiZWZvcmUgdGhlCisgICAgICAgICAgICAgICAgLy8gZmlyc3QgbG9jYWwgZmlsZSBoZWFkZXIgLSBsb29rIGZvciBpdCBhbmQgZmFpbCB3aXRoCisgICAgICAgICAgICAgICAgLy8gdGhlIGFwcHJvcHJpYXRlIGVycm9yIG1lc3NhZ2UgaWYgdGhpcyBpcyBhIHNwbGl0CisgICAgICAgICAgICAgICAgLy8gYXJjaGl2ZS4KKyAgICAgICAgICAgICAgICByZWFkRmlyc3RMb2NhbEZpbGVIZWFkZXIobGZoQnVmKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcmVhZEZ1bGx5KGxmaEJ1Zik7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIEVPRkV4Y2VwdGlvbiBlKSB7IC8vTk9TT05BUgorICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBmaW5hbCBaaXBMb25nIHNpZyA9IG5ldyBaaXBMb25nKGxmaEJ1Zik7CisgICAgICAgIGlmICghc2lnLmVxdWFscyhaaXBMb25nLkxGSF9TSUcpKSB7CisgICAgICAgICAgICBpZiAoc2lnLmVxdWFscyhaaXBMb25nLkNGSF9TSUcpIHx8IHNpZy5lcXVhbHMoWmlwTG9uZy5BRURfU0lHKSB8fCBpc0Fwa1NpZ25pbmdCbG9jayhsZmhCdWYpKSB7CisgICAgICAgICAgICAgICAgaGl0Q2VudHJhbERpcmVjdG9yeSA9IHRydWU7CisgICAgICAgICAgICAgICAgc2tpcFJlbWFpbmRlck9mQXJjaGl2ZSgpOworICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhyb3cgbmV3IFppcEV4Y2VwdGlvbihTdHJpbmcuZm9ybWF0KCJVbmV4cGVjdGVkIHJlY29yZCBzaWduYXR1cmU6IDBYJVgiLCBzaWcuZ2V0VmFsdWUoKSkpOworICAgICAgICB9CisKKyAgICAgICAgaW50IG9mZiA9IFdPUkQ7CisgICAgICAgIGN1cnJlbnQgPSBuZXcgQ3VycmVudEVudHJ5KCk7CisKKyAgICAgICAgZmluYWwgaW50IHZlcnNpb25NYWRlQnkgPSBaaXBTaG9ydC5nZXRWYWx1ZShsZmhCdWYsIG9mZik7CisgICAgICAgIG9mZiArPSBTSE9SVDsKKyAgICAgICAgY3VycmVudC5lbnRyeS5zZXRQbGF0Zm9ybSgodmVyc2lvbk1hZGVCeSA+PiBaaXBGaWxlLkJZVEVfU0hJRlQpICYgWmlwRmlsZS5OSUJMRVRfTUFTSyk7CisKKyAgICAgICAgZmluYWwgR2VuZXJhbFB1cnBvc2VCaXQgZ3BGbGFnID0gR2VuZXJhbFB1cnBvc2VCaXQucGFyc2UobGZoQnVmLCBvZmYpOworICAgICAgICBmaW5hbCBib29sZWFuIGhhc1VURjhGbGFnID0gZ3BGbGFnLnVzZXNVVEY4Rm9yTmFtZXMoKTsKKyAgICAgICAgZmluYWwgWmlwRW5jb2RpbmcgZW50cnlFbmNvZGluZyA9IGhhc1VURjhGbGFnID8gWmlwRW5jb2RpbmdIZWxwZXIuVVRGOF9aSVBfRU5DT0RJTkcgOiB6aXBFbmNvZGluZzsKKyAgICAgICAgY3VycmVudC5oYXNEYXRhRGVzY3JpcHRvciA9IGdwRmxhZy51c2VzRGF0YURlc2NyaXB0b3IoKTsKKyAgICAgICAgY3VycmVudC5lbnRyeS5zZXRHZW5lcmFsUHVycG9zZUJpdChncEZsYWcpOworCisgICAgICAgIG9mZiArPSBTSE9SVDsKKworICAgICAgICBjdXJyZW50LmVudHJ5LnNldE1ldGhvZChaaXBTaG9ydC5nZXRWYWx1ZShsZmhCdWYsIG9mZikpOworICAgICAgICBvZmYgKz0gU0hPUlQ7CisKKyAgICAgICAgZmluYWwgbG9uZyB0aW1lID0gWmlwVXRpbC5kb3NUb0phdmFUaW1lKFppcExvbmcuZ2V0VmFsdWUobGZoQnVmLCBvZmYpKTsKKyAgICAgICAgY3VycmVudC5lbnRyeS5zZXRUaW1lKHRpbWUpOworICAgICAgICBvZmYgKz0gV09SRDsKKworICAgICAgICBaaXBMb25nIHNpemUgPSBudWxsLCBjU2l6ZSA9IG51bGw7CisgICAgICAgIGlmICghY3VycmVudC5oYXNEYXRhRGVzY3JpcHRvcikgeworICAgICAgICAgICAgY3VycmVudC5lbnRyeS5zZXRDcmMoWmlwTG9uZy5nZXRWYWx1ZShsZmhCdWYsIG9mZikpOworICAgICAgICAgICAgb2ZmICs9IFdPUkQ7CisKKyAgICAgICAgICAgIGNTaXplID0gbmV3IFppcExvbmcobGZoQnVmLCBvZmYpOworICAgICAgICAgICAgb2ZmICs9IFdPUkQ7CisKKyAgICAgICAgICAgIHNpemUgPSBuZXcgWmlwTG9uZyhsZmhCdWYsIG9mZik7CisgICAgICAgICAgICBvZmYgKz0gV09SRDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIG9mZiArPSAzICogV09SRDsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIGludCBmaWxlTmFtZUxlbiA9IFppcFNob3J0LmdldFZhbHVlKGxmaEJ1Ziwgb2ZmKTsKKworICAgICAgICBvZmYgKz0gU0hPUlQ7CisKKyAgICAgICAgZmluYWwgaW50IGV4dHJhTGVuID0gWmlwU2hvcnQuZ2V0VmFsdWUobGZoQnVmLCBvZmYpOworICAgICAgICBvZmYgKz0gU0hPUlQ7IC8vIE5PU09OQVIgLSBhc3NpZ25tZW50IGFzIGRvY3VtZW50YXRpb24KKworICAgICAgICBmaW5hbCBieXRlW10gZmlsZU5hbWUgPSBuZXcgYnl0ZVtmaWxlTmFtZUxlbl07CisgICAgICAgIHJlYWRGdWxseShmaWxlTmFtZSk7CisgICAgICAgIGN1cnJlbnQuZW50cnkuc2V0TmFtZShlbnRyeUVuY29kaW5nLmRlY29kZShmaWxlTmFtZSksIGZpbGVOYW1lKTsKKyAgICAgICAgaWYgKGhhc1VURjhGbGFnKSB7CisgICAgICAgICAgICBjdXJyZW50LmVudHJ5LnNldE5hbWVTb3VyY2UoWmlwQXJjaGl2ZUVudHJ5Lk5hbWVTb3VyY2UuTkFNRV9XSVRIX0VGU19GTEFHKTsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIGJ5dGVbXSBleHRyYURhdGEgPSBuZXcgYnl0ZVtleHRyYUxlbl07CisgICAgICAgIHJlYWRGdWxseShleHRyYURhdGEpOworICAgICAgICBjdXJyZW50LmVudHJ5LnNldEV4dHJhKGV4dHJhRGF0YSk7CisKKyAgICAgICAgaWYgKCFoYXNVVEY4RmxhZyAmJiB1c2VVbmljb2RlRXh0cmFGaWVsZHMpIHsKKyAgICAgICAgICAgIFppcFV0aWwuc2V0TmFtZUFuZENvbW1lbnRGcm9tRXh0cmFGaWVsZHMoY3VycmVudC5lbnRyeSwgZmlsZU5hbWUsIG51bGwpOworICAgICAgICB9CisKKyAgICAgICAgcHJvY2Vzc1ppcDY0RXh0cmEoc2l6ZSwgY1NpemUpOworCisgICAgICAgIGN1cnJlbnQuZW50cnkuc2V0TG9jYWxIZWFkZXJPZmZzZXQoY3VycmVudEhlYWRlck9mZnNldCk7CisgICAgICAgIGN1cnJlbnQuZW50cnkuc2V0RGF0YU9mZnNldChnZXRCeXRlc1JlYWQoKSk7CisgICAgICAgIGN1cnJlbnQuZW50cnkuc2V0U3RyZWFtQ29udGlndW91cyh0cnVlKTsKKworICAgICAgICBaaXBNZXRob2QgbSA9IFppcE1ldGhvZC5nZXRNZXRob2RCeUNvZGUoY3VycmVudC5lbnRyeS5nZXRNZXRob2QoKSk7CisgICAgICAgIGlmIChjdXJyZW50LmVudHJ5LmdldENvbXByZXNzZWRTaXplKCkgIT0gQXJjaGl2ZUVudHJ5LlNJWkVfVU5LTk9XTikgeworICAgICAgICAgICAgaWYgKFppcFV0aWwuY2FuSGFuZGxlRW50cnlEYXRhKGN1cnJlbnQuZW50cnkpICYmIG0gIT0gWmlwTWV0aG9kLlNUT1JFRCAmJiBtICE9IFppcE1ldGhvZC5ERUZMQVRFRCkgeworICAgICAgICAgICAgICAgIElucHV0U3RyZWFtIGJpcyA9IG5ldyBCb3VuZGVkSW5wdXRTdHJlYW0oaW4sIGN1cnJlbnQuZW50cnkuZ2V0Q29tcHJlc3NlZFNpemUoKSk7CisgICAgICAgICAgICAgICAgc3dpdGNoIChtKSB7CisgICAgICAgICAgICAgICAgY2FzZSBVTlNIUklOS0lORzoKKyAgICAgICAgICAgICAgICAgICAgY3VycmVudC5pbiA9IG5ldyBVbnNocmlua2luZ0lucHV0U3RyZWFtKGJpcyk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgSU1QTE9ESU5HOgorICAgICAgICAgICAgICAgICAgICBjdXJyZW50LmluID0gbmV3IEV4cGxvZGluZ0lucHV0U3RyZWFtKAorICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudC5lbnRyeS5nZXRHZW5lcmFsUHVycG9zZUJpdCgpLmdldFNsaWRpbmdEaWN0aW9uYXJ5U2l6ZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudC5lbnRyeS5nZXRHZW5lcmFsUHVycG9zZUJpdCgpLmdldE51bWJlck9mU2hhbm5vbkZhbm9UcmVlcygpLAorICAgICAgICAgICAgICAgICAgICAgICAgYmlzKTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgY2FzZSBCWklQMjoKKyAgICAgICAgICAgICAgICAgICAgY3VycmVudC5pbiA9IG5ldyBCWmlwMkNvbXByZXNzb3JJbnB1dFN0cmVhbShiaXMpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlIEVOSEFOQ0VEX0RFRkxBVEVEOgorICAgICAgICAgICAgICAgICAgICBjdXJyZW50LmluID0gbmV3IERlZmxhdGU2NENvbXByZXNzb3JJbnB1dFN0cmVhbShiaXMpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgICAgICAvLyB3ZSBzaG91bGQgbmV2ZXIgZ2V0IGhlcmUgYXMgYWxsIHN1cHBvcnRlZCBtZXRob2RzIGhhdmUgYmVlbiBjb3ZlcmVkCisgICAgICAgICAgICAgICAgICAgIC8vIHdpbGwgY2F1c2UgYW4gZXJyb3Igd2hlbiByZWFkIGlzIGludm9rZWQsIGRvbid0IHRocm93IGFuIGV4Y2VwdGlvbiBoZXJlIHNvIHBlb3BsZSBjYW4KKyAgICAgICAgICAgICAgICAgICAgLy8gc2tpcCB1bnN1cHBvcnRlZCBlbnRyaWVzCisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIGlmIChtID09IFppcE1ldGhvZC5FTkhBTkNFRF9ERUZMQVRFRCkgeworICAgICAgICAgICAgY3VycmVudC5pbiA9IG5ldyBEZWZsYXRlNjRDb21wcmVzc29ySW5wdXRTdHJlYW0oaW4pOworICAgICAgICB9CisKKyAgICAgICAgZW50cmllc1JlYWQrKzsKKyAgICAgICAgcmV0dXJuIGN1cnJlbnQuZW50cnk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmlsbHMgdGhlIGdpdmVuIGFycmF5IHdpdGggdGhlIGZpcnN0IGxvY2FsIGZpbGUgaGVhZGVyIGFuZAorICAgICAqIGRlYWxzIHdpdGggc3BsaXR0aW5nL3NwYW5uaW5nIG1hcmtlcnMgdGhhdCBtYXkgcHJlZml4IHRoZSBmaXJzdAorICAgICAqIExGSC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcmVhZEZpcnN0TG9jYWxGaWxlSGVhZGVyKGZpbmFsIGJ5dGVbXSBsZmgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJlYWRGdWxseShsZmgpOworICAgICAgICBmaW5hbCBaaXBMb25nIHNpZyA9IG5ldyBaaXBMb25nKGxmaCk7CisgICAgICAgIGlmIChzaWcuZXF1YWxzKFppcExvbmcuRERfU0lHKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkWmlwRmVhdHVyZUV4Y2VwdGlvbihVbnN1cHBvcnRlZFppcEZlYXR1cmVFeGNlcHRpb24uRmVhdHVyZS5TUExJVFRJTkcpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHNpZy5lcXVhbHMoWmlwTG9uZy5TSU5HTEVfU0VHTUVOVF9TUExJVF9NQVJLRVIpKSB7CisgICAgICAgICAgICAvLyBUaGUgYXJjaGl2ZSBpcyBub3QgcmVhbGx5IHNwbGl0IGFzIG9ubHkgb25lIHNlZ21lbnQgd2FzCisgICAgICAgICAgICAvLyBuZWVkZWQgaW4gdGhlIGVuZC4gIEp1c3Qgc2tpcCBvdmVyIHRoZSBtYXJrZXIuCisgICAgICAgICAgICBmaW5hbCBieXRlW10gbWlzc2VkTGZoQnl0ZXMgPSBuZXcgYnl0ZVs0XTsKKyAgICAgICAgICAgIHJlYWRGdWxseShtaXNzZWRMZmhCeXRlcyk7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGxmaCwgNCwgbGZoLCAwLCBMRkhfTEVOIC0gNCk7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG1pc3NlZExmaEJ5dGVzLCAwLCBsZmgsIExGSF9MRU4gLSA0LCA0KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlY29yZHMgd2hldGhlciBhIFppcDY0IGV4dHJhIGlzIHByZXNlbnQgYW5kIHNldHMgdGhlIHNpemUKKyAgICAgKiBpbmZvcm1hdGlvbiBmcm9tIGl0IGlmIHNpemVzIGFyZSAweEZGRkZGRkZGIGFuZCB0aGUgZW50cnkKKyAgICAgKiBkb2Vzbid0IHVzZSBhIGRhdGEgZGVzY3JpcHRvci4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcHJvY2Vzc1ppcDY0RXh0cmEoZmluYWwgWmlwTG9uZyBzaXplLCBmaW5hbCBaaXBMb25nIGNTaXplKSB7CisgICAgICAgIGZpbmFsIFppcDY0RXh0ZW5kZWRJbmZvcm1hdGlvbkV4dHJhRmllbGQgejY0ID0KKyAgICAgICAgICAgIChaaXA2NEV4dGVuZGVkSW5mb3JtYXRpb25FeHRyYUZpZWxkKQorICAgICAgICAgICAgY3VycmVudC5lbnRyeS5nZXRFeHRyYUZpZWxkKFppcDY0RXh0ZW5kZWRJbmZvcm1hdGlvbkV4dHJhRmllbGQuSEVBREVSX0lEKTsKKyAgICAgICAgY3VycmVudC51c2VzWmlwNjQgPSB6NjQgIT0gbnVsbDsKKyAgICAgICAgaWYgKCFjdXJyZW50Lmhhc0RhdGFEZXNjcmlwdG9yKSB7CisgICAgICAgICAgICBpZiAoejY0ICE9IG51bGwgLy8gc2FtZSBhcyBjdXJyZW50LnVzZXNaaXA2NCBidXQgYXZvaWRzIE5QRSB3YXJuaW5nCisgICAgICAgICAgICAgICAgICAgICYmIChjU2l6ZS5lcXVhbHMoWmlwTG9uZy5aSVA2NF9NQUdJQykgfHwgc2l6ZS5lcXVhbHMoWmlwTG9uZy5aSVA2NF9NQUdJQykpICkgeworICAgICAgICAgICAgICAgIGN1cnJlbnQuZW50cnkuc2V0Q29tcHJlc3NlZFNpemUoejY0LmdldENvbXByZXNzZWRTaXplKCkuZ2V0TG9uZ1ZhbHVlKCkpOworICAgICAgICAgICAgICAgIGN1cnJlbnQuZW50cnkuc2V0U2l6ZSh6NjQuZ2V0U2l6ZSgpLmdldExvbmdWYWx1ZSgpKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgY3VycmVudC5lbnRyeS5zZXRDb21wcmVzc2VkU2l6ZShjU2l6ZS5nZXRWYWx1ZSgpKTsKKyAgICAgICAgICAgICAgICBjdXJyZW50LmVudHJ5LnNldFNpemUoc2l6ZS5nZXRWYWx1ZSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBBcmNoaXZlRW50cnkgZ2V0TmV4dEVudHJ5KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGdldE5leHRaaXBFbnRyeSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdoZXRoZXIgdGhpcyBjbGFzcyBpcyBhYmxlIHRvIHJlYWQgdGhlIGdpdmVuIGVudHJ5LgorICAgICAqCisgICAgICogPHA+TWF5IHJldHVybiBmYWxzZSBpZiBpdCBpcyBzZXQgdXAgdG8gdXNlIGVuY3J5cHRpb24gb3IgYQorICAgICAqIGNvbXByZXNzaW9uIG1ldGhvZCB0aGF0IGhhc24ndCBiZWVuIGltcGxlbWVudGVkIHlldC48L3A+CisgICAgICogQHNpbmNlIDEuMQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGNhblJlYWRFbnRyeURhdGEoZmluYWwgQXJjaGl2ZUVudHJ5IGFlKSB7CisgICAgICAgIGlmIChhZSBpbnN0YW5jZW9mIFppcEFyY2hpdmVFbnRyeSkgeworICAgICAgICAgICAgZmluYWwgWmlwQXJjaGl2ZUVudHJ5IHplID0gKFppcEFyY2hpdmVFbnRyeSkgYWU7CisgICAgICAgICAgICByZXR1cm4gWmlwVXRpbC5jYW5IYW5kbGVFbnRyeURhdGEoemUpCisgICAgICAgICAgICAgICAgJiYgc3VwcG9ydHNEYXRhRGVzY3JpcHRvckZvcih6ZSkKKyAgICAgICAgICAgICAgICAmJiBzdXBwb3J0c0NvbXByZXNzZWRTaXplRm9yKHplKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCByZWFkKGZpbmFsIGJ5dGVbXSBidWZmZXIsIGZpbmFsIGludCBvZmZzZXQsIGZpbmFsIGludCBsZW5ndGgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChjbG9zZWQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiVGhlIHN0cmVhbSBpcyBjbG9zZWQiKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChjdXJyZW50ID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIGF2b2lkIGludCBvdmVyZmxvdywgY2hlY2sgbnVsbCBidWZmZXIKKyAgICAgICAgaWYgKG9mZnNldCA+IGJ1ZmZlci5sZW5ndGggfHwgbGVuZ3RoIDwgMCB8fCBvZmZzZXQgPCAwIHx8IGJ1ZmZlci5sZW5ndGggLSBvZmZzZXQgPCBsZW5ndGgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIFppcFV0aWwuY2hlY2tSZXF1ZXN0ZWRGZWF0dXJlcyhjdXJyZW50LmVudHJ5KTsKKyAgICAgICAgaWYgKCFzdXBwb3J0c0RhdGFEZXNjcmlwdG9yRm9yKGN1cnJlbnQuZW50cnkpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRaaXBGZWF0dXJlRXhjZXB0aW9uKFVuc3VwcG9ydGVkWmlwRmVhdHVyZUV4Y2VwdGlvbi5GZWF0dXJlLkRBVEFfREVTQ1JJUFRPUiwKKyAgICAgICAgICAgICAgICAgICAgY3VycmVudC5lbnRyeSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCFzdXBwb3J0c0NvbXByZXNzZWRTaXplRm9yKGN1cnJlbnQuZW50cnkpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRaaXBGZWF0dXJlRXhjZXB0aW9uKFVuc3VwcG9ydGVkWmlwRmVhdHVyZUV4Y2VwdGlvbi5GZWF0dXJlLlVOS05PV05fQ09NUFJFU1NFRF9TSVpFLAorICAgICAgICAgICAgICAgICAgICBjdXJyZW50LmVudHJ5KTsKKyAgICAgICAgfQorCisgICAgICAgIGludCByZWFkOworICAgICAgICBpZiAoY3VycmVudC5lbnRyeS5nZXRNZXRob2QoKSA9PSBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtLlNUT1JFRCkgeworICAgICAgICAgICAgcmVhZCA9IHJlYWRTdG9yZWQoYnVmZmVyLCBvZmZzZXQsIGxlbmd0aCk7CisgICAgICAgIH0gZWxzZSBpZiAoY3VycmVudC5lbnRyeS5nZXRNZXRob2QoKSA9PSBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtLkRFRkxBVEVEKSB7CisgICAgICAgICAgICByZWFkID0gcmVhZERlZmxhdGVkKGJ1ZmZlciwgb2Zmc2V0LCBsZW5ndGgpOworICAgICAgICB9IGVsc2UgaWYgKGN1cnJlbnQuZW50cnkuZ2V0TWV0aG9kKCkgPT0gWmlwTWV0aG9kLlVOU0hSSU5LSU5HLmdldENvZGUoKQorICAgICAgICAgICAgICAgIHx8IGN1cnJlbnQuZW50cnkuZ2V0TWV0aG9kKCkgPT0gWmlwTWV0aG9kLklNUExPRElORy5nZXRDb2RlKCkKKyAgICAgICAgICAgICAgICB8fCBjdXJyZW50LmVudHJ5LmdldE1ldGhvZCgpID09IFppcE1ldGhvZC5FTkhBTkNFRF9ERUZMQVRFRC5nZXRDb2RlKCkKKyAgICAgICAgICAgICAgICB8fCBjdXJyZW50LmVudHJ5LmdldE1ldGhvZCgpID09IFppcE1ldGhvZC5CWklQMi5nZXRDb2RlKCkpIHsKKyAgICAgICAgICAgIHJlYWQgPSBjdXJyZW50LmluLnJlYWQoYnVmZmVyLCBvZmZzZXQsIGxlbmd0aCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRaaXBGZWF0dXJlRXhjZXB0aW9uKFppcE1ldGhvZC5nZXRNZXRob2RCeUNvZGUoY3VycmVudC5lbnRyeS5nZXRNZXRob2QoKSksCisgICAgICAgICAgICAgICAgICAgIGN1cnJlbnQuZW50cnkpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHJlYWQgPj0gMCkgeworICAgICAgICAgICAgY3VycmVudC5jcmMudXBkYXRlKGJ1ZmZlciwgb2Zmc2V0LCByZWFkKTsKKyAgICAgICAgICAgIHVuY29tcHJlc3NlZENvdW50ICs9IHJlYWQ7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gcmVhZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2luY2UgMS4xNworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBsb25nIGdldENvbXByZXNzZWRDb3VudCgpIHsKKyAgICAgICAgaWYgKGN1cnJlbnQuZW50cnkuZ2V0TWV0aG9kKCkgPT0gWmlwQXJjaGl2ZU91dHB1dFN0cmVhbS5TVE9SRUQpIHsKKyAgICAgICAgICAgIHJldHVybiBjdXJyZW50LmJ5dGVzUmVhZDsKKyAgICAgICAgfSBlbHNlIGlmIChjdXJyZW50LmVudHJ5LmdldE1ldGhvZCgpID09IFppcEFyY2hpdmVPdXRwdXRTdHJlYW0uREVGTEFURUQpIHsKKyAgICAgICAgICAgIHJldHVybiBnZXRCeXRlc0luZmxhdGVkKCk7CisgICAgICAgIH0gZWxzZSBpZiAoY3VycmVudC5lbnRyeS5nZXRNZXRob2QoKSA9PSBaaXBNZXRob2QuVU5TSFJJTktJTkcuZ2V0Q29kZSgpKSB7CisgICAgICAgICAgICByZXR1cm4gKChVbnNocmlua2luZ0lucHV0U3RyZWFtKSBjdXJyZW50LmluKS5nZXRDb21wcmVzc2VkQ291bnQoKTsKKyAgICAgICAgfSBlbHNlIGlmIChjdXJyZW50LmVudHJ5LmdldE1ldGhvZCgpID09IFppcE1ldGhvZC5JTVBMT0RJTkcuZ2V0Q29kZSgpKSB7CisgICAgICAgICAgICByZXR1cm4gKChFeHBsb2RpbmdJbnB1dFN0cmVhbSkgY3VycmVudC5pbikuZ2V0Q29tcHJlc3NlZENvdW50KCk7CisgICAgICAgIH0gZWxzZSBpZiAoY3VycmVudC5lbnRyeS5nZXRNZXRob2QoKSA9PSBaaXBNZXRob2QuRU5IQU5DRURfREVGTEFURUQuZ2V0Q29kZSgpKSB7CisgICAgICAgICAgICByZXR1cm4gKChEZWZsYXRlNjRDb21wcmVzc29ySW5wdXRTdHJlYW0pIGN1cnJlbnQuaW4pLmdldENvbXByZXNzZWRDb3VudCgpOworICAgICAgICB9IGVsc2UgaWYgKGN1cnJlbnQuZW50cnkuZ2V0TWV0aG9kKCkgPT0gWmlwTWV0aG9kLkJaSVAyLmdldENvZGUoKSkgeworICAgICAgICAgICAgcmV0dXJuICgoQlppcDJDb21wcmVzc29ySW5wdXRTdHJlYW0pIGN1cnJlbnQuaW4pLmdldENvbXByZXNzZWRDb3VudCgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNpbmNlIDEuMTcKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgbG9uZyBnZXRVbmNvbXByZXNzZWRDb3VudCgpIHsKKyAgICAgICAgcmV0dXJuIHVuY29tcHJlc3NlZENvdW50OworICAgIH0KKworICAgIC8qKgorICAgICAqIEltcGxlbWVudGF0aW9uIG9mIHJlYWQgZm9yIFNUT1JFRCBlbnRyaWVzLgorICAgICAqLworICAgIHByaXZhdGUgaW50IHJlYWRTdG9yZWQoZmluYWwgYnl0ZVtdIGJ1ZmZlciwgZmluYWwgaW50IG9mZnNldCwgZmluYWwgaW50IGxlbmd0aCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKworICAgICAgICBpZiAoY3VycmVudC5oYXNEYXRhRGVzY3JpcHRvcikgeworICAgICAgICAgICAgaWYgKGxhc3RTdG9yZWRFbnRyeSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmVhZFN0b3JlZEVudHJ5KCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbGFzdFN0b3JlZEVudHJ5LnJlYWQoYnVmZmVyLCBvZmZzZXQsIGxlbmd0aCk7CisgICAgICAgIH0KKworICAgICAgICBmaW5hbCBsb25nIGNzaXplID0gY3VycmVudC5lbnRyeS5nZXRTaXplKCk7CisgICAgICAgIGlmIChjdXJyZW50LmJ5dGVzUmVhZCA+PSBjc2l6ZSkgeworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGJ1Zi5wb3NpdGlvbigpID49IGJ1Zi5saW1pdCgpKSB7CisgICAgICAgICAgICBidWYucG9zaXRpb24oMCk7CisgICAgICAgICAgICBmaW5hbCBpbnQgbCA9IGluLnJlYWQoYnVmLmFycmF5KCkpOworICAgICAgICAgICAgaWYgKGwgPT0gLTEpIHsKKyAgICAgICAgICAgICAgICBidWYubGltaXQoMCk7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJUcnVuY2F0ZWQgWklQIGZpbGUiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJ1Zi5saW1pdChsKTsKKworICAgICAgICAgICAgY291bnQobCk7CisgICAgICAgICAgICBjdXJyZW50LmJ5dGVzUmVhZEZyb21TdHJlYW0gKz0gbDsKKyAgICAgICAgfQorCisgICAgICAgIGludCB0b1JlYWQgPSBNYXRoLm1pbihidWYucmVtYWluaW5nKCksIGxlbmd0aCk7CisgICAgICAgIGlmICgoY3NpemUgLSBjdXJyZW50LmJ5dGVzUmVhZCkgPCB0b1JlYWQpIHsKKyAgICAgICAgICAgIC8vIGlmIGl0IGlzIHNtYWxsZXIgdGhhbiB0b1JlYWQgdGhlbiBpdCBmaXRzIGludG8gYW4gaW50CisgICAgICAgICAgICB0b1JlYWQgPSAoaW50KSAoY3NpemUgLSBjdXJyZW50LmJ5dGVzUmVhZCk7CisgICAgICAgIH0KKyAgICAgICAgYnVmLmdldChidWZmZXIsIG9mZnNldCwgdG9SZWFkKTsKKyAgICAgICAgY3VycmVudC5ieXRlc1JlYWQgKz0gdG9SZWFkOworICAgICAgICByZXR1cm4gdG9SZWFkOworICAgIH0KKworICAgIC8qKgorICAgICAqIEltcGxlbWVudGF0aW9uIG9mIHJlYWQgZm9yIERFRkxBVEVEIGVudHJpZXMuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgcmVhZERlZmxhdGVkKGZpbmFsIGJ5dGVbXSBidWZmZXIsIGZpbmFsIGludCBvZmZzZXQsIGZpbmFsIGludCBsZW5ndGgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIGludCByZWFkID0gcmVhZEZyb21JbmZsYXRlcihidWZmZXIsIG9mZnNldCwgbGVuZ3RoKTsKKyAgICAgICAgaWYgKHJlYWQgPD0gMCkgeworICAgICAgICAgICAgaWYgKGluZi5maW5pc2hlZCgpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgfSBlbHNlIGlmIChpbmYubmVlZHNEaWN0aW9uYXJ5KCkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWmlwRXhjZXB0aW9uKCJUaGlzIGFyY2hpdmUgbmVlZHMgYSBwcmVzZXQgZGljdGlvbmFyeSIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiB3aGljaCBpcyBub3Qgc3VwcG9ydGVkIGJ5IENvbW1vbnMiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgQ29tcHJlc3MuIik7CisgICAgICAgICAgICB9IGVsc2UgaWYgKHJlYWQgPT0gLTEpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlRydW5jYXRlZCBaSVAgZmlsZSIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiByZWFkOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBvdGVudGlhbGx5IHJlYWRzIG1vcmUgYnl0ZXMgdG8gZmlsbCB0aGUgaW5mbGF0ZXIncyBidWZmZXIgYW5kCisgICAgICogcmVhZHMgZnJvbSBpdC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCByZWFkRnJvbUluZmxhdGVyKGZpbmFsIGJ5dGVbXSBidWZmZXIsIGZpbmFsIGludCBvZmZzZXQsIGZpbmFsIGludCBsZW5ndGgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCByZWFkID0gMDsKKyAgICAgICAgZG8geworICAgICAgICAgICAgaWYgKGluZi5uZWVkc0lucHV0KCkpIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBpbnQgbCA9IGZpbGwoKTsKKyAgICAgICAgICAgICAgICBpZiAobCA+IDApIHsKKyAgICAgICAgICAgICAgICAgICAgY3VycmVudC5ieXRlc1JlYWRGcm9tU3RyZWFtICs9IGJ1Zi5saW1pdCgpOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobCA9PSAtMSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICByZWFkID0gaW5mLmluZmxhdGUoYnVmZmVyLCBvZmZzZXQsIGxlbmd0aCk7CisgICAgICAgICAgICB9IGNhdGNoIChmaW5hbCBEYXRhRm9ybWF0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyAoSU9FeGNlcHRpb24pIG5ldyBaaXBFeGNlcHRpb24oZS5nZXRNZXNzYWdlKCkpLmluaXRDYXVzZShlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSB3aGlsZSAocmVhZCA9PSAwICYmIGluZi5uZWVkc0lucHV0KCkpOworICAgICAgICByZXR1cm4gcmVhZDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICghY2xvc2VkKSB7CisgICAgICAgICAgICBjbG9zZWQgPSB0cnVlOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBpbmYuZW5kKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTa2lwcyBvdmVyIGFuZCBkaXNjYXJkcyB2YWx1ZSBieXRlcyBvZiBkYXRhIGZyb20gdGhpcyBpbnB1dAorICAgICAqIHN0cmVhbS4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgaW1wbGVtZW50YXRpb24gbWF5IGVuZCB1cCBza2lwcGluZyBvdmVyIHNvbWUgc21hbGxlcgorICAgICAqIG51bWJlciBvZiBieXRlcywgcG9zc2libHkgMCwgaWYgYW5kIG9ubHkgaWYgaXQgcmVhY2hlcyB0aGUgZW5kCisgICAgICogb2YgdGhlIHVuZGVybHlpbmcgc3RyZWFtLjwvcD4KKyAgICAgKgorICAgICAqIDxwPlRoZSBhY3R1YWwgbnVtYmVyIG9mIGJ5dGVzIHNraXBwZWQgaXMgcmV0dXJuZWQuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlIHRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gYmUgc2tpcHBlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBhY3R1YWwgbnVtYmVyIG9mIGJ5dGVzIHNraXBwZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiAtIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gLSBpZiB2YWx1ZSBpcyBuZWdhdGl2ZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgbG9uZyBza2lwKGZpbmFsIGxvbmcgdmFsdWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICh2YWx1ZSA+PSAwKSB7CisgICAgICAgICAgICBsb25nIHNraXBwZWQgPSAwOworICAgICAgICAgICAgd2hpbGUgKHNraXBwZWQgPCB2YWx1ZSkgeworICAgICAgICAgICAgICAgIGZpbmFsIGxvbmcgcmVtID0gdmFsdWUgLSBza2lwcGVkOworICAgICAgICAgICAgICAgIGZpbmFsIGludCB4ID0gcmVhZChza2lwQnVmLCAwLCAoaW50KSAoc2tpcEJ1Zi5sZW5ndGggPiByZW0gPyByZW0gOiBza2lwQnVmLmxlbmd0aCkpOworICAgICAgICAgICAgICAgIGlmICh4ID09IC0xKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBza2lwcGVkOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBza2lwcGVkICs9IHg7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gc2tpcHBlZDsKKyAgICAgICAgfQorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIHRoZSBzaWduYXR1cmUgbWF0Y2hlcyB3aGF0IGlzIGV4cGVjdGVkIGZvciBhIHppcCBmaWxlLgorICAgICAqIERvZXMgbm90IGN1cnJlbnRseSBoYW5kbGUgc2VsZi1leHRyYWN0aW5nIHppcHMgd2hpY2ggbWF5IGhhdmUgYXJiaXRyYXJ5CisgICAgICogbGVhZGluZyBjb250ZW50LgorICAgICAqCisgICAgICogQHBhcmFtIHNpZ25hdHVyZSB0aGUgYnl0ZXMgdG8gY2hlY2sKKyAgICAgKiBAcGFyYW0gbGVuZ3RoICAgIHRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gY2hlY2sKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoaXMgc3RyZWFtIGlzIGEgemlwIGFyY2hpdmUgc3RyZWFtLCBmYWxzZSBvdGhlcndpc2UKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gbWF0Y2hlcyhmaW5hbCBieXRlW10gc2lnbmF0dXJlLCBmaW5hbCBpbnQgbGVuZ3RoKSB7CisgICAgICAgIGlmIChsZW5ndGggPCBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtLkxGSF9TSUcubGVuZ3RoKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gY2hlY2tzaWcoc2lnbmF0dXJlLCBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtLkxGSF9TSUcpIC8vIG5vcm1hbCBmaWxlCisgICAgICAgICAgICB8fCBjaGVja3NpZyhzaWduYXR1cmUsIFppcEFyY2hpdmVPdXRwdXRTdHJlYW0uRU9DRF9TSUcpIC8vIGVtcHR5IHppcAorICAgICAgICAgICAgfHwgY2hlY2tzaWcoc2lnbmF0dXJlLCBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtLkREX1NJRykgLy8gc3BsaXQgemlwCisgICAgICAgICAgICB8fCBjaGVja3NpZyhzaWduYXR1cmUsIFppcExvbmcuU0lOR0xFX1NFR01FTlRfU1BMSVRfTUFSS0VSLmdldEJ5dGVzKCkpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gY2hlY2tzaWcoZmluYWwgYnl0ZVtdIHNpZ25hdHVyZSwgZmluYWwgYnl0ZVtdIGV4cGVjdGVkKSB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZXhwZWN0ZWQubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGlmIChzaWduYXR1cmVbaV0gIT0gZXhwZWN0ZWRbaV0pIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvc2VzIHRoZSBjdXJyZW50IFpJUCBhcmNoaXZlIGVudHJ5IGFuZCBwb3NpdGlvbnMgdGhlIHVuZGVybHlpbmcKKyAgICAgKiBzdHJlYW0gdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUgbmV4dCBlbnRyeS4gQWxsIHBlci1lbnRyeSB2YXJpYWJsZXMKKyAgICAgKiBhbmQgZGF0YSBzdHJ1Y3R1cmVzIGFyZSBjbGVhcmVkLgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSBjb21wcmVzc2VkIHNpemUgb2YgdGhpcyBlbnRyeSBpcyBpbmNsdWRlZCBpbiB0aGUgZW50cnkgaGVhZGVyLAorICAgICAqIHRoZW4gYW55IG91dHN0YW5kaW5nIGJ5dGVzIGFyZSBzaW1wbHkgc2tpcHBlZCBmcm9tIHRoZSB1bmRlcmx5aW5nCisgICAgICogc3RyZWFtIHdpdGhvdXQgdW5jb21wcmVzc2luZyB0aGVtLiBUaGlzIGFsbG93cyBhbiBlbnRyeSB0byBiZSBzYWZlbHkKKyAgICAgKiBjbG9zZWQgZXZlbiBpZiB0aGUgY29tcHJlc3Npb24gbWV0aG9kIGlzIHVuc3VwcG9ydGVkLgorICAgICAqIDxwPgorICAgICAqIEluIGNhc2Ugd2UgZG9uJ3Qga25vdyB0aGUgY29tcHJlc3NlZCBzaXplIG9mIHRoaXMgZW50cnkgb3IgaGF2ZQorICAgICAqIGFscmVhZHkgYnVmZmVyZWQgdG9vIG11Y2ggZGF0YSBmcm9tIHRoZSB1bmRlcmx5aW5nIHN0cmVhbSB0byBzdXBwb3J0CisgICAgICogdW5jb21wcmVzc2lvbiwgdGhlbiB0aGUgdW5jb21wcmVzc2lvbiBwcm9jZXNzIGlzIGNvbXBsZXRlZCBhbmQgdGhlCisgICAgICogZW5kIHBvc2l0aW9uIG9mIHRoZSBzdHJlYW0gaXMgYWRqdXN0ZWQgYmFzZWQgb24gdGhlIHJlc3VsdCBvZiB0aGF0CisgICAgICogcHJvY2Vzcy4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgYW4gZXJyb3Igb2NjdXJzCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGNsb3NlRW50cnkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoY2xvc2VkKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlRoZSBzdHJlYW0gaXMgY2xvc2VkIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGN1cnJlbnQgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgLy8gRW5zdXJlIGFsbCBlbnRyeSBieXRlcyBhcmUgcmVhZAorICAgICAgICBpZiAoY3VycmVudEVudHJ5SGFzT3V0c3RhbmRpbmdCeXRlcygpKSB7CisgICAgICAgICAgICBkcmFpbkN1cnJlbnRFbnRyeURhdGEoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8vIHRoaXMgaXMgZ3VhcmFudGVlZCB0byBleGhhdXN0IHRoZSBzdHJlYW0KKyAgICAgICAgICAgIHNraXAoTG9uZy5NQVhfVkFMVUUpOyAvL05PU09OQVIKKworICAgICAgICAgICAgZmluYWwgbG9uZyBpbkIgPSBjdXJyZW50LmVudHJ5LmdldE1ldGhvZCgpID09IFppcEFyY2hpdmVPdXRwdXRTdHJlYW0uREVGTEFURUQKKyAgICAgICAgICAgICAgICAgICAgICAgPyBnZXRCeXRlc0luZmxhdGVkKCkgOiBjdXJyZW50LmJ5dGVzUmVhZDsKKworICAgICAgICAgICAgLy8gdGhpcyBpcyBhdCBtb3N0IGEgc2luZ2xlIHJlYWQoKSBvcGVyYXRpb24gYW5kIGNhbid0CisgICAgICAgICAgICAvLyBleGNlZWQgdGhlIHJhbmdlIG9mIGludAorICAgICAgICAgICAgZmluYWwgaW50IGRpZmYgPSAoaW50KSAoY3VycmVudC5ieXRlc1JlYWRGcm9tU3RyZWFtIC0gaW5CKTsKKworICAgICAgICAgICAgLy8gUHVzaGJhY2sgYW55IHJlcXVpcmVkIGJ5dGVzCisgICAgICAgICAgICBpZiAoZGlmZiA+IDApIHsKKyAgICAgICAgICAgICAgICBwdXNoYmFjayhidWYuYXJyYXkoKSwgYnVmLmxpbWl0KCkgLSBkaWZmLCBkaWZmKTsKKyAgICAgICAgICAgICAgICBjdXJyZW50LmJ5dGVzUmVhZEZyb21TdHJlYW0gLT0gZGlmZjsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gRHJhaW4gcmVtYWluZGVyIG9mIGVudHJ5IGlmIG5vdCBhbGwgZGF0YSBieXRlcyB3ZXJlIHJlcXVpcmVkCisgICAgICAgICAgICBpZiAoY3VycmVudEVudHJ5SGFzT3V0c3RhbmRpbmdCeXRlcygpKSB7CisgICAgICAgICAgICAgICAgZHJhaW5DdXJyZW50RW50cnlEYXRhKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBpZiAobGFzdFN0b3JlZEVudHJ5ID09IG51bGwgJiYgY3VycmVudC5oYXNEYXRhRGVzY3JpcHRvcikgeworICAgICAgICAgICAgcmVhZERhdGFEZXNjcmlwdG9yKCk7CisgICAgICAgIH0KKworICAgICAgICBpbmYucmVzZXQoKTsKKyAgICAgICAgYnVmLmNsZWFyKCkuZmxpcCgpOworICAgICAgICBjdXJyZW50ID0gbnVsbDsKKyAgICAgICAgbGFzdFN0b3JlZEVudHJ5ID0gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJZiB0aGUgY29tcHJlc3NlZCBzaXplIG9mIHRoZSBjdXJyZW50IGVudHJ5IGlzIGluY2x1ZGVkIGluIHRoZSBlbnRyeSBoZWFkZXIKKyAgICAgKiBhbmQgdGhlcmUgYXJlIGFueSBvdXRzdGFuZGluZyBieXRlcyBpbiB0aGUgdW5kZXJseWluZyBzdHJlYW0sIHRoZW4KKyAgICAgKiB0aGlzIHJldHVybnMgdHJ1ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgY3VycmVudCBlbnRyeSBpcyBkZXRlcm1pbmVkIHRvIGhhdmUgb3V0c3RhbmRpbmcgYnl0ZXMsIGZhbHNlIG90aGVyd2lzZQorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBjdXJyZW50RW50cnlIYXNPdXRzdGFuZGluZ0J5dGVzKCkgeworICAgICAgICByZXR1cm4gY3VycmVudC5ieXRlc1JlYWRGcm9tU3RyZWFtIDw9IGN1cnJlbnQuZW50cnkuZ2V0Q29tcHJlc3NlZFNpemUoKQorICAgICAgICAgICAgICAgICYmICFjdXJyZW50Lmhhc0RhdGFEZXNjcmlwdG9yOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWQgYWxsIGRhdGEgb2YgdGhlIGN1cnJlbnQgZW50cnkgZnJvbSB0aGUgdW5kZXJseWluZyBzdHJlYW0KKyAgICAgKiB0aGF0IGhhc24ndCBiZWVuIHJlYWQsIHlldC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgZHJhaW5DdXJyZW50RW50cnlEYXRhKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgbG9uZyByZW1haW5pbmcgPSBjdXJyZW50LmVudHJ5LmdldENvbXByZXNzZWRTaXplKCkgLSBjdXJyZW50LmJ5dGVzUmVhZEZyb21TdHJlYW07CisgICAgICAgIHdoaWxlIChyZW1haW5pbmcgPiAwKSB7CisgICAgICAgICAgICBmaW5hbCBsb25nIG4gPSBpbi5yZWFkKGJ1Zi5hcnJheSgpLCAwLCAoaW50KSBNYXRoLm1pbihidWYuY2FwYWNpdHkoKSwgcmVtYWluaW5nKSk7CisgICAgICAgICAgICBpZiAobiA8IDApIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRU9GRXhjZXB0aW9uKCJUcnVuY2F0ZWQgWklQIGVudHJ5OiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIEFyY2hpdmVVdGlscy5zYW5pdGl6ZShjdXJyZW50LmVudHJ5LmdldE5hbWUoKSkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgY291bnQobik7CisgICAgICAgICAgICByZW1haW5pbmcgLT0gbjsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgbnVtYmVyIG9mIGJ5dGVzIEluZmxhdGVyIGhhcyBhY3R1YWxseSBwcm9jZXNzZWQuCisgICAgICoKKyAgICAgKiA8cD5mb3IgSmF2YSAmbHQ7IEphdmE3IHRoZSBnZXRCeXRlcyogbWV0aG9kcyBpbgorICAgICAqIEluZmxhdGVyL0RlZmxhdGVyIHNlZW0gdG8gcmV0dXJuIHVuc2lnbmVkIGludHMgcmF0aGVyIHRoYW4KKyAgICAgKiBsb25ncyB0aGF0IHN0YXJ0IG92ZXIgd2l0aCAwIGF0IDJeMzIuPC9wPgorICAgICAqCisgICAgICogPHA+VGhlIHN0cmVhbSBrbm93cyBob3cgbWFueSBieXRlcyBpdCBoYXMgcmVhZCwgYnV0IG5vdCBob3cKKyAgICAgKiBtYW55IHRoZSBJbmZsYXRlciBhY3R1YWxseSBjb25zdW1lZCAtIGl0IHNob3VsZCBiZSBiZXR3ZWVuIHRoZQorICAgICAqIHRvdGFsIG51bWJlciBvZiBieXRlcyByZWFkIGZvciB0aGUgZW50cnkgYW5kIHRoZSB0b3RhbCBudW1iZXIKKyAgICAgKiBtaW51cyB0aGUgbGFzdCByZWFkIG9wZXJhdGlvbi4gIEhlcmUgd2UganVzdCB0cnkgdG8gbWFrZSB0aGUKKyAgICAgKiB2YWx1ZSBjbG9zZSBlbm91Z2ggdG8gdGhlIGJ5dGVzIHdlJ3ZlIHJlYWQgYnkgYXNzdW1pbmcgdGhlCisgICAgICogbnVtYmVyIG9mIGJ5dGVzIGNvbnN1bWVkIG11c3QgYmUgc21hbGxlciB0aGFuIChvciBlcXVhbCB0bykgdGhlCisgICAgICogbnVtYmVyIG9mIGJ5dGVzIHJlYWQgYnV0IG5vdCBzbWFsbGVyIGJ5IG1vcmUgdGhhbiAyXjMyLjwvcD4KKyAgICAgKi8KKyAgICBwcml2YXRlIGxvbmcgZ2V0Qnl0ZXNJbmZsYXRlZCgpIHsKKyAgICAgICAgbG9uZyBpbkIgPSBpbmYuZ2V0Qnl0ZXNSZWFkKCk7CisgICAgICAgIGlmIChjdXJyZW50LmJ5dGVzUmVhZEZyb21TdHJlYW0gPj0gVFdPX0VYUF8zMikgeworICAgICAgICAgICAgd2hpbGUgKGluQiArIFRXT19FWFBfMzIgPD0gY3VycmVudC5ieXRlc1JlYWRGcm9tU3RyZWFtKSB7CisgICAgICAgICAgICAgICAgaW5CICs9IFRXT19FWFBfMzI7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGluQjsKKyAgICB9CisKKyAgICBwcml2YXRlIGludCBmaWxsKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGNsb3NlZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJUaGUgc3RyZWFtIGlzIGNsb3NlZCIpOworICAgICAgICB9CisgICAgICAgIGZpbmFsIGludCBsZW5ndGggPSBpbi5yZWFkKGJ1Zi5hcnJheSgpKTsKKyAgICAgICAgaWYgKGxlbmd0aCA+IDApIHsKKyAgICAgICAgICAgIGJ1Zi5saW1pdChsZW5ndGgpOworICAgICAgICAgICAgY291bnQoYnVmLmxpbWl0KCkpOworICAgICAgICAgICAgaW5mLnNldElucHV0KGJ1Zi5hcnJheSgpLCAwLCBidWYubGltaXQoKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGxlbmd0aDsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcmVhZEZ1bGx5KGZpbmFsIGJ5dGVbXSBiKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZWFkRnVsbHkoYiwgMCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHJlYWRGdWxseShmaW5hbCBieXRlW10gYiwgZmluYWwgaW50IG9mZikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgaW50IGxlbiA9IGIubGVuZ3RoIC0gb2ZmOworICAgICAgICBmaW5hbCBpbnQgY291bnQgPSBJT1V0aWxzLnJlYWRGdWxseShpbiwgYiwgb2ZmLCBsZW4pOworICAgICAgICBjb3VudChjb3VudCk7CisgICAgICAgIGlmIChjb3VudCA8IGxlbikgeworICAgICAgICAgICAgdGhyb3cgbmV3IEVPRkV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHJlYWREYXRhRGVzY3JpcHRvcigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJlYWRGdWxseSh3b3JkQnVmKTsKKyAgICAgICAgWmlwTG9uZyB2YWwgPSBuZXcgWmlwTG9uZyh3b3JkQnVmKTsKKyAgICAgICAgaWYgKFppcExvbmcuRERfU0lHLmVxdWFscyh2YWwpKSB7CisgICAgICAgICAgICAvLyBkYXRhIGRlc2NyaXB0b3Igd2l0aCBzaWduYXR1cmUsIHNraXAgc2lnCisgICAgICAgICAgICByZWFkRnVsbHkod29yZEJ1Zik7CisgICAgICAgICAgICB2YWwgPSBuZXcgWmlwTG9uZyh3b3JkQnVmKTsKKyAgICAgICAgfQorICAgICAgICBjdXJyZW50LmVudHJ5LnNldENyYyh2YWwuZ2V0VmFsdWUoKSk7CisKKyAgICAgICAgLy8gaWYgdGhlcmUgaXMgYSBaSVA2NCBleHRyYSBmaWVsZCwgc2l6ZXMgYXJlIGVpZ2h0IGJ5dGVzCisgICAgICAgIC8vIGVhY2gsIG90aGVyd2lzZSBmb3VyIGJ5dGVzIGVhY2guICBVbmZvcnR1bmF0ZWx5IHNvbWUKKyAgICAgICAgLy8gaW1wbGVtZW50YXRpb25zIC0gbmFtZWx5IEphdmE3IC0gdXNlIGVpZ2h0IGJ5dGVzIHdpdGhvdXQKKyAgICAgICAgLy8gdXNpbmcgYSBaSVA2NCBleHRyYSBmaWVsZCAtCisgICAgICAgIC8vIGh0dHBzOi8vYnVncy5zdW4uY29tL2J1Z2RhdGFiYXNlL3ZpZXdfYnVnLmRvP2J1Z19pZD03MDczNTg4CisKKyAgICAgICAgLy8ganVzdCByZWFkIDE2IGJ5dGVzIGFuZCBjaGVjayB3aGV0aGVyIGJ5dGVzIG5pbmUgdG8gdHdlbHZlCisgICAgICAgIC8vIGxvb2sgbGlrZSBvbmUgb2YgdGhlIHNpZ25hdHVyZXMgb2Ygd2hhdCBjb3VsZCBmb2xsb3cgYSBkYXRhCisgICAgICAgIC8vIGRlc2NyaXB0b3IgKGlnbm9yaW5nIGFyY2hpdmUgZGVjcnlwdGlvbiBoZWFkZXJzIGZvciBub3cpLgorICAgICAgICAvLyBJZiBzbywgcHVzaCBiYWNrIGVpZ2h0IGJ5dGVzIGFuZCBhc3N1bWUgc2l6ZXMgYXJlIGZvdXIKKyAgICAgICAgLy8gYnl0ZXMsIG90aGVyd2lzZSBzaXplcyBhcmUgZWlnaHQgYnl0ZXMgZWFjaC4KKyAgICAgICAgcmVhZEZ1bGx5KHR3b0R3b3JkQnVmKTsKKyAgICAgICAgZmluYWwgWmlwTG9uZyBwb3RlbnRpYWxTaWcgPSBuZXcgWmlwTG9uZyh0d29Ed29yZEJ1ZiwgRFdPUkQpOworICAgICAgICBpZiAocG90ZW50aWFsU2lnLmVxdWFscyhaaXBMb25nLkNGSF9TSUcpIHx8IHBvdGVudGlhbFNpZy5lcXVhbHMoWmlwTG9uZy5MRkhfU0lHKSkgeworICAgICAgICAgICAgcHVzaGJhY2sodHdvRHdvcmRCdWYsIERXT1JELCBEV09SRCk7CisgICAgICAgICAgICBjdXJyZW50LmVudHJ5LnNldENvbXByZXNzZWRTaXplKFppcExvbmcuZ2V0VmFsdWUodHdvRHdvcmRCdWYpKTsKKyAgICAgICAgICAgIGN1cnJlbnQuZW50cnkuc2V0U2l6ZShaaXBMb25nLmdldFZhbHVlKHR3b0R3b3JkQnVmLCBXT1JEKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBjdXJyZW50LmVudHJ5LnNldENvbXByZXNzZWRTaXplKFppcEVpZ2h0Qnl0ZUludGVnZXIuZ2V0TG9uZ1ZhbHVlKHR3b0R3b3JkQnVmKSk7CisgICAgICAgICAgICBjdXJyZW50LmVudHJ5LnNldFNpemUoWmlwRWlnaHRCeXRlSW50ZWdlci5nZXRMb25nVmFsdWUodHdvRHdvcmRCdWYsIERXT1JEKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXaGV0aGVyIHRoaXMgZW50cnkgcmVxdWlyZXMgYSBkYXRhIGRlc2NyaXB0b3IgdGhpcyBsaWJyYXJ5IGNhbiB3b3JrIHdpdGguCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgYWxsb3dTdG9yZWRFbnRyaWVzV2l0aERhdGFEZXNjcmlwdG9yIGlzIHRydWUsCisgICAgICogdGhlIGVudHJ5IGRvZXNuJ3QgcmVxdWlyZSBhbnkgZGF0YSBkZXNjcmlwdG9yIG9yIHRoZSBtZXRob2QgaXMKKyAgICAgKiBERUZMQVRFRCBvciBFTkhBTkNFRF9ERUZMQVRFRC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gc3VwcG9ydHNEYXRhRGVzY3JpcHRvckZvcihmaW5hbCBaaXBBcmNoaXZlRW50cnkgZW50cnkpIHsKKyAgICAgICAgcmV0dXJuICFlbnRyeS5nZXRHZW5lcmFsUHVycG9zZUJpdCgpLnVzZXNEYXRhRGVzY3JpcHRvcigpCisKKyAgICAgICAgICAgICAgICB8fCAoYWxsb3dTdG9yZWRFbnRyaWVzV2l0aERhdGFEZXNjcmlwdG9yICYmIGVudHJ5LmdldE1ldGhvZCgpID09IFppcEVudHJ5LlNUT1JFRCkKKyAgICAgICAgICAgICAgICB8fCBlbnRyeS5nZXRNZXRob2QoKSA9PSBaaXBFbnRyeS5ERUZMQVRFRAorICAgICAgICAgICAgICAgIHx8IGVudHJ5LmdldE1ldGhvZCgpID09IFppcE1ldGhvZC5FTkhBTkNFRF9ERUZMQVRFRC5nZXRDb2RlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogV2hldGhlciB0aGUgY29tcHJlc3NlZCBzaXplIGZvciB0aGUgZW50cnkgaXMgZWl0aGVyIGtub3duIG9yCisgICAgICogbm90IHJlcXVpcmVkIGJ5IHRoZSBjb21wcmVzc2lvbiBtZXRob2QgYmVpbmcgdXNlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gc3VwcG9ydHNDb21wcmVzc2VkU2l6ZUZvcihmaW5hbCBaaXBBcmNoaXZlRW50cnkgZW50cnkpIHsKKyAgICAgICAgcmV0dXJuIGVudHJ5LmdldENvbXByZXNzZWRTaXplKCkgIT0gQXJjaGl2ZUVudHJ5LlNJWkVfVU5LTk9XTgorICAgICAgICAgICAgfHwgZW50cnkuZ2V0TWV0aG9kKCkgPT0gWmlwRW50cnkuREVGTEFURUQKKyAgICAgICAgICAgIHx8IGVudHJ5LmdldE1ldGhvZCgpID09IFppcE1ldGhvZC5FTkhBTkNFRF9ERUZMQVRFRC5nZXRDb2RlKCkKKyAgICAgICAgICAgIHx8IChlbnRyeS5nZXRHZW5lcmFsUHVycG9zZUJpdCgpLnVzZXNEYXRhRGVzY3JpcHRvcigpCisgICAgICAgICAgICAgICAgJiYgYWxsb3dTdG9yZWRFbnRyaWVzV2l0aERhdGFEZXNjcmlwdG9yCisgICAgICAgICAgICAgICAgJiYgZW50cnkuZ2V0TWV0aG9kKCkgPT0gWmlwRW50cnkuU1RPUkVEKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDYWNoZXMgYSBzdG9yZWQgZW50cnkgdGhhdCB1c2VzIHRoZSBkYXRhIGRlc2NyaXB0b3IuCisgICAgICoKKyAgICAgKiA8dWw+CisgICAgICogICA8bGk+UmVhZHMgYSBzdG9yZWQgZW50cnkgdW50aWwgdGhlIHNpZ25hdHVyZSBvZiBhIGxvY2FsIGZpbGUKKyAgICAgKiAgICAgaGVhZGVyLCBjZW50cmFsIGRpcmVjdG9yeSBoZWFkZXIgb3IgZGF0YSBkZXNjcmlwdG9yIGhhcyBiZWVuCisgICAgICogICAgIGZvdW5kLjwvbGk+CisgICAgICogICA8bGk+U3RvcmVzIGFsbCBlbnRyeSBkYXRhIGluIGxhc3RTdG9yZWRFbnRyeS48L3A+CisgICAgICogICA8bGk+UmV3aW5kcyB0aGUgc3RyZWFtIHRvIHBvc2l0aW9uIGF0IHRoZSBkYXRhCisgICAgICogICAgIGRlc2NyaXB0b3IuPC9saT4KKyAgICAgKiAgIDxsaT5yZWFkcyB0aGUgZGF0YSBkZXNjcmlwdG9yPC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqCisgICAgICogPHA+QWZ0ZXIgY2FsbGluZyB0aGlzIG1ldGhvZCB0aGUgZW50cnkgc2hvdWxkIGtub3cgaXRzIHNpemUsCisgICAgICogdGhlIGVudHJ5J3MgZGF0YSBpcyBjYWNoZWQgYW5kIHRoZSBzdHJlYW0gaXMgcG9zaXRpb25lZCBhdCB0aGUKKyAgICAgKiBuZXh0IGxvY2FsIGZpbGUgb3IgY2VudHJhbCBkaXJlY3RvcnkgaGVhZGVyLjwvcD4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcmVhZFN0b3JlZEVudHJ5KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgaW50IG9mZiA9IDA7CisgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOworCisgICAgICAgIC8vIGxlbmd0aCBvZiBERCB3aXRob3V0IHNpZ25hdHVyZQorICAgICAgICBmaW5hbCBpbnQgZGRMZW4gPSBjdXJyZW50LnVzZXNaaXA2NCA/IFdPUkQgKyAyICogRFdPUkQgOiAzICogV09SRDsKKworICAgICAgICB3aGlsZSAoIWRvbmUpIHsKKyAgICAgICAgICAgIGZpbmFsIGludCByID0gaW4ucmVhZChidWYuYXJyYXkoKSwgb2ZmLCBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtLkJVRkZFUl9TSVpFIC0gb2ZmKTsKKyAgICAgICAgICAgIGlmIChyIDw9IDApIHsKKyAgICAgICAgICAgICAgICAvLyByZWFkIHRoZSB3aG9sZSBhcmNoaXZlIHdpdGhvdXQgZXZlciBmaW5kaW5nIGEKKyAgICAgICAgICAgICAgICAvLyBjZW50cmFsIGRpcmVjdG9yeQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiVHJ1bmNhdGVkIFpJUCBmaWxlIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAociArIG9mZiA8IDQpIHsKKyAgICAgICAgICAgICAgICAvLyBidWZmZXIgdG9vIHNtYWxsIHRvIGNoZWNrIGZvciBhIHNpZ25hdHVyZSwgbG9vcAorICAgICAgICAgICAgICAgIG9mZiArPSByOworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBkb25lID0gYnVmZmVyQ29udGFpbnNTaWduYXR1cmUoYm9zLCBvZmYsIHIsIGRkTGVuKTsKKyAgICAgICAgICAgIGlmICghZG9uZSkgeworICAgICAgICAgICAgICAgIG9mZiA9IGNhY2hlQnl0ZXNSZWFkKGJvcywgb2ZmLCByLCBkZExlbik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBmaW5hbCBieXRlW10gYiA9IGJvcy50b0J5dGVBcnJheSgpOworICAgICAgICBsYXN0U3RvcmVkRW50cnkgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYik7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIExGSCA9IFppcExvbmcuTEZIX1NJRy5nZXRCeXRlcygpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBDRkggPSBaaXBMb25nLkNGSF9TSUcuZ2V0Qnl0ZXMoKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gREQgPSBaaXBMb25nLkREX1NJRy5nZXRCeXRlcygpOworCisgICAgLyoqCisgICAgICogQ2hlY2tzIHdoZXRoZXIgdGhlIGN1cnJlbnQgYnVmZmVyIGNvbnRhaW5zIHRoZSBzaWduYXR1cmUgb2YgYQorICAgICAqICZxdW90O2RhdGEgZGVzY3JpcHRvciZxdW90OywgJnF1b3Q7bG9jYWwgZmlsZSBoZWFkZXImcXVvdDsgb3IKKyAgICAgKiAmcXVvdDtjZW50cmFsIGRpcmVjdG9yeSBlbnRyeSZxdW90Oy4KKyAgICAgKgorICAgICAqIDxwPklmIGl0IGNvbnRhaW5zIHN1Y2ggYSBzaWduYXR1cmUsIHJlYWRzIHRoZSBkYXRhIGRlc2NyaXB0b3IKKyAgICAgKiBhbmQgcG9zaXRpb25zIHRoZSBzdHJlYW0gcmlnaHQgYWZ0ZXIgdGhlIGRhdGEgZGVzY3JpcHRvci48L3A+CisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIGJ1ZmZlckNvbnRhaW5zU2lnbmF0dXJlKGZpbmFsIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBib3MsIGZpbmFsIGludCBvZmZzZXQsIGZpbmFsIGludCBsYXN0UmVhZCwgZmluYWwgaW50IGV4cGVjdGVkRERMZW4pCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworCisgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOworICAgICAgICBpbnQgcmVhZFRvb011Y2ggPSAwOworICAgICAgICBmb3IgKGludCBpID0gMDsgIWRvbmUgJiYgaSA8IG9mZnNldCArIGxhc3RSZWFkIC0gNDsgaSsrKSB7CisgICAgICAgICAgICBpZiAoYnVmLmFycmF5KClbaV0gPT0gTEZIWzBdICYmIGJ1Zi5hcnJheSgpW2kgKyAxXSA9PSBMRkhbMV0pIHsKKyAgICAgICAgICAgICAgICBpZiAoKGJ1Zi5hcnJheSgpW2kgKyAyXSA9PSBMRkhbMl0gJiYgYnVmLmFycmF5KClbaSArIDNdID09IExGSFszXSkKKyAgICAgICAgICAgICAgICAgICAgfHwgKGJ1Zi5hcnJheSgpW2ldID09IENGSFsyXSAmJiBidWYuYXJyYXkoKVtpICsgM10gPT0gQ0ZIWzNdKSkgeworICAgICAgICAgICAgICAgICAgICAvLyBmb3VuZCBhIExGSCBvciBDRkg6CisgICAgICAgICAgICAgICAgICAgIHJlYWRUb29NdWNoID0gb2Zmc2V0ICsgbGFzdFJlYWQgLSBpIC0gZXhwZWN0ZWRERExlbjsKKyAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGVsc2UgaWYgKGJ1Zi5hcnJheSgpW2kgKyAyXSA9PSBERFsyXSAmJiBidWYuYXJyYXkoKVtpICsgM10gPT0gRERbM10pIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gZm91bmQgREQ6CisgICAgICAgICAgICAgICAgICAgIHJlYWRUb29NdWNoID0gb2Zmc2V0ICsgbGFzdFJlYWQgLSBpOworICAgICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKGRvbmUpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gKiBwdXNoIGJhY2sgYnl0ZXMgcmVhZCBpbiBleGNlc3MgYXMgd2VsbCBhcyB0aGUgZGF0YQorICAgICAgICAgICAgICAgICAgICAvLyAgIGRlc2NyaXB0b3IKKyAgICAgICAgICAgICAgICAgICAgLy8gKiBjb3B5IHRoZSByZW1haW5pbmcgYnl0ZXMgdG8gY2FjaGUKKyAgICAgICAgICAgICAgICAgICAgLy8gKiByZWFkIGRhdGEgZGVzY3JpcHRvcgorICAgICAgICAgICAgICAgICAgICBwdXNoYmFjayhidWYuYXJyYXkoKSwgb2Zmc2V0ICsgbGFzdFJlYWQgLSByZWFkVG9vTXVjaCwgcmVhZFRvb011Y2gpOworICAgICAgICAgICAgICAgICAgICBib3Mud3JpdGUoYnVmLmFycmF5KCksIDAsIGkpOworICAgICAgICAgICAgICAgICAgICByZWFkRGF0YURlc2NyaXB0b3IoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGRvbmU7CisgICAgfQorCisgICAgLyoqCisgICAgICogSWYgdGhlIGxhc3QgcmVhZCBieXRlcyBjb3VsZCBob2xkIGEgZGF0YSBkZXNjcmlwdG9yIGFuZCBhbgorICAgICAqIGluY29tcGxldGUgc2lnbmF0dXJlIHRoZW4gc2F2ZSB0aGUgbGFzdCBieXRlcyB0byB0aGUgZnJvbnQgb2YKKyAgICAgKiB0aGUgYnVmZmVyIGFuZCBjYWNoZSBldmVyeXRoaW5nIGluIGZyb250IG9mIHRoZSBwb3RlbnRpYWwgZGF0YQorICAgICAqIGRlc2NyaXB0b3IgaW50byB0aGUgZ2l2ZW4gQnl0ZUFycmF5T3V0cHV0U3RyZWFtLgorICAgICAqCisgICAgICogPHA+RGF0YSBkZXNjcmlwdG9yIHBsdXMgaW5jb21wbGV0ZSBzaWduYXR1cmUgKDMgYnl0ZXMgaW4gdGhlCisgICAgICogd29yc3QgY2FzZSkgY2FuIGJlIDIwIGJ5dGVzIG1heC48L3A+CisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgY2FjaGVCeXRlc1JlYWQoZmluYWwgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvcywgaW50IG9mZnNldCwgZmluYWwgaW50IGxhc3RSZWFkLCBmaW5hbCBpbnQgZXhwZWN0ZURETGVuKSB7CisgICAgICAgIGZpbmFsIGludCBjYWNoZWFibGUgPSBvZmZzZXQgKyBsYXN0UmVhZCAtIGV4cGVjdGVERExlbiAtIDM7CisgICAgICAgIGlmIChjYWNoZWFibGUgPiAwKSB7CisgICAgICAgICAgICBib3Mud3JpdGUoYnVmLmFycmF5KCksIDAsIGNhY2hlYWJsZSk7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGJ1Zi5hcnJheSgpLCBjYWNoZWFibGUsIGJ1Zi5hcnJheSgpLCAwLCBleHBlY3RlRERMZW4gKyAzKTsKKyAgICAgICAgICAgIG9mZnNldCA9IGV4cGVjdGVERExlbiArIDM7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBvZmZzZXQgKz0gbGFzdFJlYWQ7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG9mZnNldDsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcHVzaGJhY2soZmluYWwgYnl0ZVtdIGJ1ZiwgZmluYWwgaW50IG9mZnNldCwgZmluYWwgaW50IGxlbmd0aCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgKChQdXNoYmFja0lucHV0U3RyZWFtKSBpbikudW5yZWFkKGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpOworICAgICAgICBwdXNoZWRCYWNrQnl0ZXMobGVuZ3RoKTsKKyAgICB9CisKKyAgICAvLyBFbmQgb2YgQ2VudHJhbCBEaXJlY3RvcnkgUmVjb3JkCisgICAgLy8gICBlbmQgb2YgY2VudHJhbCBkaXIgc2lnbmF0dXJlICAgIFdPUkQKKyAgICAvLyAgIG51bWJlciBvZiB0aGlzIGRpc2sgICAgICAgICAgICAgU0hPUlQKKyAgICAvLyAgIG51bWJlciBvZiB0aGUgZGlzayB3aXRoIHRoZQorICAgIC8vICAgc3RhcnQgb2YgdGhlIGNlbnRyYWwgZGlyZWN0b3J5ICBTSE9SVAorICAgIC8vICAgdG90YWwgbnVtYmVyIG9mIGVudHJpZXMgaW4gdGhlCisgICAgLy8gICBjZW50cmFsIGRpcmVjdG9yeSBvbiB0aGlzIGRpc2sgIFNIT1JUCisgICAgLy8gICB0b3RhbCBudW1iZXIgb2YgZW50cmllcyBpbgorICAgIC8vICAgdGhlIGNlbnRyYWwgZGlyZWN0b3J5ICAgICAgICAgICBTSE9SVAorICAgIC8vICAgc2l6ZSBvZiB0aGUgY2VudHJhbCBkaXJlY3RvcnkgICBXT1JECisgICAgLy8gICBvZmZzZXQgb2Ygc3RhcnQgb2YgY2VudHJhbAorICAgIC8vICAgZGlyZWN0b3J5IHdpdGggcmVzcGVjdCB0bworICAgIC8vICAgdGhlIHN0YXJ0aW5nIGRpc2sgbnVtYmVyICAgICAgICBXT1JECisgICAgLy8gICAuWklQIGZpbGUgY29tbWVudCBsZW5ndGggICAgICAgIFNIT1JUCisgICAgLy8gICAuWklQIGZpbGUgY29tbWVudCAgICAgICAgICAgICAgIHVwIHRvIDY0S0IKKyAgICAvLworCisgICAgLyoqCisgICAgICogUmVhZHMgdGhlIHN0cmVhbSB1bnRpbCBpdCBmaW5kIHRoZSAiRW5kIG9mIGNlbnRyYWwgZGlyZWN0b3J5CisgICAgICogcmVjb3JkIiBhbmQgY29uc3VtZXMgaXQgYXMgd2VsbC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgc2tpcFJlbWFpbmRlck9mQXJjaGl2ZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIHNraXAgb3ZlciBjZW50cmFsIGRpcmVjdG9yeS4gT25lIExGSCBoYXMgYmVlbiByZWFkIHRvbyBtdWNoCisgICAgICAgIC8vIGFscmVhZHkuICBUaGUgY2FsY3VsYXRpb24gZGlzY291bnRzIGZpbGUgbmFtZXMgYW5kIGV4dHJhCisgICAgICAgIC8vIGRhdGEgc28gaXQgd2lsbCBiZSB0b28gc2hvcnQuCisgICAgICAgIHJlYWxTa2lwKChsb25nKSBlbnRyaWVzUmVhZCAqIENGSF9MRU4gLSBMRkhfTEVOKTsKKyAgICAgICAgZmluZEVvY2RSZWNvcmQoKTsKKyAgICAgICAgcmVhbFNraXAoKGxvbmcpIFppcEZpbGUuTUlOX0VPQ0RfU0laRSAtIFdPUkQgLyogc2lnbmF0dXJlICovIC0gU0hPUlQgLyogY29tbWVudCBsZW4gKi8pOworICAgICAgICByZWFkRnVsbHkoc2hvcnRCdWYpOworICAgICAgICAvLyBmaWxlIGNvbW1lbnQKKyAgICAgICAgcmVhbFNraXAoWmlwU2hvcnQuZ2V0VmFsdWUoc2hvcnRCdWYpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBmb3J3YXJkIHVudGlsIHRoZSBzaWduYXR1cmUgb2YgdGhlICZxdW90O0VuZCBvZiBjZW50cmFsCisgICAgICogZGlyZWN0b3J5JnF1b3Q7IHJlY29yZCBpcyBmb3VuZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgZmluZEVvY2RSZWNvcmQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgY3VycmVudEJ5dGUgPSAtMTsKKyAgICAgICAgYm9vbGVhbiBza2lwUmVhZENhbGwgPSBmYWxzZTsKKyAgICAgICAgd2hpbGUgKHNraXBSZWFkQ2FsbCB8fCAoY3VycmVudEJ5dGUgPSByZWFkT25lQnl0ZSgpKSA+IC0xKSB7CisgICAgICAgICAgICBza2lwUmVhZENhbGwgPSBmYWxzZTsKKyAgICAgICAgICAgIGlmICghaXNGaXJzdEJ5dGVPZkVvY2RTaWcoY3VycmVudEJ5dGUpKSB7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjdXJyZW50Qnl0ZSA9IHJlYWRPbmVCeXRlKCk7CisgICAgICAgICAgICBpZiAoY3VycmVudEJ5dGUgIT0gWmlwQXJjaGl2ZU91dHB1dFN0cmVhbS5FT0NEX1NJR1sxXSkgeworICAgICAgICAgICAgICAgIGlmIChjdXJyZW50Qnl0ZSA9PSAtMSkgeworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgc2tpcFJlYWRDYWxsID0gaXNGaXJzdEJ5dGVPZkVvY2RTaWcoY3VycmVudEJ5dGUpOworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgY3VycmVudEJ5dGUgPSByZWFkT25lQnl0ZSgpOworICAgICAgICAgICAgaWYgKGN1cnJlbnRCeXRlICE9IFppcEFyY2hpdmVPdXRwdXRTdHJlYW0uRU9DRF9TSUdbMl0pIHsKKyAgICAgICAgICAgICAgICBpZiAoY3VycmVudEJ5dGUgPT0gLTEpIHsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHNraXBSZWFkQ2FsbCA9IGlzRmlyc3RCeXRlT2ZFb2NkU2lnKGN1cnJlbnRCeXRlKTsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGN1cnJlbnRCeXRlID0gcmVhZE9uZUJ5dGUoKTsKKyAgICAgICAgICAgIGlmIChjdXJyZW50Qnl0ZSA9PSAtMQorICAgICAgICAgICAgICAgIHx8IGN1cnJlbnRCeXRlID09IFppcEFyY2hpdmVPdXRwdXRTdHJlYW0uRU9DRF9TSUdbM10pIHsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHNraXBSZWFkQ2FsbCA9IGlzRmlyc3RCeXRlT2ZFb2NkU2lnKGN1cnJlbnRCeXRlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNraXBzIGJ5dGVzIGJ5IHJlYWRpbmcgZnJvbSB0aGUgdW5kZXJseWluZyBzdHJlYW0gcmF0aGVyIHRoYW4KKyAgICAgKiB0aGUgKHBvdGVudGlhbGx5IGluZmxhdGluZykgYXJjaGl2ZSBzdHJlYW0gLSB3aGljaCB7QGxpbmsKKyAgICAgKiAjc2tpcH0gd291bGQgZG8uCisgICAgICoKKyAgICAgKiBBbHNvIHVwZGF0ZXMgYnl0ZXMtcmVhZCBjb3VudGVyLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCByZWFsU2tpcChmaW5hbCBsb25nIHZhbHVlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAodmFsdWUgPj0gMCkgeworICAgICAgICAgICAgbG9uZyBza2lwcGVkID0gMDsKKyAgICAgICAgICAgIHdoaWxlIChza2lwcGVkIDwgdmFsdWUpIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBsb25nIHJlbSA9IHZhbHVlIC0gc2tpcHBlZDsKKyAgICAgICAgICAgICAgICBmaW5hbCBpbnQgeCA9IGluLnJlYWQoc2tpcEJ1ZiwgMCwgKGludCkgKHNraXBCdWYubGVuZ3RoID4gcmVtID8gcmVtIDogc2tpcEJ1Zi5sZW5ndGgpKTsKKyAgICAgICAgICAgICAgICBpZiAoeCA9PSAtMSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGNvdW50KHgpOworICAgICAgICAgICAgICAgIHNraXBwZWQgKz0geDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgYnl0ZXMgYnkgcmVhZGluZyBmcm9tIHRoZSB1bmRlcmx5aW5nIHN0cmVhbSByYXRoZXIgdGhhbgorICAgICAqIHRoZSAocG90ZW50aWFsbHkgaW5mbGF0aW5nKSBhcmNoaXZlIHN0cmVhbSAtIHdoaWNoIHtAbGluayAjcmVhZH0gd291bGQgZG8uCisgICAgICoKKyAgICAgKiBBbHNvIHVwZGF0ZXMgYnl0ZXMtcmVhZCBjb3VudGVyLgorICAgICAqLworICAgIHByaXZhdGUgaW50IHJlYWRPbmVCeXRlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgaW50IGIgPSBpbi5yZWFkKCk7CisgICAgICAgIGlmIChiICE9IC0xKSB7CisgICAgICAgICAgICBjb3VudCgxKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYjsKKyAgICB9CisKKyAgICBwcml2YXRlIGJvb2xlYW4gaXNGaXJzdEJ5dGVPZkVvY2RTaWcoZmluYWwgaW50IGIpIHsKKyAgICAgICAgcmV0dXJuIGIgPT0gWmlwQXJjaGl2ZU91dHB1dFN0cmVhbS5FT0NEX1NJR1swXTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gQVBLX1NJR05JTkdfQkxPQ0tfTUFHSUMgPSBuZXcgYnl0ZVtdIHsKKyAgICAgICAgJ0EnLCAnUCcsICdLJywgJyAnLCAnUycsICdpJywgJ2cnLCAnICcsICdCJywgJ2wnLCAnbycsICdjJywgJ2snLCAnICcsICc0JywgJzInLAorICAgIH07CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQmlnSW50ZWdlciBMT05HX01BWCA9IEJpZ0ludGVnZXIudmFsdWVPZihMb25nLk1BWF9WQUxVRSk7CisKKyAgICAvKioKKyAgICAgKiBDaGVja3Mgd2hldGhlciB0aGlzIG1pZ2h0IGJlIGFuIEFQSyBTaWduaW5nIEJsb2NrLgorICAgICAqCisgICAgICogPHA+VW5mb3J0dW5hdGVseSB0aGUgQVBLIHNpZ25pbmcgYmxvY2sgZG9lcyBub3Qgc3RhcnQgd2l0aCBzb21lIGtpbmQgb2Ygc2lnbmF0dXJlLCBpdCByYXRoZXIgZW5kcyB3aXRoIG9uZS4gSXQKKyAgICAgKiBzdGFydHMgd2l0aCBhIGxlbmd0aCwgc28gd2hhdCB3ZSBkbyBpcyBwYXJzZSB0aGUgc3VzcGVjdCBsZW5ndGgsIHNraXAgYWhlYWQgZmFyIGVub3VnaCwgbG9vayBmb3IgdGhlIHNpZ25hdHVyZQorICAgICAqIGFuZCBpZiB3ZSd2ZSBmb3VuZCBpdCwgcmV0dXJuIHRydWUuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIHN1c3BlY3RMb2NhbEZpbGVIZWFkZXIgdGhlIGJ5dGVzIHJlYWQgZnJvbSB0aGUgdW5kZXJseWluZyBzdHJlYW0gaW4gdGhlIGV4cGVjdGF0aW9uIHRoYXQgdGhleSB3b3VsZCBob2xkCisgICAgICogdGhlIGxvY2FsIGZpbGUgaGVhZGVyIG9mIHRoZSBuZXh0IGVudHJ5LgorICAgICAqCisgICAgICogQHJldHVybiB0cnVlIGlmIHRoaXMgbG9va3MgbGlrZSBhIEFQSyBzaWduaW5nIGJsb2NrCisgICAgICoKKyAgICAgKiBAc2VlIDxhIGhyZWY9Imh0dHBzOi8vc291cmNlLmFuZHJvaWQuY29tL3NlY3VyaXR5L2Fwa3NpZ25pbmcvdjIiPmh0dHBzOi8vc291cmNlLmFuZHJvaWQuY29tL3NlY3VyaXR5L2Fwa3NpZ25pbmcvdjI8L2E+CisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIGlzQXBrU2lnbmluZ0Jsb2NrKGJ5dGVbXSBzdXNwZWN0TG9jYWxGaWxlSGVhZGVyKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBsZW5ndGggb2YgYmxvY2sgZXhjbHVkaW5nIHRoZSBzaXplIGZpZWxkIGl0c2VsZgorICAgICAgICBCaWdJbnRlZ2VyIGxlbiA9IFppcEVpZ2h0Qnl0ZUludGVnZXIuZ2V0VmFsdWUoc3VzcGVjdExvY2FsRmlsZUhlYWRlcik7CisgICAgICAgIC8vIExGSCBoYXMgYWxyZWFkeSBiZWVuIHJlYWQgYW5kIGFsbCBidXQgdGhlIGZpcnN0IGVpZ2h0IGJ5dGVzIGNvbnRhaW4gKHBhcnQgb2YpIHRoZSBBUEsgc2lnbmluZyBibG9jaywKKyAgICAgICAgLy8gYWxzbyBzdWJ0cmFjdCAxNiBieXRlcyBpbiBvcmRlciB0byBwb3NpdGlvbiB1cyBhdCB0aGUgbWFnaWMgc3RyaW5nCisgICAgICAgIEJpZ0ludGVnZXIgdG9Ta2lwID0gbGVuLmFkZChCaWdJbnRlZ2VyLnZhbHVlT2YoRFdPUkQgLSBzdXNwZWN0TG9jYWxGaWxlSGVhZGVyLmxlbmd0aAorICAgICAgICAgICAgLSAobG9uZykgQVBLX1NJR05JTkdfQkxPQ0tfTUFHSUMubGVuZ3RoKSk7CisgICAgICAgIGJ5dGVbXSBtYWdpYyA9IG5ldyBieXRlW0FQS19TSUdOSU5HX0JMT0NLX01BR0lDLmxlbmd0aF07CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlmICh0b1NraXAuc2lnbnVtKCkgPCAwKSB7CisgICAgICAgICAgICAgICAgLy8gc3VzcGVjdExvY2FsRmlsZUhlYWRlciBjb250YWlucyB0aGUgc3RhcnQgb2Ygc3VzcGVjdCBtYWdpYyBzdHJpbmcKKyAgICAgICAgICAgICAgICBpbnQgb2ZmID0gc3VzcGVjdExvY2FsRmlsZUhlYWRlci5sZW5ndGggKyB0b1NraXAuaW50VmFsdWUoKTsKKyAgICAgICAgICAgICAgICAvLyBsZW5ndGggd2FzIHNob3J0ZXIgdGhhbiBtYWdpYyBsZW5ndGgKKyAgICAgICAgICAgICAgICBpZiAob2ZmIDwgRFdPUkQpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpbnQgYnl0ZXNJbkJ1ZmZlciA9IE1hdGguYWJzKHRvU2tpcC5pbnRWYWx1ZSgpKTsKKyAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHN1c3BlY3RMb2NhbEZpbGVIZWFkZXIsIG9mZiwgbWFnaWMsIDAsIE1hdGgubWluKGJ5dGVzSW5CdWZmZXIsIG1hZ2ljLmxlbmd0aCkpOworICAgICAgICAgICAgICAgIGlmIChieXRlc0luQnVmZmVyIDwgbWFnaWMubGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgICAgIHJlYWRGdWxseShtYWdpYywgYnl0ZXNJbkJ1ZmZlcik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB3aGlsZSAodG9Ta2lwLmNvbXBhcmVUbyhMT05HX01BWCkgPiAwKSB7CisgICAgICAgICAgICAgICAgICAgIHJlYWxTa2lwKExvbmcuTUFYX1ZBTFVFKTsKKyAgICAgICAgICAgICAgICAgICAgdG9Ta2lwID0gdG9Ta2lwLmFkZChMT05HX01BWC5uZWdhdGUoKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJlYWxTa2lwKHRvU2tpcC5sb25nVmFsdWUoKSk7CisgICAgICAgICAgICAgICAgcmVhZEZ1bGx5KG1hZ2ljKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoRU9GRXhjZXB0aW9uIGV4KSB7IC8vTk9TT05BUgorICAgICAgICAgICAgLy8gbGVuZ3RoIHdhcyBpbnZhbGlkCisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIEFycmF5cy5lcXVhbHMobWFnaWMsIEFQS19TSUdOSU5HX0JMT0NLX01BR0lDKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTdHJ1Y3R1cmUgY29sbGVjdGluZyBpbmZvcm1hdGlvbiBmb3IgdGhlIGVudHJ5IHRoYXQgaXMKKyAgICAgKiBjdXJyZW50bHkgYmVpbmcgcmVhZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBDdXJyZW50RW50cnkgeworCisgICAgICAgIC8qKgorICAgICAgICAgKiBDdXJyZW50IFpJUCBlbnRyeS4KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgZmluYWwgWmlwQXJjaGl2ZUVudHJ5IGVudHJ5ID0gbmV3IFppcEFyY2hpdmVFbnRyeSgpOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBEb2VzIHRoZSBlbnRyeSB1c2UgYSBkYXRhIGRlc2NyaXB0b3I/CisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIGJvb2xlYW4gaGFzRGF0YURlc2NyaXB0b3I7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIERvZXMgdGhlIGVudHJ5IGhhdmUgYSBaSVA2NCBleHRlbmRlZCBpbmZvcm1hdGlvbiBleHRyYSBmaWVsZC4KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgYm9vbGVhbiB1c2VzWmlwNjQ7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIE51bWJlciBvZiBieXRlcyBvZiBlbnRyeSBjb250ZW50IHJlYWQgYnkgdGhlIGNsaWVudCBpZiB0aGUKKyAgICAgICAgICogZW50cnkgaXMgU1RPUkVELgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBsb25nIGJ5dGVzUmVhZDsKKworICAgICAgICAvKioKKyAgICAgICAgICogTnVtYmVyIG9mIGJ5dGVzIG9mIGVudHJ5IGNvbnRlbnQgcmVhZCBmcm9tIHRoZSBzdHJlYW0uCisgICAgICAgICAqCisgICAgICAgICAqIDxwPlRoaXMgbWF5IGJlIG1vcmUgdGhhbiB0aGUgYWN0dWFsIGVudHJ5J3MgbGVuZ3RoIGFzIHNvbWUKKyAgICAgICAgICogc3R1ZmYgZ2V0cyBidWZmZXJlZCB1cCBhbmQgbmVlZHMgdG8gYmUgcHVzaGVkIGJhY2sgd2hlbiB0aGUKKyAgICAgICAgICogZW5kIG9mIHRoZSBlbnRyeSBoYXMgYmVlbiByZWFjaGVkLjwvcD4KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgbG9uZyBieXRlc1JlYWRGcm9tU3RyZWFtOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgY2hlY2tzdW0gY2FsY3VsYXRlZCBhcyB0aGUgY3VycmVudCBlbnRyeSBpcyByZWFkLgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBDUkMzMiBjcmMgPSBuZXcgQ1JDMzIoKTsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIGlucHV0IHN0cmVhbSBkZWNvbXByZXNzaW5nIHRoZSBkYXRhIGZvciBzaHJ1bmsgYW5kIGltcGxvZGVkIGVudHJpZXMuCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIElucHV0U3RyZWFtIGluOworICAgIH0KKworICAgIC8qKgorICAgICAqIEJvdW5kZWQgaW5wdXQgc3RyZWFtIGFkYXB0ZWQgZnJvbSBjb21tb25zLWlvCisgICAgICovCisgICAgcHJpdmF0ZSBjbGFzcyBCb3VuZGVkSW5wdXRTdHJlYW0gZXh0ZW5kcyBJbnB1dFN0cmVhbSB7CisKKyAgICAgICAgLyoqIHRoZSB3cmFwcGVkIGlucHV0IHN0cmVhbSAqLworICAgICAgICBwcml2YXRlIGZpbmFsIElucHV0U3RyZWFtIGluOworCisgICAgICAgIC8qKiB0aGUgbWF4IGxlbmd0aCB0byBwcm92aWRlICovCisgICAgICAgIHByaXZhdGUgZmluYWwgbG9uZyBtYXg7CisKKyAgICAgICAgLyoqIHRoZSBudW1iZXIgb2YgYnl0ZXMgYWxyZWFkeSByZXR1cm5lZCAqLworICAgICAgICBwcml2YXRlIGxvbmcgcG9zID0gMDsKKworICAgICAgICAvKioKKyAgICAgICAgICogQ3JlYXRlcyBhIG5ldyA8Y29kZT5Cb3VuZGVkSW5wdXRTdHJlYW08L2NvZGU+IHRoYXQgd3JhcHMgdGhlIGdpdmVuIGlucHV0CisgICAgICAgICAqIHN0cmVhbSBhbmQgbGltaXRzIGl0IHRvIGEgY2VydGFpbiBzaXplLgorICAgICAgICAgKgorICAgICAgICAgKiBAcGFyYW0gaW4gVGhlIHdyYXBwZWQgaW5wdXQgc3RyZWFtCisgICAgICAgICAqIEBwYXJhbSBzaXplIFRoZSBtYXhpbXVtIG51bWJlciBvZiBieXRlcyB0byByZXR1cm4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBCb3VuZGVkSW5wdXRTdHJlYW0oZmluYWwgSW5wdXRTdHJlYW0gaW4sIGZpbmFsIGxvbmcgc2l6ZSkgeworICAgICAgICAgICAgdGhpcy5tYXggPSBzaXplOworICAgICAgICAgICAgdGhpcy5pbiA9IGluOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBpZiAobWF4ID49IDAgJiYgcG9zID49IG1heCkgeworICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZpbmFsIGludCByZXN1bHQgPSBpbi5yZWFkKCk7CisgICAgICAgICAgICBwb3MrKzsKKyAgICAgICAgICAgIGNvdW50KDEpOworICAgICAgICAgICAgY3VycmVudC5ieXRlc1JlYWRGcm9tU3RyZWFtKys7CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBpbnQgcmVhZChmaW5hbCBieXRlW10gYikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiB0aGlzLnJlYWQoYiwgMCwgYi5sZW5ndGgpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBpbnQgcmVhZChmaW5hbCBieXRlW10gYiwgZmluYWwgaW50IG9mZiwgZmluYWwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGlmIChtYXggPj0gMCAmJiBwb3MgPj0gbWF4KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZmluYWwgbG9uZyBtYXhSZWFkID0gbWF4ID49IDAgPyBNYXRoLm1pbihsZW4sIG1heCAtIHBvcykgOiBsZW47CisgICAgICAgICAgICBmaW5hbCBpbnQgYnl0ZXNSZWFkID0gaW4ucmVhZChiLCBvZmYsIChpbnQpIG1heFJlYWQpOworCisgICAgICAgICAgICBpZiAoYnl0ZXNSZWFkID09IC0xKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwb3MgKz0gYnl0ZXNSZWFkOworICAgICAgICAgICAgY291bnQoYnl0ZXNSZWFkKTsKKyAgICAgICAgICAgIGN1cnJlbnQuYnl0ZXNSZWFkRnJvbVN0cmVhbSArPSBieXRlc1JlYWQ7CisgICAgICAgICAgICByZXR1cm4gYnl0ZXNSZWFkOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBsb25nIHNraXAoZmluYWwgbG9uZyBuKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgZmluYWwgbG9uZyB0b1NraXAgPSBtYXggPj0gMCA/IE1hdGgubWluKG4sIG1heCAtIHBvcykgOiBuOworICAgICAgICAgICAgZmluYWwgbG9uZyBza2lwcGVkQnl0ZXMgPSBJT1V0aWxzLnNraXAoaW4sIHRvU2tpcCk7CisgICAgICAgICAgICBwb3MgKz0gc2tpcHBlZEJ5dGVzOworICAgICAgICAgICAgcmV0dXJuIHNraXBwZWRCeXRlczsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgaW50IGF2YWlsYWJsZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBpZiAobWF4ID49IDAgJiYgcG9zID49IG1heCkgeworICAgICAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGluLmF2YWlsYWJsZSgpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9aaXBBcmNoaXZlT3V0cHV0U3RyZWFtLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1ppcEFyY2hpdmVPdXRwdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NmFhMGUxCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9aaXBBcmNoaXZlT3V0cHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwxNjk2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5TZWVrYWJsZUJ5dGVDaGFubmVsOworaW1wb3J0IGphdmEubmlvLmZpbGUuRmlsZXM7CitpbXBvcnQgamF2YS5uaW8uZmlsZS5TdGFuZGFyZE9wZW5PcHRpb247CitpbXBvcnQgamF2YS51dGlsLkNhbGVuZGFyOworaW1wb3J0IGphdmEudXRpbC5FbnVtU2V0OworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5MaW5rZWRMaXN0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLnppcC5EZWZsYXRlcjsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLlppcEV4Y2VwdGlvbjsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZUVudHJ5OworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuSU9VdGlsczsKKworaW1wb3J0IHN0YXRpYyBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcC5aaXBDb25zdGFudHMuREFUQV9ERVNDUklQVE9SX01JTl9WRVJTSU9OOworaW1wb3J0IHN0YXRpYyBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcC5aaXBDb25zdGFudHMuREVGTEFURV9NSU5fVkVSU0lPTjsKK2ltcG9ydCBzdGF0aWMgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXAuWmlwQ29uc3RhbnRzLkRXT1JEOworaW1wb3J0IHN0YXRpYyBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcC5aaXBDb25zdGFudHMuSU5JVElBTF9WRVJTSU9OOworaW1wb3J0IHN0YXRpYyBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcC5aaXBDb25zdGFudHMuU0hPUlQ7CitpbXBvcnQgc3RhdGljIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwLlppcENvbnN0YW50cy5XT1JEOworaW1wb3J0IHN0YXRpYyBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcC5aaXBDb25zdGFudHMuWklQNjRfTUFHSUM7CitpbXBvcnQgc3RhdGljIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwLlppcENvbnN0YW50cy5aSVA2NF9NQUdJQ19TSE9SVDsKK2ltcG9ydCBzdGF0aWMgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXAuWmlwQ29uc3RhbnRzLlpJUDY0X01JTl9WRVJTSU9OOworaW1wb3J0IHN0YXRpYyBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcC5aaXBMb25nLnB1dExvbmc7CitpbXBvcnQgc3RhdGljIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwLlppcFNob3J0LnB1dFNob3J0OworCisvKioKKyAqIFJlaW1wbGVtZW50YXRpb24gb2Yge0BsaW5rIGphdmEudXRpbC56aXAuWmlwT3V0cHV0U3RyZWFtCisgKiBqYXZhLnV0aWwuemlwLlppcE91dHB1dFN0cmVhbX0gdGhhdCBkb2VzIGhhbmRsZSB0aGUgZXh0ZW5kZWQKKyAqIGZ1bmN0aW9uYWxpdHkgb2YgdGhpcyBwYWNrYWdlLCBlc3BlY2lhbGx5IGludGVybmFsL2V4dGVybmFsIGZpbGUKKyAqIGF0dHJpYnV0ZXMgYW5kIGV4dHJhIGZpZWxkcyB3aXRoIGRpZmZlcmVudCBsYXlvdXRzIGZvciBsb2NhbCBmaWxlCisgKiBkYXRhIGFuZCBjZW50cmFsIGRpcmVjdG9yeSBlbnRyaWVzLgorICoKKyAqIDxwPlRoaXMgY2xhc3Mgd2lsbCB0cnkgdG8gdXNlIHtAbGluaworICogamF2YS5uaW8uY2hhbm5lbHMuU2Vla2FibGVCeXRlQ2hhbm5lbH0gd2hlbiBpdCBrbm93cyB0aGF0IHRoZQorICogb3V0cHV0IGlzIGdvaW5nIHRvIGdvIHRvIGEgZmlsZS48L3A+CisgKgorICogPHA+SWYgU2Vla2FibGVCeXRlQ2hhbm5lbCBjYW5ub3QgYmUgdXNlZCwgdGhpcyBpbXBsZW1lbnRhdGlvbiB3aWxsIHVzZQorICogYSBEYXRhIERlc2NyaXB0b3IgdG8gc3RvcmUgc2l6ZSBhbmQgQ1JDIGluZm9ybWF0aW9uIGZvciB7QGxpbmsKKyAqICNERUZMQVRFRCBERUZMQVRFRH0gZW50cmllcywgdGhpcyBtZWFucywgeW91IGRvbid0IG5lZWQgdG8KKyAqIGNhbGN1bGF0ZSB0aGVtIHlvdXJzZWxmLiAgVW5mb3J0dW5hdGVseSB0aGlzIGlzIG5vdCBwb3NzaWJsZSBmb3IKKyAqIHRoZSB7QGxpbmsgI1NUT1JFRCBTVE9SRUR9IG1ldGhvZCwgaGVyZSBzZXR0aW5nIHRoZSBDUkMgYW5kCisgKiB1bmNvbXByZXNzZWQgc2l6ZSBpbmZvcm1hdGlvbiBpcyByZXF1aXJlZCBiZWZvcmUge0BsaW5rCisgKiAjcHV0QXJjaGl2ZUVudHJ5KEFyY2hpdmVFbnRyeSl9IGNhbiBiZSBjYWxsZWQuPC9wPgorICoKKyAqIDxwPkFzIG9mIEFwYWNoZSBDb21tb25zIENvbXByZXNzIDEuMyBpdCB0cmFuc3BhcmVudGx5IHN1cHBvcnRzIFppcDY0CisgKiBleHRlbnNpb25zIGFuZCB0aHVzIGluZGl2aWR1YWwgZW50cmllcyBhbmQgYXJjaGl2ZXMgbGFyZ2VyIHRoYW4gNAorICogR0Igb3Igd2l0aCBtb3JlIHRoYW4gNjU1MzYgZW50cmllcyBpbiBtb3N0IGNhc2VzIGJ1dCBleHBsaWNpdAorICogY29udHJvbCBpcyBwcm92aWRlZCB2aWEge0BsaW5rICNzZXRVc2VaaXA2NH0uICBJZiB0aGUgc3RyZWFtIGNhbiBub3QKKyAqIHVzZSBTZWVrYWJsZUJ5dGVDaGFubmVsIGFuZCB5b3UgdHJ5IHRvIHdyaXRlIGEgWmlwQXJjaGl2ZUVudHJ5IG9mCisgKiB1bmtub3duIHNpemUgdGhlbiBaaXA2NCBleHRlbnNpb25zIHdpbGwgYmUgZGlzYWJsZWQgYnkgZGVmYXVsdC48L3A+CisgKgorICogQE5vdFRocmVhZFNhZmUKKyAqLworcHVibGljIGNsYXNzIFppcEFyY2hpdmVPdXRwdXRTdHJlYW0gZXh0ZW5kcyBBcmNoaXZlT3V0cHV0U3RyZWFtIHsKKworICAgIHN0YXRpYyBmaW5hbCBpbnQgQlVGRkVSX1NJWkUgPSA1MTI7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IExGSF9TSUdfT0ZGU0VUID0gMDsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTEZIX1ZFUlNJT05fTkVFREVEX09GRlNFVCA9IDQ7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IExGSF9HUEJfT0ZGU0VUID0gNjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTEZIX01FVEhPRF9PRkZTRVQgPSA4OworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBMRkhfVElNRV9PRkZTRVQgPSAxMDsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTEZIX0NSQ19PRkZTRVQgPSAxNDsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTEZIX0NPTVBSRVNTRURfU0laRV9PRkZTRVQgPSAxODsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTEZIX09SSUdJTkFMX1NJWkVfT0ZGU0VUID0gMjI7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IExGSF9GSUxFTkFNRV9MRU5HVEhfT0ZGU0VUID0gMjY7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IExGSF9FWFRSQV9MRU5HVEhfT0ZGU0VUID0gMjg7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IExGSF9GSUxFTkFNRV9PRkZTRVQgPSAzMDsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQ0ZIX1NJR19PRkZTRVQgPSAwOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBDRkhfVkVSU0lPTl9NQURFX0JZX09GRlNFVCA9IDQ7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IENGSF9WRVJTSU9OX05FRURFRF9PRkZTRVQgPSA2OworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBDRkhfR1BCX09GRlNFVCA9IDg7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IENGSF9NRVRIT0RfT0ZGU0VUID0gMTA7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IENGSF9USU1FX09GRlNFVCA9IDEyOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBDRkhfQ1JDX09GRlNFVCA9IDE2OworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBDRkhfQ09NUFJFU1NFRF9TSVpFX09GRlNFVCA9IDIwOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBDRkhfT1JJR0lOQUxfU0laRV9PRkZTRVQgPSAyNDsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQ0ZIX0ZJTEVOQU1FX0xFTkdUSF9PRkZTRVQgPSAyODsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQ0ZIX0VYVFJBX0xFTkdUSF9PRkZTRVQgPSAzMDsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQ0ZIX0NPTU1FTlRfTEVOR1RIX09GRlNFVCA9IDMyOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBDRkhfRElTS19OVU1CRVJfT0ZGU0VUID0gMzQ7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IENGSF9JTlRFUk5BTF9BVFRSSUJVVEVTX09GRlNFVCA9IDM2OworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBDRkhfRVhURVJOQUxfQVRUUklCVVRFU19PRkZTRVQgPSAzODsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQ0ZIX0xGSF9PRkZTRVQgPSA0MjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQ0ZIX0ZJTEVOQU1FX09GRlNFVCA9IDQ2OworCisgICAgLyoqIGluZGljYXRlcyBpZiB0aGlzIGFyY2hpdmUgaXMgZmluaXNoZWQuIHByb3RlY3RlZCBmb3IgdXNlIGluIEphciBpbXBsZW1lbnRhdGlvbiAqLworICAgIHByb3RlY3RlZCBib29sZWFuIGZpbmlzaGVkID0gZmFsc2U7CisKKyAgICAvKioKKyAgICAgKiBDb21wcmVzc2lvbiBtZXRob2QgZm9yIGRlZmxhdGVkIGVudHJpZXMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREVGTEFURUQgPSBqYXZhLnV0aWwuemlwLlppcEVudHJ5LkRFRkxBVEVEOworCisgICAgLyoqCisgICAgICogRGVmYXVsdCBjb21wcmVzc2lvbiBsZXZlbCBmb3IgZGVmbGF0ZWQgZW50cmllcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX0NPTVBSRVNTSU9OID0gRGVmbGF0ZXIuREVGQVVMVF9DT01QUkVTU0lPTjsKKworICAgIC8qKgorICAgICAqIENvbXByZXNzaW9uIG1ldGhvZCBmb3Igc3RvcmVkIGVudHJpZXMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1RPUkVEID0gamF2YS51dGlsLnppcC5aaXBFbnRyeS5TVE9SRUQ7CisKKyAgICAvKioKKyAgICAgKiBkZWZhdWx0IGVuY29kaW5nIGZvciBmaWxlIG5hbWVzIGFuZCBjb21tZW50LgorICAgICAqLworICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgREVGQVVMVF9FTkNPRElORyA9IFppcEVuY29kaW5nSGVscGVyLlVURjg7CisKKyAgICAvKioKKyAgICAgKiBHZW5lcmFsIHB1cnBvc2UgZmxhZywgd2hpY2ggaW5kaWNhdGVzIHRoYXQgZmlsZW5hbWVzIGFyZQorICAgICAqIHdyaXR0ZW4gaW4gVVRGLTguCisgICAgICogQGRlcHJlY2F0ZWQgdXNlIHtAbGluayBHZW5lcmFsUHVycG9zZUJpdCNVRlQ4X05BTUVTX0ZMQUd9IGluc3RlYWQKKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVGU19GTEFHID0gR2VuZXJhbFB1cnBvc2VCaXQuVUZUOF9OQU1FU19GTEFHOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIEVNUFRZID0gbmV3IGJ5dGVbMF07CisKKyAgICAvKioKKyAgICAgKiBDdXJyZW50IGVudHJ5LgorICAgICAqLworICAgIHByaXZhdGUgQ3VycmVudEVudHJ5IGVudHJ5OworCisgICAgLyoqCisgICAgICogVGhlIGZpbGUgY29tbWVudC4KKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyBjb21tZW50ID0gIiI7CisKKyAgICAvKioKKyAgICAgKiBDb21wcmVzc2lvbiBsZXZlbCBmb3IgbmV4dCBlbnRyeS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBsZXZlbCA9IERFRkFVTFRfQ09NUFJFU1NJT047CisKKyAgICAvKioKKyAgICAgKiBIYXMgdGhlIGNvbXByZXNzaW9uIGxldmVsIGNoYW5nZWQgd2hlbiBjb21wYXJlZCB0byB0aGUgbGFzdAorICAgICAqIGVudHJ5PworICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBoYXNDb21wcmVzc2lvbkxldmVsQ2hhbmdlZCA9IGZhbHNlOworCisgICAgLyoqCisgICAgICogRGVmYXVsdCBjb21wcmVzc2lvbiBtZXRob2QgZm9yIG5leHQgZW50cnkuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgbWV0aG9kID0gamF2YS51dGlsLnppcC5aaXBFbnRyeS5ERUZMQVRFRDsKKworICAgIC8qKgorICAgICAqIExpc3Qgb2YgWmlwQXJjaGl2ZUVudHJpZXMgd3JpdHRlbiBzbyBmYXIuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBMaXN0PFppcEFyY2hpdmVFbnRyeT4gZW50cmllcyA9CisgICAgICAgIG5ldyBMaW5rZWRMaXN0PD4oKTsKKworICAgIHByaXZhdGUgZmluYWwgU3RyZWFtQ29tcHJlc3NvciBzdHJlYW1Db21wcmVzc29yOworCisgICAgLyoqCisgICAgICogU3RhcnQgb2YgY2VudHJhbCBkaXJlY3RvcnkuCisgICAgICovCisgICAgcHJpdmF0ZSBsb25nIGNkT2Zmc2V0ID0gMDsKKworICAgIC8qKgorICAgICAqIExlbmd0aCBvZiBjZW50cmFsIGRpcmVjdG9yeS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGxvbmcgY2RMZW5ndGggPSAwOworCisgICAgLyoqCisgICAgICogSGVscGVyLCBhIDAgYXMgWmlwU2hvcnQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIFpFUk8gPSB7MCwgMH07CisKKyAgICAvKioKKyAgICAgKiBIZWxwZXIsIGEgMCBhcyBaaXBMb25nLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBMWkVSTyA9IHswLCAwLCAwLCAwfTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBPTkUgPSBaaXBMb25nLmdldEJ5dGVzKDFMKTsKKworICAgIC8qKgorICAgICAqIEhvbGRzIHNvbWUgYm9vay1rZWVwaW5nIGRhdGEgZm9yIGVhY2ggZW50cnkuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBNYXA8WmlwQXJjaGl2ZUVudHJ5LCBFbnRyeU1ldGFEYXRhPiBtZXRhRGF0YSA9CisgICAgICAgIG5ldyBIYXNoTWFwPD4oKTsKKworICAgIC8qKgorICAgICAqIFRoZSBlbmNvZGluZyB0byB1c2UgZm9yIGZpbGVuYW1lcyBhbmQgdGhlIGZpbGUgY29tbWVudC4KKyAgICAgKgorICAgICAqIDxwPkZvciBhIGxpc3Qgb2YgcG9zc2libGUgdmFsdWVzIHNlZSA8YQorICAgICAqIGhyZWY9Imh0dHA6Ly9qYXZhLnN1bi5jb20vajJzZS8xLjUuMC9kb2NzL2d1aWRlL2ludGwvZW5jb2RpbmcuZG9jLmh0bWwiPmh0dHA6Ly9qYXZhLnN1bi5jb20vajJzZS8xLjUuMC9kb2NzL2d1aWRlL2ludGwvZW5jb2RpbmcuZG9jLmh0bWw8L2E+LgorICAgICAqIERlZmF1bHRzIHRvIFVURi04LjwvcD4KKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyBlbmNvZGluZyA9IERFRkFVTFRfRU5DT0RJTkc7CisKKyAgICAvKioKKyAgICAgKiBUaGUgemlwIGVuY29kaW5nIHRvIHVzZSBmb3IgZmlsZW5hbWVzIGFuZCB0aGUgZmlsZSBjb21tZW50LgorICAgICAqCisgICAgICogVGhpcyBmaWVsZCBpcyBvZiBpbnRlcm5hbCB1c2UgYW5kIHdpbGwgYmUgc2V0IGluIHtAbGluaworICAgICAqICNzZXRFbmNvZGluZyhTdHJpbmcpfS4KKyAgICAgKi8KKyAgICBwcml2YXRlIFppcEVuY29kaW5nIHppcEVuY29kaW5nID0KKyAgICAgICAgWmlwRW5jb2RpbmdIZWxwZXIuZ2V0WmlwRW5jb2RpbmcoREVGQVVMVF9FTkNPRElORyk7CisKKworICAgIC8qKgorICAgICAqIFRoaXMgRGVmbGF0ZXIgb2JqZWN0IGlzIHVzZWQgZm9yIG91dHB1dC4KKyAgICAgKgorICAgICAqLworICAgIHByb3RlY3RlZCBmaW5hbCBEZWZsYXRlciBkZWY7CisgICAgLyoqCisgICAgICogT3B0aW9uYWwgcmFuZG9tIGFjY2VzcyBvdXRwdXQuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBTZWVrYWJsZUJ5dGVDaGFubmVsIGNoYW5uZWw7CisKKyAgICBwcml2YXRlIGZpbmFsIE91dHB1dFN0cmVhbSBvdXQ7CisKKyAgICAvKioKKyAgICAgKiB3aGV0aGVyIHRvIHVzZSB0aGUgZ2VuZXJhbCBwdXJwb3NlIGJpdCBmbGFnIHdoZW4gd3JpdGluZyBVVEYtOAorICAgICAqIGZpbGVuYW1lcyBvciBub3QuCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIHVzZVVURjhGbGFnID0gdHJ1ZTsKKworICAgIC8qKgorICAgICAqIFdoZXRoZXIgdG8gZW5jb2RlIG5vbi1lbmNvZGFibGUgZmlsZSBuYW1lcyBhcyBVVEYtOC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gZmFsbGJhY2tUb1VURjggPSBmYWxzZTsKKworICAgIC8qKgorICAgICAqIHdoZXRoZXIgdG8gY3JlYXRlIFVuaWNvZGVQYXRoRXh0cmFGaWVsZC1zIGZvciBlYWNoIGVudHJ5LgorICAgICAqLworICAgIHByaXZhdGUgVW5pY29kZUV4dHJhRmllbGRQb2xpY3kgY3JlYXRlVW5pY29kZUV4dHJhRmllbGRzID0gVW5pY29kZUV4dHJhRmllbGRQb2xpY3kuTkVWRVI7CisKKyAgICAvKioKKyAgICAgKiBXaGV0aGVyIGFueXRoaW5nIGluc2lkZSB0aGlzIGFyY2hpdmUgaGFzIHVzZWQgYSBaSVA2NCBmZWF0dXJlLgorICAgICAqCisgICAgICogQHNpbmNlIDEuMworICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBoYXNVc2VkWmlwNjQgPSBmYWxzZTsKKworICAgIHByaXZhdGUgWmlwNjRNb2RlIHppcDY0TW9kZSA9IFppcDY0TW9kZS5Bc05lZWRlZDsKKworICAgIHByaXZhdGUgZmluYWwgYnl0ZVtdIGNvcHlCdWZmZXIgPSBuZXcgYnl0ZVszMjc2OF07CisgICAgcHJpdmF0ZSBmaW5hbCBDYWxlbmRhciBjYWxlbmRhckluc3RhbmNlID0gQ2FsZW5kYXIuZ2V0SW5zdGFuY2UoKTsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgWklQIE91dHB1dFN0cmVhbSBmaWx0ZXJpbmcgdGhlIHVuZGVybHlpbmcgc3RyZWFtLgorICAgICAqIEBwYXJhbSBvdXQgdGhlIG91dHB1dHN0cmVhbSB0byB6aXAKKyAgICAgKi8KKyAgICBwdWJsaWMgWmlwQXJjaGl2ZU91dHB1dFN0cmVhbShmaW5hbCBPdXRwdXRTdHJlYW0gb3V0KSB7CisgICAgICAgIHRoaXMub3V0ID0gb3V0OworICAgICAgICB0aGlzLmNoYW5uZWwgPSBudWxsOworICAgICAgICBkZWYgPSBuZXcgRGVmbGF0ZXIobGV2ZWwsIHRydWUpOworICAgICAgICBzdHJlYW1Db21wcmVzc29yID0gU3RyZWFtQ29tcHJlc3Nvci5jcmVhdGUob3V0LCBkZWYpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgWklQIE91dHB1dFN0cmVhbSB3cml0aW5nIHRvIGEgRmlsZS4gIFdpbGwgdXNlCisgICAgICogcmFuZG9tIGFjY2VzcyBpZiBwb3NzaWJsZS4KKyAgICAgKiBAcGFyYW0gZmlsZSB0aGUgZmlsZSB0byB6aXAgdG8KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIG9uIGVycm9yCisgICAgICovCisgICAgcHVibGljIFppcEFyY2hpdmVPdXRwdXRTdHJlYW0oZmluYWwgRmlsZSBmaWxlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBkZWYgPSBuZXcgRGVmbGF0ZXIobGV2ZWwsIHRydWUpOworICAgICAgICBPdXRwdXRTdHJlYW0gbyA9IG51bGw7CisgICAgICAgIFNlZWthYmxlQnl0ZUNoYW5uZWwgX2NoYW5uZWwgPSBudWxsOworICAgICAgICBTdHJlYW1Db21wcmVzc29yIF9zdHJlYW1Db21wcmVzc29yID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIF9jaGFubmVsID0gRmlsZXMubmV3Qnl0ZUNoYW5uZWwoZmlsZS50b1BhdGgoKSwKKyAgICAgICAgICAgICAgICBFbnVtU2V0Lm9mKFN0YW5kYXJkT3Blbk9wdGlvbi5DUkVBVEUsIFN0YW5kYXJkT3Blbk9wdGlvbi5XUklURSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0YW5kYXJkT3Blbk9wdGlvbi5SRUFELAorICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RhbmRhcmRPcGVuT3B0aW9uLlRSVU5DQVRFX0VYSVNUSU5HKSk7CisgICAgICAgICAgICAvLyB3aWxsIG5ldmVyIGdldCBvcGVuZWQgcHJvcGVybHkgd2hlbiBhbiBleGNlcHRpb24gaXMgdGhyb3duIHNvIGRvZXNuJ3QgbmVlZCB0byBnZXQgY2xvc2VkCisgICAgICAgICAgICBfc3RyZWFtQ29tcHJlc3NvciA9IFN0cmVhbUNvbXByZXNzb3IuY3JlYXRlKF9jaGFubmVsLCBkZWYpOyAvL05PU09OQVIKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgSU9VdGlscy5jbG9zZVF1aWV0bHkoX2NoYW5uZWwpOworICAgICAgICAgICAgX2NoYW5uZWwgPSBudWxsOworICAgICAgICAgICAgbyA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKGZpbGUpOworICAgICAgICAgICAgX3N0cmVhbUNvbXByZXNzb3IgPSBTdHJlYW1Db21wcmVzc29yLmNyZWF0ZShvLCBkZWYpOworICAgICAgICB9CisgICAgICAgIG91dCA9IG87CisgICAgICAgIGNoYW5uZWwgPSBfY2hhbm5lbDsKKyAgICAgICAgc3RyZWFtQ29tcHJlc3NvciA9IF9zdHJlYW1Db21wcmVzc29yOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgWklQIE91dHB1dFN0cmVhbSB3cml0aW5nIHRvIGEgU2Vla2FibGVCeXRlQ2hhbm5lbC4KKyAgICAgKgorICAgICAqIDxwPntAbGluaworICAgICAqIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5TZWVrYWJsZUluTWVtb3J5Qnl0ZUNoYW5uZWx9CisgICAgICogYWxsb3dzIHlvdSB0byB3cml0ZSB0byBhbiBpbi1tZW1vcnkgYXJjaGl2ZSB1c2luZyByYW5kb20KKyAgICAgKiBhY2Nlc3MuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGNoYW5uZWwgdGhlIGNoYW5uZWwgdG8gemlwIHRvCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBvbiBlcnJvcgorICAgICAqIEBzaW5jZSAxLjEzCisgICAgICovCisgICAgcHVibGljIFppcEFyY2hpdmVPdXRwdXRTdHJlYW0oU2Vla2FibGVCeXRlQ2hhbm5lbCBjaGFubmVsKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzLmNoYW5uZWwgPSBjaGFubmVsOworICAgICAgICBkZWYgPSBuZXcgRGVmbGF0ZXIobGV2ZWwsIHRydWUpOworICAgICAgICBzdHJlYW1Db21wcmVzc29yID0gU3RyZWFtQ29tcHJlc3Nvci5jcmVhdGUoY2hhbm5lbCwgZGVmKTsKKyAgICAgICAgb3V0ID0gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBpbmRpY2F0ZXMgd2hldGhlciB0aGlzIGFyY2hpdmUgaXMgd3JpdGluZyB0byBhCisgICAgICogc2Vla2FibGUgc3RyZWFtIChpLmUuLCB0byBhIHJhbmRvbSBhY2Nlc3MgZmlsZSkuCisgICAgICoKKyAgICAgKiA8cD5Gb3Igc2Vla2FibGUgc3RyZWFtcywgeW91IGRvbid0IG5lZWQgdG8gY2FsY3VsYXRlIHRoZSBDUkMgb3IKKyAgICAgKiB1bmNvbXByZXNzZWQgc2l6ZSBmb3Ige0BsaW5rICNTVE9SRUR9IGVudHJpZXMgYmVmb3JlCisgICAgICogaW52b2tpbmcge0BsaW5rICNwdXRBcmNoaXZlRW50cnkoQXJjaGl2ZUVudHJ5KX0uCisgICAgICogQHJldHVybiB0cnVlIGlmIHNlZWthYmxlCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNTZWVrYWJsZSgpIHsKKyAgICAgICAgcmV0dXJuIGNoYW5uZWwgIT0gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgZW5jb2RpbmcgdG8gdXNlIGZvciBmaWxlbmFtZXMgYW5kIHRoZSBmaWxlIGNvbW1lbnQuCisgICAgICoKKyAgICAgKiA8cD5Gb3IgYSBsaXN0IG9mIHBvc3NpYmxlIHZhbHVlcyBzZWUgPGEKKyAgICAgKiBocmVmPSJodHRwOi8vamF2YS5zdW4uY29tL2oyc2UvMS41LjAvZG9jcy9ndWlkZS9pbnRsL2VuY29kaW5nLmRvYy5odG1sIj5odHRwOi8vamF2YS5zdW4uY29tL2oyc2UvMS41LjAvZG9jcy9ndWlkZS9pbnRsL2VuY29kaW5nLmRvYy5odG1sPC9hPi4KKyAgICAgKiBEZWZhdWx0cyB0byBVVEYtOC48L3A+CisgICAgICogQHBhcmFtIGVuY29kaW5nIHRoZSBlbmNvZGluZyB0byB1c2UgZm9yIGZpbGUgbmFtZXMsIHVzZSBudWxsCisgICAgICogZm9yIHRoZSBwbGF0Zm9ybSdzIGRlZmF1bHQgZW5jb2RpbmcKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRFbmNvZGluZyhmaW5hbCBTdHJpbmcgZW5jb2RpbmcpIHsKKyAgICAgICAgdGhpcy5lbmNvZGluZyA9IGVuY29kaW5nOworICAgICAgICB0aGlzLnppcEVuY29kaW5nID0gWmlwRW5jb2RpbmdIZWxwZXIuZ2V0WmlwRW5jb2RpbmcoZW5jb2RpbmcpOworICAgICAgICBpZiAodXNlVVRGOEZsYWcgJiYgIVppcEVuY29kaW5nSGVscGVyLmlzVVRGOChlbmNvZGluZykpIHsKKyAgICAgICAgICAgIHVzZVVURjhGbGFnID0gZmFsc2U7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgZW5jb2RpbmcgdG8gdXNlIGZvciBmaWxlbmFtZXMgYW5kIHRoZSBmaWxlIGNvbW1lbnQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIG51bGwgaWYgdXNpbmcgdGhlIHBsYXRmb3JtJ3MgZGVmYXVsdCBjaGFyYWN0ZXIgZW5jb2RpbmcuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRFbmNvZGluZygpIHsKKyAgICAgICAgcmV0dXJuIGVuY29kaW5nOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdoZXRoZXIgdG8gc2V0IHRoZSBsYW5ndWFnZSBlbmNvZGluZyBmbGFnIGlmIHRoZSBmaWxlIG5hbWUKKyAgICAgKiBlbmNvZGluZyBpcyBVVEYtOC4KKyAgICAgKgorICAgICAqIDxwPkRlZmF1bHRzIHRvIHRydWUuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGIgd2hldGhlciB0byBzZXQgdGhlIGxhbmd1YWdlIGVuY29kaW5nIGZsYWcgaWYgdGhlIGZpbGUKKyAgICAgKiBuYW1lIGVuY29kaW5nIGlzIFVURi04CisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0VXNlTGFuZ3VhZ2VFbmNvZGluZ0ZsYWcoZmluYWwgYm9vbGVhbiBiKSB7CisgICAgICAgIHVzZVVURjhGbGFnID0gYiAmJiBaaXBFbmNvZGluZ0hlbHBlci5pc1VURjgoZW5jb2RpbmcpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdoZXRoZXIgdG8gY3JlYXRlIFVuaWNvZGUgRXh0cmEgRmllbGRzLgorICAgICAqCisgICAgICogPHA+RGVmYXVsdHMgdG8gTkVWRVIuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGIgd2hldGhlciB0byBjcmVhdGUgVW5pY29kZSBFeHRyYSBGaWVsZHMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Q3JlYXRlVW5pY29kZUV4dHJhRmllbGRzKGZpbmFsIFVuaWNvZGVFeHRyYUZpZWxkUG9saWN5IGIpIHsKKyAgICAgICAgY3JlYXRlVW5pY29kZUV4dHJhRmllbGRzID0gYjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXaGV0aGVyIHRvIGZhbGwgYmFjayB0byBVVEYgYW5kIHRoZSBsYW5ndWFnZSBlbmNvZGluZyBmbGFnIGlmCisgICAgICogdGhlIGZpbGUgbmFtZSBjYW5ub3QgYmUgZW5jb2RlZCB1c2luZyB0aGUgc3BlY2lmaWVkIGVuY29kaW5nLgorICAgICAqCisgICAgICogPHA+RGVmYXVsdHMgdG8gZmFsc2UuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGIgd2hldGhlciB0byBmYWxsIGJhY2sgdG8gVVRGIGFuZCB0aGUgbGFuZ3VhZ2UgZW5jb2RpbmcKKyAgICAgKiBmbGFnIGlmIHRoZSBmaWxlIG5hbWUgY2Fubm90IGJlIGVuY29kZWQgdXNpbmcgdGhlIHNwZWNpZmllZAorICAgICAqIGVuY29kaW5nLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEZhbGxiYWNrVG9VVEY4KGZpbmFsIGJvb2xlYW4gYikgeworICAgICAgICBmYWxsYmFja1RvVVRGOCA9IGI7CisgICAgfQorCisgICAgLyoqCisgICAgICogV2hldGhlciBaaXA2NCBleHRlbnNpb25zIHdpbGwgYmUgdXNlZC4KKyAgICAgKgorICAgICAqIDxwPldoZW4gc2V0dGluZyB0aGUgbW9kZSB0byB7QGxpbmsgWmlwNjRNb2RlI05ldmVyIE5ldmVyfSwKKyAgICAgKiB7QGxpbmsgI3B1dEFyY2hpdmVFbnRyeX0sIHtAbGluayAjY2xvc2VBcmNoaXZlRW50cnl9LCB7QGxpbmsKKyAgICAgKiAjZmluaXNofSBvciB7QGxpbmsgI2Nsb3NlfSBtYXkgdGhyb3cgYSB7QGxpbmsKKyAgICAgKiBaaXA2NFJlcXVpcmVkRXhjZXB0aW9ufSBpZiB0aGUgZW50cnkncyBzaXplIG9yIHRoZSB0b3RhbCBzaXplCisgICAgICogb2YgdGhlIGFyY2hpdmUgZXhjZWVkcyA0R0Igb3IgdGhlcmUgYXJlIG1vcmUgdGhhbiA2NTUzNiBlbnRyaWVzCisgICAgICogaW5zaWRlIHRoZSBhcmNoaXZlLiAgQW55IGFyY2hpdmUgY3JlYXRlZCBpbiB0aGlzIG1vZGUgd2lsbCBiZQorICAgICAqIHJlYWRhYmxlIGJ5IGltcGxlbWVudGF0aW9ucyB0aGF0IGRvbid0IHN1cHBvcnQgWmlwNjQuPC9wPgorICAgICAqCisgICAgICogPHA+V2hlbiBzZXR0aW5nIHRoZSBtb2RlIHRvIHtAbGluayBaaXA2NE1vZGUjQWx3YXlzIEFsd2F5c30sCisgICAgICogWmlwNjQgZXh0ZW5zaW9ucyB3aWxsIGJlIHVzZWQgZm9yIGFsbCBlbnRyaWVzLiAgQW55IGFyY2hpdmUKKyAgICAgKiBjcmVhdGVkIGluIHRoaXMgbW9kZSBtYXkgYmUgdW5yZWFkYWJsZSBieSBpbXBsZW1lbnRhdGlvbnMgdGhhdAorICAgICAqIGRvbid0IHN1cHBvcnQgWmlwNjQgZXZlbiBpZiBhbGwgaXRzIGNvbnRlbnRzIHdvdWxkIGJlLjwvcD4KKyAgICAgKgorICAgICAqIDxwPldoZW4gc2V0dGluZyB0aGUgbW9kZSB0byB7QGxpbmsgWmlwNjRNb2RlI0FzTmVlZGVkCisgICAgICogQXNOZWVkZWR9LCBaaXA2NCBleHRlbnNpb25zIHdpbGwgdHJhbnNwYXJlbnRseSBiZSB1c2VkIGZvcgorICAgICAqIHRob3NlIGVudHJpZXMgdGhhdCByZXF1aXJlIHRoZW0uICBUaGlzIG1vZGUgY2FuIG9ubHkgYmUgdXNlZCBpZgorICAgICAqIHRoZSB1bmNvbXByZXNzZWQgc2l6ZSBvZiB0aGUge0BsaW5rIFppcEFyY2hpdmVFbnRyeX0gaXMga25vd24KKyAgICAgKiB3aGVuIGNhbGxpbmcge0BsaW5rICNwdXRBcmNoaXZlRW50cnl9IG9yIHRoZSBhcmNoaXZlIGlzIHdyaXR0ZW4KKyAgICAgKiB0byBhIHNlZWthYmxlIG91dHB1dCAoaS5lLiB5b3UgaGF2ZSB1c2VkIHRoZSB7QGxpbmsKKyAgICAgKiAjWmlwQXJjaGl2ZU91dHB1dFN0cmVhbShqYXZhLmlvLkZpbGUpIEZpbGUtYXJnIGNvbnN0cnVjdG9yfSkgLQorICAgICAqIHRoaXMgbW9kZSBpcyBub3QgdmFsaWQgd2hlbiB0aGUgb3V0cHV0IHN0cmVhbSBpcyBub3Qgc2Vla2FibGUKKyAgICAgKiBhbmQgdGhlIHVuY29tcHJlc3NlZCBzaXplIGlzIHVua25vd24gd2hlbiB7QGxpbmsKKyAgICAgKiAjcHV0QXJjaGl2ZUVudHJ5fSBpcyBjYWxsZWQuPC9wPgorICAgICAqCisgICAgICogPHA+SWYgbm8gZW50cnkgaW5zaWRlIHRoZSByZXN1bHRpbmcgYXJjaGl2ZSByZXF1aXJlcyBaaXA2NAorICAgICAqIGV4dGVuc2lvbnMgdGhlbiB7QGxpbmsgWmlwNjRNb2RlI05ldmVyIE5ldmVyfSB3aWxsIGNyZWF0ZSB0aGUKKyAgICAgKiBzbWFsbGVzdCBhcmNoaXZlLiAge0BsaW5rIFppcDY0TW9kZSNBc05lZWRlZCBBc05lZWRlZH0gd2lsbAorICAgICAqIGNyZWF0ZSBhIHNsaWdodGx5IGJpZ2dlciBhcmNoaXZlIGlmIHRoZSB1bmNvbXByZXNzZWQgc2l6ZSBvZgorICAgICAqIGFueSBlbnRyeSBoYXMgaW5pdGlhbGx5IGJlZW4gdW5rbm93biBhbmQgY3JlYXRlIGFuIGFyY2hpdmUKKyAgICAgKiBpZGVudGljYWwgdG8ge0BsaW5rIFppcDY0TW9kZSNOZXZlciBOZXZlcn0gb3RoZXJ3aXNlLiAge0BsaW5rCisgICAgICogWmlwNjRNb2RlI0Fsd2F5cyBBbHdheXN9IHdpbGwgY3JlYXRlIGFuIGFyY2hpdmUgdGhhdCBpcyBhdAorICAgICAqIGxlYXN0IDI0IGJ5dGVzIHBlciBlbnRyeSBiaWdnZXIgdGhhbiB0aGUgb25lIHtAbGluaworICAgICAqIFppcDY0TW9kZSNOZXZlciBOZXZlcn0gd291bGQgY3JlYXRlLjwvcD4KKyAgICAgKgorICAgICAqIDxwPkRlZmF1bHRzIHRvIHtAbGluayBaaXA2NE1vZGUjQXNOZWVkZWQgQXNOZWVkZWR9IHVubGVzcworICAgICAqIHtAbGluayAjcHV0QXJjaGl2ZUVudHJ5fSBpcyBjYWxsZWQgd2l0aCBhbiBlbnRyeSBvZiB1bmtub3duCisgICAgICogc2l6ZSBhbmQgZGF0YSBpcyB3cml0dGVuIHRvIGEgbm9uLXNlZWthYmxlIHN0cmVhbSAtIGluIHRoaXMKKyAgICAgKiBjYXNlIHRoZSBkZWZhdWx0IGlzIHtAbGluayBaaXA2NE1vZGUjTmV2ZXIgTmV2ZXJ9LjwvcD4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjMKKyAgICAgKiBAcGFyYW0gbW9kZSBXaGV0aGVyIFppcDY0IGV4dGVuc2lvbnMgd2lsbCBiZSB1c2VkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFVzZVppcDY0KGZpbmFsIFppcDY0TW9kZSBtb2RlKSB7CisgICAgICAgIHppcDY0TW9kZSA9IG1vZGU7CisgICAgfQorCisgICAgLyoqCisgICAgICoge0Bpbmhlcml0RG9jfQorICAgICAqIEB0aHJvd3MgWmlwNjRSZXF1aXJlZEV4Y2VwdGlvbiBpZiB0aGUgYXJjaGl2ZSdzIHNpemUgZXhjZWVkcyA0CisgICAgICogR0J5dGUgb3IgdGhlcmUgYXJlIG1vcmUgdGhhbiA2NTUzNSBlbnRyaWVzIGluc2lkZSB0aGUgYXJjaGl2ZQorICAgICAqIGFuZCB7QGxpbmsgI3NldFVzZVppcDY0fSBpcyB7QGxpbmsgWmlwNjRNb2RlI05ldmVyfS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBmaW5pc2goKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoZmluaXNoZWQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiVGhpcyBhcmNoaXZlIGhhcyBhbHJlYWR5IGJlZW4gZmluaXNoZWQiKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChlbnRyeSAhPSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlRoaXMgYXJjaGl2ZSBjb250YWlucyB1bmNsb3NlZCBlbnRyaWVzLiIpOworICAgICAgICB9CisKKyAgICAgICAgY2RPZmZzZXQgPSBzdHJlYW1Db21wcmVzc29yLmdldFRvdGFsQnl0ZXNXcml0dGVuKCk7CisgICAgICAgIHdyaXRlQ2VudHJhbERpcmVjdG9yeUluQ2h1bmtzKCk7CisKKyAgICAgICAgY2RMZW5ndGggPSBzdHJlYW1Db21wcmVzc29yLmdldFRvdGFsQnl0ZXNXcml0dGVuKCkgLSBjZE9mZnNldDsKKyAgICAgICAgd3JpdGVaaXA2NENlbnRyYWxEaXJlY3RvcnkoKTsKKyAgICAgICAgd3JpdGVDZW50cmFsRGlyZWN0b3J5RW5kKCk7CisgICAgICAgIG1ldGFEYXRhLmNsZWFyKCk7CisgICAgICAgIGVudHJpZXMuY2xlYXIoKTsKKyAgICAgICAgc3RyZWFtQ29tcHJlc3Nvci5jbG9zZSgpOworICAgICAgICBmaW5pc2hlZCA9IHRydWU7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlQ2VudHJhbERpcmVjdG9yeUluQ2h1bmtzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgaW50IE5VTV9QRVJfV1JJVEUgPSAxMDAwOworICAgICAgICBmaW5hbCBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYnl0ZUFycmF5T3V0cHV0U3RyZWFtID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSg3MCAqIE5VTV9QRVJfV1JJVEUpOworICAgICAgICBpbnQgY291bnQgPSAwOworICAgICAgICBmb3IgKGZpbmFsIFppcEFyY2hpdmVFbnRyeSB6ZSA6IGVudHJpZXMpIHsKKyAgICAgICAgICAgIGJ5dGVBcnJheU91dHB1dFN0cmVhbS53cml0ZShjcmVhdGVDZW50cmFsRmlsZUhlYWRlcih6ZSkpOworICAgICAgICAgICAgaWYgKCsrY291bnQgPiBOVU1fUEVSX1dSSVRFKXsKKyAgICAgICAgICAgICAgICB3cml0ZUNvdW50ZWQoYnl0ZUFycmF5T3V0cHV0U3RyZWFtLnRvQnl0ZUFycmF5KCkpOworICAgICAgICAgICAgICAgIGJ5dGVBcnJheU91dHB1dFN0cmVhbS5yZXNldCgpOworICAgICAgICAgICAgICAgIGNvdW50ID0gMDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICB3cml0ZUNvdW50ZWQoYnl0ZUFycmF5T3V0cHV0U3RyZWFtLnRvQnl0ZUFycmF5KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyBhbGwgbmVjZXNzYXJ5IGRhdGEgZm9yIHRoaXMgZW50cnkuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBvbiBlcnJvcgorICAgICAqIEB0aHJvd3MgWmlwNjRSZXF1aXJlZEV4Y2VwdGlvbiBpZiB0aGUgZW50cnkncyB1bmNvbXByZXNzZWQgb3IKKyAgICAgKiBjb21wcmVzc2VkIHNpemUgZXhjZWVkcyA0IEdCeXRlIGFuZCB7QGxpbmsgI3NldFVzZVppcDY0fQorICAgICAqIGlzIHtAbGluayBaaXA2NE1vZGUjTmV2ZXJ9LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlQXJjaGl2ZUVudHJ5KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcHJlQ2xvc2UoKTsKKworICAgICAgICBmbHVzaERlZmxhdGVyKCk7CisKKyAgICAgICAgZmluYWwgbG9uZyBieXRlc1dyaXR0ZW4gPSBzdHJlYW1Db21wcmVzc29yLmdldFRvdGFsQnl0ZXNXcml0dGVuKCkgLSBlbnRyeS5kYXRhU3RhcnQ7CisgICAgICAgIGZpbmFsIGxvbmcgcmVhbENyYyA9IHN0cmVhbUNvbXByZXNzb3IuZ2V0Q3JjMzIoKTsKKyAgICAgICAgZW50cnkuYnl0ZXNSZWFkID0gc3RyZWFtQ29tcHJlc3Nvci5nZXRCeXRlc1JlYWQoKTsKKyAgICAgICAgZmluYWwgWmlwNjRNb2RlIGVmZmVjdGl2ZU1vZGUgPSBnZXRFZmZlY3RpdmVaaXA2NE1vZGUoZW50cnkuZW50cnkpOworICAgICAgICBmaW5hbCBib29sZWFuIGFjdHVhbGx5TmVlZHNaaXA2NCA9IGhhbmRsZVNpemVzQW5kQ3JjKGJ5dGVzV3JpdHRlbiwgcmVhbENyYywgZWZmZWN0aXZlTW9kZSk7CisgICAgICAgIGNsb3NlRW50cnkoYWN0dWFsbHlOZWVkc1ppcDY0LCBmYWxzZSk7CisgICAgICAgIHN0cmVhbUNvbXByZXNzb3IucmVzZXQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgYWxsIG5lY2Vzc2FyeSBkYXRhIGZvciB0aGlzIGVudHJ5LgorICAgICAqCisgICAgICogQHBhcmFtIHBoYXNlZCAgICAgICAgICAgICAgVGhpcyBlbnRyeSBpcyBzZWNvbmQgcGhhc2Ugb2YgYSAyLXBoYXNlIHppcCBjcmVhdGlvbiwgc2l6ZSwgY29tcHJlc3NlZCBzaXplIGFuZCBjcmMKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmUga25vd24gaW4gWmlwQXJjaGl2ZUVudHJ5CisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiAgICAgICAgICAgIG9uIGVycm9yCisgICAgICogQHRocm93cyBaaXA2NFJlcXVpcmVkRXhjZXB0aW9uIGlmIHRoZSBlbnRyeSdzIHVuY29tcHJlc3NlZCBvcgorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wcmVzc2VkIHNpemUgZXhjZWVkcyA0IEdCeXRlIGFuZCB7QGxpbmsgI3NldFVzZVppcDY0fQorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpcyB7QGxpbmsgWmlwNjRNb2RlI05ldmVyfS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgY2xvc2VDb3BpZWRFbnRyeShmaW5hbCBib29sZWFuIHBoYXNlZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcHJlQ2xvc2UoKTsKKyAgICAgICAgZW50cnkuYnl0ZXNSZWFkID0gZW50cnkuZW50cnkuZ2V0U2l6ZSgpOworICAgICAgICBmaW5hbCBaaXA2NE1vZGUgZWZmZWN0aXZlTW9kZSA9IGdldEVmZmVjdGl2ZVppcDY0TW9kZShlbnRyeS5lbnRyeSk7CisgICAgICAgIGZpbmFsIGJvb2xlYW4gYWN0dWFsbHlOZWVkc1ppcDY0ID0gY2hlY2tJZk5lZWRzWmlwNjQoZWZmZWN0aXZlTW9kZSk7CisgICAgICAgIGNsb3NlRW50cnkoYWN0dWFsbHlOZWVkc1ppcDY0LCBwaGFzZWQpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBjbG9zZUVudHJ5KGZpbmFsIGJvb2xlYW4gYWN0dWFsbHlOZWVkc1ppcDY0LCBmaW5hbCBib29sZWFuIHBoYXNlZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFwaGFzZWQgJiYgY2hhbm5lbCAhPSBudWxsKSB7CisgICAgICAgICAgICByZXdyaXRlU2l6ZXNBbmRDcmMoYWN0dWFsbHlOZWVkc1ppcDY0KTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICghcGhhc2VkKSB7CisgICAgICAgICAgICB3cml0ZURhdGFEZXNjcmlwdG9yKGVudHJ5LmVudHJ5KTsKKyAgICAgICAgfQorICAgICAgICBlbnRyeSA9IG51bGw7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHByZUNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGZpbmlzaGVkKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlN0cmVhbSBoYXMgYWxyZWFkeSBiZWVuIGZpbmlzaGVkIik7CisgICAgICAgIH0KKworICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJObyBjdXJyZW50IGVudHJ5IHRvIGNsb3NlIik7CisgICAgICAgIH0KKworICAgICAgICBpZiAoIWVudHJ5Lmhhc1dyaXR0ZW4pIHsKKyAgICAgICAgICAgIHdyaXRlKEVNUFRZLCAwLCAwKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgYW4gYXJjaGl2ZSBlbnRyeSB3aXRoIGEgcmF3IGlucHV0IHN0cmVhbS4KKyAgICAgKgorICAgICAqIElmIGNyYywgc2l6ZSBhbmQgY29tcHJlc3NlZCBzaXplIGFyZSBzdXBwbGllZCBvbiB0aGUgZW50cnksIHRoZXNlIHZhbHVlcyB3aWxsIGJlIHVzZWQgYXMtaXMuCisgICAgICogWmlwNjQgc3RhdHVzIGlzIHJlLWVzdGFibGlzaGVkIGJhc2VkIG9uIHRoZSBzZXR0aW5ncyBpbiB0aGlzIHN0cmVhbSwgYW5kIHRoZSBzdXBwbGllZCB2YWx1ZQorICAgICAqIGlzIGlnbm9yZWQuCisgICAgICoKKyAgICAgKiBUaGUgZW50cnkgaXMgcHV0IGFuZCBjbG9zZWQgaW1tZWRpYXRlbHkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZW50cnkgVGhlIGFyY2hpdmUgZW50cnkgdG8gYWRkCisgICAgICogQHBhcmFtIHJhd1N0cmVhbSBUaGUgcmF3IGlucHV0IHN0cmVhbSBvZiBhIGRpZmZlcmVudCBlbnRyeS4gTWF5IGJlIGNvbXByZXNzZWQvZW5jcnlwdGVkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gSWYgY29weWluZyBmYWlscworICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFkZFJhd0FyY2hpdmVFbnRyeShmaW5hbCBaaXBBcmNoaXZlRW50cnkgZW50cnksIGZpbmFsIElucHV0U3RyZWFtIHJhd1N0cmVhbSkKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFppcEFyY2hpdmVFbnRyeSBhZSA9IG5ldyBaaXBBcmNoaXZlRW50cnkoZW50cnkpOworICAgICAgICBpZiAoaGFzWmlwNjRFeHRyYShhZSkpIHsKKyAgICAgICAgICAgIC8vIFdpbGwgYmUgcmUtYWRkZWQgYXMgcmVxdWlyZWQuIHRoaXMgbWF5IG1ha2UgdGhlIGZpbGUgZ2VuZXJhdGVkIHdpdGggdGhpcyBtZXRob2QKKyAgICAgICAgICAgIC8vIHNvbWV3aGF0IHNtYWxsZXIgdGhhbiBzdGFuZGFyZCBtb2RlLAorICAgICAgICAgICAgLy8gc2luY2Ugc3RhbmRhcmQgbW9kZSBpcyB1bmFibGUgdG8gcmVtb3ZlIHRoZSB6aXAgNjQgaGVhZGVyLgorICAgICAgICAgICAgYWUucmVtb3ZlRXh0cmFGaWVsZChaaXA2NEV4dGVuZGVkSW5mb3JtYXRpb25FeHRyYUZpZWxkLkhFQURFUl9JRCk7CisgICAgICAgIH0KKyAgICAgICAgZmluYWwgYm9vbGVhbiBpczJQaGFzZVNvdXJjZSA9IGFlLmdldENyYygpICE9IFppcEFyY2hpdmVFbnRyeS5DUkNfVU5LTk9XTgorICAgICAgICAgICAgICAgICYmIGFlLmdldFNpemUoKSAhPSBBcmNoaXZlRW50cnkuU0laRV9VTktOT1dOCisgICAgICAgICAgICAgICAgJiYgYWUuZ2V0Q29tcHJlc3NlZFNpemUoKSAhPSBBcmNoaXZlRW50cnkuU0laRV9VTktOT1dOOworICAgICAgICBwdXRBcmNoaXZlRW50cnkoYWUsIGlzMlBoYXNlU291cmNlKTsKKyAgICAgICAgY29weUZyb21aaXBJbnB1dFN0cmVhbShyYXdTdHJlYW0pOworICAgICAgICBjbG9zZUNvcGllZEVudHJ5KGlzMlBoYXNlU291cmNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFbnN1cmVzIGFsbCBieXRlcyBzZW50IHRvIHRoZSBkZWZsYXRlciBhcmUgd3JpdHRlbiB0byB0aGUgc3RyZWFtLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBmbHVzaERlZmxhdGVyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGVudHJ5LmVudHJ5LmdldE1ldGhvZCgpID09IERFRkxBVEVEKSB7CisgICAgICAgICAgICBzdHJlYW1Db21wcmVzc29yLmZsdXNoRGVmbGF0ZXIoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEVuc3VyZXMgdGhlIGN1cnJlbnQgZW50cnkncyBzaXplIGFuZCBDUkMgaW5mb3JtYXRpb24gaXMgc2V0IHRvCisgICAgICogdGhlIHZhbHVlcyBqdXN0IHdyaXR0ZW4sIHZlcmlmaWVzIGl0IGlzbid0IHRvbyBiaWcgaW4gdGhlCisgICAgICogWmlwNjRNb2RlLk5ldmVyIGNhc2UgYW5kIHJldHVybnMgd2hldGhlciB0aGUgZW50cnkgd291bGQKKyAgICAgKiByZXF1aXJlIGEgWmlwNjQgZXh0cmEgZmllbGQuCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIGhhbmRsZVNpemVzQW5kQ3JjKGZpbmFsIGxvbmcgYnl0ZXNXcml0dGVuLCBmaW5hbCBsb25nIGNyYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgWmlwNjRNb2RlIGVmZmVjdGl2ZU1vZGUpCisgICAgICAgIHRocm93cyBaaXBFeGNlcHRpb24geworICAgICAgICBpZiAoZW50cnkuZW50cnkuZ2V0TWV0aG9kKCkgPT0gREVGTEFURUQpIHsKKyAgICAgICAgICAgIC8qIEl0IHR1cm5zIG91dCBkZWYuZ2V0Qnl0ZXNSZWFkKCkgcmV0dXJucyB3cm9uZyB2YWx1ZXMgaWYKKyAgICAgICAgICAgICAqIHRoZSBzaXplIGV4Y2VlZHMgNCBHQiBvbiBKYXZhIDwgSmF2YTcKKyAgICAgICAgICAgIGVudHJ5LmVudHJ5LnNldFNpemUoZGVmLmdldEJ5dGVzUmVhZCgpKTsKKyAgICAgICAgICAgICovCisgICAgICAgICAgICBlbnRyeS5lbnRyeS5zZXRTaXplKGVudHJ5LmJ5dGVzUmVhZCk7CisgICAgICAgICAgICBlbnRyeS5lbnRyeS5zZXRDb21wcmVzc2VkU2l6ZShieXRlc1dyaXR0ZW4pOworICAgICAgICAgICAgZW50cnkuZW50cnkuc2V0Q3JjKGNyYyk7CisKKyAgICAgICAgfSBlbHNlIGlmIChjaGFubmVsID09IG51bGwpIHsKKyAgICAgICAgICAgIGlmIChlbnRyeS5lbnRyeS5nZXRDcmMoKSAhPSBjcmMpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWmlwRXhjZXB0aW9uKCJiYWQgQ1JDIGNoZWNrc3VtIGZvciBlbnRyeSAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGVudHJ5LmVudHJ5LmdldE5hbWUoKSArICI6ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgTG9uZy50b0hleFN0cmluZyhlbnRyeS5lbnRyeS5nZXRDcmMoKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiBpbnN0ZWFkIG9mICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgTG9uZy50b0hleFN0cmluZyhjcmMpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKGVudHJ5LmVudHJ5LmdldFNpemUoKSAhPSBieXRlc1dyaXR0ZW4pIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWmlwRXhjZXB0aW9uKCJiYWQgc2l6ZSBmb3IgZW50cnkgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBlbnRyeS5lbnRyeS5nZXROYW1lKCkgKyAiOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGVudHJ5LmVudHJ5LmdldFNpemUoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIGluc3RlYWQgb2YgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBieXRlc1dyaXR0ZW4pOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeyAvKiBtZXRob2QgaXMgU1RPUkVEIGFuZCB3ZSB1c2VkIFNlZWthYmxlQnl0ZUNoYW5uZWwgKi8KKyAgICAgICAgICAgIGVudHJ5LmVudHJ5LnNldFNpemUoYnl0ZXNXcml0dGVuKTsKKyAgICAgICAgICAgIGVudHJ5LmVudHJ5LnNldENvbXByZXNzZWRTaXplKGJ5dGVzV3JpdHRlbik7CisgICAgICAgICAgICBlbnRyeS5lbnRyeS5zZXRDcmMoY3JjKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBjaGVja0lmTmVlZHNaaXA2NChlZmZlY3RpdmVNb2RlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBWZXJpZmllcyB0aGUgc2l6ZXMgYXJlbid0IHRvbyBiaWcgaW4gdGhlIFppcDY0TW9kZS5OZXZlciBjYXNlCisgICAgICogYW5kIHJldHVybnMgd2hldGhlciB0aGUgZW50cnkgd291bGQgcmVxdWlyZSBhIFppcDY0IGV4dHJhCisgICAgICogZmllbGQuCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIGNoZWNrSWZOZWVkc1ppcDY0KGZpbmFsIFppcDY0TW9kZSBlZmZlY3RpdmVNb2RlKQorICAgICAgICAgICAgdGhyb3dzIFppcEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIGJvb2xlYW4gYWN0dWFsbHlOZWVkc1ppcDY0ID0gaXNaaXA2NFJlcXVpcmVkKGVudHJ5LmVudHJ5LCBlZmZlY3RpdmVNb2RlKTsKKyAgICAgICAgaWYgKGFjdHVhbGx5TmVlZHNaaXA2NCAmJiBlZmZlY3RpdmVNb2RlID09IFppcDY0TW9kZS5OZXZlcikgeworICAgICAgICAgICAgdGhyb3cgbmV3IFppcDY0UmVxdWlyZWRFeGNlcHRpb24oWmlwNjRSZXF1aXJlZEV4Y2VwdGlvbi5nZXRFbnRyeVRvb0JpZ01lc3NhZ2UoZW50cnkuZW50cnkpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYWN0dWFsbHlOZWVkc1ppcDY0OworICAgIH0KKworICAgIHByaXZhdGUgYm9vbGVhbiBpc1ppcDY0UmVxdWlyZWQoZmluYWwgWmlwQXJjaGl2ZUVudHJ5IGVudHJ5MSwgZmluYWwgWmlwNjRNb2RlIHJlcXVlc3RlZE1vZGUpIHsKKyAgICAgICAgcmV0dXJuIHJlcXVlc3RlZE1vZGUgPT0gWmlwNjRNb2RlLkFsd2F5cyB8fCBpc1Rvb0xhZ2VGb3JaaXAzMihlbnRyeTEpOworICAgIH0KKworICAgIHByaXZhdGUgYm9vbGVhbiBpc1Rvb0xhZ2VGb3JaaXAzMihmaW5hbCBaaXBBcmNoaXZlRW50cnkgemlwQXJjaGl2ZUVudHJ5KXsKKyAgICAgICAgcmV0dXJuIHppcEFyY2hpdmVFbnRyeS5nZXRTaXplKCkgPj0gWklQNjRfTUFHSUMgfHwgemlwQXJjaGl2ZUVudHJ5LmdldENvbXByZXNzZWRTaXplKCkgPj0gWklQNjRfTUFHSUM7CisgICAgfQorCisgICAgLyoqCisgICAgICogV2hlbiB1c2luZyByYW5kb20gYWNjZXNzIG91dHB1dCwgd3JpdGUgdGhlIGxvY2FsIGZpbGUgaGVhZGVyCisgICAgICogYW5kIHBvdGVudGlhbGwgdGhlIFpJUDY0IGV4dHJhIGNvbnRhaW5pbmcgdGhlIGNvcnJlY3QgQ1JDIGFuZAorICAgICAqIGNvbXByZXNzZWQvdW5jb21wcmVzc2VkIHNpemVzLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCByZXdyaXRlU2l6ZXNBbmRDcmMoZmluYWwgYm9vbGVhbiBhY3R1YWxseU5lZWRzWmlwNjQpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIGxvbmcgc2F2ZSA9IGNoYW5uZWwucG9zaXRpb24oKTsKKworICAgICAgICBjaGFubmVsLnBvc2l0aW9uKGVudHJ5LmxvY2FsRGF0YVN0YXJ0KTsKKyAgICAgICAgd3JpdGVPdXQoWmlwTG9uZy5nZXRCeXRlcyhlbnRyeS5lbnRyeS5nZXRDcmMoKSkpOworICAgICAgICBpZiAoIWhhc1ppcDY0RXh0cmEoZW50cnkuZW50cnkpIHx8ICFhY3R1YWxseU5lZWRzWmlwNjQpIHsKKyAgICAgICAgICAgIHdyaXRlT3V0KFppcExvbmcuZ2V0Qnl0ZXMoZW50cnkuZW50cnkuZ2V0Q29tcHJlc3NlZFNpemUoKSkpOworICAgICAgICAgICAgd3JpdGVPdXQoWmlwTG9uZy5nZXRCeXRlcyhlbnRyeS5lbnRyeS5nZXRTaXplKCkpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHdyaXRlT3V0KFppcExvbmcuWklQNjRfTUFHSUMuZ2V0Qnl0ZXMoKSk7CisgICAgICAgICAgICB3cml0ZU91dChaaXBMb25nLlpJUDY0X01BR0lDLmdldEJ5dGVzKCkpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGhhc1ppcDY0RXh0cmEoZW50cnkuZW50cnkpKSB7CisgICAgICAgICAgICBmaW5hbCBCeXRlQnVmZmVyIG5hbWUgPSBnZXROYW1lKGVudHJ5LmVudHJ5KTsKKyAgICAgICAgICAgIGZpbmFsIGludCBuYW1lTGVuID0gbmFtZS5saW1pdCgpIC0gbmFtZS5wb3NpdGlvbigpOworICAgICAgICAgICAgLy8gc2VlayB0byBaSVA2NCBleHRyYSwgc2tpcCBoZWFkZXIgYW5kIHNpemUgaW5mb3JtYXRpb24KKyAgICAgICAgICAgIGNoYW5uZWwucG9zaXRpb24oZW50cnkubG9jYWxEYXRhU3RhcnQgKyAzICogV09SRCArIDIgKiBTSE9SVAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIG5hbWVMZW4gKyAyICogU0hPUlQpOworICAgICAgICAgICAgLy8gaW5zaWRlIHRoZSBaSVA2NCBleHRyYSB1bmNvbXByZXNzZWQgc2l6ZSBjb21lcworICAgICAgICAgICAgLy8gZmlyc3QsIHVubGlrZSB0aGUgTEZILCBDRCBvciBkYXRhIGRlc2NyaXB0b3IKKyAgICAgICAgICAgIHdyaXRlT3V0KFppcEVpZ2h0Qnl0ZUludGVnZXIuZ2V0Qnl0ZXMoZW50cnkuZW50cnkuZ2V0U2l6ZSgpKSk7CisgICAgICAgICAgICB3cml0ZU91dChaaXBFaWdodEJ5dGVJbnRlZ2VyLmdldEJ5dGVzKGVudHJ5LmVudHJ5LmdldENvbXByZXNzZWRTaXplKCkpKTsKKworICAgICAgICAgICAgaWYgKCFhY3R1YWxseU5lZWRzWmlwNjQpIHsKKyAgICAgICAgICAgICAgICAvLyBkbyBzb21lIGNsZWFudXA6CisgICAgICAgICAgICAgICAgLy8gKiByZXdyaXRlIHZlcnNpb24gbmVlZGVkIHRvIGV4dHJhY3QKKyAgICAgICAgICAgICAgICBjaGFubmVsLnBvc2l0aW9uKGVudHJ5LmxvY2FsRGF0YVN0YXJ0ICAtIDUgKiBTSE9SVCk7CisgICAgICAgICAgICAgICAgd3JpdGVPdXQoWmlwU2hvcnQuZ2V0Qnl0ZXModmVyc2lvbk5lZWRlZFRvRXh0cmFjdChlbnRyeS5lbnRyeS5nZXRNZXRob2QoKSwgZmFsc2UsIGZhbHNlKSkpOworCisgICAgICAgICAgICAgICAgLy8gKiByZW1vdmUgWklQNjQgZXh0cmEgc28gaXQgZG9lc24ndCBnZXQgd3JpdHRlbgorICAgICAgICAgICAgICAgIC8vICAgdG8gdGhlIGNlbnRyYWwgZGlyZWN0b3J5CisgICAgICAgICAgICAgICAgZW50cnkuZW50cnkucmVtb3ZlRXh0cmFGaWVsZChaaXA2NEV4dGVuZGVkSW5mb3JtYXRpb25FeHRyYUZpZWxkCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuSEVBREVSX0lEKTsKKyAgICAgICAgICAgICAgICBlbnRyeS5lbnRyeS5zZXRFeHRyYSgpOworCisgICAgICAgICAgICAgICAgLy8gKiByZXNldCBoYXNVc2VkWmlwNjQgaWYgaXQgaGFzIGJlZW4gc2V0IGJlY2F1c2UKKyAgICAgICAgICAgICAgICAvLyAgIG9mIHRoaXMgZW50cnkKKyAgICAgICAgICAgICAgICBpZiAoZW50cnkuY2F1c2VkVXNlT2ZaaXA2NCkgeworICAgICAgICAgICAgICAgICAgICBoYXNVc2VkWmlwNjQgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgY2hhbm5lbC5wb3NpdGlvbihzYXZlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB7QGluaGVyaXREb2N9CisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gaWYgZW50cnkgaXMgbm90IGFuIGluc3RhbmNlIG9mIFppcEFyY2hpdmVFbnRyeQorICAgICAqIEB0aHJvd3MgWmlwNjRSZXF1aXJlZEV4Y2VwdGlvbiBpZiB0aGUgZW50cnkncyB1bmNvbXByZXNzZWQgb3IKKyAgICAgKiBjb21wcmVzc2VkIHNpemUgaXMga25vd24gdG8gZXhjZWVkIDQgR0J5dGUgYW5kIHtAbGluayAjc2V0VXNlWmlwNjR9CisgICAgICogaXMge0BsaW5rIFppcDY0TW9kZSNOZXZlcn0uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcHV0QXJjaGl2ZUVudHJ5KGZpbmFsIEFyY2hpdmVFbnRyeSBhcmNoaXZlRW50cnkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHB1dEFyY2hpdmVFbnRyeShhcmNoaXZlRW50cnksIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgdGhlIGhlYWRlcnMgZm9yIGFuIGFyY2hpdmUgZW50cnkgdG8gdGhlIG91dHB1dCBzdHJlYW0uCisgICAgICogVGhlIGNhbGxlciBtdXN0IHRoZW4gd3JpdGUgdGhlIGNvbnRlbnQgdG8gdGhlIHN0cmVhbSBhbmQgY2FsbAorICAgICAqIHtAbGluayAjY2xvc2VBcmNoaXZlRW50cnkoKX0gdG8gY29tcGxldGUgdGhlIHByb2Nlc3MuCisKKyAgICAgKiBAcGFyYW0gYXJjaGl2ZUVudHJ5IFRoZSBhcmNoaXZlRW50cnkKKyAgICAgKiBAcGFyYW0gcGhhc2VkIElmIHRydWUgc2l6ZSwgY29tcHJlc3NlZFNpemUgYW5kIGNyYyByZXF1aXJlZCB0byBiZSBrbm93biB1cC1mcm9udCBpbiB0aGUgYXJjaGl2ZUVudHJ5CisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gaWYgZW50cnkgaXMgbm90IGFuIGluc3RhbmNlIG9mIFppcEFyY2hpdmVFbnRyeQorICAgICAqIEB0aHJvd3MgWmlwNjRSZXF1aXJlZEV4Y2VwdGlvbiBpZiB0aGUgZW50cnkncyB1bmNvbXByZXNzZWQgb3IKKyAgICAgKiBjb21wcmVzc2VkIHNpemUgaXMga25vd24gdG8gZXhjZWVkIDQgR0J5dGUgYW5kIHtAbGluayAjc2V0VXNlWmlwNjR9CisgICAgICogaXMge0BsaW5rIFppcDY0TW9kZSNOZXZlcn0uCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHB1dEFyY2hpdmVFbnRyeShmaW5hbCBBcmNoaXZlRW50cnkgYXJjaGl2ZUVudHJ5LCBmaW5hbCBib29sZWFuIHBoYXNlZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGZpbmlzaGVkKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlN0cmVhbSBoYXMgYWxyZWFkeSBiZWVuIGZpbmlzaGVkIik7CisgICAgICAgIH0KKworICAgICAgICBpZiAoZW50cnkgIT0gbnVsbCkgeworICAgICAgICAgICAgY2xvc2VBcmNoaXZlRW50cnkoKTsKKyAgICAgICAgfQorCisgICAgICAgIGVudHJ5ID0gbmV3IEN1cnJlbnRFbnRyeSgoWmlwQXJjaGl2ZUVudHJ5KSBhcmNoaXZlRW50cnkpOworICAgICAgICBlbnRyaWVzLmFkZChlbnRyeS5lbnRyeSk7CisKKyAgICAgICAgc2V0RGVmYXVsdHMoZW50cnkuZW50cnkpOworCisgICAgICAgIGZpbmFsIFppcDY0TW9kZSBlZmZlY3RpdmVNb2RlID0gZ2V0RWZmZWN0aXZlWmlwNjRNb2RlKGVudHJ5LmVudHJ5KTsKKyAgICAgICAgdmFsaWRhdGVTaXplSW5mb3JtYXRpb24oZWZmZWN0aXZlTW9kZSk7CisKKyAgICAgICAgaWYgKHNob3VsZEFkZFppcDY0RXh0cmEoZW50cnkuZW50cnksIGVmZmVjdGl2ZU1vZGUpKSB7CisKKyAgICAgICAgICAgIGZpbmFsIFppcDY0RXh0ZW5kZWRJbmZvcm1hdGlvbkV4dHJhRmllbGQgejY0ID0gZ2V0WmlwNjRFeHRyYShlbnRyeS5lbnRyeSk7CisKKyAgICAgICAgICAgIFppcEVpZ2h0Qnl0ZUludGVnZXIgc2l6ZTsKKyAgICAgICAgICAgIFppcEVpZ2h0Qnl0ZUludGVnZXIgY29tcHJlc3NlZFNpemU7CisgICAgICAgICAgICBpZiAocGhhc2VkKSB7CisgICAgICAgICAgICAgICAgLy8gc2l6ZXMgYXJlIGFscmVhZHkga25vd24KKyAgICAgICAgICAgICAgICBzaXplID0gbmV3IFppcEVpZ2h0Qnl0ZUludGVnZXIoZW50cnkuZW50cnkuZ2V0U2l6ZSgpKTsKKyAgICAgICAgICAgICAgICBjb21wcmVzc2VkU2l6ZSA9IG5ldyBaaXBFaWdodEJ5dGVJbnRlZ2VyKGVudHJ5LmVudHJ5LmdldENvbXByZXNzZWRTaXplKCkpOworICAgICAgICAgICAgfSBlbHNlIGlmIChlbnRyeS5lbnRyeS5nZXRNZXRob2QoKSA9PSBTVE9SRUQKKyAgICAgICAgICAgICAgICAgICAgJiYgZW50cnkuZW50cnkuZ2V0U2l6ZSgpICE9IEFyY2hpdmVFbnRyeS5TSVpFX1VOS05PV04pIHsKKyAgICAgICAgICAgICAgICAvLyBhY3R1YWxseSwgd2UgYWxyZWFkeSBrbm93IHRoZSBzaXplcworICAgICAgICAgICAgICAgIGNvbXByZXNzZWRTaXplID0gc2l6ZSA9IG5ldyBaaXBFaWdodEJ5dGVJbnRlZ2VyKGVudHJ5LmVudHJ5LmdldFNpemUoKSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIC8vIGp1c3QgYSBwbGFjZWhvbGRlciwgcmVhbCBkYXRhIHdpbGwgYmUgaW4gZGF0YQorICAgICAgICAgICAgICAgIC8vIGRlc2NyaXB0b3Igb3IgaW5zZXJ0ZWQgbGF0ZXIgdmlhIFNlZWthYmxlQnl0ZUNoYW5uZWwKKyAgICAgICAgICAgICAgICBjb21wcmVzc2VkU2l6ZSA9IHNpemUgPSBaaXBFaWdodEJ5dGVJbnRlZ2VyLlpFUk87CisgICAgICAgICAgICB9CisgICAgICAgICAgICB6NjQuc2V0U2l6ZShzaXplKTsKKyAgICAgICAgICAgIHo2NC5zZXRDb21wcmVzc2VkU2l6ZShjb21wcmVzc2VkU2l6ZSk7CisgICAgICAgICAgICBlbnRyeS5lbnRyeS5zZXRFeHRyYSgpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGVudHJ5LmVudHJ5LmdldE1ldGhvZCgpID09IERFRkxBVEVEICYmIGhhc0NvbXByZXNzaW9uTGV2ZWxDaGFuZ2VkKSB7CisgICAgICAgICAgICBkZWYuc2V0TGV2ZWwobGV2ZWwpOworICAgICAgICAgICAgaGFzQ29tcHJlc3Npb25MZXZlbENoYW5nZWQgPSBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICB3cml0ZUxvY2FsRmlsZUhlYWRlcigoWmlwQXJjaGl2ZUVudHJ5KSBhcmNoaXZlRW50cnksIHBoYXNlZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJvdmlkZXMgZGVmYXVsdCB2YWx1ZXMgZm9yIGNvbXByZXNzaW9uIG1ldGhvZCBhbmQgbGFzdAorICAgICAqIG1vZGlmaWNhdGlvbiB0aW1lLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBzZXREZWZhdWx0cyhmaW5hbCBaaXBBcmNoaXZlRW50cnkgZW50cnkpIHsKKyAgICAgICAgaWYgKGVudHJ5LmdldE1ldGhvZCgpID09IC0xKSB7IC8vIG5vdCBzcGVjaWZpZWQKKyAgICAgICAgICAgIGVudHJ5LnNldE1ldGhvZChtZXRob2QpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGVudHJ5LmdldFRpbWUoKSA9PSAtMSkgeyAvLyBub3Qgc3BlY2lmaWVkCisgICAgICAgICAgICBlbnRyeS5zZXRUaW1lKFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRocm93cyBhbiBleGNlcHRpb24gaWYgdGhlIHNpemUgaXMgdW5rbm93biBmb3IgYSBzdG9yZWQgZW50cnkKKyAgICAgKiB0aGF0IGlzIHdyaXR0ZW4gdG8gYSBub24tc2Vla2FibGUgb3V0cHV0IG9yIHRoZSBlbnRyeSBpcyB0b28KKyAgICAgKiBiaWcgdG8gYmUgd3JpdHRlbiB3aXRob3V0IFppcDY0IGV4dHJhIGJ1dCB0aGUgbW9kZSBoYXMgYmVlbiBzZXQKKyAgICAgKiB0byBOZXZlci4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgdmFsaWRhdGVTaXplSW5mb3JtYXRpb24oZmluYWwgWmlwNjRNb2RlIGVmZmVjdGl2ZU1vZGUpCisgICAgICAgIHRocm93cyBaaXBFeGNlcHRpb24geworICAgICAgICAvLyBTaXplL0NSQyBub3QgcmVxdWlyZWQgaWYgU2Vla2FibGVCeXRlQ2hhbm5lbCBpcyB1c2VkCisgICAgICAgIGlmIChlbnRyeS5lbnRyeS5nZXRNZXRob2QoKSA9PSBTVE9SRUQgJiYgY2hhbm5lbCA9PSBudWxsKSB7CisgICAgICAgICAgICBpZiAoZW50cnkuZW50cnkuZ2V0U2l6ZSgpID09IEFyY2hpdmVFbnRyeS5TSVpFX1VOS05PV04pIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWmlwRXhjZXB0aW9uKCJ1bmNvbXByZXNzZWQgc2l6ZSBpcyByZXF1aXJlZCBmb3IiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgU1RPUkVEIG1ldGhvZCB3aGVuIG5vdCB3cml0aW5nIHRvIGEiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgZmlsZSIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGVudHJ5LmVudHJ5LmdldENyYygpID09IFppcEFyY2hpdmVFbnRyeS5DUkNfVU5LTk9XTikgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBaaXBFeGNlcHRpb24oImNyYyBjaGVja3N1bSBpcyByZXF1aXJlZCBmb3IgU1RPUkVEIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIG1ldGhvZCB3aGVuIG5vdCB3cml0aW5nIHRvIGEgZmlsZSIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZW50cnkuZW50cnkuc2V0Q29tcHJlc3NlZFNpemUoZW50cnkuZW50cnkuZ2V0U2l6ZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICgoZW50cnkuZW50cnkuZ2V0U2l6ZSgpID49IFpJUDY0X01BR0lDCisgICAgICAgICAgICAgfHwgZW50cnkuZW50cnkuZ2V0Q29tcHJlc3NlZFNpemUoKSA+PSBaSVA2NF9NQUdJQykKKyAgICAgICAgICAgICYmIGVmZmVjdGl2ZU1vZGUgPT0gWmlwNjRNb2RlLk5ldmVyKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgWmlwNjRSZXF1aXJlZEV4Y2VwdGlvbihaaXA2NFJlcXVpcmVkRXhjZXB0aW9uCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0RW50cnlUb29CaWdNZXNzYWdlKGVudHJ5LmVudHJ5KSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXaGV0aGVyIHRvIGFkZGQgYSBaaXA2NCBleHRlbmRlZCBpbmZvcm1hdGlvbiBleHRyYSBmaWVsZCB0byB0aGUKKyAgICAgKiBsb2NhbCBmaWxlIGhlYWRlci4KKyAgICAgKgorICAgICAqIDxwPlJldHVybnMgdHJ1ZSBpZjwvcD4KKyAgICAgKgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+bW9kZSBpcyBBbHdheXM8L2xpPgorICAgICAqIDxsaT5vciB3ZSBhbHJlYWR5IGtub3cgaXQgaXMgZ29pbmcgdG8gYmUgbmVlZGVkPC9saT4KKyAgICAgKiA8bGk+b3IgdGhlIHNpemUgaXMgdW5rbm93biBhbmQgd2UgY2FuIGVuc3VyZSBpdCB3b24ndCBodXJ0CisgICAgICogb3RoZXIgaW1wbGVtZW50YXRpb25zIGlmIHdlIGFkZCBpdCAoaS5lLiB3ZSBjYW4gZXJhc2UgaXRzCisgICAgICogdXNhZ2U8L2xpPgorICAgICAqIDwvdWw+CisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIHNob3VsZEFkZFppcDY0RXh0cmEoZmluYWwgWmlwQXJjaGl2ZUVudHJ5IGVudHJ5LCBmaW5hbCBaaXA2NE1vZGUgbW9kZSkgeworICAgICAgICByZXR1cm4gbW9kZSA9PSBaaXA2NE1vZGUuQWx3YXlzCisgICAgICAgICAgICB8fCBlbnRyeS5nZXRTaXplKCkgPj0gWklQNjRfTUFHSUMKKyAgICAgICAgICAgIHx8IGVudHJ5LmdldENvbXByZXNzZWRTaXplKCkgPj0gWklQNjRfTUFHSUMKKyAgICAgICAgICAgIHx8IChlbnRyeS5nZXRTaXplKCkgPT0gQXJjaGl2ZUVudHJ5LlNJWkVfVU5LTk9XTgorICAgICAgICAgICAgICAgICYmIGNoYW5uZWwgIT0gbnVsbCAmJiBtb2RlICE9IFppcDY0TW9kZS5OZXZlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBmaWxlIGNvbW1lbnQuCisgICAgICogQHBhcmFtIGNvbW1lbnQgdGhlIGNvbW1lbnQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRDb21tZW50KGZpbmFsIFN0cmluZyBjb21tZW50KSB7CisgICAgICAgIHRoaXMuY29tbWVudCA9IGNvbW1lbnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgY29tcHJlc3Npb24gbGV2ZWwgZm9yIHN1YnNlcXVlbnQgZW50cmllcy4KKyAgICAgKgorICAgICAqIDxwPkRlZmF1bHQgaXMgRGVmbGF0ZXIuREVGQVVMVF9DT01QUkVTU0lPTi48L3A+CisgICAgICogQHBhcmFtIGxldmVsIHRoZSBjb21wcmVzc2lvbiBsZXZlbC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBhbiBpbnZhbGlkIGNvbXByZXNzaW9uCisgICAgICogbGV2ZWwgaXMgc3BlY2lmaWVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldExldmVsKGZpbmFsIGludCBsZXZlbCkgeworICAgICAgICBpZiAobGV2ZWwgPCBEZWZsYXRlci5ERUZBVUxUX0NPTVBSRVNTSU9OCisgICAgICAgICAgICB8fCBsZXZlbCA+IERlZmxhdGVyLkJFU1RfQ09NUFJFU1NJT04pIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkludmFsaWQgY29tcHJlc3Npb24gbGV2ZWw6ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBsZXZlbCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHRoaXMubGV2ZWwgPT0gbGV2ZWwpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBoYXNDb21wcmVzc2lvbkxldmVsQ2hhbmdlZCA9IHRydWU7CisgICAgICAgIHRoaXMubGV2ZWwgPSBsZXZlbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBkZWZhdWx0IGNvbXByZXNzaW9uIG1ldGhvZCBmb3Igc3Vic2VxdWVudCBlbnRyaWVzLgorICAgICAqCisgICAgICogPHA+RGVmYXVsdCBpcyBERUZMQVRFRC48L3A+CisgICAgICogQHBhcmFtIG1ldGhvZCBhbiA8Y29kZT5pbnQ8L2NvZGU+IGZyb20gamF2YS51dGlsLnppcC5aaXBFbnRyeQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE1ldGhvZChmaW5hbCBpbnQgbWV0aG9kKSB7CisgICAgICAgIHRoaXMubWV0aG9kID0gbWV0aG9kOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdoZXRoZXIgdGhpcyBzdHJlYW0gaXMgYWJsZSB0byB3cml0ZSB0aGUgZ2l2ZW4gZW50cnkuCisgICAgICoKKyAgICAgKiA8cD5NYXkgcmV0dXJuIGZhbHNlIGlmIGl0IGlzIHNldCB1cCB0byB1c2UgZW5jcnlwdGlvbiBvciBhCisgICAgICogY29tcHJlc3Npb24gbWV0aG9kIHRoYXQgaGFzbid0IGJlZW4gaW1wbGVtZW50ZWQgeWV0LjwvcD4KKyAgICAgKiBAc2luY2UgMS4xCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gY2FuV3JpdGVFbnRyeURhdGEoZmluYWwgQXJjaGl2ZUVudHJ5IGFlKSB7CisgICAgICAgIGlmIChhZSBpbnN0YW5jZW9mIFppcEFyY2hpdmVFbnRyeSkgeworICAgICAgICAgICAgZmluYWwgWmlwQXJjaGl2ZUVudHJ5IHphZSA9IChaaXBBcmNoaXZlRW50cnkpIGFlOworICAgICAgICAgICAgcmV0dXJuIHphZS5nZXRNZXRob2QoKSAhPSBaaXBNZXRob2QuSU1QTE9ESU5HLmdldENvZGUoKQorICAgICAgICAgICAgICAgICYmIHphZS5nZXRNZXRob2QoKSAhPSBaaXBNZXRob2QuVU5TSFJJTktJTkcuZ2V0Q29kZSgpCisgICAgICAgICAgICAgICAgJiYgWmlwVXRpbC5jYW5IYW5kbGVFbnRyeURhdGEoemFlKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIGJ5dGVzIHRvIFpJUCBlbnRyeS4KKyAgICAgKiBAcGFyYW0gYiB0aGUgYnl0ZSBhcnJheSB0byB3cml0ZQorICAgICAqIEBwYXJhbSBvZmZzZXQgdGhlIHN0YXJ0IHBvc2l0aW9uIHRvIHdyaXRlIGZyb20KKyAgICAgKiBAcGFyYW0gbGVuZ3RoIHRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gd3JpdGUKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIG9uIGVycm9yCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGUoZmluYWwgYnl0ZVtdIGIsIGZpbmFsIGludCBvZmZzZXQsIGZpbmFsIGludCBsZW5ndGgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJObyBjdXJyZW50IGVudHJ5Iik7CisgICAgICAgIH0KKyAgICAgICAgWmlwVXRpbC5jaGVja1JlcXVlc3RlZEZlYXR1cmVzKGVudHJ5LmVudHJ5KTsKKyAgICAgICAgZmluYWwgbG9uZyB3cml0dGVuVGhpc1RpbWUgPSBzdHJlYW1Db21wcmVzc29yLndyaXRlKGIsIG9mZnNldCwgbGVuZ3RoLCBlbnRyeS5lbnRyeS5nZXRNZXRob2QoKSk7CisgICAgICAgIGNvdW50KHdyaXR0ZW5UaGlzVGltZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGUgYnl0ZXMgdG8gb3V0cHV0IG9yIHJhbmRvbSBhY2Nlc3MgZmlsZS4KKyAgICAgKiBAcGFyYW0gZGF0YSB0aGUgYnl0ZSBhcnJheSB0byB3cml0ZQorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gb24gZXJyb3IKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgd3JpdGVDb3VudGVkKGZpbmFsIGJ5dGVbXSBkYXRhKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzdHJlYW1Db21wcmVzc29yLndyaXRlQ291bnRlZChkYXRhKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY29weUZyb21aaXBJbnB1dFN0cmVhbShmaW5hbCBJbnB1dFN0cmVhbSBzcmMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJObyBjdXJyZW50IGVudHJ5Iik7CisgICAgICAgIH0KKyAgICAgICAgWmlwVXRpbC5jaGVja1JlcXVlc3RlZEZlYXR1cmVzKGVudHJ5LmVudHJ5KTsKKyAgICAgICAgZW50cnkuaGFzV3JpdHRlbiA9IHRydWU7CisgICAgICAgIGludCBsZW5ndGg7CisgICAgICAgIHdoaWxlICgobGVuZ3RoID0gc3JjLnJlYWQoY29weUJ1ZmZlcikpID49IDAgKQorICAgICAgICB7CisgICAgICAgICAgICBzdHJlYW1Db21wcmVzc29yLndyaXRlQ291bnRlZChjb3B5QnVmZmVyLCAwLCBsZW5ndGgpOworICAgICAgICAgICAgY291bnQoIGxlbmd0aCApOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvc2VzIHRoaXMgb3V0cHV0IHN0cmVhbSBhbmQgcmVsZWFzZXMgYW55IHN5c3RlbSByZXNvdXJjZXMKKyAgICAgKiBhc3NvY2lhdGVkIHdpdGggdGhlIHN0cmVhbS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgIElPRXhjZXB0aW9uICBpZiBhbiBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqIEB0aHJvd3MgWmlwNjRSZXF1aXJlZEV4Y2VwdGlvbiBpZiB0aGUgYXJjaGl2ZSdzIHNpemUgZXhjZWVkcyA0CisgICAgICogR0J5dGUgb3IgdGhlcmUgYXJlIG1vcmUgdGhhbiA2NTUzNSBlbnRyaWVzIGluc2lkZSB0aGUgYXJjaGl2ZQorICAgICAqIGFuZCB7QGxpbmsgI3NldFVzZVppcDY0fSBpcyB7QGxpbmsgWmlwNjRNb2RlI05ldmVyfS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAoIWZpbmlzaGVkKSB7CisgICAgICAgICAgICAgICAgZmluaXNoKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBkZXN0cm95KCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGbHVzaGVzIHRoaXMgb3V0cHV0IHN0cmVhbSBhbmQgZm9yY2VzIGFueSBidWZmZXJlZCBvdXRwdXQgYnl0ZXMKKyAgICAgKiB0byBiZSB3cml0dGVuIG91dCB0byB0aGUgc3RyZWFtLgorICAgICAqCisgICAgICogQHRocm93cyAgSU9FeGNlcHRpb24gIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZmx1c2goKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAob3V0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIG91dC5mbHVzaCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoKKyAgICAgKiBWYXJpb3VzIFpJUCBjb25zdGFudHMgc2hhcmVkIGJldHdlZW4gdGhpcyBjbGFzcywgWmlwQXJjaGl2ZUlucHV0U3RyZWFtIGFuZCBaaXBGaWxlCisgICAgICovCisgICAgLyoqCisgICAgICogbG9jYWwgZmlsZSBoZWFkZXIgc2lnbmF0dXJlCisgICAgICovCisgICAgc3RhdGljIGZpbmFsIGJ5dGVbXSBMRkhfU0lHID0gWmlwTG9uZy5MRkhfU0lHLmdldEJ5dGVzKCk7IC8vTk9TT05BUgorICAgIC8qKgorICAgICAqIGRhdGEgZGVzY3JpcHRvciBzaWduYXR1cmUKKyAgICAgKi8KKyAgICBzdGF0aWMgZmluYWwgYnl0ZVtdIEREX1NJRyA9IFppcExvbmcuRERfU0lHLmdldEJ5dGVzKCk7IC8vTk9TT05BUgorICAgIC8qKgorICAgICAqIGNlbnRyYWwgZmlsZSBoZWFkZXIgc2lnbmF0dXJlCisgICAgICovCisgICAgc3RhdGljIGZpbmFsIGJ5dGVbXSBDRkhfU0lHID0gWmlwTG9uZy5DRkhfU0lHLmdldEJ5dGVzKCk7IC8vTk9TT05BUgorICAgIC8qKgorICAgICAqIGVuZCBvZiBjZW50cmFsIGRpciBzaWduYXR1cmUKKyAgICAgKi8KKyAgICBzdGF0aWMgZmluYWwgYnl0ZVtdIEVPQ0RfU0lHID0gWmlwTG9uZy5nZXRCeXRlcygwWDA2MDU0QjUwTCk7IC8vTk9TT05BUgorICAgIC8qKgorICAgICAqIFpJUDY0IGVuZCBvZiBjZW50cmFsIGRpciBzaWduYXR1cmUKKyAgICAgKi8KKyAgICBzdGF0aWMgZmluYWwgYnl0ZVtdIFpJUDY0X0VPQ0RfU0lHID0gWmlwTG9uZy5nZXRCeXRlcygwWDA2MDY0QjUwTCk7IC8vTk9TT05BUgorICAgIC8qKgorICAgICAqIFpJUDY0IGVuZCBvZiBjZW50cmFsIGRpciBsb2NhdG9yIHNpZ25hdHVyZQorICAgICAqLworICAgIHN0YXRpYyBmaW5hbCBieXRlW10gWklQNjRfRU9DRF9MT0NfU0lHID0gWmlwTG9uZy5nZXRCeXRlcygwWDA3MDY0QjUwTCk7IC8vTk9TT05BUgorCisgICAgLyoqCisgICAgICogV3JpdGVzIG5leHQgYmxvY2sgb2YgY29tcHJlc3NlZCBkYXRhIHRvIHRoZSBvdXRwdXQgc3RyZWFtLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gb24gZXJyb3IKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgZmluYWwgdm9pZCBkZWZsYXRlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3RyZWFtQ29tcHJlc3Nvci5kZWZsYXRlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIHRoZSBsb2NhbCBmaWxlIGhlYWRlciBlbnRyeQorICAgICAqIEBwYXJhbSB6ZSB0aGUgZW50cnkgdG8gd3JpdGUKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIG9uIGVycm9yCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgd3JpdGVMb2NhbEZpbGVIZWFkZXIoZmluYWwgWmlwQXJjaGl2ZUVudHJ5IHplKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB3cml0ZUxvY2FsRmlsZUhlYWRlcih6ZSwgZmFsc2UpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB3cml0ZUxvY2FsRmlsZUhlYWRlcihmaW5hbCBaaXBBcmNoaXZlRW50cnkgemUsIGZpbmFsIGJvb2xlYW4gcGhhc2VkKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBib29sZWFuIGVuY29kYWJsZSA9IHppcEVuY29kaW5nLmNhbkVuY29kZSh6ZS5nZXROYW1lKCkpOworICAgICAgICBmaW5hbCBCeXRlQnVmZmVyIG5hbWUgPSBnZXROYW1lKHplKTsKKworICAgICAgICBpZiAoY3JlYXRlVW5pY29kZUV4dHJhRmllbGRzICE9IFVuaWNvZGVFeHRyYUZpZWxkUG9saWN5Lk5FVkVSKSB7CisgICAgICAgICAgICBhZGRVbmljb2RlRXh0cmFGaWVsZHMoemUsIGVuY29kYWJsZSwgbmFtZSk7CisgICAgICAgIH0KKworICAgICAgICBmaW5hbCBsb25nIGxvY2FsSGVhZGVyU3RhcnQgPSBzdHJlYW1Db21wcmVzc29yLmdldFRvdGFsQnl0ZXNXcml0dGVuKCk7CisgICAgICAgIGZpbmFsIGJ5dGVbXSBsb2NhbEhlYWRlciA9IGNyZWF0ZUxvY2FsRmlsZUhlYWRlcih6ZSwgbmFtZSwgZW5jb2RhYmxlLCBwaGFzZWQsIGxvY2FsSGVhZGVyU3RhcnQpOworICAgICAgICBtZXRhRGF0YS5wdXQoemUsIG5ldyBFbnRyeU1ldGFEYXRhKGxvY2FsSGVhZGVyU3RhcnQsIHVzZXNEYXRhRGVzY3JpcHRvcih6ZS5nZXRNZXRob2QoKSwgcGhhc2VkKSkpOworICAgICAgICBlbnRyeS5sb2NhbERhdGFTdGFydCA9IGxvY2FsSGVhZGVyU3RhcnQgKyBMRkhfQ1JDX09GRlNFVDsgLy8gQXQgY3JjIG9mZnNldAorICAgICAgICB3cml0ZUNvdW50ZWQobG9jYWxIZWFkZXIpOworICAgICAgICBlbnRyeS5kYXRhU3RhcnQgPSBzdHJlYW1Db21wcmVzc29yLmdldFRvdGFsQnl0ZXNXcml0dGVuKCk7CisgICAgfQorCisKKyAgICBwcml2YXRlIGJ5dGVbXSBjcmVhdGVMb2NhbEZpbGVIZWFkZXIoZmluYWwgWmlwQXJjaGl2ZUVudHJ5IHplLCBmaW5hbCBCeXRlQnVmZmVyIG5hbWUsIGZpbmFsIGJvb2xlYW4gZW5jb2RhYmxlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBib29sZWFuIHBoYXNlZCwgbG9uZyBhcmNoaXZlT2Zmc2V0KSB7CisgICAgICAgIFJlc291cmNlQWxpZ25tZW50RXh0cmFGaWVsZCBvbGRBbGlnbm1lbnRFeCA9CisgICAgICAgICAgICAoUmVzb3VyY2VBbGlnbm1lbnRFeHRyYUZpZWxkKSB6ZS5nZXRFeHRyYUZpZWxkKFJlc291cmNlQWxpZ25tZW50RXh0cmFGaWVsZC5JRCk7CisgICAgICAgIGlmIChvbGRBbGlnbm1lbnRFeCAhPSBudWxsKSB7CisgICAgICAgICAgICB6ZS5yZW1vdmVFeHRyYUZpZWxkKFJlc291cmNlQWxpZ25tZW50RXh0cmFGaWVsZC5JRCk7CisgICAgICAgIH0KKworICAgICAgICBpbnQgYWxpZ25tZW50ID0gemUuZ2V0QWxpZ25tZW50KCk7CisgICAgICAgIGlmIChhbGlnbm1lbnQgPD0gMCAmJiBvbGRBbGlnbm1lbnRFeCAhPSBudWxsKSB7CisgICAgICAgICAgICBhbGlnbm1lbnQgPSBvbGRBbGlnbm1lbnRFeC5nZXRBbGlnbm1lbnQoKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChhbGlnbm1lbnQgPiAxIHx8IChvbGRBbGlnbm1lbnRFeCAhPSBudWxsICYmICFvbGRBbGlnbm1lbnRFeC5hbGxvd01ldGhvZENoYW5nZSgpKSkgeworICAgICAgICAgICAgaW50IG9sZExlbmd0aCA9IExGSF9GSUxFTkFNRV9PRkZTRVQgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUubGltaXQoKSAtIG5hbWUucG9zaXRpb24oKSArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgemUuZ2V0TG9jYWxGaWxlRGF0YUV4dHJhKCkubGVuZ3RoOworCisgICAgICAgICAgICBpbnQgcGFkZGluZyA9IChpbnQpICgoLWFyY2hpdmVPZmZzZXQgLSBvbGRMZW5ndGggLSBaaXBFeHRyYUZpZWxkLkVYVFJBRklFTERfSEVBREVSX1NJWkUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAtIFJlc291cmNlQWxpZ25tZW50RXh0cmFGaWVsZC5CQVNFX1NJWkUpICYKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYWxpZ25tZW50IC0gMSkpOworICAgICAgICAgICAgemUuYWRkRXh0cmFGaWVsZChuZXcgUmVzb3VyY2VBbGlnbm1lbnRFeHRyYUZpZWxkKGFsaWdubWVudCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbGRBbGlnbm1lbnRFeCAhPSBudWxsICYmIG9sZEFsaWdubWVudEV4LmFsbG93TWV0aG9kQ2hhbmdlKCksIHBhZGRpbmcpKTsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIGJ5dGVbXSBleHRyYSA9IHplLmdldExvY2FsRmlsZURhdGFFeHRyYSgpOworICAgICAgICBmaW5hbCBpbnQgbmFtZUxlbiA9IG5hbWUubGltaXQoKSAtIG5hbWUucG9zaXRpb24oKTsKKyAgICAgICAgZmluYWwgaW50IGxlbiA9IExGSF9GSUxFTkFNRV9PRkZTRVQgKyBuYW1lTGVuICsgZXh0cmEubGVuZ3RoOworICAgICAgICBmaW5hbCBieXRlW10gYnVmID0gbmV3IGJ5dGVbbGVuXTsKKworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KExGSF9TSUcsICAwLCBidWYsIExGSF9TSUdfT0ZGU0VULCBXT1JEKTsKKworICAgICAgICAvL3N0b3JlIG1ldGhvZCBpbiBsb2NhbCB2YXJpYWJsZSB0byBwcmV2ZW50IG11bHRpcGxlIG1ldGhvZCBjYWxscworICAgICAgICBmaW5hbCBpbnQgemlwTWV0aG9kID0gemUuZ2V0TWV0aG9kKCk7CisgICAgICAgIGZpbmFsIGJvb2xlYW4gZGF0YURlc2NyaXB0b3IgPSB1c2VzRGF0YURlc2NyaXB0b3IoemlwTWV0aG9kLCBwaGFzZWQpOworCisgICAgICAgIHB1dFNob3J0KHZlcnNpb25OZWVkZWRUb0V4dHJhY3QoemlwTWV0aG9kLCBoYXNaaXA2NEV4dHJhKHplKSwgZGF0YURlc2NyaXB0b3IpLCBidWYsIExGSF9WRVJTSU9OX05FRURFRF9PRkZTRVQpOworCisgICAgICAgIGZpbmFsIEdlbmVyYWxQdXJwb3NlQml0IGdlbmVyYWxQdXJwb3NlQml0ID0gZ2V0R2VuZXJhbFB1cnBvc2VCaXRzKCFlbmNvZGFibGUgJiYgZmFsbGJhY2tUb1VURjgsIGRhdGFEZXNjcmlwdG9yKTsKKyAgICAgICAgZ2VuZXJhbFB1cnBvc2VCaXQuZW5jb2RlKGJ1ZiwgTEZIX0dQQl9PRkZTRVQpOworCisgICAgICAgIC8vIGNvbXByZXNzaW9uIG1ldGhvZAorICAgICAgICBwdXRTaG9ydCh6aXBNZXRob2QsIGJ1ZiwgTEZIX01FVEhPRF9PRkZTRVQpOworCisgICAgICAgIFppcFV0aWwudG9Eb3NUaW1lKGNhbGVuZGFySW5zdGFuY2UsIHplLmdldFRpbWUoKSwgYnVmLCBMRkhfVElNRV9PRkZTRVQpOworCisgICAgICAgIC8vIENSQworICAgICAgICBpZiAocGhhc2VkKXsKKyAgICAgICAgICAgIHB1dExvbmcoemUuZ2V0Q3JjKCksIGJ1ZiwgTEZIX0NSQ19PRkZTRVQpOworICAgICAgICB9IGVsc2UgaWYgKHppcE1ldGhvZCA9PSBERUZMQVRFRCB8fCBjaGFubmVsICE9IG51bGwpIHsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoTFpFUk8sIDAsIGJ1ZiwgTEZIX0NSQ19PRkZTRVQsIFdPUkQpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcHV0TG9uZyh6ZS5nZXRDcmMoKSwgYnVmLCBMRkhfQ1JDX09GRlNFVCk7CisgICAgICAgIH0KKworICAgICAgICAvLyBjb21wcmVzc2VkIGxlbmd0aAorICAgICAgICAvLyB1bmNvbXByZXNzZWQgbGVuZ3RoCisgICAgICAgIGlmIChoYXNaaXA2NEV4dHJhKGVudHJ5LmVudHJ5KSl7CisgICAgICAgICAgICAvLyBwb2ludCB0byBaSVA2NCBleHRlbmRlZCBpbmZvcm1hdGlvbiBleHRyYSBmaWVsZCBmb3IKKyAgICAgICAgICAgIC8vIHNpemVzLCBtYXkgZ2V0IHJld3JpdHRlbiBvbmNlIHNpemVzIGFyZSBrbm93biBpZgorICAgICAgICAgICAgLy8gc3RyZWFtIGlzIHNlZWthYmxlCisgICAgICAgICAgICBaaXBMb25nLlpJUDY0X01BR0lDLnB1dExvbmcoYnVmLCBMRkhfQ09NUFJFU1NFRF9TSVpFX09GRlNFVCk7CisgICAgICAgICAgICBaaXBMb25nLlpJUDY0X01BR0lDLnB1dExvbmcoYnVmLCBMRkhfT1JJR0lOQUxfU0laRV9PRkZTRVQpOworICAgICAgICB9IGVsc2UgaWYgKHBoYXNlZCkgeworICAgICAgICAgICAgcHV0TG9uZyh6ZS5nZXRDb21wcmVzc2VkU2l6ZSgpLCBidWYsIExGSF9DT01QUkVTU0VEX1NJWkVfT0ZGU0VUKTsKKyAgICAgICAgICAgIHB1dExvbmcoemUuZ2V0U2l6ZSgpLCBidWYsIExGSF9PUklHSU5BTF9TSVpFX09GRlNFVCk7CisgICAgICAgIH0gZWxzZSBpZiAoemlwTWV0aG9kID09IERFRkxBVEVEIHx8IGNoYW5uZWwgIT0gbnVsbCkgeworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShMWkVSTywgMCwgYnVmLCBMRkhfQ09NUFJFU1NFRF9TSVpFX09GRlNFVCwgV09SRCk7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KExaRVJPLCAwLCBidWYsIExGSF9PUklHSU5BTF9TSVpFX09GRlNFVCwgV09SRCk7CisgICAgICAgIH0gZWxzZSB7IC8vIFN0b3JlZAorICAgICAgICAgICAgcHV0TG9uZyh6ZS5nZXRTaXplKCksIGJ1ZiwgTEZIX0NPTVBSRVNTRURfU0laRV9PRkZTRVQpOworICAgICAgICAgICAgcHV0TG9uZyh6ZS5nZXRTaXplKCksIGJ1ZiwgTEZIX09SSUdJTkFMX1NJWkVfT0ZGU0VUKTsKKyAgICAgICAgfQorICAgICAgICAvLyBmaWxlIG5hbWUgbGVuZ3RoCisgICAgICAgIHB1dFNob3J0KG5hbWVMZW4sIGJ1ZiwgTEZIX0ZJTEVOQU1FX0xFTkdUSF9PRkZTRVQpOworCisgICAgICAgIC8vIGV4dHJhIGZpZWxkIGxlbmd0aAorICAgICAgICBwdXRTaG9ydChleHRyYS5sZW5ndGgsIGJ1ZiwgTEZIX0VYVFJBX0xFTkdUSF9PRkZTRVQpOworCisgICAgICAgIC8vIGZpbGUgbmFtZQorICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KCBuYW1lLmFycmF5KCksIG5hbWUuYXJyYXlPZmZzZXQoKSwgYnVmLCBMRkhfRklMRU5BTUVfT0ZGU0VULCBuYW1lTGVuKTsKKworICAgICAgICAvLyBleHRyYSBmaWVsZHMKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShleHRyYSwgMCwgYnVmLCBMRkhfRklMRU5BTUVfT0ZGU0VUICsgbmFtZUxlbiwgZXh0cmEubGVuZ3RoKTsKKworICAgICAgICByZXR1cm4gYnVmOworICAgIH0KKworCisgICAgLyoqCisgICAgICogQWRkcyBVbmljb2RlRXh0cmEgZmllbGRzIGZvciBuYW1lIGFuZCBmaWxlIGNvbW1lbnQgaWYgbW9kZSBpcworICAgICAqIEFMV0FZUyBvciB0aGUgZGF0YSBjYW5ub3QgYmUgZW5jb2RlZCB1c2luZyB0aGUgY29uZmlndXJlZAorICAgICAqIGVuY29kaW5nLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBhZGRVbmljb2RlRXh0cmFGaWVsZHMoZmluYWwgWmlwQXJjaGl2ZUVudHJ5IHplLCBmaW5hbCBib29sZWFuIGVuY29kYWJsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEJ5dGVCdWZmZXIgbmFtZSkKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGNyZWF0ZVVuaWNvZGVFeHRyYUZpZWxkcyA9PSBVbmljb2RlRXh0cmFGaWVsZFBvbGljeS5BTFdBWVMKKyAgICAgICAgICAgIHx8ICFlbmNvZGFibGUpIHsKKyAgICAgICAgICAgIHplLmFkZEV4dHJhRmllbGQobmV3IFVuaWNvZGVQYXRoRXh0cmFGaWVsZCh6ZS5nZXROYW1lKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZS5hcnJheSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUuYXJyYXlPZmZzZXQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lLmxpbWl0KCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtIG5hbWUucG9zaXRpb24oKSkpOworICAgICAgICB9CisKKyAgICAgICAgZmluYWwgU3RyaW5nIGNvbW0gPSB6ZS5nZXRDb21tZW50KCk7CisgICAgICAgIGlmIChjb21tICE9IG51bGwgJiYgISIiLmVxdWFscyhjb21tKSkgeworCisgICAgICAgICAgICBmaW5hbCBib29sZWFuIGNvbW1lbnRFbmNvZGFibGUgPSB6aXBFbmNvZGluZy5jYW5FbmNvZGUoY29tbSk7CisKKyAgICAgICAgICAgIGlmIChjcmVhdGVVbmljb2RlRXh0cmFGaWVsZHMgPT0gVW5pY29kZUV4dHJhRmllbGRQb2xpY3kuQUxXQVlTCisgICAgICAgICAgICAgICAgfHwgIWNvbW1lbnRFbmNvZGFibGUpIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBCeXRlQnVmZmVyIGNvbW1lbnRCID0gZ2V0RW50cnlFbmNvZGluZyh6ZSkuZW5jb2RlKGNvbW0pOworICAgICAgICAgICAgICAgIHplLmFkZEV4dHJhRmllbGQobmV3IFVuaWNvZGVDb21tZW50RXh0cmFGaWVsZChjb21tLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21tZW50Qi5hcnJheSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21tZW50Qi5hcnJheU9mZnNldCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21tZW50Qi5saW1pdCgpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0gY29tbWVudEIucG9zaXRpb24oKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgdGhlIGRhdGEgZGVzY3JpcHRvciBlbnRyeS4KKyAgICAgKiBAcGFyYW0gemUgdGhlIGVudHJ5IHRvIHdyaXRlCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBvbiBlcnJvcgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHdyaXRlRGF0YURlc2NyaXB0b3IoZmluYWwgWmlwQXJjaGl2ZUVudHJ5IHplKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoIXVzZXNEYXRhRGVzY3JpcHRvcih6ZS5nZXRNZXRob2QoKSwgZmFsc2UpKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgd3JpdGVDb3VudGVkKEREX1NJRyk7CisgICAgICAgIHdyaXRlQ291bnRlZChaaXBMb25nLmdldEJ5dGVzKHplLmdldENyYygpKSk7CisgICAgICAgIGlmICghaGFzWmlwNjRFeHRyYSh6ZSkpIHsKKyAgICAgICAgICAgIHdyaXRlQ291bnRlZChaaXBMb25nLmdldEJ5dGVzKHplLmdldENvbXByZXNzZWRTaXplKCkpKTsKKyAgICAgICAgICAgIHdyaXRlQ291bnRlZChaaXBMb25nLmdldEJ5dGVzKHplLmdldFNpemUoKSkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgd3JpdGVDb3VudGVkKFppcEVpZ2h0Qnl0ZUludGVnZXIuZ2V0Qnl0ZXMoemUuZ2V0Q29tcHJlc3NlZFNpemUoKSkpOworICAgICAgICAgICAgd3JpdGVDb3VudGVkKFppcEVpZ2h0Qnl0ZUludGVnZXIuZ2V0Qnl0ZXMoemUuZ2V0U2l6ZSgpKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgdGhlIGNlbnRyYWwgZmlsZSBoZWFkZXIgZW50cnkuCisgICAgICogQHBhcmFtIHplIHRoZSBlbnRyeSB0byB3cml0ZQorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gb24gZXJyb3IKKyAgICAgKiBAdGhyb3dzIFppcDY0UmVxdWlyZWRFeGNlcHRpb24gaWYgdGhlIGFyY2hpdmUncyBzaXplIGV4Y2VlZHMgNAorICAgICAqIEdCeXRlIGFuZCB7QGxpbmsgWmlwNjRNb2RlICNzZXRVc2VaaXA2NH0gaXMge0BsaW5rCisgICAgICogWmlwNjRNb2RlI05ldmVyfS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCB3cml0ZUNlbnRyYWxGaWxlSGVhZGVyKGZpbmFsIFppcEFyY2hpdmVFbnRyeSB6ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGNlbnRyYWxGaWxlSGVhZGVyID0gY3JlYXRlQ2VudHJhbEZpbGVIZWFkZXIoemUpOworICAgICAgICB3cml0ZUNvdW50ZWQoY2VudHJhbEZpbGVIZWFkZXIpOworICAgIH0KKworICAgIHByaXZhdGUgYnl0ZVtdIGNyZWF0ZUNlbnRyYWxGaWxlSGVhZGVyKGZpbmFsIFppcEFyY2hpdmVFbnRyeSB6ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKworICAgICAgICBmaW5hbCBFbnRyeU1ldGFEYXRhIGVudHJ5TWV0YURhdGEgPSBtZXRhRGF0YS5nZXQoemUpOworICAgICAgICBmaW5hbCBib29sZWFuIG5lZWRzWmlwNjRFeHRyYSA9IGhhc1ppcDY0RXh0cmEoemUpCisgICAgICAgICAgICAgICAgfHwgemUuZ2V0Q29tcHJlc3NlZFNpemUoKSA+PSBaSVA2NF9NQUdJQworICAgICAgICAgICAgICAgIHx8IHplLmdldFNpemUoKSA+PSBaSVA2NF9NQUdJQworICAgICAgICAgICAgICAgIHx8IGVudHJ5TWV0YURhdGEub2Zmc2V0ID49IFpJUDY0X01BR0lDCisgICAgICAgICAgICAgICAgfHwgemlwNjRNb2RlID09IFppcDY0TW9kZS5BbHdheXM7CisKKyAgICAgICAgaWYgKG5lZWRzWmlwNjRFeHRyYSAmJiB6aXA2NE1vZGUgPT0gWmlwNjRNb2RlLk5ldmVyKSB7CisgICAgICAgICAgICAvLyBtdXN0IGJlIHRoZSBvZmZzZXQgdGhhdCBpcyB0b28gYmlnLCBvdGhlcndpc2UgYW4KKyAgICAgICAgICAgIC8vIGV4Y2VwdGlvbiB3b3VsZCBoYXZlIGJlZW4gdGhyb3cgaW4gcHV0QXJjaGl2ZUVudHJ5IG9yCisgICAgICAgICAgICAvLyBjbG9zZUFyY2hpdmVFbnRyeQorICAgICAgICAgICAgdGhyb3cgbmV3IFppcDY0UmVxdWlyZWRFeGNlcHRpb24oWmlwNjRSZXF1aXJlZEV4Y2VwdGlvbgorICAgICAgICAgICAgICAgICAgICAuQVJDSElWRV9UT09fQklHX01FU1NBR0UpOworICAgICAgICB9CisKKworICAgICAgICBoYW5kbGVaaXA2NEV4dHJhKHplLCBlbnRyeU1ldGFEYXRhLm9mZnNldCwgbmVlZHNaaXA2NEV4dHJhKTsKKworICAgICAgICByZXR1cm4gY3JlYXRlQ2VudHJhbEZpbGVIZWFkZXIoemUsIGdldE5hbWUoemUpLCBlbnRyeU1ldGFEYXRhLCBuZWVkc1ppcDY0RXh0cmEpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyB0aGUgY2VudHJhbCBmaWxlIGhlYWRlciBlbnRyeS4KKyAgICAgKiBAcGFyYW0gemUgdGhlIGVudHJ5IHRvIHdyaXRlCisgICAgICogQHBhcmFtIG5hbWUgVGhlIGVuY29kZWQgbmFtZQorICAgICAqIEBwYXJhbSBlbnRyeU1ldGFEYXRhIG1ldGEgZGF0YSBmb3IgdGhpcyBmaWxlCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBvbiBlcnJvcgorICAgICAqLworICAgIHByaXZhdGUgYnl0ZVtdIGNyZWF0ZUNlbnRyYWxGaWxlSGVhZGVyKGZpbmFsIFppcEFyY2hpdmVFbnRyeSB6ZSwgZmluYWwgQnl0ZUJ1ZmZlciBuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEVudHJ5TWV0YURhdGEgZW50cnlNZXRhRGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBib29sZWFuIG5lZWRzWmlwNjRFeHRyYSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGV4dHJhID0gemUuZ2V0Q2VudHJhbERpcmVjdG9yeUV4dHJhKCk7CisKKyAgICAgICAgLy8gZmlsZSBjb21tZW50IGxlbmd0aAorICAgICAgICBTdHJpbmcgY29tbSA9IHplLmdldENvbW1lbnQoKTsKKyAgICAgICAgaWYgKGNvbW0gPT0gbnVsbCkgeworICAgICAgICAgICAgY29tbSA9ICIiOworICAgICAgICB9CisKKyAgICAgICAgZmluYWwgQnl0ZUJ1ZmZlciBjb21tZW50QiA9IGdldEVudHJ5RW5jb2RpbmcoemUpLmVuY29kZShjb21tKTsKKyAgICAgICAgZmluYWwgaW50IG5hbWVMZW4gPSBuYW1lLmxpbWl0KCkgLSBuYW1lLnBvc2l0aW9uKCk7CisgICAgICAgIGZpbmFsIGludCBjb21tZW50TGVuID0gY29tbWVudEIubGltaXQoKSAtIGNvbW1lbnRCLnBvc2l0aW9uKCk7CisgICAgICAgIGZpbmFsIGludCBsZW49IENGSF9GSUxFTkFNRV9PRkZTRVQgKyBuYW1lTGVuICsgZXh0cmEubGVuZ3RoICsgY29tbWVudExlbjsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGJ1ZiA9IG5ldyBieXRlW2xlbl07CisKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShDRkhfU0lHLCAgMCwgYnVmLCBDRkhfU0lHX09GRlNFVCwgV09SRCk7CisKKyAgICAgICAgLy8gdmVyc2lvbiBtYWRlIGJ5CisgICAgICAgIC8vIENoZWNrU3R5bGU6TWFnaWNOdW1iZXIgT0ZGCisgICAgICAgIHB1dFNob3J0KCh6ZS5nZXRQbGF0Zm9ybSgpIDw8IDgpIHwgKCFoYXNVc2VkWmlwNjQgPyBEQVRBX0RFU0NSSVBUT1JfTUlOX1ZFUlNJT04gOiBaSVA2NF9NSU5fVkVSU0lPTiksCisgICAgICAgICAgICAgICAgYnVmLCBDRkhfVkVSU0lPTl9NQURFX0JZX09GRlNFVCk7CisKKyAgICAgICAgZmluYWwgaW50IHppcE1ldGhvZCA9IHplLmdldE1ldGhvZCgpOworICAgICAgICBmaW5hbCBib29sZWFuIGVuY29kYWJsZSA9IHppcEVuY29kaW5nLmNhbkVuY29kZSh6ZS5nZXROYW1lKCkpOworICAgICAgICBwdXRTaG9ydCh2ZXJzaW9uTmVlZGVkVG9FeHRyYWN0KHppcE1ldGhvZCwgbmVlZHNaaXA2NEV4dHJhLCBlbnRyeU1ldGFEYXRhLnVzZXNEYXRhRGVzY3JpcHRvciksCisgICAgICAgICAgICBidWYsIENGSF9WRVJTSU9OX05FRURFRF9PRkZTRVQpOworICAgICAgICBnZXRHZW5lcmFsUHVycG9zZUJpdHMoIWVuY29kYWJsZSAmJiBmYWxsYmFja1RvVVRGOCwgZW50cnlNZXRhRGF0YS51c2VzRGF0YURlc2NyaXB0b3IpLmVuY29kZShidWYsIENGSF9HUEJfT0ZGU0VUKTsKKworICAgICAgICAvLyBjb21wcmVzc2lvbiBtZXRob2QKKyAgICAgICAgcHV0U2hvcnQoemlwTWV0aG9kLCBidWYsIENGSF9NRVRIT0RfT0ZGU0VUKTsKKworCisgICAgICAgIC8vIGxhc3QgbW9kLiB0aW1lIGFuZCBkYXRlCisgICAgICAgIFppcFV0aWwudG9Eb3NUaW1lKGNhbGVuZGFySW5zdGFuY2UsIHplLmdldFRpbWUoKSwgYnVmLCBDRkhfVElNRV9PRkZTRVQpOworCisgICAgICAgIC8vIENSQworICAgICAgICAvLyBjb21wcmVzc2VkIGxlbmd0aAorICAgICAgICAvLyB1bmNvbXByZXNzZWQgbGVuZ3RoCisgICAgICAgIHB1dExvbmcoemUuZ2V0Q3JjKCksIGJ1ZiwgQ0ZIX0NSQ19PRkZTRVQpOworICAgICAgICBpZiAoemUuZ2V0Q29tcHJlc3NlZFNpemUoKSA+PSBaSVA2NF9NQUdJQworICAgICAgICAgICAgICAgIHx8IHplLmdldFNpemUoKSA+PSBaSVA2NF9NQUdJQworICAgICAgICAgICAgICAgIHx8IHppcDY0TW9kZSA9PSBaaXA2NE1vZGUuQWx3YXlzKSB7CisgICAgICAgICAgICBaaXBMb25nLlpJUDY0X01BR0lDLnB1dExvbmcoYnVmLCBDRkhfQ09NUFJFU1NFRF9TSVpFX09GRlNFVCk7CisgICAgICAgICAgICBaaXBMb25nLlpJUDY0X01BR0lDLnB1dExvbmcoYnVmLCBDRkhfT1JJR0lOQUxfU0laRV9PRkZTRVQpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcHV0TG9uZyh6ZS5nZXRDb21wcmVzc2VkU2l6ZSgpLCBidWYsIENGSF9DT01QUkVTU0VEX1NJWkVfT0ZGU0VUKTsKKyAgICAgICAgICAgIHB1dExvbmcoemUuZ2V0U2l6ZSgpLCBidWYsIENGSF9PUklHSU5BTF9TSVpFX09GRlNFVCk7CisgICAgICAgIH0KKworICAgICAgICBwdXRTaG9ydChuYW1lTGVuLCBidWYsIENGSF9GSUxFTkFNRV9MRU5HVEhfT0ZGU0VUKTsKKworICAgICAgICAvLyBleHRyYSBmaWVsZCBsZW5ndGgKKyAgICAgICAgcHV0U2hvcnQoZXh0cmEubGVuZ3RoLCBidWYsIENGSF9FWFRSQV9MRU5HVEhfT0ZGU0VUKTsKKworICAgICAgICBwdXRTaG9ydChjb21tZW50TGVuLCBidWYsIENGSF9DT01NRU5UX0xFTkdUSF9PRkZTRVQpOworCisgICAgICAgIC8vIGRpc2sgbnVtYmVyIHN0YXJ0CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoWkVSTywgMCwgYnVmLCBDRkhfRElTS19OVU1CRVJfT0ZGU0VULCBTSE9SVCk7CisKKyAgICAgICAgLy8gaW50ZXJuYWwgZmlsZSBhdHRyaWJ1dGVzCisgICAgICAgIHB1dFNob3J0KHplLmdldEludGVybmFsQXR0cmlidXRlcygpLCBidWYsIENGSF9JTlRFUk5BTF9BVFRSSUJVVEVTX09GRlNFVCk7CisKKyAgICAgICAgLy8gZXh0ZXJuYWwgZmlsZSBhdHRyaWJ1dGVzCisgICAgICAgIHB1dExvbmcoemUuZ2V0RXh0ZXJuYWxBdHRyaWJ1dGVzKCksIGJ1ZiwgQ0ZIX0VYVEVSTkFMX0FUVFJJQlVURVNfT0ZGU0VUKTsKKworICAgICAgICAvLyByZWxhdGl2ZSBvZmZzZXQgb2YgTEZICisgICAgICAgIGlmIChlbnRyeU1ldGFEYXRhLm9mZnNldCA+PSBaSVA2NF9NQUdJQyB8fCB6aXA2NE1vZGUgPT0gWmlwNjRNb2RlLkFsd2F5cykgeworICAgICAgICAgICAgcHV0TG9uZyhaSVA2NF9NQUdJQywgYnVmLCBDRkhfTEZIX09GRlNFVCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBwdXRMb25nKE1hdGgubWluKGVudHJ5TWV0YURhdGEub2Zmc2V0LCBaSVA2NF9NQUdJQyksIGJ1ZiwgQ0ZIX0xGSF9PRkZTRVQpOworICAgICAgICB9CisKKyAgICAgICAgLy8gZmlsZSBuYW1lCisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkobmFtZS5hcnJheSgpLCBuYW1lLmFycmF5T2Zmc2V0KCksIGJ1ZiwgQ0ZIX0ZJTEVOQU1FX09GRlNFVCwgbmFtZUxlbik7CisKKyAgICAgICAgZmluYWwgaW50IGV4dHJhU3RhcnQgPSBDRkhfRklMRU5BTUVfT0ZGU0VUICsgbmFtZUxlbjsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShleHRyYSwgMCwgYnVmLCBleHRyYVN0YXJ0LCBleHRyYS5sZW5ndGgpOworCisgICAgICAgIGZpbmFsIGludCBjb21tZW50U3RhcnQgPSBleHRyYVN0YXJ0ICsgZXh0cmEubGVuZ3RoOworCisgICAgICAgIC8vIGZpbGUgY29tbWVudAorICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGNvbW1lbnRCLmFycmF5KCksIGNvbW1lbnRCLmFycmF5T2Zmc2V0KCksIGJ1ZiwgY29tbWVudFN0YXJ0LCBjb21tZW50TGVuKTsKKyAgICAgICAgcmV0dXJuIGJ1ZjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJZiB0aGUgZW50cnkgbmVlZHMgWmlwNjQgZXh0cmEgaW5mb3JtYXRpb24gaW5zaWRlIHRoZSBjZW50cmFsCisgICAgICogZGlyZWN0b3J5IHRoZW4gY29uZmlndXJlIGl0cyBkYXRhLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBoYW5kbGVaaXA2NEV4dHJhKGZpbmFsIFppcEFyY2hpdmVFbnRyeSB6ZSwgZmluYWwgbG9uZyBsZmhPZmZzZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgYm9vbGVhbiBuZWVkc1ppcDY0RXh0cmEpIHsKKyAgICAgICAgaWYgKG5lZWRzWmlwNjRFeHRyYSkgeworICAgICAgICAgICAgZmluYWwgWmlwNjRFeHRlbmRlZEluZm9ybWF0aW9uRXh0cmFGaWVsZCB6NjQgPSBnZXRaaXA2NEV4dHJhKHplKTsKKyAgICAgICAgICAgIGlmICh6ZS5nZXRDb21wcmVzc2VkU2l6ZSgpID49IFpJUDY0X01BR0lDCisgICAgICAgICAgICAgICAgfHwgemUuZ2V0U2l6ZSgpID49IFpJUDY0X01BR0lDCisgICAgICAgICAgICAgICAgfHwgemlwNjRNb2RlID09IFppcDY0TW9kZS5BbHdheXMpIHsKKyAgICAgICAgICAgICAgICB6NjQuc2V0Q29tcHJlc3NlZFNpemUobmV3IFppcEVpZ2h0Qnl0ZUludGVnZXIoemUuZ2V0Q29tcHJlc3NlZFNpemUoKSkpOworICAgICAgICAgICAgICAgIHo2NC5zZXRTaXplKG5ldyBaaXBFaWdodEJ5dGVJbnRlZ2VyKHplLmdldFNpemUoKSkpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAvLyByZXNldCB2YWx1ZSB0aGF0IG1heSBoYXZlIGJlZW4gc2V0IGZvciBMRkgKKyAgICAgICAgICAgICAgICB6NjQuc2V0Q29tcHJlc3NlZFNpemUobnVsbCk7CisgICAgICAgICAgICAgICAgejY0LnNldFNpemUobnVsbCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAobGZoT2Zmc2V0ID49IFpJUDY0X01BR0lDIHx8IHppcDY0TW9kZSA9PSBaaXA2NE1vZGUuQWx3YXlzKSB7CisgICAgICAgICAgICAgICAgejY0LnNldFJlbGF0aXZlSGVhZGVyT2Zmc2V0KG5ldyBaaXBFaWdodEJ5dGVJbnRlZ2VyKGxmaE9mZnNldCkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgemUuc2V0RXh0cmEoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyB0aGUgJnF1b3Q7RW5kIG9mIGNlbnRyYWwgZGlyIHJlY29yZCZxdW90Oy4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIG9uIGVycm9yCisgICAgICogQHRocm93cyBaaXA2NFJlcXVpcmVkRXhjZXB0aW9uIGlmIHRoZSBhcmNoaXZlJ3Mgc2l6ZSBleGNlZWRzIDQKKyAgICAgKiBHQnl0ZSBvciB0aGVyZSBhcmUgbW9yZSB0aGFuIDY1NTM1IGVudHJpZXMgaW5zaWRlIHRoZSBhcmNoaXZlCisgICAgICogYW5kIHtAbGluayBaaXA2NE1vZGUgI3NldFVzZVppcDY0fSBpcyB7QGxpbmsgWmlwNjRNb2RlI05ldmVyfS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCB3cml0ZUNlbnRyYWxEaXJlY3RvcnlFbmQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB3cml0ZUNvdW50ZWQoRU9DRF9TSUcpOworCisgICAgICAgIC8vIGRpc2sgbnVtYmVycworICAgICAgICB3cml0ZUNvdW50ZWQoWkVSTyk7CisgICAgICAgIHdyaXRlQ291bnRlZChaRVJPKTsKKworICAgICAgICAvLyBudW1iZXIgb2YgZW50cmllcworICAgICAgICBmaW5hbCBpbnQgbnVtYmVyT2ZFbnRyaWVzID0gZW50cmllcy5zaXplKCk7CisgICAgICAgIGlmIChudW1iZXJPZkVudHJpZXMgPiBaSVA2NF9NQUdJQ19TSE9SVAorICAgICAgICAgICAgJiYgemlwNjRNb2RlID09IFppcDY0TW9kZS5OZXZlcikgeworICAgICAgICAgICAgdGhyb3cgbmV3IFppcDY0UmVxdWlyZWRFeGNlcHRpb24oWmlwNjRSZXF1aXJlZEV4Y2VwdGlvbgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLlRPT19NQU5ZX0VOVFJJRVNfTUVTU0FHRSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGNkT2Zmc2V0ID4gWklQNjRfTUFHSUMgJiYgemlwNjRNb2RlID09IFppcDY0TW9kZS5OZXZlcikgeworICAgICAgICAgICAgdGhyb3cgbmV3IFppcDY0UmVxdWlyZWRFeGNlcHRpb24oWmlwNjRSZXF1aXJlZEV4Y2VwdGlvbgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLkFSQ0hJVkVfVE9PX0JJR19NRVNTQUdFKTsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIGJ5dGVbXSBudW0gPSBaaXBTaG9ydC5nZXRCeXRlcyhNYXRoLm1pbihudW1iZXJPZkVudHJpZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBaSVA2NF9NQUdJQ19TSE9SVCkpOworICAgICAgICB3cml0ZUNvdW50ZWQobnVtKTsKKyAgICAgICAgd3JpdGVDb3VudGVkKG51bSk7CisKKyAgICAgICAgLy8gbGVuZ3RoIGFuZCBsb2NhdGlvbiBvZiBDRAorICAgICAgICB3cml0ZUNvdW50ZWQoWmlwTG9uZy5nZXRCeXRlcyhNYXRoLm1pbihjZExlbmd0aCwgWklQNjRfTUFHSUMpKSk7CisgICAgICAgIHdyaXRlQ291bnRlZChaaXBMb25nLmdldEJ5dGVzKE1hdGgubWluKGNkT2Zmc2V0LCBaSVA2NF9NQUdJQykpKTsKKworICAgICAgICAvLyBaSVAgZmlsZSBjb21tZW50CisgICAgICAgIGZpbmFsIEJ5dGVCdWZmZXIgZGF0YSA9IHRoaXMuemlwRW5jb2RpbmcuZW5jb2RlKGNvbW1lbnQpOworICAgICAgICBmaW5hbCBpbnQgZGF0YUxlbiA9IGRhdGEubGltaXQoKSAtIGRhdGEucG9zaXRpb24oKTsKKyAgICAgICAgd3JpdGVDb3VudGVkKFppcFNob3J0LmdldEJ5dGVzKGRhdGFMZW4pKTsKKyAgICAgICAgc3RyZWFtQ29tcHJlc3Nvci53cml0ZUNvdW50ZWQoZGF0YS5hcnJheSgpLCBkYXRhLmFycmF5T2Zmc2V0KCksIGRhdGFMZW4pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyB0aGUgJnF1b3Q7WklQNjQgRW5kIG9mIGNlbnRyYWwgZGlyIHJlY29yZCZxdW90OyBhbmQKKyAgICAgKiAmcXVvdDtaSVA2NCBFbmQgb2YgY2VudHJhbCBkaXIgbG9jYXRvciZxdW90Oy4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIG9uIGVycm9yCisgICAgICogQHNpbmNlIDEuMworICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHdyaXRlWmlwNjRDZW50cmFsRGlyZWN0b3J5KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHppcDY0TW9kZSA9PSBaaXA2NE1vZGUuTmV2ZXIpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIGlmICghaGFzVXNlZFppcDY0CisgICAgICAgICAgICAmJiAoY2RPZmZzZXQgPj0gWklQNjRfTUFHSUMgfHwgY2RMZW5ndGggPj0gWklQNjRfTUFHSUMKKyAgICAgICAgICAgICAgICB8fCBlbnRyaWVzLnNpemUoKSA+PSBaSVA2NF9NQUdJQ19TSE9SVCkpIHsKKyAgICAgICAgICAgIC8vIGFjdHVhbGx5ICJ3aWxsIHVzZSIKKyAgICAgICAgICAgIGhhc1VzZWRaaXA2NCA9IHRydWU7CisgICAgICAgIH0KKworICAgICAgICBpZiAoIWhhc1VzZWRaaXA2NCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgZmluYWwgbG9uZyBvZmZzZXQgPSBzdHJlYW1Db21wcmVzc29yLmdldFRvdGFsQnl0ZXNXcml0dGVuKCk7CisKKyAgICAgICAgd3JpdGVPdXQoWklQNjRfRU9DRF9TSUcpOworICAgICAgICAvLyBzaXplLCB3ZSBkb24ndCBoYXZlIGFueSB2YXJpYWJsZSBsZW5ndGggYXMgd2UgZG9uJ3Qgc3VwcG9ydAorICAgICAgICAvLyB0aGUgZXh0ZW5zaWJsZSBkYXRhIHNlY3RvciwgeWV0CisgICAgICAgIHdyaXRlT3V0KFppcEVpZ2h0Qnl0ZUludGVnZXIKKyAgICAgICAgICAgICAgICAgLmdldEJ5dGVzKFNIT1JUICAgLyogdmVyc2lvbiBtYWRlIGJ5ICovCisgICAgICAgICAgICAgICAgICAgICAgICAgICArIFNIT1JUIC8qIHZlcnNpb24gbmVlZGVkIHRvIGV4dHJhY3QgKi8KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICsgV09SRCAgLyogZGlzayBudW1iZXIgKi8KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICsgV09SRCAgLyogZGlzayB3aXRoIGNlbnRyYWwgZGlyZWN0b3J5ICovCisgICAgICAgICAgICAgICAgICAgICAgICAgICArIERXT1JEIC8qIG51bWJlciBvZiBlbnRyaWVzIGluIENEIG9uIHRoaXMgZGlzayAqLworICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBEV09SRCAvKiB0b3RhbCBudW1iZXIgb2YgZW50cmllcyAqLworICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBEV09SRCAvKiBzaXplIG9mIENEICovCisgICAgICAgICAgICAgICAgICAgICAgICAgICArIChsb25nKSBEV09SRCAvKiBvZmZzZXQgb2YgQ0QgKi8KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICkpOworCisgICAgICAgIC8vIHZlcnNpb24gbWFkZSBieSBhbmQgdmVyc2lvbiBuZWVkZWQgdG8gZXh0cmFjdAorICAgICAgICB3cml0ZU91dChaaXBTaG9ydC5nZXRCeXRlcyhaSVA2NF9NSU5fVkVSU0lPTikpOworICAgICAgICB3cml0ZU91dChaaXBTaG9ydC5nZXRCeXRlcyhaSVA2NF9NSU5fVkVSU0lPTikpOworCisgICAgICAgIC8vIGRpc2sgbnVtYmVycyAtIGZvdXIgYnl0ZXMgdGhpcyB0aW1lCisgICAgICAgIHdyaXRlT3V0KExaRVJPKTsKKyAgICAgICAgd3JpdGVPdXQoTFpFUk8pOworCisgICAgICAgIC8vIG51bWJlciBvZiBlbnRyaWVzCisgICAgICAgIGZpbmFsIGJ5dGVbXSBudW0gPSBaaXBFaWdodEJ5dGVJbnRlZ2VyLmdldEJ5dGVzKGVudHJpZXMuc2l6ZSgpKTsKKyAgICAgICAgd3JpdGVPdXQobnVtKTsKKyAgICAgICAgd3JpdGVPdXQobnVtKTsKKworICAgICAgICAvLyBsZW5ndGggYW5kIGxvY2F0aW9uIG9mIENECisgICAgICAgIHdyaXRlT3V0KFppcEVpZ2h0Qnl0ZUludGVnZXIuZ2V0Qnl0ZXMoY2RMZW5ndGgpKTsKKyAgICAgICAgd3JpdGVPdXQoWmlwRWlnaHRCeXRlSW50ZWdlci5nZXRCeXRlcyhjZE9mZnNldCkpOworCisgICAgICAgIC8vIG5vICJ6aXA2NCBleHRlbnNpYmxlIGRhdGEgc2VjdG9yIiBmb3Igbm93CisKKyAgICAgICAgLy8gYW5kIG5vdyB0aGUgIlpJUDY0IGVuZCBvZiBjZW50cmFsIGRpcmVjdG9yeSBsb2NhdG9yIgorICAgICAgICB3cml0ZU91dChaSVA2NF9FT0NEX0xPQ19TSUcpOworCisgICAgICAgIC8vIGRpc2sgbnVtYmVyIGhvbGRpbmcgdGhlIFpJUDY0IEVPQ0QgcmVjb3JkCisgICAgICAgIHdyaXRlT3V0KExaRVJPKTsKKyAgICAgICAgLy8gcmVsYXRpdmUgb2Zmc2V0IG9mIFpJUDY0IEVPQ0QgcmVjb3JkCisgICAgICAgIHdyaXRlT3V0KFppcEVpZ2h0Qnl0ZUludGVnZXIuZ2V0Qnl0ZXMob2Zmc2V0KSk7CisgICAgICAgIC8vIHRvdGFsIG51bWJlciBvZiBkaXNrcworICAgICAgICB3cml0ZU91dChPTkUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlIGJ5dGVzIHRvIG91dHB1dCBvciByYW5kb20gYWNjZXNzIGZpbGUuCisgICAgICogQHBhcmFtIGRhdGEgdGhlIGJ5dGUgYXJyYXkgdG8gd3JpdGUKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIG9uIGVycm9yCisgICAgICovCisgICAgcHJvdGVjdGVkIGZpbmFsIHZvaWQgd3JpdGVPdXQoZmluYWwgYnl0ZVtdIGRhdGEpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN0cmVhbUNvbXByZXNzb3Iud3JpdGVPdXQoZGF0YSwgMCwgZGF0YS5sZW5ndGgpOworICAgIH0KKworCisgICAgLyoqCisgICAgICogV3JpdGUgYnl0ZXMgdG8gb3V0cHV0IG9yIHJhbmRvbSBhY2Nlc3MgZmlsZS4KKyAgICAgKiBAcGFyYW0gZGF0YSB0aGUgYnl0ZSBhcnJheSB0byB3cml0ZQorICAgICAqIEBwYXJhbSBvZmZzZXQgdGhlIHN0YXJ0IHBvc2l0aW9uIHRvIHdyaXRlIGZyb20KKyAgICAgKiBAcGFyYW0gbGVuZ3RoIHRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gd3JpdGUKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIG9uIGVycm9yCisgICAgICovCisgICAgcHJvdGVjdGVkIGZpbmFsIHZvaWQgd3JpdGVPdXQoZmluYWwgYnl0ZVtdIGRhdGEsIGZpbmFsIGludCBvZmZzZXQsIGZpbmFsIGludCBsZW5ndGgpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzdHJlYW1Db21wcmVzc29yLndyaXRlT3V0KGRhdGEsIG9mZnNldCwgbGVuZ3RoKTsKKyAgICB9CisKKworICAgIHByaXZhdGUgR2VuZXJhbFB1cnBvc2VCaXQgZ2V0R2VuZXJhbFB1cnBvc2VCaXRzKGZpbmFsIGJvb2xlYW4gdXRmRmFsbGJhY2ssIGJvb2xlYW4gdXNlc0RhdGFEZXNjcmlwdG9yKSB7CisgICAgICAgIGZpbmFsIEdlbmVyYWxQdXJwb3NlQml0IGIgPSBuZXcgR2VuZXJhbFB1cnBvc2VCaXQoKTsKKyAgICAgICAgYi51c2VVVEY4Rm9yTmFtZXModXNlVVRGOEZsYWcgfHwgdXRmRmFsbGJhY2spOworICAgICAgICBpZiAodXNlc0RhdGFEZXNjcmlwdG9yKSB7CisgICAgICAgICAgICBiLnVzZURhdGFEZXNjcmlwdG9yKHRydWUpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBiOworICAgIH0KKworICAgIHByaXZhdGUgaW50IHZlcnNpb25OZWVkZWRUb0V4dHJhY3QoZmluYWwgaW50IHppcE1ldGhvZCwgZmluYWwgYm9vbGVhbiB6aXA2NCwgZmluYWwgYm9vbGVhbiB1c2VkRGF0YURlc2NyaXB0b3IpIHsKKyAgICAgICAgaWYgKHppcDY0KSB7CisgICAgICAgICAgICByZXR1cm4gWklQNjRfTUlOX1ZFUlNJT047CisgICAgICAgIH0KKyAgICAgICAgaWYgKHVzZWREYXRhRGVzY3JpcHRvcikgeworICAgICAgICAgICAgcmV0dXJuIERBVEFfREVTQ1JJUFRPUl9NSU5fVkVSU0lPTjsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdmVyc2lvbk5lZWRlZFRvRXh0cmFjdE1ldGhvZCh6aXBNZXRob2QpOworICAgIH0KKworICAgIHByaXZhdGUgYm9vbGVhbiB1c2VzRGF0YURlc2NyaXB0b3IoZmluYWwgaW50IHppcE1ldGhvZCwgYm9vbGVhbiBwaGFzZWQpIHsKKyAgICAgICAgcmV0dXJuICFwaGFzZWQgJiYgemlwTWV0aG9kID09IERFRkxBVEVEICYmIGNoYW5uZWwgPT0gbnVsbDsKKyAgICB9CisKKyAgICBwcml2YXRlIGludCB2ZXJzaW9uTmVlZGVkVG9FeHRyYWN0TWV0aG9kKGludCB6aXBNZXRob2QpIHsKKyAgICAgICAgcmV0dXJuIHppcE1ldGhvZCA9PSBERUZMQVRFRCA/IERFRkxBVEVfTUlOX1ZFUlNJT04gOiBJTklUSUFMX1ZFUlNJT047CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB6aXAgZW50cnkgdGFraW5nIHNvbWUgaW5mb3JtYXRpb24gZnJvbSB0aGUgZ2l2ZW4KKyAgICAgKiBmaWxlIGFuZCB1c2luZyB0aGUgcHJvdmlkZWQgbmFtZS4KKyAgICAgKgorICAgICAqIDxwPlRoZSBuYW1lIHdpbGwgYmUgYWRqdXN0ZWQgdG8gZW5kIHdpdGggYSBmb3J3YXJkIHNsYXNoICIvIiBpZgorICAgICAqIHRoZSBmaWxlIGlzIGEgZGlyZWN0b3J5LiAgSWYgdGhlIGZpbGUgaXMgbm90IGEgZGlyZWN0b3J5IGEKKyAgICAgKiBwb3RlbnRpYWwgdHJhaWxpbmcgZm9yd2FyZCBzbGFzaCB3aWxsIGJlIHN0cmlwcGVkIGZyb20gdGhlCisgICAgICogZW50cnkgbmFtZS48L3A+CisgICAgICoKKyAgICAgKiA8cD5NdXN0IG5vdCBiZSB1c2VkIGlmIHRoZSBzdHJlYW0gaGFzIGFscmVhZHkgYmVlbiBjbG9zZWQuPC9wPgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBBcmNoaXZlRW50cnkgY3JlYXRlQXJjaGl2ZUVudHJ5KGZpbmFsIEZpbGUgaW5wdXRGaWxlLCBmaW5hbCBTdHJpbmcgZW50cnlOYW1lKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoZmluaXNoZWQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiU3RyZWFtIGhhcyBhbHJlYWR5IGJlZW4gZmluaXNoZWQiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IFppcEFyY2hpdmVFbnRyeShpbnB1dEZpbGUsIGVudHJ5TmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBleGlzdGluZyBaSVA2NCBleHRlbmRlZCBpbmZvcm1hdGlvbiBleHRyYSBmaWVsZCBvcgorICAgICAqIGNyZWF0ZSBhIG5ldyBvbmUgYW5kIGFkZCBpdCB0byB0aGUgZW50cnkuCisgICAgICoKKyAgICAgKiBAc2luY2UgMS4zCisgICAgICovCisgICAgcHJpdmF0ZSBaaXA2NEV4dGVuZGVkSW5mb3JtYXRpb25FeHRyYUZpZWxkCisgICAgICAgIGdldFppcDY0RXh0cmEoZmluYWwgWmlwQXJjaGl2ZUVudHJ5IHplKSB7CisgICAgICAgIGlmIChlbnRyeSAhPSBudWxsKSB7CisgICAgICAgICAgICBlbnRyeS5jYXVzZWRVc2VPZlppcDY0ID0gIWhhc1VzZWRaaXA2NDsKKyAgICAgICAgfQorICAgICAgICBoYXNVc2VkWmlwNjQgPSB0cnVlOworICAgICAgICBaaXA2NEV4dGVuZGVkSW5mb3JtYXRpb25FeHRyYUZpZWxkIHo2NCA9CisgICAgICAgICAgICAoWmlwNjRFeHRlbmRlZEluZm9ybWF0aW9uRXh0cmFGaWVsZCkKKyAgICAgICAgICAgIHplLmdldEV4dHJhRmllbGQoWmlwNjRFeHRlbmRlZEluZm9ybWF0aW9uRXh0cmFGaWVsZAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuSEVBREVSX0lEKTsKKyAgICAgICAgaWYgKHo2NCA9PSBudWxsKSB7CisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkFkZGluZyB6NjQgZm9yICIgKyB6ZS5nZXROYW1lKCkKKyAgICAgICAgICAgICAgKyAiLCBtZXRob2Q6ICIgKyB6ZS5nZXRNZXRob2QoKQorICAgICAgICAgICAgICArICIgKCIgKyAoemUuZ2V0TWV0aG9kKCkgPT0gU1RPUkVEKSArICIpIgorICAgICAgICAgICAgICArICIsIGNoYW5uZWw6ICIgKyAoY2hhbm5lbCAhPSBudWxsKSk7CisgICAgICAgICAgICAqLworICAgICAgICAgICAgejY0ID0gbmV3IFppcDY0RXh0ZW5kZWRJbmZvcm1hdGlvbkV4dHJhRmllbGQoKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIGV2ZW4gaWYgdGhlIGZpZWxkIGlzIHRoZXJlIGFscmVhZHksIG1ha2Ugc3VyZSBpdCBpcyB0aGUgZmlyc3Qgb25lCisgICAgICAgIHplLmFkZEFzRmlyc3RFeHRyYUZpZWxkKHo2NCk7CisKKyAgICAgICAgcmV0dXJuIHo2NDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJcyB0aGVyZSBhIFpJUDY0IGV4dGVuZGVkIGluZm9ybWF0aW9uIGV4dHJhIGZpZWxkIGZvciB0aGUKKyAgICAgKiBlbnRyeT8KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjMKKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gaGFzWmlwNjRFeHRyYShmaW5hbCBaaXBBcmNoaXZlRW50cnkgemUpIHsKKyAgICAgICAgcmV0dXJuIHplLmdldEV4dHJhRmllbGQoWmlwNjRFeHRlbmRlZEluZm9ybWF0aW9uRXh0cmFGaWVsZAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuSEVBREVSX0lEKQorICAgICAgICAgICAgIT0gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJZiB0aGUgbW9kZSBpcyBBc05lZWRlZCBhbmQgdGhlIGVudHJ5IGlzIGEgY29tcHJlc3NlZCBlbnRyeSBvZgorICAgICAqIHVua25vd24gc2l6ZSB0aGF0IGdldHMgd3JpdHRlbiB0byBhIG5vbi1zZWVrYWJsZSBzdHJlYW0gdGhlbgorICAgICAqIGNoYW5nZSB0aGUgZGVmYXVsdCB0byBOZXZlci4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjMKKyAgICAgKi8KKyAgICBwcml2YXRlIFppcDY0TW9kZSBnZXRFZmZlY3RpdmVaaXA2NE1vZGUoZmluYWwgWmlwQXJjaGl2ZUVudHJ5IHplKSB7CisgICAgICAgIGlmICh6aXA2NE1vZGUgIT0gWmlwNjRNb2RlLkFzTmVlZGVkCisgICAgICAgICAgICB8fCBjaGFubmVsICE9IG51bGwKKyAgICAgICAgICAgIHx8IHplLmdldE1ldGhvZCgpICE9IERFRkxBVEVECisgICAgICAgICAgICB8fCB6ZS5nZXRTaXplKCkgIT0gQXJjaGl2ZUVudHJ5LlNJWkVfVU5LTk9XTikgeworICAgICAgICAgICAgcmV0dXJuIHppcDY0TW9kZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gWmlwNjRNb2RlLk5ldmVyOworICAgIH0KKworICAgIHByaXZhdGUgWmlwRW5jb2RpbmcgZ2V0RW50cnlFbmNvZGluZyhmaW5hbCBaaXBBcmNoaXZlRW50cnkgemUpIHsKKyAgICAgICAgZmluYWwgYm9vbGVhbiBlbmNvZGFibGUgPSB6aXBFbmNvZGluZy5jYW5FbmNvZGUoemUuZ2V0TmFtZSgpKTsKKyAgICAgICAgcmV0dXJuICFlbmNvZGFibGUgJiYgZmFsbGJhY2tUb1VURjgKKyAgICAgICAgICAgID8gWmlwRW5jb2RpbmdIZWxwZXIuVVRGOF9aSVBfRU5DT0RJTkcgOiB6aXBFbmNvZGluZzsKKyAgICB9CisKKyAgICBwcml2YXRlIEJ5dGVCdWZmZXIgZ2V0TmFtZShmaW5hbCBaaXBBcmNoaXZlRW50cnkgemUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBnZXRFbnRyeUVuY29kaW5nKHplKS5lbmNvZGUoemUuZ2V0TmFtZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbG9zZXMgdGhlIHVuZGVybHlpbmcgc3RyZWFtL2ZpbGUgd2l0aG91dCBmaW5pc2hpbmcgdGhlCisgICAgICogYXJjaGl2ZSwgdGhlIHJlc3VsdCB3aWxsIGxpa2VseSBiZSBhIGNvcnJ1cHQgYXJjaGl2ZS4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIG9ubHkgZXhpc3RzIHRvIHN1cHBvcnQgdGVzdHMgdGhhdCBnZW5lcmF0ZQorICAgICAqIGNvcnJ1cHQgYXJjaGl2ZXMgc28gdGhleSBjYW4gY2xlYW4gdXAgYW55IHRlbXBvcmFyeSBmaWxlcy48L3A+CisgICAgICovCisgICAgdm9pZCBkZXN0cm95KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlmIChjaGFubmVsICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBjaGFubmVsLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAob3V0ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGVudW0gdGhhdCByZXByZXNlbnRzIHRoZSBwb3NzaWJsZSBwb2xpY2llcyBmb3IgY3JlYXRpbmcgVW5pY29kZQorICAgICAqIGV4dHJhIGZpZWxkcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFVuaWNvZGVFeHRyYUZpZWxkUG9saWN5IHsKKyAgICAgICAgLyoqCisgICAgICAgICAqIEFsd2F5cyBjcmVhdGUgVW5pY29kZSBleHRyYSBmaWVsZHMuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFVuaWNvZGVFeHRyYUZpZWxkUG9saWN5IEFMV0FZUyA9IG5ldyBVbmljb2RlRXh0cmFGaWVsZFBvbGljeSgiYWx3YXlzIik7CisgICAgICAgIC8qKgorICAgICAgICAgKiBOZXZlciBjcmVhdGUgVW5pY29kZSBleHRyYSBmaWVsZHMuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFVuaWNvZGVFeHRyYUZpZWxkUG9saWN5IE5FVkVSID0gbmV3IFVuaWNvZGVFeHRyYUZpZWxkUG9saWN5KCJuZXZlciIpOworICAgICAgICAvKioKKyAgICAgICAgICogQ3JlYXRlIFVuaWNvZGUgZXh0cmEgZmllbGRzIGZvciBmaWxlbmFtZXMgdGhhdCBjYW5ub3QgYmUKKyAgICAgICAgICogZW5jb2RlZCB1c2luZyB0aGUgc3BlY2lmaWVkIGVuY29kaW5nLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlRXh0cmFGaWVsZFBvbGljeSBOT1RfRU5DT0RFQUJMRSA9CisgICAgICAgICAgICBuZXcgVW5pY29kZUV4dHJhRmllbGRQb2xpY3koIm5vdCBlbmNvZGVhYmxlIik7CisKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgbmFtZTsKKyAgICAgICAgcHJpdmF0ZSBVbmljb2RlRXh0cmFGaWVsZFBvbGljeShmaW5hbCBTdHJpbmcgbikgeworICAgICAgICAgICAgbmFtZSA9IG47CisgICAgICAgIH0KKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgICAgICByZXR1cm4gbmFtZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFN0cnVjdHVyZSBjb2xsZWN0aW5nIGluZm9ybWF0aW9uIGZvciB0aGUgZW50cnkgdGhhdCBpcworICAgICAqIGN1cnJlbnRseSBiZWluZyB3cml0dGVuLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEN1cnJlbnRFbnRyeSB7CisgICAgICAgIHByaXZhdGUgQ3VycmVudEVudHJ5KGZpbmFsIFppcEFyY2hpdmVFbnRyeSBlbnRyeSkgeworICAgICAgICAgICAgdGhpcy5lbnRyeSA9IGVudHJ5OworICAgICAgICB9CisgICAgICAgIC8qKgorICAgICAgICAgKiBDdXJyZW50IFpJUCBlbnRyeS4KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgZmluYWwgWmlwQXJjaGl2ZUVudHJ5IGVudHJ5OworICAgICAgICAvKioKKyAgICAgICAgICogT2Zmc2V0IGZvciBDUkMgZW50cnkgaW4gdGhlIGxvY2FsIGZpbGUgaGVhZGVyIGRhdGEgZm9yIHRoZQorICAgICAgICAgKiBjdXJyZW50IGVudHJ5IHN0YXJ0cyBoZXJlLgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBsb25nIGxvY2FsRGF0YVN0YXJ0ID0gMDsKKyAgICAgICAgLyoqCisgICAgICAgICAqIERhdGEgZm9yIGxvY2FsIGhlYWRlciBkYXRhCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIGxvbmcgZGF0YVN0YXJ0ID0gMDsKKyAgICAgICAgLyoqCisgICAgICAgICAqIE51bWJlciBvZiBieXRlcyByZWFkIGZvciB0aGUgY3VycmVudCBlbnRyeSAoY2FuJ3QgcmVseSBvbgorICAgICAgICAgKiBEZWZsYXRlciNnZXRCeXRlc1JlYWQpIHdoZW4gdXNpbmcgREVGTEFURUQuCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIGxvbmcgYnl0ZXNSZWFkID0gMDsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFdoZXRoZXIgY3VycmVudCBlbnRyeSB3YXMgdGhlIGZpcnN0IG9uZSB1c2luZyBaSVA2NCBmZWF0dXJlcy4KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgYm9vbGVhbiBjYXVzZWRVc2VPZlppcDY0ID0gZmFsc2U7CisgICAgICAgIC8qKgorICAgICAgICAgKiBXaGV0aGVyIHdyaXRlKCkgaGFzIGJlZW4gY2FsbGVkIGF0IGFsbC4KKyAgICAgICAgICoKKyAgICAgICAgICogPHA+SW4gb3JkZXIgdG8gY3JlYXRlIGEgdmFsaWQgYXJjaGl2ZSB7QGxpbmsKKyAgICAgICAgICogI2Nsb3NlQXJjaGl2ZUVudHJ5IGNsb3NlQXJjaGl2ZUVudHJ5fSB3aWxsIHdyaXRlIGFuIGVtcHR5CisgICAgICAgICAqIGFycmF5IHRvIGdldCB0aGUgQ1JDIHJpZ2h0IGlmIG5vdGhpbmcgaGFzIGJlZW4gd3JpdHRlbiB0bworICAgICAgICAgKiB0aGUgc3RyZWFtIGF0IGFsbC48L3A+CisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIGJvb2xlYW4gaGFzV3JpdHRlbjsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBFbnRyeU1ldGFEYXRhIHsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBsb25nIG9mZnNldDsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIHVzZXNEYXRhRGVzY3JpcHRvcjsKKyAgICAgICAgcHJpdmF0ZSBFbnRyeU1ldGFEYXRhKGxvbmcgb2Zmc2V0LCBib29sZWFuIHVzZXNEYXRhRGVzY3JpcHRvcikgeworICAgICAgICAgICAgdGhpcy5vZmZzZXQgPSBvZmZzZXQ7CisgICAgICAgICAgICB0aGlzLnVzZXNEYXRhRGVzY3JpcHRvciA9IHVzZXNEYXRhRGVzY3JpcHRvcjsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvWmlwQ29uc3RhbnRzLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1ppcENvbnN0YW50cy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMyMzA5OTEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1ppcENvbnN0YW50cy5qYXZhCkBAIC0wLDAgKzEsNjcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXA7CisKKy8qKgorICogVmFyaW91cyBjb25zdGFudHMgdXNlZCB0aHJvdWdob3V0IHRoZSBwYWNrYWdlLgorICoKKyAqIEBzaW5jZSAxLjMKKyAqLworZmluYWwgY2xhc3MgWmlwQ29uc3RhbnRzIHsKKyAgICAvKiogTWFza3MgbGFzdCBlaWdodCBiaXRzICovCisgICAgc3RhdGljIGZpbmFsIGludCBCWVRFX01BU0sgPSAweEZGOworCisgICAgLyoqIGxlbmd0aCBvZiBhIFppcFNob3J0IGluIGJ5dGVzICovCisgICAgc3RhdGljIGZpbmFsIGludCBTSE9SVCA9IDI7CisKKyAgICAvKiogbGVuZ3RoIG9mIGEgWmlwTG9uZyBpbiBieXRlcyAqLworICAgIHN0YXRpYyBmaW5hbCBpbnQgV09SRCA9IDQ7CisKKyAgICAvKiogbGVuZ3RoIG9mIGEgWmlwRWlnaHRCeXRlSW50ZWdlciBpbiBieXRlcyAqLworICAgIHN0YXRpYyBmaW5hbCBpbnQgRFdPUkQgPSA4OworCisgICAgLyoqIEluaXRpYWwgWklQIHNwZWNpZmljYXRpb24gdmVyc2lvbiAqLworICAgIHN0YXRpYyBmaW5hbCBpbnQgSU5JVElBTF9WRVJTSU9OID0gMTA7CisKKyAgICAvKioKKyAgICAgKiBaSVAgc3BlY2lmaWNhdGlvbiB2ZXJzaW9uIHRoYXQgaW50cm9kdWNlZCBERUZMQVRFIGNvbXByZXNzaW9uIG1ldGhvZC4KKyAgICAgKiBAc2luY2UgMS4xNQorICAgICAqLworICAgIHN0YXRpYyBmaW5hbCBpbnQgREVGTEFURV9NSU5fVkVSU0lPTiA9IDIwOworCisgICAgLyoqIFpJUCBzcGVjaWZpY2F0aW9uIHZlcnNpb24gdGhhdCBpbnRyb2R1Y2VkIGRhdGEgZGVzY3JpcHRvciBtZXRob2QgKi8KKyAgICBzdGF0aWMgZmluYWwgaW50IERBVEFfREVTQ1JJUFRPUl9NSU5fVkVSU0lPTiA9IDIwOworCisgICAgLyoqIFpJUCBzcGVjaWZpY2F0aW9uIHZlcnNpb24gdGhhdCBpbnRyb2R1Y2VkIFpJUDY0ICovCisgICAgc3RhdGljIGZpbmFsIGludCBaSVA2NF9NSU5fVkVSU0lPTiA9IDQ1OworCisgICAgLyoqCisgICAgICogVmFsdWUgc3RvcmVkIGluIHR3by1ieXRlIHNpemUgYW5kIHNpbWlsYXIgZmllbGRzIGlmIFpJUDY0CisgICAgICogZXh0ZW5zaW9ucyBhcmUgdXNlZC4KKyAgICAgKi8KKyAgICBzdGF0aWMgZmluYWwgaW50IFpJUDY0X01BR0lDX1NIT1JUID0gMHhGRkZGOworCisgICAgLyoqCisgICAgICogVmFsdWUgc3RvcmVkIGluIGZvdXItYnl0ZSBzaXplIGFuZCBzaW1pbGFyIGZpZWxkcyBpZiBaSVA2NAorICAgICAqIGV4dGVuc2lvbnMgYXJlIHVzZWQuCisgICAgICovCisgICAgc3RhdGljIGZpbmFsIGxvbmcgWklQNjRfTUFHSUMgPSAweEZGRkZGRkZGTDsKKworICAgIHByaXZhdGUgWmlwQ29uc3RhbnRzKCkgeyB9CisKK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvWmlwRWlnaHRCeXRlSW50ZWdlci5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9aaXBFaWdodEJ5dGVJbnRlZ2VyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWQ5ZTJlYwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvWmlwRWlnaHRCeXRlSW50ZWdlci5qYXZhCkBAIC0wLDAgKzEsMjM0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwOworCitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CitpbXBvcnQgamF2YS5tYXRoLkJpZ0ludGVnZXI7CisKK2ltcG9ydCBzdGF0aWMgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXAuWmlwQ29uc3RhbnRzLkJZVEVfTUFTSzsKKworLyoqCisgKiBVdGlsaXR5IGNsYXNzIHRoYXQgcmVwcmVzZW50cyBhbiBlaWdodCBieXRlIGludGVnZXIgd2l0aCBjb252ZXJzaW9uCisgKiBydWxlcyBmb3IgdGhlIGxpdHRsZSBlbmRpYW4gYnl0ZSBvcmRlciBvZiBaSVAgZmlsZXMuCisgKiBASW1tdXRhYmxlCisgKgorICogQHNpbmNlIDEuMgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgWmlwRWlnaHRCeXRlSW50ZWdlciBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQllURV8xID0gMTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQllURV8xX01BU0sgPSAweEZGMDA7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEJZVEVfMV9TSElGVCA9IDg7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQllURV8yID0gMjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQllURV8yX01BU0sgPSAweEZGMDAwMDsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQllURV8yX1NISUZUID0gMTY7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQllURV8zID0gMzsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIEJZVEVfM19NQVNLID0gMHhGRjAwMDAwMEw7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEJZVEVfM19TSElGVCA9IDI0OworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEJZVEVfNCA9IDQ7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBCWVRFXzRfTUFTSyA9IDB4RkYwMDAwMDAwMEw7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEJZVEVfNF9TSElGVCA9IDMyOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEJZVEVfNSA9IDU7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBCWVRFXzVfTUFTSyA9IDB4RkYwMDAwMDAwMDAwTDsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQllURV81X1NISUZUID0gNDA7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQllURV82ID0gNjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIEJZVEVfNl9NQVNLID0gMHhGRjAwMDAwMDAwMDAwMEw7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEJZVEVfNl9TSElGVCA9IDQ4OworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEJZVEVfNyA9IDc7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBCWVRFXzdfTUFTSyA9IDB4N0YwMDAwMDAwMDAwMDAwMEw7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEJZVEVfN19TSElGVCA9IDU2OworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IExFRlRNT1NUX0JJVF9TSElGVCA9IDYzOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGUgTEVGVE1PU1RfQklUID0gKGJ5dGUpIDB4ODA7CisKKyAgICBwcml2YXRlIGZpbmFsIEJpZ0ludGVnZXIgdmFsdWU7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFppcEVpZ2h0Qnl0ZUludGVnZXIgWkVSTyA9IG5ldyBaaXBFaWdodEJ5dGVJbnRlZ2VyKDApOworCisgICAgLyoqCisgICAgICogQ3JlYXRlIGluc3RhbmNlIGZyb20gYSBudW1iZXIuCisgICAgICogQHBhcmFtIHZhbHVlIHRoZSBsb25nIHRvIHN0b3JlIGFzIGEgWmlwRWlnaHRCeXRlSW50ZWdlcgorICAgICAqLworICAgIHB1YmxpYyBaaXBFaWdodEJ5dGVJbnRlZ2VyKGZpbmFsIGxvbmcgdmFsdWUpIHsKKyAgICAgICAgdGhpcyhCaWdJbnRlZ2VyLnZhbHVlT2YodmFsdWUpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgaW5zdGFuY2UgZnJvbSBhIG51bWJlci4KKyAgICAgKiBAcGFyYW0gdmFsdWUgdGhlIEJpZ0ludGVnZXIgdG8gc3RvcmUgYXMgYSBaaXBFaWdodEJ5dGVJbnRlZ2VyCisgICAgICovCisgICAgcHVibGljIFppcEVpZ2h0Qnl0ZUludGVnZXIoZmluYWwgQmlnSW50ZWdlciB2YWx1ZSkgeworICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlIGluc3RhbmNlIGZyb20gYnl0ZXMuCisgICAgICogQHBhcmFtIGJ5dGVzIHRoZSBieXRlcyB0byBzdG9yZSBhcyBhIFppcEVpZ2h0Qnl0ZUludGVnZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgWmlwRWlnaHRCeXRlSW50ZWdlciAoZmluYWwgYnl0ZVtdIGJ5dGVzKSB7CisgICAgICAgIHRoaXMoYnl0ZXMsIDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZSBpbnN0YW5jZSBmcm9tIHRoZSBlaWdodCBieXRlcyBzdGFydGluZyBhdCBvZmZzZXQuCisgICAgICogQHBhcmFtIGJ5dGVzIHRoZSBieXRlcyB0byBzdG9yZSBhcyBhIFppcEVpZ2h0Qnl0ZUludGVnZXIKKyAgICAgKiBAcGFyYW0gb2Zmc2V0IHRoZSBvZmZzZXQgdG8gc3RhcnQKKyAgICAgKi8KKyAgICBwdWJsaWMgWmlwRWlnaHRCeXRlSW50ZWdlciAoZmluYWwgYnl0ZVtdIGJ5dGVzLCBmaW5hbCBpbnQgb2Zmc2V0KSB7CisgICAgICAgIHZhbHVlID0gWmlwRWlnaHRCeXRlSW50ZWdlci5nZXRWYWx1ZShieXRlcywgb2Zmc2V0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdmFsdWUgYXMgZWlnaHQgYnl0ZXMgaW4gYmlnIGVuZGlhbiBieXRlIG9yZGVyLgorICAgICAqIEByZXR1cm4gdmFsdWUgYXMgZWlnaHQgYnl0ZXMgaW4gYmlnIGVuZGlhbiBvcmRlcgorICAgICAqLworICAgIHB1YmxpYyBieXRlW10gZ2V0Qnl0ZXMoKSB7CisgICAgICAgIHJldHVybiBaaXBFaWdodEJ5dGVJbnRlZ2VyLmdldEJ5dGVzKHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdmFsdWUgYXMgSmF2YSBsb25nLgorICAgICAqIEByZXR1cm4gdmFsdWUgYXMgYSBsb25nCisgICAgICovCisgICAgcHVibGljIGxvbmcgZ2V0TG9uZ1ZhbHVlKCkgeworICAgICAgICByZXR1cm4gdmFsdWUubG9uZ1ZhbHVlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHZhbHVlIGFzIEphdmEgbG9uZy4KKyAgICAgKiBAcmV0dXJuIHZhbHVlIGFzIGEgbG9uZworICAgICAqLworICAgIHB1YmxpYyBCaWdJbnRlZ2VyIGdldFZhbHVlKCkgeworICAgICAgICByZXR1cm4gdmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHZhbHVlIGFzIGVpZ2h0IGJ5dGVzIGluIGJpZyBlbmRpYW4gYnl0ZSBvcmRlci4KKyAgICAgKiBAcGFyYW0gdmFsdWUgdGhlIHZhbHVlIHRvIGNvbnZlcnQKKyAgICAgKiBAcmV0dXJuIHZhbHVlIGFzIGVpZ2h0IGJ5dGVzIGluIGJpZyBlbmRpYW4gYnl0ZSBvcmRlcgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYnl0ZVtdIGdldEJ5dGVzKGZpbmFsIGxvbmcgdmFsdWUpIHsKKyAgICAgICAgcmV0dXJuIGdldEJ5dGVzKEJpZ0ludGVnZXIudmFsdWVPZih2YWx1ZSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB2YWx1ZSBhcyBlaWdodCBieXRlcyBpbiBiaWcgZW5kaWFuIGJ5dGUgb3JkZXIuCisgICAgICogQHBhcmFtIHZhbHVlIHRoZSB2YWx1ZSB0byBjb252ZXJ0CisgICAgICogQHJldHVybiB2YWx1ZSBhcyBlaWdodCBieXRlcyBpbiBiaWcgZW5kaWFuIGJ5dGUgb3JkZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJ5dGVbXSBnZXRCeXRlcyhmaW5hbCBCaWdJbnRlZ2VyIHZhbHVlKSB7CisgICAgICAgIGZpbmFsIGJ5dGVbXSByZXN1bHQgPSBuZXcgYnl0ZVs4XTsKKyAgICAgICAgZmluYWwgbG9uZyB2YWwgPSB2YWx1ZS5sb25nVmFsdWUoKTsKKyAgICAgICAgcmVzdWx0WzBdID0gKGJ5dGUpICgodmFsICYgQllURV9NQVNLKSk7CisgICAgICAgIHJlc3VsdFtCWVRFXzFdID0gKGJ5dGUpICgodmFsICYgQllURV8xX01BU0spID4+IEJZVEVfMV9TSElGVCk7CisgICAgICAgIHJlc3VsdFtCWVRFXzJdID0gKGJ5dGUpICgodmFsICYgQllURV8yX01BU0spID4+IEJZVEVfMl9TSElGVCk7CisgICAgICAgIHJlc3VsdFtCWVRFXzNdID0gKGJ5dGUpICgodmFsICYgQllURV8zX01BU0spID4+IEJZVEVfM19TSElGVCk7CisgICAgICAgIHJlc3VsdFtCWVRFXzRdID0gKGJ5dGUpICgodmFsICYgQllURV80X01BU0spID4+IEJZVEVfNF9TSElGVCk7CisgICAgICAgIHJlc3VsdFtCWVRFXzVdID0gKGJ5dGUpICgodmFsICYgQllURV81X01BU0spID4+IEJZVEVfNV9TSElGVCk7CisgICAgICAgIHJlc3VsdFtCWVRFXzZdID0gKGJ5dGUpICgodmFsICYgQllURV82X01BU0spID4+IEJZVEVfNl9TSElGVCk7CisgICAgICAgIHJlc3VsdFtCWVRFXzddID0gKGJ5dGUpICgodmFsICYgQllURV83X01BU0spID4+IEJZVEVfN19TSElGVCk7CisgICAgICAgIGlmICh2YWx1ZS50ZXN0Qml0KExFRlRNT1NUX0JJVF9TSElGVCkpIHsKKyAgICAgICAgICAgIHJlc3VsdFtCWVRFXzddIHw9IExFRlRNT1NUX0JJVDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIEhlbHBlciBtZXRob2QgdG8gZ2V0IHRoZSB2YWx1ZSBhcyBhIEphdmEgbG9uZyBmcm9tIGVpZ2h0IGJ5dGVzCisgICAgICogc3RhcnRpbmcgYXQgZ2l2ZW4gYXJyYXkgb2Zmc2V0CisgICAgICogQHBhcmFtIGJ5dGVzIHRoZSBhcnJheSBvZiBieXRlcworICAgICAqIEBwYXJhbSBvZmZzZXQgdGhlIG9mZnNldCB0byBzdGFydAorICAgICAqIEByZXR1cm4gdGhlIGNvcnJlc3BvbmRpbmcgSmF2YSBsb25nIHZhbHVlCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBsb25nIGdldExvbmdWYWx1ZShmaW5hbCBieXRlW10gYnl0ZXMsIGZpbmFsIGludCBvZmZzZXQpIHsKKyAgICAgICAgcmV0dXJuIGdldFZhbHVlKGJ5dGVzLCBvZmZzZXQpLmxvbmdWYWx1ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEhlbHBlciBtZXRob2QgdG8gZ2V0IHRoZSB2YWx1ZSBhcyBhIEphdmEgQmlnSW50ZWdlciBmcm9tIGVpZ2h0CisgICAgICogYnl0ZXMgc3RhcnRpbmcgYXQgZ2l2ZW4gYXJyYXkgb2Zmc2V0CisgICAgICogQHBhcmFtIGJ5dGVzIHRoZSBhcnJheSBvZiBieXRlcworICAgICAqIEBwYXJhbSBvZmZzZXQgdGhlIG9mZnNldCB0byBzdGFydAorICAgICAqIEByZXR1cm4gdGhlIGNvcnJlc3BvbmRpbmcgSmF2YSBCaWdJbnRlZ2VyIHZhbHVlCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBCaWdJbnRlZ2VyIGdldFZhbHVlKGZpbmFsIGJ5dGVbXSBieXRlcywgZmluYWwgaW50IG9mZnNldCkgeworICAgICAgICBsb25nIHZhbHVlID0gKChsb25nKSBieXRlc1tvZmZzZXQgKyBCWVRFXzddIDw8IEJZVEVfN19TSElGVCkgJiBCWVRFXzdfTUFTSzsKKyAgICAgICAgdmFsdWUgKz0gKChsb25nKSBieXRlc1tvZmZzZXQgKyBCWVRFXzZdIDw8IEJZVEVfNl9TSElGVCkgJiBCWVRFXzZfTUFTSzsKKyAgICAgICAgdmFsdWUgKz0gKChsb25nKSBieXRlc1tvZmZzZXQgKyBCWVRFXzVdIDw8IEJZVEVfNV9TSElGVCkgJiBCWVRFXzVfTUFTSzsKKyAgICAgICAgdmFsdWUgKz0gKChsb25nKSBieXRlc1tvZmZzZXQgKyBCWVRFXzRdIDw8IEJZVEVfNF9TSElGVCkgJiBCWVRFXzRfTUFTSzsKKyAgICAgICAgdmFsdWUgKz0gKChsb25nKSBieXRlc1tvZmZzZXQgKyBCWVRFXzNdIDw8IEJZVEVfM19TSElGVCkgJiBCWVRFXzNfTUFTSzsKKyAgICAgICAgdmFsdWUgKz0gKChsb25nKSBieXRlc1tvZmZzZXQgKyBCWVRFXzJdIDw8IEJZVEVfMl9TSElGVCkgJiBCWVRFXzJfTUFTSzsKKyAgICAgICAgdmFsdWUgKz0gKChsb25nKSBieXRlc1tvZmZzZXQgKyBCWVRFXzFdIDw8IEJZVEVfMV9TSElGVCkgJiBCWVRFXzFfTUFTSzsKKyAgICAgICAgdmFsdWUgKz0gKChsb25nKSBieXRlc1tvZmZzZXRdICYgQllURV9NQVNLKTsKKyAgICAgICAgZmluYWwgQmlnSW50ZWdlciB2YWwgPSBCaWdJbnRlZ2VyLnZhbHVlT2YodmFsdWUpOworICAgICAgICByZXR1cm4gKGJ5dGVzW29mZnNldCArIEJZVEVfN10gJiBMRUZUTU9TVF9CSVQpID09IExFRlRNT1NUX0JJVAorICAgICAgICAgICAgPyB2YWwuc2V0Qml0KExFRlRNT1NUX0JJVF9TSElGVCkgOiB2YWw7CisgICAgfQorCisgICAgLyoqCisgICAgICogSGVscGVyIG1ldGhvZCB0byBnZXQgdGhlIHZhbHVlIGFzIGEgSmF2YSBsb25nIGZyb20gYW4gZWlnaHQtYnl0ZSBhcnJheQorICAgICAqIEBwYXJhbSBieXRlcyB0aGUgYXJyYXkgb2YgYnl0ZXMKKyAgICAgKiBAcmV0dXJuIHRoZSBjb3JyZXNwb25kaW5nIEphdmEgbG9uZyB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbG9uZyBnZXRMb25nVmFsdWUoZmluYWwgYnl0ZVtdIGJ5dGVzKSB7CisgICAgICAgIHJldHVybiBnZXRMb25nVmFsdWUoYnl0ZXMsIDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIEhlbHBlciBtZXRob2QgdG8gZ2V0IHRoZSB2YWx1ZSBhcyBhIEphdmEgbG9uZyBmcm9tIGFuIGVpZ2h0LWJ5dGUgYXJyYXkKKyAgICAgKiBAcGFyYW0gYnl0ZXMgdGhlIGFycmF5IG9mIGJ5dGVzCisgICAgICogQHJldHVybiB0aGUgY29ycmVzcG9uZGluZyBKYXZhIEJpZ0ludGVnZXIgdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEJpZ0ludGVnZXIgZ2V0VmFsdWUoZmluYWwgYnl0ZVtdIGJ5dGVzKSB7CisgICAgICAgIHJldHVybiBnZXRWYWx1ZShieXRlcywgMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogT3ZlcnJpZGUgdG8gbWFrZSB0d28gaW5zdGFuY2VzIHdpdGggc2FtZSB2YWx1ZSBlcXVhbC4KKyAgICAgKiBAcGFyYW0gbyBhbiBvYmplY3QgdG8gY29tcGFyZQorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgb2JqZWN0cyBhcmUgZXF1YWwKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgT2JqZWN0IG8pIHsKKyAgICAgICAgaWYgKG8gPT0gbnVsbCB8fCAhKG8gaW5zdGFuY2VvZiBaaXBFaWdodEJ5dGVJbnRlZ2VyKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIHJldHVybiB2YWx1ZS5lcXVhbHMoKChaaXBFaWdodEJ5dGVJbnRlZ2VyKSBvKS5nZXRWYWx1ZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBPdmVycmlkZSB0byBtYWtlIHR3byBpbnN0YW5jZXMgd2l0aCBzYW1lIHZhbHVlIGVxdWFsLgorICAgICAqIEByZXR1cm4gdGhlIGhhc2hDb2RlIG9mIHRoZSB2YWx1ZSBzdG9yZWQgaW4gdGhlIFppcEVpZ2h0Qnl0ZUludGVnZXIKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICByZXR1cm4gdmFsdWUuaGFzaENvZGUoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICByZXR1cm4gIlppcEVpZ2h0Qnl0ZUludGVnZXIgdmFsdWU6ICIgKyB2YWx1ZTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1ppcEVuY29kaW5nLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1ppcEVuY29kaW5nLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGFjZDA2MwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvWmlwRW5jb2RpbmcuamF2YQpAQCAtMCwwICsxLDg0IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKKworLyoqCisgKiBBbiBpbnRlcmZhY2UgZm9yIGVuY29kZXJzIHRoYXQgZG8gYSBwcmV0dHkgZW5jb2Rpbmcgb2YgWklQCisgKiBmaWxlbmFtZXMuCisgKgorICogPHA+VGhlcmUgYXJlIG1vc3RseSB0d28gaW1wbGVtZW50YXRpb25zLCBvbmUgdGhhdCB1c2VzIGphdmEubmlvCisgKiB7QGxpbmsgamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0IENoYXJzZXR9IGFuZCBvbmUgaW1wbGVtZW50YXRpb24sCisgKiB3aGljaCBjb3BlcyB3aXRoIHNpbXBsZSA4IGJpdCBjaGFyc2V0cywgYmVjYXVzZSBqYXZhLTEuNCBkaWQgbm90CisgKiBzdXBwb3J0IENwNDM3IGluIGphdmEubmlvLjwvcD4KKyAqCisgKiA8cD5UaGUgbWFpbiByZWFzb24gZm9yIGRlZmluaW5nIGFuIG93biBlbmNvZGluZyBsYXllciBjb21lcyBmcm9tCisgKiB0aGUgcHJvYmxlbXMgd2l0aCB7QGxpbmsgamF2YS5sYW5nLlN0cmluZyNnZXRCeXRlcyhTdHJpbmcpCisgKiBTdHJpbmcuZ2V0Qnl0ZXN9LCB3aGljaCBlbmNvZGVzIHVua25vd24gY2hhcmFjdGVycyBhcyBBU0NJSQorICogcXVvdGF0aW9uIG1hcmtzICgnPycpLiBRdW90YXRpb24gbWFya3MgYXJlIHBlciBkZWZpbml0aW9uIGFuCisgKiBpbnZhbGlkIGZpbGVuYW1lIG9uIHNvbWUgb3BlcmF0aW5nIHN5c3RlbXMgIGxpa2UgV2luZG93cywgd2hpY2gKKyAqIGxlYWRzIHRvIGlnbm9yZWQgWklQIGVudHJpZXMuPC9wPgorICoKKyAqIDxwPkFsbCBpbXBsZW1lbnRhdGlvbnMgc2hvdWxkIGltcGxlbWVudCB0aGlzIGludGVyZmFjZSBpbiBhCisgKiByZWVudHJhbnQgd2F5LjwvcD4KKyAqLworcHVibGljIGludGVyZmFjZSBaaXBFbmNvZGluZyB7CisgICAgLyoqCisgICAgICogQ2hlY2ssIHdoZXRoZXIgdGhlIGdpdmVuIHN0cmluZyBtYXkgYmUgbG9zc2xlc3NseSBlbmNvZGVkIHVzaW5nIHRoaXMKKyAgICAgKiBlbmNvZGluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lIEEgZmlsZW5hbWUgb3IgWklQIGNvbW1lbnQuCisgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBnaXZlbiBuYW1lIG1heSBiZSBlbmNvZGVkIHdpdGggb3V0IGFueSBsb3NzZXMuCisgICAgICovCisgICAgYm9vbGVhbiBjYW5FbmNvZGUoU3RyaW5nIG5hbWUpOworCisgICAgLyoqCisgICAgICogRW5jb2RlIGEgZmlsZW5hbWUgb3IgYSBjb21tZW50IHRvIGEgYnl0ZSBhcnJheSBzdWl0YWJsZSBmb3IKKyAgICAgKiBzdG9yaW5nIGl0IHRvIGEgc2VyaWFsaXplZCB6aXAgZW50cnkuCisgICAgICoKKyAgICAgKiA8cD5FeGFtcGxlcyBmb3IgQ1AgNDM3IChpbiBwc2V1ZG8tbm90YXRpb24sIHJpZ2h0IGhhbmQgc2lkZSBpcworICAgICAqIEMtc3R5bGUgbm90YXRpb24pOjwvcD4KKyAgICAgKiA8cHJlPgorICAgICAqICBlbmNvZGUoIlx1MjBBQ19mb3JfRG9sbGFyLnR4dCIpID0gIiVVMjBBQ19mb3JfRG9sbGFyLnR4dCIKKyAgICAgKiAgZW5jb2RlKCJcdTAwRDZsZlx1MDBFNHNzZXIudHh0IikgPSAiXDIzMWxmXDIwNHNzZXIudHh0IgorICAgICAqIDwvcHJlPgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgQSBmaWxlbmFtZSBvciBaSVAgY29tbWVudC4KKyAgICAgKiBAcmV0dXJuIEEgYnl0ZSBidWZmZXIgd2l0aCBhIGJhY2tpbmcgYXJyYXkgY29udGFpbmluZyB0aGUKKyAgICAgKiAgICAgICAgIGVuY29kZWQgbmFtZS4gIFVubWFwcGFibGUgY2hhcmFjdGVycyBvciBtYWxmb3JtZWQKKyAgICAgKiAgICAgICAgIGNoYXJhY3RlciBzZXF1ZW5jZXMgYXJlIG1hcHBlZCB0byBhIHNlcXVlbmNlIG9mIHV0Zi0xNgorICAgICAqICAgICAgICAgd29yZHMgZW5jb2RlZCBpbiB0aGUgZm9ybWF0IDxjb2RlPiVVeHh4eDwvY29kZT4uICBJdCBpcworICAgICAqICAgICAgICAgYXNzdW1lZCwgdGhhdCB0aGUgYnl0ZSBidWZmZXIgaXMgcG9zaXRpb25lZCBhdCB0aGUKKyAgICAgKiAgICAgICAgIGJlZ2lubmluZyBvZiB0aGUgZW5jb2RlZCByZXN1bHQsIHRoZSBieXRlIGJ1ZmZlciBoYXMgYQorICAgICAqICAgICAgICAgYmFja2luZyBhcnJheSBhbmQgdGhlIGxpbWl0IG9mIHRoZSBieXRlIGJ1ZmZlciBwb2ludHMKKyAgICAgKiAgICAgICAgIHRvIHRoZSBlbmQgb2YgdGhlIGVuY29kZWQgcmVzdWx0LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gb24gZXJyb3IKKyAgICAgKi8KKyAgICBCeXRlQnVmZmVyIGVuY29kZShTdHJpbmcgbmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQHBhcmFtIGRhdGEgVGhlIGJ5dGUgdmFsdWVzIHRvIGRlY29kZS4KKyAgICAgKiBAcmV0dXJuIFRoZSBkZWNvZGVkIHN0cmluZy4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIG9uIGVycm9yCisgICAgICovCisgICAgU3RyaW5nIGRlY29kZShieXRlIFtdIGRhdGEpIHRocm93cyBJT0V4Y2VwdGlvbjsKK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvWmlwRW5jb2RpbmdIZWxwZXIuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvWmlwRW5jb2RpbmdIZWxwZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44YWViNzg5Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9aaXBFbmNvZGluZ0hlbHBlci5qYXZhCkBAIC0wLDAgKzEsOTYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcDsKKworaW1wb3J0IGphdmEubmlvLkJ5dGVCdWZmZXI7CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0OworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuU3RhbmRhcmRDaGFyc2V0czsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LlVuc3VwcG9ydGVkQ2hhcnNldEV4Y2VwdGlvbjsKKworLyoqCisgKiBTdGF0aWMgaGVscGVyIGZ1bmN0aW9ucyBmb3Igcm9idXN0bHkgZW5jb2RpbmcgZmlsZW5hbWVzIGluIHppcCBmaWxlcy4KKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIFppcEVuY29kaW5nSGVscGVyIHsKKworCisgICAgLyoqCisgICAgICogbmFtZSBvZiB0aGUgZW5jb2RpbmcgVVRGLTgKKyAgICAgKi8KKyAgICBzdGF0aWMgZmluYWwgU3RyaW5nIFVURjggPSAiVVRGOCI7CisKKyAgICAvKioKKyAgICAgKiB0aGUgZW5jb2RpbmcgVVRGLTgKKyAgICAgKi8KKyAgICBzdGF0aWMgZmluYWwgWmlwRW5jb2RpbmcgVVRGOF9aSVBfRU5DT0RJTkcgPSBnZXRaaXBFbmNvZGluZyhVVEY4KTsKKworICAgIC8qKgorICAgICAqIEluc3RhbnRpYXRlcyBhIHppcCBlbmNvZGluZy4gQW4gTklPIGJhc2VkIGNoYXJhY3RlciBzZXQgZW5jb2Rlci9kZWNvZGVyIHdpbGwgYmUgcmV0dXJuZWQuCisgICAgICogQXMgYSBzcGVjaWFsIGNhc2UsIGlmIHRoZSBjaGFyYWN0ZXIgc2V0IGlzIFVURi04LCB0aGUgbmlvIGVuY29kZXIgd2lsbCBiZSBjb25maWd1cmVkICByZXBsYWNlIG1hbGZvcm1lZCBhbmQKKyAgICAgKiB1bm1hcHBhYmxlIGNoYXJhY3RlcnMgd2l0aCAnPycuIFRoaXMgbWF0Y2hlcyBleGlzdGluZyBiZWhhdmlvciBmcm9tIHRoZSBvbGRlciBmYWxsYmFjayBlbmNvZGVyLgorICAgICAqIDxwPgorICAgICAqICAgICBJZiB0aGUgcmVxdWVzdGVkIGNoYXJhY2VyIHNldCBjYW5ub3QgYmUgZm91bmQsIHRoZSBwbGF0Zm9ybSBkZWZhdWx0IHdpbGwKKyAgICAgKiAgICAgYmUgdXNlZCBpbnN0ZWFkLgorICAgICAqIDwvcD4KKyAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgemlwIGVuY29kaW5nLiBTcGVjaWZ5IHtAY29kZSBudWxsfSBmb3IKKyAgICAgKiAgICAgICAgICAgICB0aGUgcGxhdGZvcm0ncyBkZWZhdWx0IGVuY29kaW5nLgorICAgICAqIEByZXR1cm4gQSB6aXAgZW5jb2RpbmcgZm9yIHRoZSBnaXZlbiBlbmNvZGluZyBuYW1lLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgWmlwRW5jb2RpbmcgZ2V0WmlwRW5jb2RpbmcoZmluYWwgU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgQ2hhcnNldCBjcyA9IENoYXJzZXQuZGVmYXVsdENoYXJzZXQoKTsKKyAgICAgICAgaWYgKG5hbWUgIT0gbnVsbCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBjcyA9IENoYXJzZXQuZm9yTmFtZShuYW1lKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkQ2hhcnNldEV4Y2VwdGlvbiBlKSB7IC8vIE5PU09OQVIgd2UgdXNlIHRoZSBkZWZhdWx0IGVuY29kaW5nIGluc3RlYWQKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBib29sZWFuIHVzZVJlcGxhY2VtZW50ID0gaXNVVEY4KGNzLm5hbWUoKSk7CisgICAgICAgIHJldHVybiBuZXcgTmlvWmlwRW5jb2RpbmcoY3MsIHVzZVJlcGxhY2VtZW50KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgYSBnaXZlbiBlbmNvZGluZyBpcyBVVEYtOC4gSWYgdGhlIGdpdmVuIG5hbWUgaXMgbnVsbCwgdGhlbiBjaGVjayB0aGUgcGxhdGZvcm0ncyBkZWZhdWx0IGVuY29kaW5nLgorICAgICAqCisgICAgICogQHBhcmFtIGNoYXJzZXROYW1lIElmIHRoZSBnaXZlbiBuYW1lIGlzIG51bGwsIHRoZW4gY2hlY2sgdGhlIHBsYXRmb3JtJ3MgZGVmYXVsdCBlbmNvZGluZy4KKyAgICAgKi8KKyAgICBzdGF0aWMgYm9vbGVhbiBpc1VURjgoU3RyaW5nIGNoYXJzZXROYW1lKSB7CisgICAgICAgIGlmIChjaGFyc2V0TmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICAvLyBjaGVjayBwbGF0Zm9ybSdzIGRlZmF1bHQgZW5jb2RpbmcKKyAgICAgICAgICAgIGNoYXJzZXROYW1lID0gQ2hhcnNldC5kZWZhdWx0Q2hhcnNldCgpLm5hbWUoKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoU3RhbmRhcmRDaGFyc2V0cy5VVEZfOC5uYW1lKCkuZXF1YWxzSWdub3JlQ2FzZShjaGFyc2V0TmFtZSkpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIGZvciAoZmluYWwgU3RyaW5nIGFsaWFzIDogU3RhbmRhcmRDaGFyc2V0cy5VVEZfOC5hbGlhc2VzKCkpIHsKKyAgICAgICAgICAgIGlmIChhbGlhcy5lcXVhbHNJZ25vcmVDYXNlKGNoYXJzZXROYW1lKSkgeworICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBzdGF0aWMgQnl0ZUJ1ZmZlciBncm93QnVmZmVyQnkoQnl0ZUJ1ZmZlciBidWZmZXIsIGludCBpbmNyZW1lbnQpIHsKKyAgICAgICAgYnVmZmVyLmxpbWl0KGJ1ZmZlci5wb3NpdGlvbigpKTsKKyAgICAgICAgYnVmZmVyLnJld2luZCgpOworCisgICAgICAgIGZpbmFsIEJ5dGVCdWZmZXIgb24gPSBCeXRlQnVmZmVyLmFsbG9jYXRlKGJ1ZmZlci5jYXBhY2l0eSgpICsgaW5jcmVtZW50KTsKKworICAgICAgICBvbi5wdXQoYnVmZmVyKTsKKyAgICAgICAgcmV0dXJuIG9uOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvWmlwRXh0cmFGaWVsZC5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9aaXBFeHRyYUZpZWxkLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmM0NGIyYQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvWmlwRXh0cmFGaWVsZC5qYXZhCkBAIC0wLDAgKzEsOTYgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcDsKKworaW1wb3J0IGphdmEudXRpbC56aXAuWmlwRXhjZXB0aW9uOworCisvKioKKyAqIEdlbmVyYWwgZm9ybWF0IG9mIGV4dHJhIGZpZWxkIGRhdGEuCisgKgorICogPHA+RXh0cmEgZmllbGRzIHVzdWFsbHkgYXBwZWFyIHR3aWNlIHBlciBmaWxlLCBvbmNlIGluIHRoZSBsb2NhbAorICogZmlsZSBkYXRhIGFuZCBvbmNlIGluIHRoZSBjZW50cmFsIGRpcmVjdG9yeS4gIFVzdWFsbHkgdGhleSBhcmUgdGhlCisgKiBzYW1lLCBidXQgdGhleSBkb24ndCBoYXZlIHRvIGJlLiAge0BsaW5rCisgKiBqYXZhLnV0aWwuemlwLlppcE91dHB1dFN0cmVhbSBqYXZhLnV0aWwuemlwLlppcE91dHB1dFN0cmVhbX0gd2lsbAorICogb25seSB1c2UgdGhlIGxvY2FsIGZpbGUgZGF0YSBpbiBib3RoIHBsYWNlcy48L3A+CisgKgorICovCitwdWJsaWMgaW50ZXJmYWNlIFppcEV4dHJhRmllbGQgeworICAgIC8qKgorICAgICAqIFNpemUgb2YgYW4gZXh0cmEgZmllbGQgZmllbGQgaGVhZGVyIChpZCArIGxlbmd0aCkuCisgICAgICogQHNpbmNlIDEuMTQKKyAgICAgKi8KKyAgICBpbnQgRVhUUkFGSUVMRF9IRUFERVJfU0laRSA9IDQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgSGVhZGVyLUlELgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgSGVhZGVySWQgdmFsdWUKKyAgICAgKi8KKyAgICBaaXBTaG9ydCBnZXRIZWFkZXJJZCgpOworCisgICAgLyoqCisgICAgICogTGVuZ3RoIG9mIHRoZSBleHRyYSBmaWVsZCBpbiB0aGUgbG9jYWwgZmlsZSBkYXRhIC0gd2l0aG91dAorICAgICAqIEhlYWRlci1JRCBvciBsZW5ndGggc3BlY2lmaWVyLgorICAgICAqIEByZXR1cm4gdGhlIGxlbmd0aCBvZiB0aGUgZmllbGQgaW4gdGhlIGxvY2FsIGZpbGUgZGF0YQorICAgICAqLworICAgIFppcFNob3J0IGdldExvY2FsRmlsZURhdGFMZW5ndGgoKTsKKworICAgIC8qKgorICAgICAqIExlbmd0aCBvZiB0aGUgZXh0cmEgZmllbGQgaW4gdGhlIGNlbnRyYWwgZGlyZWN0b3J5IC0gd2l0aG91dAorICAgICAqIEhlYWRlci1JRCBvciBsZW5ndGggc3BlY2lmaWVyLgorICAgICAqIEByZXR1cm4gdGhlIGxlbmd0aCBvZiB0aGUgZmllbGQgaW4gdGhlIGNlbnRyYWwgZGlyZWN0b3J5CisgICAgICovCisgICAgWmlwU2hvcnQgZ2V0Q2VudHJhbERpcmVjdG9yeUxlbmd0aCgpOworCisgICAgLyoqCisgICAgICogVGhlIGFjdHVhbCBkYXRhIHRvIHB1dCBpbnRvIGxvY2FsIGZpbGUgZGF0YSAtIHdpdGhvdXQgSGVhZGVyLUlECisgICAgICogb3IgbGVuZ3RoIHNwZWNpZmllci4KKyAgICAgKiBAcmV0dXJuIHRoZSBkYXRhCisgICAgICovCisgICAgYnl0ZVtdIGdldExvY2FsRmlsZURhdGFEYXRhKCk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgYWN0dWFsIGRhdGEgdG8gcHV0IGludG8gY2VudHJhbCBkaXJlY3RvcnkgLSB3aXRob3V0IEhlYWRlci1JRCBvcgorICAgICAqIGxlbmd0aCBzcGVjaWZpZXIuCisgICAgICogQHJldHVybiB0aGUgZGF0YQorICAgICAqLworICAgIGJ5dGVbXSBnZXRDZW50cmFsRGlyZWN0b3J5RGF0YSgpOworCisgICAgLyoqCisgICAgICogUG9wdWxhdGUgZGF0YSBmcm9tIHRoaXMgYXJyYXkgYXMgaWYgaXQgd2FzIGluIGxvY2FsIGZpbGUgZGF0YS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBidWZmZXIgdGhlIGJ1ZmZlciB0byByZWFkIGRhdGEgZnJvbQorICAgICAqIEBwYXJhbSBvZmZzZXQgb2Zmc2V0IGludG8gYnVmZmVyIHRvIHJlYWQgZGF0YQorICAgICAqIEBwYXJhbSBsZW5ndGggdGhlIGxlbmd0aCBvZiBkYXRhCisgICAgICogQHRocm93cyBaaXBFeGNlcHRpb24gb24gZXJyb3IKKyAgICAgKi8KKyAgICB2b2lkIHBhcnNlRnJvbUxvY2FsRmlsZURhdGEoYnl0ZVtdIGJ1ZmZlciwgaW50IG9mZnNldCwgaW50IGxlbmd0aCkKKyAgICAgICAgdGhyb3dzIFppcEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFBvcHVsYXRlIGRhdGEgZnJvbSB0aGlzIGFycmF5IGFzIGlmIGl0IHdhcyBpbiBjZW50cmFsIGRpcmVjdG9yeSBkYXRhLgorICAgICAqCisgICAgICogQHBhcmFtIGJ1ZmZlciB0aGUgYnVmZmVyIHRvIHJlYWQgZGF0YSBmcm9tCisgICAgICogQHBhcmFtIG9mZnNldCBvZmZzZXQgaW50byBidWZmZXIgdG8gcmVhZCBkYXRhCisgICAgICogQHBhcmFtIGxlbmd0aCB0aGUgbGVuZ3RoIG9mIGRhdGEKKyAgICAgKiBAdGhyb3dzIFppcEV4Y2VwdGlvbiBvbiBlcnJvcgorICAgICAqLworICAgIHZvaWQgcGFyc2VGcm9tQ2VudHJhbERpcmVjdG9yeURhdGEoYnl0ZVtdIGJ1ZmZlciwgaW50IG9mZnNldCwgaW50IGxlbmd0aCkKKyAgICAgICAgdGhyb3dzIFppcEV4Y2VwdGlvbjsKK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvWmlwRmlsZS5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9aaXBGaWxlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmJlZWRjYgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvWmlwRmlsZS5qYXZhCkBAIC0wLDAgKzEsMTI3OCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICoKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcDsKKworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQ2xvc2VhYmxlOworaW1wb3J0IGphdmEuaW8uRU9GRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5TZXF1ZW5jZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEubmlvLkJ5dGVCdWZmZXI7CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuRmlsZUNoYW5uZWw7CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuU2Vla2FibGVCeXRlQ2hhbm5lbDsKK2ltcG9ydCBqYXZhLm5pby5maWxlLkZpbGVzOworaW1wb3J0IGphdmEubmlvLmZpbGUuU3RhbmRhcmRPcGVuT3B0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5Db21wYXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuRW51bVNldDsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlua2VkTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC56aXAuSW5mbGF0ZXI7CitpbXBvcnQgamF2YS51dGlsLnppcC5aaXBFeGNlcHRpb247CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuYnppcDIuQlppcDJDb21wcmVzc29ySW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLmRlZmxhdGU2NC5EZWZsYXRlNjRDb21wcmVzc29ySW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLkNvdW50aW5nSW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLklPVXRpbHM7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLklucHV0U3RyZWFtU3RhdGlzdGljczsKKworaW1wb3J0IHN0YXRpYyBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcC5aaXBDb25zdGFudHMuRFdPUkQ7CitpbXBvcnQgc3RhdGljIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwLlppcENvbnN0YW50cy5TSE9SVDsKK2ltcG9ydCBzdGF0aWMgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXAuWmlwQ29uc3RhbnRzLldPUkQ7CitpbXBvcnQgc3RhdGljIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwLlppcENvbnN0YW50cy5aSVA2NF9NQUdJQzsKK2ltcG9ydCBzdGF0aWMgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXAuWmlwQ29uc3RhbnRzLlpJUDY0X01BR0lDX1NIT1JUOworCisvKioKKyAqIFJlcGxhY2VtZW50IGZvciA8Y29kZT5qYXZhLnV0aWwuWmlwRmlsZTwvY29kZT4uCisgKgorICogPHA+VGhpcyBjbGFzcyBhZGRzIHN1cHBvcnQgZm9yIGZpbGUgbmFtZSBlbmNvZGluZ3Mgb3RoZXIgdGhhbiBVVEYtOAorICogKHdoaWNoIGlzIHJlcXVpcmVkIHRvIHdvcmsgb24gWklQIGZpbGVzIGNyZWF0ZWQgYnkgbmF0aXZlIHppcCB0b29scworICogYW5kIGlzIGFibGUgdG8gc2tpcCBhIHByZWFtYmxlIGxpa2UgdGhlIG9uZSBmb3VuZCBpbiBzZWxmCisgKiBleHRyYWN0aW5nIGFyY2hpdmVzLiAgRnVydGhlcm1vcmUgaXQgcmV0dXJucyBpbnN0YW5jZXMgb2YKKyAqIDxjb2RlPm9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwLlppcEFyY2hpdmVFbnRyeTwvY29kZT4KKyAqIGluc3RlYWQgb2YgPGNvZGU+amF2YS51dGlsLnppcC5aaXBFbnRyeTwvY29kZT4uPC9wPgorICoKKyAqIDxwPkl0IGRvZXNuJ3QgZXh0ZW5kIDxjb2RlPmphdmEudXRpbC56aXAuWmlwRmlsZTwvY29kZT4gYXMgaXQgd291bGQKKyAqIGhhdmUgdG8gcmVpbXBsZW1lbnQgYWxsIG1ldGhvZHMgYW55d2F5LiAgTGlrZQorICogPGNvZGU+amF2YS51dGlsLlppcEZpbGU8L2NvZGU+LCBpdCB1c2VzIFNlZWthYmxlQnl0ZUNoYW5uZWwgdW5kZXIgdGhlCisgKiBjb3ZlcnMgYW5kIHN1cHBvcnRzIGNvbXByZXNzZWQgYW5kIHVuY29tcHJlc3NlZCBlbnRyaWVzLiAgQXMgb2YKKyAqIEFwYWNoZSBDb21tb25zIENvbXByZXNzIDEuMyBpdCBhbHNvIHRyYW5zcGFyZW50bHkgc3VwcG9ydHMgWmlwNjQKKyAqIGV4dGVuc2lvbnMgYW5kIHRodXMgaW5kaXZpZHVhbCBlbnRyaWVzIGFuZCBhcmNoaXZlcyBsYXJnZXIgdGhhbiA0CisgKiBHQiBvciB3aXRoIG1vcmUgdGhhbiA2NTUzNiBlbnRyaWVzLjwvcD4KKyAqCisgKiA8cD5UaGUgbWV0aG9kIHNpZ25hdHVyZXMgbWltaWMgdGhlIG9uZXMgb2YKKyAqIDxjb2RlPmphdmEudXRpbC56aXAuWmlwRmlsZTwvY29kZT4sIHdpdGggYSBjb3VwbGUgb2YgZXhjZXB0aW9uczoKKyAqCisgKiA8dWw+CisgKiAgIDxsaT5UaGVyZSBpcyBubyBnZXROYW1lIG1ldGhvZC48L2xpPgorICogICA8bGk+ZW50cmllcyBoYXMgYmVlbiByZW5hbWVkIHRvIGdldEVudHJpZXMuPC9saT4KKyAqICAgPGxpPmdldEVudHJpZXMgYW5kIGdldEVudHJ5IHJldHVybgorICogICA8Y29kZT5vcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcC5aaXBBcmNoaXZlRW50cnk8L2NvZGU+CisgKiAgIGluc3RhbmNlcy48L2xpPgorICogICA8bGk+Y2xvc2UgaXMgYWxsb3dlZCB0byB0aHJvdyBJT0V4Y2VwdGlvbi48L2xpPgorICogPC91bD4KKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBaaXBGaWxlIGltcGxlbWVudHMgQ2xvc2VhYmxlIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgSEFTSF9TSVpFID0gNTA5OworICAgIHN0YXRpYyBmaW5hbCBpbnQgTklCTEVUX01BU0sgPSAweDBmOworICAgIHN0YXRpYyBmaW5hbCBpbnQgQllURV9TSElGVCA9IDg7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFBPU18wID0gMDsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgUE9TXzEgPSAxOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBQT1NfMiA9IDI7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFBPU18zID0gMzsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gT05FX1pFUk9fQllURSA9IG5ldyBieXRlWzFdOworCisgICAgLyoqCisgICAgICogTGlzdCBvZiBlbnRyaWVzIGluIHRoZSBvcmRlciB0aGV5IGFwcGVhciBpbnNpZGUgdGhlIGNlbnRyYWwKKyAgICAgKiBkaXJlY3RvcnkuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBMaXN0PFppcEFyY2hpdmVFbnRyeT4gZW50cmllcyA9CisgICAgICAgIG5ldyBMaW5rZWRMaXN0PD4oKTsKKworICAgIC8qKgorICAgICAqIE1hcHMgU3RyaW5nIHRvIGxpc3Qgb2YgWmlwQXJjaGl2ZUVudHJ5cywgbmFtZSAtPiBhY3R1YWwgZW50cmllcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIE1hcDxTdHJpbmcsIExpbmtlZExpc3Q8WmlwQXJjaGl2ZUVudHJ5Pj4gbmFtZU1hcCA9CisgICAgICAgIG5ldyBIYXNoTWFwPD4oSEFTSF9TSVpFKTsKKworICAgIC8qKgorICAgICAqIFRoZSBlbmNvZGluZyB0byB1c2UgZm9yIGZpbGVuYW1lcyBhbmQgdGhlIGZpbGUgY29tbWVudC4KKyAgICAgKgorICAgICAqIDxwPkZvciBhIGxpc3Qgb2YgcG9zc2libGUgdmFsdWVzIHNlZSA8YQorICAgICAqIGhyZWY9Imh0dHA6Ly9qYXZhLnN1bi5jb20vajJzZS8xLjUuMC9kb2NzL2d1aWRlL2ludGwvZW5jb2RpbmcuZG9jLmh0bWwiPmh0dHA6Ly9qYXZhLnN1bi5jb20vajJzZS8xLjUuMC9kb2NzL2d1aWRlL2ludGwvZW5jb2RpbmcuZG9jLmh0bWw8L2E+LgorICAgICAqIERlZmF1bHRzIHRvIFVURi04LjwvcD4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBlbmNvZGluZzsKKworICAgIC8qKgorICAgICAqIFRoZSB6aXAgZW5jb2RpbmcgdG8gdXNlIGZvciBmaWxlbmFtZXMgYW5kIHRoZSBmaWxlIGNvbW1lbnQuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBaaXBFbmNvZGluZyB6aXBFbmNvZGluZzsKKworICAgIC8qKgorICAgICAqIEZpbGUgbmFtZSBvZiBhY3R1YWwgc291cmNlLgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGFyY2hpdmVOYW1lOworCisgICAgLyoqCisgICAgICogVGhlIGFjdHVhbCBkYXRhIHNvdXJjZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIFNlZWthYmxlQnl0ZUNoYW5uZWwgYXJjaGl2ZTsKKworICAgIC8qKgorICAgICAqIFdoZXRoZXIgdG8gbG9vayBmb3IgYW5kIHVzZSBVbmljb2RlIGV4dHJhIGZpZWxkcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gdXNlVW5pY29kZUV4dHJhRmllbGRzOworCisgICAgLyoqCisgICAgICogV2hldGhlciB0aGUgZmlsZSBpcyBjbG9zZWQuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2xhdGlsZSBib29sZWFuIGNsb3NlZCA9IHRydWU7CisKKyAgICAvLyBjYWNoZWQgYnVmZmVycyAtIG11c3Qgb25seSBiZSB1c2VkIGxvY2FsbHkgaW4gdGhlIGNsYXNzIChDT01QUkVTUy0xNzIgLSByZWR1Y2UgZ2FyYmFnZSBjb2xsZWN0aW9uKQorICAgIHByaXZhdGUgZmluYWwgYnl0ZVtdIGR3b3JkQnVmID0gbmV3IGJ5dGVbRFdPUkRdOworICAgIHByaXZhdGUgZmluYWwgYnl0ZVtdIHdvcmRCdWYgPSBuZXcgYnl0ZVtXT1JEXTsKKyAgICBwcml2YXRlIGZpbmFsIGJ5dGVbXSBjZmhCdWYgPSBuZXcgYnl0ZVtDRkhfTEVOXTsKKyAgICBwcml2YXRlIGZpbmFsIGJ5dGVbXSBzaG9ydEJ1ZiA9IG5ldyBieXRlW1NIT1JUXTsKKyAgICBwcml2YXRlIGZpbmFsIEJ5dGVCdWZmZXIgZHdvcmRCYnVmID0gQnl0ZUJ1ZmZlci53cmFwKGR3b3JkQnVmKTsKKyAgICBwcml2YXRlIGZpbmFsIEJ5dGVCdWZmZXIgd29yZEJidWYgPSBCeXRlQnVmZmVyLndyYXAod29yZEJ1Zik7CisgICAgcHJpdmF0ZSBmaW5hbCBCeXRlQnVmZmVyIGNmaEJidWYgPSBCeXRlQnVmZmVyLndyYXAoY2ZoQnVmKTsKKworICAgIC8qKgorICAgICAqIE9wZW5zIHRoZSBnaXZlbiBmaWxlIGZvciByZWFkaW5nLCBhc3N1bWluZyAiVVRGOCIgZm9yIGZpbGUgbmFtZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZiB0aGUgYXJjaGl2ZS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIHJlYWRpbmcgdGhlIGZpbGUuCisgICAgICovCisgICAgcHVibGljIFppcEZpbGUoZmluYWwgRmlsZSBmKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzKGYsIFppcEVuY29kaW5nSGVscGVyLlVURjgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIE9wZW5zIHRoZSBnaXZlbiBmaWxlIGZvciByZWFkaW5nLCBhc3N1bWluZyAiVVRGOCIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSBuYW1lIG9mIHRoZSBhcmNoaXZlLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgcmVhZGluZyB0aGUgZmlsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgWmlwRmlsZShmaW5hbCBTdHJpbmcgbmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcyhuZXcgRmlsZShuYW1lKSwgWmlwRW5jb2RpbmdIZWxwZXIuVVRGOCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogT3BlbnMgdGhlIGdpdmVuIGZpbGUgZm9yIHJlYWRpbmcsIGFzc3VtaW5nIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBlbmNvZGluZyBmb3IgZmlsZSBuYW1lcywgc2Nhbm5pbmcgdW5pY29kZSBleHRyYSBmaWVsZHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSBuYW1lIG9mIHRoZSBhcmNoaXZlLgorICAgICAqIEBwYXJhbSBlbmNvZGluZyB0aGUgZW5jb2RpbmcgdG8gdXNlIGZvciBmaWxlIG5hbWVzLCB1c2UgbnVsbAorICAgICAqIGZvciB0aGUgcGxhdGZvcm0ncyBkZWZhdWx0IGVuY29kaW5nCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSByZWFkaW5nIHRoZSBmaWxlLgorICAgICAqLworICAgIHB1YmxpYyBaaXBGaWxlKGZpbmFsIFN0cmluZyBuYW1lLCBmaW5hbCBTdHJpbmcgZW5jb2RpbmcpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMobmV3IEZpbGUobmFtZSksIGVuY29kaW5nLCB0cnVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBPcGVucyB0aGUgZ2l2ZW4gZmlsZSBmb3IgcmVhZGluZywgYXNzdW1pbmcgdGhlIHNwZWNpZmllZAorICAgICAqIGVuY29kaW5nIGZvciBmaWxlIG5hbWVzIGFuZCBzY2FubmluZyBmb3IgdW5pY29kZSBleHRyYSBmaWVsZHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZiB0aGUgYXJjaGl2ZS4KKyAgICAgKiBAcGFyYW0gZW5jb2RpbmcgdGhlIGVuY29kaW5nIHRvIHVzZSBmb3IgZmlsZSBuYW1lcywgdXNlIG51bGwKKyAgICAgKiBmb3IgdGhlIHBsYXRmb3JtJ3MgZGVmYXVsdCBlbmNvZGluZworICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgcmVhZGluZyB0aGUgZmlsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgWmlwRmlsZShmaW5hbCBGaWxlIGYsIGZpbmFsIFN0cmluZyBlbmNvZGluZykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcyhmLCBlbmNvZGluZywgdHJ1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogT3BlbnMgdGhlIGdpdmVuIGZpbGUgZm9yIHJlYWRpbmcsIGFzc3VtaW5nIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBlbmNvZGluZyBmb3IgZmlsZSBuYW1lcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmIHRoZSBhcmNoaXZlLgorICAgICAqIEBwYXJhbSBlbmNvZGluZyB0aGUgZW5jb2RpbmcgdG8gdXNlIGZvciBmaWxlIG5hbWVzLCB1c2UgbnVsbAorICAgICAqIGZvciB0aGUgcGxhdGZvcm0ncyBkZWZhdWx0IGVuY29kaW5nCisgICAgICogQHBhcmFtIHVzZVVuaWNvZGVFeHRyYUZpZWxkcyB3aGV0aGVyIHRvIHVzZSBJbmZvWklQIFVuaWNvZGUKKyAgICAgKiBFeHRyYSBGaWVsZHMgKGlmIHByZXNlbnQpIHRvIHNldCB0aGUgZmlsZSBuYW1lcy4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIHJlYWRpbmcgdGhlIGZpbGUuCisgICAgICovCisgICAgcHVibGljIFppcEZpbGUoZmluYWwgRmlsZSBmLCBmaW5hbCBTdHJpbmcgZW5jb2RpbmcsIGZpbmFsIGJvb2xlYW4gdXNlVW5pY29kZUV4dHJhRmllbGRzKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzKEZpbGVzLm5ld0J5dGVDaGFubmVsKGYudG9QYXRoKCksIEVudW1TZXQub2YoU3RhbmRhcmRPcGVuT3B0aW9uLlJFQUQpKSwKKyAgICAgICAgICAgICBmLmdldEFic29sdXRlUGF0aCgpLCBlbmNvZGluZywgdXNlVW5pY29kZUV4dHJhRmllbGRzLCB0cnVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBPcGVucyB0aGUgZ2l2ZW4gY2hhbm5lbCBmb3IgcmVhZGluZywgYXNzdW1pbmcgIlVURjgiIGZvciBmaWxlIG5hbWVzLgorICAgICAqCisgICAgICogPHA+e0BsaW5rCisgICAgICogb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLlNlZWthYmxlSW5NZW1vcnlCeXRlQ2hhbm5lbH0KKyAgICAgKiBhbGxvd3MgeW91IHRvIHJlYWQgZnJvbSBhbiBpbi1tZW1vcnkgYXJjaGl2ZS48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gY2hhbm5lbCB0aGUgYXJjaGl2ZS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIHJlYWRpbmcgdGhlIGZpbGUuCisgICAgICogQHNpbmNlIDEuMTMKKyAgICAgKi8KKyAgICBwdWJsaWMgWmlwRmlsZShmaW5hbCBTZWVrYWJsZUJ5dGVDaGFubmVsIGNoYW5uZWwpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzKGNoYW5uZWwsICJ1bmtub3duIGFyY2hpdmUiLCBaaXBFbmNvZGluZ0hlbHBlci5VVEY4LCB0cnVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBPcGVucyB0aGUgZ2l2ZW4gY2hhbm5lbCBmb3IgcmVhZGluZywgYXNzdW1pbmcgdGhlIHNwZWNpZmllZAorICAgICAqIGVuY29kaW5nIGZvciBmaWxlIG5hbWVzLgorICAgICAqCisgICAgICogPHA+e0BsaW5rCisgICAgICogb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLlNlZWthYmxlSW5NZW1vcnlCeXRlQ2hhbm5lbH0KKyAgICAgKiBhbGxvd3MgeW91IHRvIHJlYWQgZnJvbSBhbiBpbi1tZW1vcnkgYXJjaGl2ZS48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gY2hhbm5lbCB0aGUgYXJjaGl2ZS4KKyAgICAgKiBAcGFyYW0gZW5jb2RpbmcgdGhlIGVuY29kaW5nIHRvIHVzZSBmb3IgZmlsZSBuYW1lcywgdXNlIG51bGwKKyAgICAgKiBmb3IgdGhlIHBsYXRmb3JtJ3MgZGVmYXVsdCBlbmNvZGluZworICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgcmVhZGluZyB0aGUgZmlsZS4KKyAgICAgKiBAc2luY2UgMS4xMworICAgICAqLworICAgIHB1YmxpYyBaaXBGaWxlKGZpbmFsIFNlZWthYmxlQnl0ZUNoYW5uZWwgY2hhbm5lbCwgZmluYWwgU3RyaW5nIGVuY29kaW5nKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzKGNoYW5uZWwsICJ1bmtub3duIGFyY2hpdmUiLCBlbmNvZGluZywgdHJ1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogT3BlbnMgdGhlIGdpdmVuIGNoYW5uZWwgZm9yIHJlYWRpbmcsIGFzc3VtaW5nIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBlbmNvZGluZyBmb3IgZmlsZSBuYW1lcy4KKyAgICAgKgorICAgICAqIDxwPntAbGluaworICAgICAqIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5TZWVrYWJsZUluTWVtb3J5Qnl0ZUNoYW5uZWx9CisgICAgICogYWxsb3dzIHlvdSB0byByZWFkIGZyb20gYW4gaW4tbWVtb3J5IGFyY2hpdmUuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGNoYW5uZWwgdGhlIGFyY2hpdmUuCisgICAgICogQHBhcmFtIGFyY2hpdmVOYW1lIG5hbWUgb2YgdGhlIGFyY2hpdmUsIHVzZWQgZm9yIGVycm9yIG1lc3NhZ2VzIG9ubHkuCisgICAgICogQHBhcmFtIGVuY29kaW5nIHRoZSBlbmNvZGluZyB0byB1c2UgZm9yIGZpbGUgbmFtZXMsIHVzZSBudWxsCisgICAgICogZm9yIHRoZSBwbGF0Zm9ybSdzIGRlZmF1bHQgZW5jb2RpbmcKKyAgICAgKiBAcGFyYW0gdXNlVW5pY29kZUV4dHJhRmllbGRzIHdoZXRoZXIgdG8gdXNlIEluZm9aSVAgVW5pY29kZQorICAgICAqIEV4dHJhIEZpZWxkcyAoaWYgcHJlc2VudCkgdG8gc2V0IHRoZSBmaWxlIG5hbWVzLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgcmVhZGluZyB0aGUgZmlsZS4KKyAgICAgKiBAc2luY2UgMS4xMworICAgICAqLworICAgIHB1YmxpYyBaaXBGaWxlKGZpbmFsIFNlZWthYmxlQnl0ZUNoYW5uZWwgY2hhbm5lbCwgZmluYWwgU3RyaW5nIGFyY2hpdmVOYW1lLAorICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBlbmNvZGluZywgZmluYWwgYm9vbGVhbiB1c2VVbmljb2RlRXh0cmFGaWVsZHMpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMoY2hhbm5lbCwgYXJjaGl2ZU5hbWUsIGVuY29kaW5nLCB1c2VVbmljb2RlRXh0cmFGaWVsZHMsIGZhbHNlKTsKKyAgICB9CisKKyAgICBwcml2YXRlIFppcEZpbGUoZmluYWwgU2Vla2FibGVCeXRlQ2hhbm5lbCBjaGFubmVsLCBmaW5hbCBTdHJpbmcgYXJjaGl2ZU5hbWUsCisgICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBlbmNvZGluZywgZmluYWwgYm9vbGVhbiB1c2VVbmljb2RlRXh0cmFGaWVsZHMsCisgICAgICAgICAgICAgICAgICAgIGZpbmFsIGJvb2xlYW4gY2xvc2VPbkVycm9yKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzLmFyY2hpdmVOYW1lID0gYXJjaGl2ZU5hbWU7CisgICAgICAgIHRoaXMuZW5jb2RpbmcgPSBlbmNvZGluZzsKKyAgICAgICAgdGhpcy56aXBFbmNvZGluZyA9IFppcEVuY29kaW5nSGVscGVyLmdldFppcEVuY29kaW5nKGVuY29kaW5nKTsKKyAgICAgICAgdGhpcy51c2VVbmljb2RlRXh0cmFGaWVsZHMgPSB1c2VVbmljb2RlRXh0cmFGaWVsZHM7CisgICAgICAgIGFyY2hpdmUgPSBjaGFubmVsOworICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZpbmFsIE1hcDxaaXBBcmNoaXZlRW50cnksIE5hbWVBbmRDb21tZW50PiBlbnRyaWVzV2l0aG91dFVURjhGbGFnID0KKyAgICAgICAgICAgICAgICBwb3B1bGF0ZUZyb21DZW50cmFsRGlyZWN0b3J5KCk7CisgICAgICAgICAgICByZXNvbHZlTG9jYWxGaWxlSGVhZGVyRGF0YShlbnRyaWVzV2l0aG91dFVURjhGbGFnKTsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSB0cnVlOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgY2xvc2VkID0gIXN1Y2Nlc3M7CisgICAgICAgICAgICBpZiAoIXN1Y2Nlc3MgJiYgY2xvc2VPbkVycm9yKSB7CisgICAgICAgICAgICAgICAgSU9VdGlscy5jbG9zZVF1aWV0bHkoYXJjaGl2ZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgZW5jb2RpbmcgdG8gdXNlIGZvciBmaWxlbmFtZXMgYW5kIHRoZSBmaWxlIGNvbW1lbnQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIG51bGwgaWYgdXNpbmcgdGhlIHBsYXRmb3JtJ3MgZGVmYXVsdCBjaGFyYWN0ZXIgZW5jb2RpbmcuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRFbmNvZGluZygpIHsKKyAgICAgICAgcmV0dXJuIGVuY29kaW5nOworICAgIH0KKworICAgIC8qKgorICAgICAqIENsb3NlcyB0aGUgYXJjaGl2ZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIGFuIGVycm9yIG9jY3VycyBjbG9zaW5nIHRoZSBhcmNoaXZlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gdGhpcyBmbGFnIGlzIG9ubHkgd3JpdHRlbiBoZXJlIGFuZCByZWFkIGluIGZpbmFsaXplKCkgd2hpY2gKKyAgICAgICAgLy8gY2FuIG5ldmVyIGJlIHJ1biBpbiBwYXJhbGxlbC4KKyAgICAgICAgLy8gbm8gc3luY2hyb25pemF0aW9uIG5lZWRlZC4KKyAgICAgICAgY2xvc2VkID0gdHJ1ZTsKKworICAgICAgICBhcmNoaXZlLmNsb3NlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogY2xvc2UgYSB6aXBmaWxlIHF1aWV0bHk7IHRocm93IG5vIGlvIGZhdWx0LCBkbyBub3RoaW5nCisgICAgICogb24gYSBudWxsIHBhcmFtZXRlcgorICAgICAqIEBwYXJhbSB6aXBmaWxlIGZpbGUgdG8gY2xvc2UsIGNhbiBiZSBudWxsCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGNsb3NlUXVpZXRseShmaW5hbCBaaXBGaWxlIHppcGZpbGUpIHsKKyAgICAgICAgSU9VdGlscy5jbG9zZVF1aWV0bHkoemlwZmlsZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbGwgZW50cmllcy4KKyAgICAgKgorICAgICAqIDxwPkVudHJpZXMgd2lsbCBiZSByZXR1cm5lZCBpbiB0aGUgc2FtZSBvcmRlciB0aGV5IGFwcGVhcgorICAgICAqIHdpdGhpbiB0aGUgYXJjaGl2ZSdzIGNlbnRyYWwgZGlyZWN0b3J5LjwvcD4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYWxsIGVudHJpZXMgYXMge0BsaW5rIFppcEFyY2hpdmVFbnRyeX0gaW5zdGFuY2VzCisgICAgICovCisgICAgcHVibGljIEVudW1lcmF0aW9uPFppcEFyY2hpdmVFbnRyeT4gZ2V0RW50cmllcygpIHsKKyAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLmVudW1lcmF0aW9uKGVudHJpZXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYWxsIGVudHJpZXMgaW4gcGh5c2ljYWwgb3JkZXIuCisgICAgICoKKyAgICAgKiA8cD5FbnRyaWVzIHdpbGwgYmUgcmV0dXJuZWQgaW4gdGhlIHNhbWUgb3JkZXIgdGhlaXIgY29udGVudHMKKyAgICAgKiBhcHBlYXIgd2l0aGluIHRoZSBhcmNoaXZlLjwvcD4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYWxsIGVudHJpZXMgYXMge0BsaW5rIFppcEFyY2hpdmVFbnRyeX0gaW5zdGFuY2VzCisgICAgICoKKyAgICAgKiBAc2luY2UgMS4xCisgICAgICovCisgICAgcHVibGljIEVudW1lcmF0aW9uPFppcEFyY2hpdmVFbnRyeT4gZ2V0RW50cmllc0luUGh5c2ljYWxPcmRlcigpIHsKKyAgICAgICAgZmluYWwgWmlwQXJjaGl2ZUVudHJ5W10gYWxsRW50cmllcyA9IGVudHJpZXMudG9BcnJheShuZXcgWmlwQXJjaGl2ZUVudHJ5W2VudHJpZXMuc2l6ZSgpXSk7CisgICAgICAgIEFycmF5cy5zb3J0KGFsbEVudHJpZXMsIG9mZnNldENvbXBhcmF0b3IpOworICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMuZW51bWVyYXRpb24oQXJyYXlzLmFzTGlzdChhbGxFbnRyaWVzKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5hbWVkIGVudHJ5IC0gb3Ige0Bjb2RlIG51bGx9IGlmIG5vIGVudHJ5IGJ5CisgICAgICogdGhhdCBuYW1lIGV4aXN0cy4KKyAgICAgKgorICAgICAqIDxwPklmIG11bHRpcGxlIGVudHJpZXMgd2l0aCB0aGUgc2FtZSBuYW1lIGV4aXN0IHRoZSBmaXJzdCBlbnRyeQorICAgICAqIGluIHRoZSBhcmNoaXZlJ3MgY2VudHJhbCBkaXJlY3RvcnkgYnkgdGhhdCBuYW1lIGlzCisgICAgICogcmV0dXJuZWQuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgbmFtZSBvZiB0aGUgZW50cnkuCisgICAgICogQHJldHVybiB0aGUgWmlwQXJjaGl2ZUVudHJ5IGNvcnJlc3BvbmRpbmcgdG8gdGhlIGdpdmVuIG5hbWUgLSBvcgorICAgICAqIHtAY29kZSBudWxsfSBpZiBub3QgcHJlc2VudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgWmlwQXJjaGl2ZUVudHJ5IGdldEVudHJ5KGZpbmFsIFN0cmluZyBuYW1lKSB7CisgICAgICAgIGZpbmFsIExpbmtlZExpc3Q8WmlwQXJjaGl2ZUVudHJ5PiBlbnRyaWVzT2ZUaGF0TmFtZSA9IG5hbWVNYXAuZ2V0KG5hbWUpOworICAgICAgICByZXR1cm4gZW50cmllc09mVGhhdE5hbWUgIT0gbnVsbCA/IGVudHJpZXNPZlRoYXROYW1lLmdldEZpcnN0KCkgOiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYWxsIG5hbWVkIGVudHJpZXMgaW4gdGhlIHNhbWUgb3JkZXIgdGhleSBhcHBlYXIgd2l0aGluCisgICAgICogdGhlIGFyY2hpdmUncyBjZW50cmFsIGRpcmVjdG9yeS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lIG5hbWUgb2YgdGhlIGVudHJ5LgorICAgICAqIEByZXR1cm4gdGhlIEl0ZXJhYmxlJmx0O1ppcEFyY2hpdmVFbnRyeSZndDsgY29ycmVzcG9uZGluZyB0byB0aGUKKyAgICAgKiBnaXZlbiBuYW1lCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBJdGVyYWJsZTxaaXBBcmNoaXZlRW50cnk+IGdldEVudHJpZXMoZmluYWwgU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgZmluYWwgTGlzdDxaaXBBcmNoaXZlRW50cnk+IGVudHJpZXNPZlRoYXROYW1lID0gbmFtZU1hcC5nZXQobmFtZSk7CisgICAgICAgIHJldHVybiBlbnRyaWVzT2ZUaGF0TmFtZSAhPSBudWxsID8gZW50cmllc09mVGhhdE5hbWUKKyAgICAgICAgICAgIDogQ29sbGVjdGlvbnMuPFppcEFyY2hpdmVFbnRyeT5lbXB0eUxpc3QoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFsbCBuYW1lZCBlbnRyaWVzIGluIHRoZSBzYW1lIG9yZGVyIHRoZWlyIGNvbnRlbnRzCisgICAgICogYXBwZWFyIHdpdGhpbiB0aGUgYXJjaGl2ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lIG5hbWUgb2YgdGhlIGVudHJ5LgorICAgICAqIEByZXR1cm4gdGhlIEl0ZXJhYmxlJmx0O1ppcEFyY2hpdmVFbnRyeSZndDsgY29ycmVzcG9uZGluZyB0byB0aGUKKyAgICAgKiBnaXZlbiBuYW1lCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBJdGVyYWJsZTxaaXBBcmNoaXZlRW50cnk+IGdldEVudHJpZXNJblBoeXNpY2FsT3JkZXIoZmluYWwgU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgWmlwQXJjaGl2ZUVudHJ5W10gZW50cmllc09mVGhhdE5hbWUgPSBuZXcgWmlwQXJjaGl2ZUVudHJ5WzBdOworICAgICAgICBpZiAobmFtZU1hcC5jb250YWluc0tleShuYW1lKSkgeworICAgICAgICAgICAgZW50cmllc09mVGhhdE5hbWUgPSBuYW1lTWFwLmdldChuYW1lKS50b0FycmF5KGVudHJpZXNPZlRoYXROYW1lKTsKKyAgICAgICAgICAgIEFycmF5cy5zb3J0KGVudHJpZXNPZlRoYXROYW1lLCBvZmZzZXRDb21wYXJhdG9yKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gQXJyYXlzLmFzTGlzdChlbnRyaWVzT2ZUaGF0TmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogV2hldGhlciB0aGlzIGNsYXNzIGlzIGFibGUgdG8gcmVhZCB0aGUgZ2l2ZW4gZW50cnkuCisgICAgICoKKyAgICAgKiA8cD5NYXkgcmV0dXJuIGZhbHNlIGlmIGl0IGlzIHNldCB1cCB0byB1c2UgZW5jcnlwdGlvbiBvciBhCisgICAgICogY29tcHJlc3Npb24gbWV0aG9kIHRoYXQgaGFzbid0IGJlZW4gaW1wbGVtZW50ZWQgeWV0LjwvcD4KKyAgICAgKiBAc2luY2UgMS4xCisgICAgICogQHBhcmFtIHplIHRoZSBlbnRyeQorICAgICAqIEByZXR1cm4gd2hldGhlciB0aGlzIGNsYXNzIGlzIGFibGUgdG8gcmVhZCB0aGUgZ2l2ZW4gZW50cnkuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gY2FuUmVhZEVudHJ5RGF0YShmaW5hbCBaaXBBcmNoaXZlRW50cnkgemUpIHsKKyAgICAgICAgcmV0dXJuIFppcFV0aWwuY2FuSGFuZGxlRW50cnlEYXRhKHplKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFeHBvc2UgdGhlIHJhdyBzdHJlYW0gb2YgdGhlIGFyY2hpdmUgZW50cnkgKGNvbXByZXNzZWQgZm9ybSkuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBkb2VzIG5vdCByZWxhdGUgdG8gaG93L2lmIHdlIHVuZGVyc3RhbmQgdGhlIHBheWxvYWQgaW4gdGhlCisgICAgICogc3RyZWFtLCBzaW5jZSB3ZSByZWFsbHkgb25seSBpbnRlbmQgdG8gbW92ZSBpdCBvbiB0byBzb21ld2hlcmUgZWxzZS48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gemUgVGhlIGVudHJ5IHRvIGdldCB0aGUgc3RyZWFtIGZvcgorICAgICAqIEByZXR1cm4gVGhlIHJhdyBpbnB1dCBzdHJlYW0gY29udGFpbmluZyAocG9zc2libHkpIGNvbXByZXNzZWQgZGF0YS4KKyAgICAgKiBAc2luY2UgMS4xMQorICAgICAqLworICAgIHB1YmxpYyBJbnB1dFN0cmVhbSBnZXRSYXdJbnB1dFN0cmVhbShmaW5hbCBaaXBBcmNoaXZlRW50cnkgemUpIHsKKyAgICAgICAgaWYgKCEoemUgaW5zdGFuY2VvZiBFbnRyeSkpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIGZpbmFsIGxvbmcgc3RhcnQgPSB6ZS5nZXREYXRhT2Zmc2V0KCk7CisgICAgICAgIHJldHVybiBjcmVhdGVCb3VuZGVkSW5wdXRTdHJlYW0oc3RhcnQsIHplLmdldENvbXByZXNzZWRTaXplKCkpOworICAgIH0KKworCisgICAgLyoqCisgICAgICogVHJhbnNmZXIgc2VsZWN0ZWQgZW50cmllcyBmcm9tIHRoaXMgemlwZmlsZSB0byBhIGdpdmVuICNaaXBBcmNoaXZlT3V0cHV0U3RyZWFtLgorICAgICAqIENvbXByZXNzaW9uIGFuZCBhbGwgb3RoZXIgYXR0cmlidXRlcyB3aWxsIGJlIGFzIGluIHRoaXMgZmlsZS4KKyAgICAgKiA8cD5UaGlzIG1ldGhvZCB0cmFuc2ZlcnMgZW50cmllcyBiYXNlZCBvbiB0aGUgY2VudHJhbCBkaXJlY3Rvcnkgb2YgdGhlIHppcCBmaWxlLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0YXJnZXQgVGhlIHppcEFyY2hpdmVPdXRwdXRTdHJlYW0gdG8gd3JpdGUgdGhlIGVudHJpZXMgdG8KKyAgICAgKiBAcGFyYW0gcHJlZGljYXRlIEEgcHJlZGljYXRlIHRoYXQgc2VsZWN0cyB3aGljaCBlbnRyaWVzIHRvIHdyaXRlCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBvbiBlcnJvcgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNvcHlSYXdFbnRyaWVzKGZpbmFsIFppcEFyY2hpdmVPdXRwdXRTdHJlYW0gdGFyZ2V0LCBmaW5hbCBaaXBBcmNoaXZlRW50cnlQcmVkaWNhdGUgcHJlZGljYXRlKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgRW51bWVyYXRpb248WmlwQXJjaGl2ZUVudHJ5PiBzcmMgPSBnZXRFbnRyaWVzSW5QaHlzaWNhbE9yZGVyKCk7CisgICAgICAgIHdoaWxlIChzcmMuaGFzTW9yZUVsZW1lbnRzKCkpIHsKKyAgICAgICAgICAgIGZpbmFsIFppcEFyY2hpdmVFbnRyeSBlbnRyeSA9IHNyYy5uZXh0RWxlbWVudCgpOworICAgICAgICAgICAgaWYgKHByZWRpY2F0ZS50ZXN0KCBlbnRyeSkpIHsKKyAgICAgICAgICAgICAgICB0YXJnZXQuYWRkUmF3QXJjaGl2ZUVudHJ5KGVudHJ5LCBnZXRSYXdJbnB1dFN0cmVhbShlbnRyeSkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBJbnB1dFN0cmVhbSBmb3IgcmVhZGluZyB0aGUgY29udGVudHMgb2YgdGhlIGdpdmVuIGVudHJ5LgorICAgICAqCisgICAgICogQHBhcmFtIHplIHRoZSBlbnRyeSB0byBnZXQgdGhlIHN0cmVhbSBmb3IuCisgICAgICogQHJldHVybiBhIHN0cmVhbSB0byByZWFkIHRoZSBlbnRyeSBmcm9tLiBUaGUgcmV0dXJuZWQgc3RyZWFtCisgICAgICogaW1wbGVtZW50cyB7QGxpbmsgSW5wdXRTdHJlYW1TdGF0aXN0aWNzfS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHVuYWJsZSB0byBjcmVhdGUgYW4gaW5wdXQgc3RyZWFtIGZyb20gdGhlIHppcGVudHJ5CisgICAgICovCisgICAgcHVibGljIElucHV0U3RyZWFtIGdldElucHV0U3RyZWFtKGZpbmFsIFppcEFyY2hpdmVFbnRyeSB6ZSkKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCEoemUgaW5zdGFuY2VvZiBFbnRyeSkpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIC8vIGNhc3QgdmFsaWRpdHkgaXMgY2hlY2tlZCBqdXN0IGFib3ZlCisgICAgICAgIFppcFV0aWwuY2hlY2tSZXF1ZXN0ZWRGZWF0dXJlcyh6ZSk7CisgICAgICAgIGZpbmFsIGxvbmcgc3RhcnQgPSB6ZS5nZXREYXRhT2Zmc2V0KCk7CisKKyAgICAgICAgLy8gZG9lc24ndCBnZXQgY2xvc2VkIGlmIHRoZSBtZXRob2QgaXMgbm90IHN1cHBvcnRlZCAtIHdoaWNoCisgICAgICAgIC8vIHNob3VsZCBuZXZlciBoYXBwZW4gYmVjYXVzZSBvZiB0aGUgY2hlY2tSZXF1ZXN0ZWRGZWF0dXJlcworICAgICAgICAvLyBjYWxsIGFib3ZlCisgICAgICAgIGZpbmFsIElucHV0U3RyZWFtIGlzID0KKyAgICAgICAgICAgIG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKGNyZWF0ZUJvdW5kZWRJbnB1dFN0cmVhbShzdGFydCwgemUuZ2V0Q29tcHJlc3NlZFNpemUoKSkpOyAvL05PU09OQVIKKyAgICAgICAgc3dpdGNoIChaaXBNZXRob2QuZ2V0TWV0aG9kQnlDb2RlKHplLmdldE1ldGhvZCgpKSkgeworICAgICAgICAgICAgY2FzZSBTVE9SRUQ6CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTdG9yZWRTdGF0aXN0aWNzU3RyZWFtKGlzKTsKKyAgICAgICAgICAgIGNhc2UgVU5TSFJJTktJTkc6CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBVbnNocmlua2luZ0lucHV0U3RyZWFtKGlzKTsKKyAgICAgICAgICAgIGNhc2UgSU1QTE9ESU5HOgorICAgICAgICAgICAgICAgIHJldHVybiBuZXcgRXhwbG9kaW5nSW5wdXRTdHJlYW0oemUuZ2V0R2VuZXJhbFB1cnBvc2VCaXQoKS5nZXRTbGlkaW5nRGljdGlvbmFyeVNpemUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHplLmdldEdlbmVyYWxQdXJwb3NlQml0KCkuZ2V0TnVtYmVyT2ZTaGFubm9uRmFub1RyZWVzKCksIGlzKTsKKyAgICAgICAgICAgIGNhc2UgREVGTEFURUQ6CisgICAgICAgICAgICAgICAgZmluYWwgSW5mbGF0ZXIgaW5mbGF0ZXIgPSBuZXcgSW5mbGF0ZXIodHJ1ZSk7CisgICAgICAgICAgICAgICAgLy8gSW5mbGF0ZXIgd2l0aCBub3dyYXA9dHJ1ZSBoYXMgdGhpcyBvZGQgY29udHJhY3QgZm9yIGEgemVybyBwYWRkaW5nCisgICAgICAgICAgICAgICAgLy8gYnl0ZSBmb2xsb3dpbmcgdGhlIGRhdGEgc3RyZWFtOyB0aGlzIHVzZWQgdG8gYmUgemxpYidzIHJlcXVpcmVtZW50CisgICAgICAgICAgICAgICAgLy8gYW5kIGhhcyBiZWVuIGZpeGVkIGEgbG9uZyB0aW1lIGFnbywgYnV0IHRoZSBjb250cmFjdCBwZXJzaXN0cyBzbworICAgICAgICAgICAgICAgIC8vIHdlIGNvbXBseS4KKyAgICAgICAgICAgICAgICAvLyBodHRwczovL2RvY3Mub3JhY2xlLmNvbS9qYXZhc2UvNy9kb2NzL2FwaS9qYXZhL3V0aWwvemlwL0luZmxhdGVyLmh0bWwjSW5mbGF0ZXIoYm9vbGVhbikKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEluZmxhdGVySW5wdXRTdHJlYW1XaXRoU3RhdGlzdGljcyhuZXcgU2VxdWVuY2VJbnB1dFN0cmVhbShpcywgbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKE9ORV9aRVJPX0JZVEUpKSwKKyAgICAgICAgICAgICAgICAgICAgaW5mbGF0ZXIpIHsKKyAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VwZXIuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5mbGF0ZXIuZW5kKCk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9OworICAgICAgICAgICAgY2FzZSBCWklQMjoKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEJaaXAyQ29tcHJlc3NvcklucHV0U3RyZWFtKGlzKTsKKyAgICAgICAgICAgIGNhc2UgRU5IQU5DRURfREVGTEFURUQ6CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBEZWZsYXRlNjRDb21wcmVzc29ySW5wdXRTdHJlYW0oaXMpOworICAgICAgICAgICAgY2FzZSBBRVNfRU5DUllQVEVEOgorICAgICAgICAgICAgY2FzZSBFWFBBTkRJTkdfTEVWRUxfMToKKyAgICAgICAgICAgIGNhc2UgRVhQQU5ESU5HX0xFVkVMXzI6CisgICAgICAgICAgICBjYXNlIEVYUEFORElOR19MRVZFTF8zOgorICAgICAgICAgICAgY2FzZSBFWFBBTkRJTkdfTEVWRUxfNDoKKyAgICAgICAgICAgIGNhc2UgSlBFRzoKKyAgICAgICAgICAgIGNhc2UgTFpNQToKKyAgICAgICAgICAgIGNhc2UgUEtXQVJFX0lNUExPRElORzoKKyAgICAgICAgICAgIGNhc2UgUFBNRDoKKyAgICAgICAgICAgIGNhc2UgVE9LRU5JWkFUSU9OOgorICAgICAgICAgICAgY2FzZSBVTktOT1dOOgorICAgICAgICAgICAgY2FzZSBXQVZQQUNLOgorICAgICAgICAgICAgY2FzZSBYWjoKKyAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFppcEV4Y2VwdGlvbigiRm91bmQgdW5zdXBwb3J0ZWQgY29tcHJlc3Npb24gbWV0aG9kICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgemUuZ2V0TWV0aG9kKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+CisgICAgICogQ29udmVuaWVuY2UgbWV0aG9kIHRvIHJldHVybiB0aGUgZW50cnkncyBjb250ZW50IGFzIGEgU3RyaW5nIGlmIGlzVW5peFN5bWxpbmsoKQorICAgICAqIHJldHVybnMgdHJ1ZSBmb3IgaXQsIG90aGVyd2lzZSByZXR1cm5zIG51bGwuCisgICAgICogPC9wPgorICAgICAqCisgICAgICogPHA+VGhpcyBtZXRob2QgYXNzdW1lcyB0aGUgc3ltYm9saWMgbGluaydzIGZpbGUgbmFtZSB1c2VzIHRoZQorICAgICAqIHNhbWUgZW5jb2RpbmcgdGhhdCBhcyBiZWVuIHNwZWNpZmllZCBmb3IgdGhpcyBaaXBGaWxlLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlbnRyeSBaaXBBcmNoaXZlRW50cnkgb2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgc3ltYm9saWMgbGluaworICAgICAqIEByZXR1cm4gZW50cnkncyBjb250ZW50IGFzIGEgU3RyaW5nCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBwcm9ibGVtIHdpdGggY29udGVudCdzIGlucHV0IHN0cmVhbQorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFVuaXhTeW1saW5rKGZpbmFsIFppcEFyY2hpdmVFbnRyeSBlbnRyeSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGVudHJ5ICE9IG51bGwgJiYgZW50cnkuaXNVbml4U3ltbGluaygpKSB7CisgICAgICAgICAgICB0cnkgKElucHV0U3RyZWFtIGluID0gZ2V0SW5wdXRTdHJlYW0oZW50cnkpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHppcEVuY29kaW5nLmRlY29kZShJT1V0aWxzLnRvQnl0ZUFycmF5KGluKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogRW5zdXJlcyB0aGF0IHRoZSBjbG9zZSBtZXRob2Qgb2YgdGhpcyB6aXBmaWxlIGlzIGNhbGxlZCB3aGVuCisgICAgICogdGhlcmUgYXJlIG5vIG1vcmUgcmVmZXJlbmNlcyB0byBpdC4KKyAgICAgKiBAc2VlICNjbG9zZSgpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgZmluYWxpemUoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlmICghY2xvc2VkKSB7CisgICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJDbGVhbmluZyB1cCB1bmNsb3NlZCBaaXBGaWxlIGZvciBhcmNoaXZlICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBhcmNoaXZlTmFtZSk7CisgICAgICAgICAgICAgICAgY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHN1cGVyLmZpbmFsaXplKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMZW5ndGggb2YgYSAiY2VudHJhbCBkaXJlY3RvcnkiIGVudHJ5IHN0cnVjdHVyZSB3aXRob3V0IGZpbGUKKyAgICAgKiBuYW1lLCBleHRyYSBmaWVsZHMgb3IgY29tbWVudC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQ0ZIX0xFTiA9CisgICAgICAgIC8qIHZlcnNpb24gbWFkZSBieSAgICAgICAgICAgICAgICAgKi8gU0hPUlQKKyAgICAgICAgLyogdmVyc2lvbiBuZWVkZWQgdG8gZXh0cmFjdCAgICAgICAqLyArIFNIT1JUCisgICAgICAgIC8qIGdlbmVyYWwgcHVycG9zZSBiaXQgZmxhZyAgICAgICAgKi8gKyBTSE9SVAorICAgICAgICAvKiBjb21wcmVzc2lvbiBtZXRob2QgICAgICAgICAgICAgICovICsgU0hPUlQKKyAgICAgICAgLyogbGFzdCBtb2QgZmlsZSB0aW1lICAgICAgICAgICAgICAqLyArIFNIT1JUCisgICAgICAgIC8qIGxhc3QgbW9kIGZpbGUgZGF0ZSAgICAgICAgICAgICAgKi8gKyBTSE9SVAorICAgICAgICAvKiBjcmMtMzIgICAgICAgICAgICAgICAgICAgICAgICAgICovICsgV09SRAorICAgICAgICAvKiBjb21wcmVzc2VkIHNpemUgICAgICAgICAgICAgICAgICovICsgV09SRAorICAgICAgICAvKiB1bmNvbXByZXNzZWQgc2l6ZSAgICAgICAgICAgICAgICovICsgV09SRAorICAgICAgICAvKiBmaWxlbmFtZSBsZW5ndGggICAgICAgICAgICAgICAgICovICsgU0hPUlQKKyAgICAgICAgLyogZXh0cmEgZmllbGQgbGVuZ3RoICAgICAgICAgICAgICAqLyArIFNIT1JUCisgICAgICAgIC8qIGZpbGUgY29tbWVudCBsZW5ndGggICAgICAgICAgICAgKi8gKyBTSE9SVAorICAgICAgICAvKiBkaXNrIG51bWJlciBzdGFydCAgICAgICAgICAgICAgICovICsgU0hPUlQKKyAgICAgICAgLyogaW50ZXJuYWwgZmlsZSBhdHRyaWJ1dGVzICAgICAgICAqLyArIFNIT1JUCisgICAgICAgIC8qIGV4dGVybmFsIGZpbGUgYXR0cmlidXRlcyAgICAgICAgKi8gKyBXT1JECisgICAgICAgIC8qIHJlbGF0aXZlIG9mZnNldCBvZiBsb2NhbCBoZWFkZXIgKi8gKyBXT1JEOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBDRkhfU0lHID0KKyAgICAgICAgWmlwTG9uZy5nZXRWYWx1ZShaaXBBcmNoaXZlT3V0cHV0U3RyZWFtLkNGSF9TSUcpOworCisgICAgLyoqCisgICAgICogUmVhZHMgdGhlIGNlbnRyYWwgZGlyZWN0b3J5IG9mIHRoZSBnaXZlbiBhcmNoaXZlIGFuZCBwb3B1bGF0ZXMKKyAgICAgKiB0aGUgaW50ZXJuYWwgdGFibGVzIHdpdGggWmlwQXJjaGl2ZUVudHJ5IGluc3RhbmNlcy4KKyAgICAgKgorICAgICAqIDxwPlRoZSBaaXBBcmNoaXZlRW50cnlzIHdpbGwga25vdyBhbGwgZGF0YSB0aGF0IGNhbiBiZSBvYnRhaW5lZCBmcm9tCisgICAgICogdGhlIGNlbnRyYWwgZGlyZWN0b3J5IGFsb25lLCBidXQgbm90IHRoZSBkYXRhIHRoYXQgcmVxdWlyZXMgdGhlCisgICAgICogbG9jYWwgZmlsZSBoZWFkZXIgb3IgYWRkaXRpb25hbCBkYXRhIHRvIGJlIHJlYWQuPC9wPgorICAgICAqCisgICAgICogQHJldHVybiBhIG1hcCBvZiB6aXBlbnRyaWVzIHRoYXQgZGlkbid0IGhhdmUgdGhlIGxhbmd1YWdlCisgICAgICogZW5jb2RpbmcgZmxhZyBzZXQgd2hlbiByZWFkLgorICAgICAqLworICAgIHByaXZhdGUgTWFwPFppcEFyY2hpdmVFbnRyeSwgTmFtZUFuZENvbW1lbnQ+IHBvcHVsYXRlRnJvbUNlbnRyYWxEaXJlY3RvcnkoKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBIYXNoTWFwPFppcEFyY2hpdmVFbnRyeSwgTmFtZUFuZENvbW1lbnQ+IG5vVVRGOEZsYWcgPQorICAgICAgICAgICAgbmV3IEhhc2hNYXA8PigpOworCisgICAgICAgIHBvc2l0aW9uQXRDZW50cmFsRGlyZWN0b3J5KCk7CisKKyAgICAgICAgd29yZEJidWYucmV3aW5kKCk7CisgICAgICAgIElPVXRpbHMucmVhZEZ1bGx5KGFyY2hpdmUsIHdvcmRCYnVmKTsKKyAgICAgICAgbG9uZyBzaWcgPSBaaXBMb25nLmdldFZhbHVlKHdvcmRCdWYpOworCisgICAgICAgIGlmIChzaWcgIT0gQ0ZIX1NJRyAmJiBzdGFydHNXaXRoTG9jYWxGaWxlSGVhZGVyKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiY2VudHJhbCBkaXJlY3RvcnkgaXMgZW1wdHksIGNhbid0IGV4cGFuZCIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgY29ycnVwdCBhcmNoaXZlLiIpOworICAgICAgICB9CisKKyAgICAgICAgd2hpbGUgKHNpZyA9PSBDRkhfU0lHKSB7CisgICAgICAgICAgICByZWFkQ2VudHJhbERpcmVjdG9yeUVudHJ5KG5vVVRGOEZsYWcpOworICAgICAgICAgICAgd29yZEJidWYucmV3aW5kKCk7CisgICAgICAgICAgICBJT1V0aWxzLnJlYWRGdWxseShhcmNoaXZlLCB3b3JkQmJ1Zik7CisgICAgICAgICAgICBzaWcgPSBaaXBMb25nLmdldFZhbHVlKHdvcmRCdWYpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBub1VURjhGbGFnOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGFuIGluZGl2aWR1YWwgZW50cnkgb2YgdGhlIGNlbnRyYWwgZGlyZWN0b3J5LCBjcmVhdHMgYW4KKyAgICAgKiBaaXBBcmNoaXZlRW50cnkgZnJvbSBpdCBhbmQgYWRkcyBpdCB0byB0aGUgZ2xvYmFsIG1hcHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbm9VVEY4RmxhZyBtYXAgdXNlZCB0byBjb2xsZWN0IGVudHJpZXMgdGhhdCBkb24ndCBoYXZlCisgICAgICogdGhlaXIgVVRGLTggZmxhZyBzZXQgYW5kIHdob3NlIG5hbWUgd2lsbCBiZSBzZXQgYnkgZGF0YSByZWFkCisgICAgICogZnJvbSB0aGUgbG9jYWwgZmlsZSBoZWFkZXIgbGF0ZXIuICBUaGUgY3VycmVudCBlbnRyeSBtYXkgYmUKKyAgICAgKiBhZGRlZCB0byB0aGlzIG1hcC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQKKyAgICAgICAgcmVhZENlbnRyYWxEaXJlY3RvcnlFbnRyeShmaW5hbCBNYXA8WmlwQXJjaGl2ZUVudHJ5LCBOYW1lQW5kQ29tbWVudD4gbm9VVEY4RmxhZykKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY2ZoQmJ1Zi5yZXdpbmQoKTsKKyAgICAgICAgSU9VdGlscy5yZWFkRnVsbHkoYXJjaGl2ZSwgY2ZoQmJ1Zik7CisgICAgICAgIGludCBvZmYgPSAwOworICAgICAgICBmaW5hbCBFbnRyeSB6ZSA9IG5ldyBFbnRyeSgpOworCisgICAgICAgIGZpbmFsIGludCB2ZXJzaW9uTWFkZUJ5ID0gWmlwU2hvcnQuZ2V0VmFsdWUoY2ZoQnVmLCBvZmYpOworICAgICAgICBvZmYgKz0gU0hPUlQ7CisgICAgICAgIHplLnNldFZlcnNpb25NYWRlQnkodmVyc2lvbk1hZGVCeSk7CisgICAgICAgIHplLnNldFBsYXRmb3JtKCh2ZXJzaW9uTWFkZUJ5ID4+IEJZVEVfU0hJRlQpICYgTklCTEVUX01BU0spOworCisgICAgICAgIHplLnNldFZlcnNpb25SZXF1aXJlZChaaXBTaG9ydC5nZXRWYWx1ZShjZmhCdWYsIG9mZikpOworICAgICAgICBvZmYgKz0gU0hPUlQ7IC8vIHZlcnNpb24gcmVxdWlyZWQKKworICAgICAgICBmaW5hbCBHZW5lcmFsUHVycG9zZUJpdCBncEZsYWcgPSBHZW5lcmFsUHVycG9zZUJpdC5wYXJzZShjZmhCdWYsIG9mZik7CisgICAgICAgIGZpbmFsIGJvb2xlYW4gaGFzVVRGOEZsYWcgPSBncEZsYWcudXNlc1VURjhGb3JOYW1lcygpOworICAgICAgICBmaW5hbCBaaXBFbmNvZGluZyBlbnRyeUVuY29kaW5nID0KKyAgICAgICAgICAgIGhhc1VURjhGbGFnID8gWmlwRW5jb2RpbmdIZWxwZXIuVVRGOF9aSVBfRU5DT0RJTkcgOiB6aXBFbmNvZGluZzsKKyAgICAgICAgaWYgKGhhc1VURjhGbGFnKSB7CisgICAgICAgICAgICB6ZS5zZXROYW1lU291cmNlKFppcEFyY2hpdmVFbnRyeS5OYW1lU291cmNlLk5BTUVfV0lUSF9FRlNfRkxBRyk7CisgICAgICAgIH0KKyAgICAgICAgemUuc2V0R2VuZXJhbFB1cnBvc2VCaXQoZ3BGbGFnKTsKKyAgICAgICAgemUuc2V0UmF3RmxhZyhaaXBTaG9ydC5nZXRWYWx1ZShjZmhCdWYsIG9mZikpOworCisgICAgICAgIG9mZiArPSBTSE9SVDsKKworICAgICAgICAvL25vaW5zcGVjdGlvbiBNYWdpY0NvbnN0YW50CisgICAgICAgIHplLnNldE1ldGhvZChaaXBTaG9ydC5nZXRWYWx1ZShjZmhCdWYsIG9mZikpOworICAgICAgICBvZmYgKz0gU0hPUlQ7CisKKyAgICAgICAgZmluYWwgbG9uZyB0aW1lID0gWmlwVXRpbC5kb3NUb0phdmFUaW1lKFppcExvbmcuZ2V0VmFsdWUoY2ZoQnVmLCBvZmYpKTsKKyAgICAgICAgemUuc2V0VGltZSh0aW1lKTsKKyAgICAgICAgb2ZmICs9IFdPUkQ7CisKKyAgICAgICAgemUuc2V0Q3JjKFppcExvbmcuZ2V0VmFsdWUoY2ZoQnVmLCBvZmYpKTsKKyAgICAgICAgb2ZmICs9IFdPUkQ7CisKKyAgICAgICAgemUuc2V0Q29tcHJlc3NlZFNpemUoWmlwTG9uZy5nZXRWYWx1ZShjZmhCdWYsIG9mZikpOworICAgICAgICBvZmYgKz0gV09SRDsKKworICAgICAgICB6ZS5zZXRTaXplKFppcExvbmcuZ2V0VmFsdWUoY2ZoQnVmLCBvZmYpKTsKKyAgICAgICAgb2ZmICs9IFdPUkQ7CisKKyAgICAgICAgZmluYWwgaW50IGZpbGVOYW1lTGVuID0gWmlwU2hvcnQuZ2V0VmFsdWUoY2ZoQnVmLCBvZmYpOworICAgICAgICBvZmYgKz0gU0hPUlQ7CisKKyAgICAgICAgZmluYWwgaW50IGV4dHJhTGVuID0gWmlwU2hvcnQuZ2V0VmFsdWUoY2ZoQnVmLCBvZmYpOworICAgICAgICBvZmYgKz0gU0hPUlQ7CisKKyAgICAgICAgZmluYWwgaW50IGNvbW1lbnRMZW4gPSBaaXBTaG9ydC5nZXRWYWx1ZShjZmhCdWYsIG9mZik7CisgICAgICAgIG9mZiArPSBTSE9SVDsKKworICAgICAgICBmaW5hbCBpbnQgZGlza1N0YXJ0ID0gWmlwU2hvcnQuZ2V0VmFsdWUoY2ZoQnVmLCBvZmYpOworICAgICAgICBvZmYgKz0gU0hPUlQ7CisKKyAgICAgICAgemUuc2V0SW50ZXJuYWxBdHRyaWJ1dGVzKFppcFNob3J0LmdldFZhbHVlKGNmaEJ1Ziwgb2ZmKSk7CisgICAgICAgIG9mZiArPSBTSE9SVDsKKworICAgICAgICB6ZS5zZXRFeHRlcm5hbEF0dHJpYnV0ZXMoWmlwTG9uZy5nZXRWYWx1ZShjZmhCdWYsIG9mZikpOworICAgICAgICBvZmYgKz0gV09SRDsKKworICAgICAgICBmaW5hbCBieXRlW10gZmlsZU5hbWUgPSBuZXcgYnl0ZVtmaWxlTmFtZUxlbl07CisgICAgICAgIElPVXRpbHMucmVhZEZ1bGx5KGFyY2hpdmUsIEJ5dGVCdWZmZXIud3JhcChmaWxlTmFtZSkpOworICAgICAgICB6ZS5zZXROYW1lKGVudHJ5RW5jb2RpbmcuZGVjb2RlKGZpbGVOYW1lKSwgZmlsZU5hbWUpOworCisgICAgICAgIC8vIExGSCBvZmZzZXQsCisgICAgICAgIHplLnNldExvY2FsSGVhZGVyT2Zmc2V0KFppcExvbmcuZ2V0VmFsdWUoY2ZoQnVmLCBvZmYpKTsKKyAgICAgICAgLy8gZGF0YSBvZmZzZXQgd2lsbCBiZSBmaWxsZWQgbGF0ZXIKKyAgICAgICAgZW50cmllcy5hZGQoemUpOworCisgICAgICAgIGZpbmFsIGJ5dGVbXSBjZEV4dHJhRGF0YSA9IG5ldyBieXRlW2V4dHJhTGVuXTsKKyAgICAgICAgSU9VdGlscy5yZWFkRnVsbHkoYXJjaGl2ZSwgQnl0ZUJ1ZmZlci53cmFwKGNkRXh0cmFEYXRhKSk7CisgICAgICAgIHplLnNldENlbnRyYWxEaXJlY3RvcnlFeHRyYShjZEV4dHJhRGF0YSk7CisKKyAgICAgICAgc2V0U2l6ZXNBbmRPZmZzZXRGcm9tWmlwNjRFeHRyYSh6ZSwgZGlza1N0YXJ0KTsKKworICAgICAgICBmaW5hbCBieXRlW10gY29tbWVudCA9IG5ldyBieXRlW2NvbW1lbnRMZW5dOworICAgICAgICBJT1V0aWxzLnJlYWRGdWxseShhcmNoaXZlLCBCeXRlQnVmZmVyLndyYXAoY29tbWVudCkpOworICAgICAgICB6ZS5zZXRDb21tZW50KGVudHJ5RW5jb2RpbmcuZGVjb2RlKGNvbW1lbnQpKTsKKworICAgICAgICBpZiAoIWhhc1VURjhGbGFnICYmIHVzZVVuaWNvZGVFeHRyYUZpZWxkcykgeworICAgICAgICAgICAgbm9VVEY4RmxhZy5wdXQoemUsIG5ldyBOYW1lQW5kQ29tbWVudChmaWxlTmFtZSwgY29tbWVudCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogSWYgdGhlIGVudHJ5IGhvbGRzIGEgWmlwNjQgZXh0ZW5kZWQgaW5mb3JtYXRpb24gZXh0cmEgZmllbGQsCisgICAgICogcmVhZCBzaXplcyBmcm9tIHRoZXJlIGlmIHRoZSBlbnRyeSdzIHNpemVzIGFyZSBzZXQgdG8KKyAgICAgKiAweEZGRkZGRkZGRiwgZG8gdGhlIHNhbWUgZm9yIHRoZSBvZmZzZXQgb2YgdGhlIGxvY2FsIGZpbGUKKyAgICAgKiBoZWFkZXIuCisgICAgICoKKyAgICAgKiA8cD5FbnN1cmVzIHRoZSBaaXA2NCBleHRyYSBlaXRoZXIga25vd3MgYm90aCBjb21wcmVzc2VkIGFuZAorICAgICAqIHVuY29tcHJlc3NlZCBzaXplIG9yIG5laXRoZXIgb2YgYm90aCBhcyB0aGUgaW50ZXJuYWwgbG9naWMgaW4KKyAgICAgKiBFeHRyYUZpZWxkVXRpbHMgZm9yY2VzIHRoZSBmaWVsZCB0byBjcmVhdGUgbG9jYWwgaGVhZGVyIGRhdGEKKyAgICAgKiBldmVuIGlmIHRoZXkgYXJlIG5ldmVyIHVzZWQgLSBhbmQgaGVyZSBhIGZpZWxkIHdpdGggb25seSBvbmUKKyAgICAgKiBzaXplIHdvdWxkIGJlIGludmFsaWQuPC9wPgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBzZXRTaXplc0FuZE9mZnNldEZyb21aaXA2NEV4dHJhKGZpbmFsIFppcEFyY2hpdmVFbnRyeSB6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgZGlza1N0YXJ0KQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBaaXA2NEV4dGVuZGVkSW5mb3JtYXRpb25FeHRyYUZpZWxkIHo2NCA9CisgICAgICAgICAgICAoWmlwNjRFeHRlbmRlZEluZm9ybWF0aW9uRXh0cmFGaWVsZCkKKyAgICAgICAgICAgIHplLmdldEV4dHJhRmllbGQoWmlwNjRFeHRlbmRlZEluZm9ybWF0aW9uRXh0cmFGaWVsZC5IRUFERVJfSUQpOworICAgICAgICBpZiAoejY0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIGZpbmFsIGJvb2xlYW4gaGFzVW5jb21wcmVzc2VkU2l6ZSA9IHplLmdldFNpemUoKSA9PSBaSVA2NF9NQUdJQzsKKyAgICAgICAgICAgIGZpbmFsIGJvb2xlYW4gaGFzQ29tcHJlc3NlZFNpemUgPSB6ZS5nZXRDb21wcmVzc2VkU2l6ZSgpID09IFpJUDY0X01BR0lDOworICAgICAgICAgICAgZmluYWwgYm9vbGVhbiBoYXNSZWxhdGl2ZUhlYWRlck9mZnNldCA9CisgICAgICAgICAgICAgICAgemUuZ2V0TG9jYWxIZWFkZXJPZmZzZXQoKSA9PSBaSVA2NF9NQUdJQzsKKyAgICAgICAgICAgIHo2NC5yZXBhcnNlQ2VudHJhbERpcmVjdG9yeURhdGEoaGFzVW5jb21wcmVzc2VkU2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFzQ29tcHJlc3NlZFNpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhc1JlbGF0aXZlSGVhZGVyT2Zmc2V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXNrU3RhcnQgPT0gWklQNjRfTUFHSUNfU0hPUlQpOworCisgICAgICAgICAgICBpZiAoaGFzVW5jb21wcmVzc2VkU2l6ZSkgeworICAgICAgICAgICAgICAgIHplLnNldFNpemUoejY0LmdldFNpemUoKS5nZXRMb25nVmFsdWUoKSk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKGhhc0NvbXByZXNzZWRTaXplKSB7CisgICAgICAgICAgICAgICAgejY0LnNldFNpemUobmV3IFppcEVpZ2h0Qnl0ZUludGVnZXIoemUuZ2V0U2l6ZSgpKSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChoYXNDb21wcmVzc2VkU2l6ZSkgeworICAgICAgICAgICAgICAgIHplLnNldENvbXByZXNzZWRTaXplKHo2NC5nZXRDb21wcmVzc2VkU2l6ZSgpLmdldExvbmdWYWx1ZSgpKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoaGFzVW5jb21wcmVzc2VkU2l6ZSkgeworICAgICAgICAgICAgICAgIHo2NC5zZXRDb21wcmVzc2VkU2l6ZShuZXcgWmlwRWlnaHRCeXRlSW50ZWdlcih6ZS5nZXRDb21wcmVzc2VkU2l6ZSgpKSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChoYXNSZWxhdGl2ZUhlYWRlck9mZnNldCkgeworICAgICAgICAgICAgICAgIHplLnNldExvY2FsSGVhZGVyT2Zmc2V0KHo2NC5nZXRSZWxhdGl2ZUhlYWRlck9mZnNldCgpLmdldExvbmdWYWx1ZSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIExlbmd0aCBvZiB0aGUgIkVuZCBvZiBjZW50cmFsIGRpcmVjdG9yeSByZWNvcmQiIC0gd2hpY2ggaXMKKyAgICAgKiBzdXBwb3NlZCB0byBiZSB0aGUgbGFzdCBzdHJ1Y3R1cmUgb2YgdGhlIGFyY2hpdmUgLSB3aXRob3V0IGZpbGUKKyAgICAgKiBjb21tZW50LgorICAgICAqLworICAgIHN0YXRpYyBmaW5hbCBpbnQgTUlOX0VPQ0RfU0laRSA9CisgICAgICAgIC8qIGVuZCBvZiBjZW50cmFsIGRpciBzaWduYXR1cmUgICAgKi8gV09SRAorICAgICAgICAvKiBudW1iZXIgb2YgdGhpcyBkaXNrICAgICAgICAgICAgICovICsgU0hPUlQKKyAgICAgICAgLyogbnVtYmVyIG9mIHRoZSBkaXNrIHdpdGggdGhlICAgICAqLworICAgICAgICAvKiBzdGFydCBvZiB0aGUgY2VudHJhbCBkaXJlY3RvcnkgICovICsgU0hPUlQKKyAgICAgICAgLyogdG90YWwgbnVtYmVyIG9mIGVudHJpZXMgaW4gICAgICAqLworICAgICAgICAvKiB0aGUgY2VudHJhbCBkaXIgb24gdGhpcyBkaXNrICAgICovICsgU0hPUlQKKyAgICAgICAgLyogdG90YWwgbnVtYmVyIG9mIGVudHJpZXMgaW4gICAgICAqLworICAgICAgICAvKiB0aGUgY2VudHJhbCBkaXIgICAgICAgICAgICAgICAgICovICsgU0hPUlQKKyAgICAgICAgLyogc2l6ZSBvZiB0aGUgY2VudHJhbCBkaXJlY3RvcnkgICAqLyArIFdPUkQKKyAgICAgICAgLyogb2Zmc2V0IG9mIHN0YXJ0IG9mIGNlbnRyYWwgICAgICAqLworICAgICAgICAvKiBkaXJlY3Rvcnkgd2l0aCByZXNwZWN0IHRvICAgICAgICovCisgICAgICAgIC8qIHRoZSBzdGFydGluZyBkaXNrIG51bWJlciAgICAgICAgKi8gKyBXT1JECisgICAgICAgIC8qIHppcGZpbGUgY29tbWVudCBsZW5ndGggICAgICAgICAgKi8gKyBTSE9SVDsKKworICAgIC8qKgorICAgICAqIE1heGltdW0gbGVuZ3RoIG9mIHRoZSAiRW5kIG9mIGNlbnRyYWwgZGlyZWN0b3J5IHJlY29yZCIgd2l0aCBhCisgICAgICogZmlsZSBjb21tZW50LgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNQVhfRU9DRF9TSVpFID0gTUlOX0VPQ0RfU0laRQorICAgICAgICAvKiBtYXhpbXVtIGxlbmd0aCBvZiB6aXBmaWxlIGNvbW1lbnQgKi8gKyBaSVA2NF9NQUdJQ19TSE9SVDsKKworICAgIC8qKgorICAgICAqIE9mZnNldCBvZiB0aGUgZmllbGQgdGhhdCBob2xkcyB0aGUgbG9jYXRpb24gb2YgdGhlIGZpcnN0CisgICAgICogY2VudHJhbCBkaXJlY3RvcnkgZW50cnkgaW5zaWRlIHRoZSAiRW5kIG9mIGNlbnRyYWwgZGlyZWN0b3J5CisgICAgICogcmVjb3JkIiByZWxhdGl2ZSB0byB0aGUgc3RhcnQgb2YgdGhlICJFbmQgb2YgY2VudHJhbCBkaXJlY3RvcnkKKyAgICAgKiByZWNvcmQiLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBDRkRfTE9DQVRPUl9PRkZTRVQgPQorICAgICAgICAvKiBlbmQgb2YgY2VudHJhbCBkaXIgc2lnbmF0dXJlICAgICovIFdPUkQKKyAgICAgICAgLyogbnVtYmVyIG9mIHRoaXMgZGlzayAgICAgICAgICAgICAqLyArIFNIT1JUCisgICAgICAgIC8qIG51bWJlciBvZiB0aGUgZGlzayB3aXRoIHRoZSAgICAgKi8KKyAgICAgICAgLyogc3RhcnQgb2YgdGhlIGNlbnRyYWwgZGlyZWN0b3J5ICAqLyArIFNIT1JUCisgICAgICAgIC8qIHRvdGFsIG51bWJlciBvZiBlbnRyaWVzIGluICAgICAgKi8KKyAgICAgICAgLyogdGhlIGNlbnRyYWwgZGlyIG9uIHRoaXMgZGlzayAgICAqLyArIFNIT1JUCisgICAgICAgIC8qIHRvdGFsIG51bWJlciBvZiBlbnRyaWVzIGluICAgICAgKi8KKyAgICAgICAgLyogdGhlIGNlbnRyYWwgZGlyICAgICAgICAgICAgICAgICAqLyArIFNIT1JUCisgICAgICAgIC8qIHNpemUgb2YgdGhlIGNlbnRyYWwgZGlyZWN0b3J5ICAgKi8gKyBXT1JEOworCisgICAgLyoqCisgICAgICogTGVuZ3RoIG9mIHRoZSAiWmlwNjQgZW5kIG9mIGNlbnRyYWwgZGlyZWN0b3J5IGxvY2F0b3IiIC0gd2hpY2gKKyAgICAgKiBzaG91bGQgYmUgcmlnaHQgaW4gZnJvbnQgb2YgdGhlICJlbmQgb2YgY2VudHJhbCBkaXJlY3RvcnkKKyAgICAgKiByZWNvcmQiIGlmIG9uZSBpcyBwcmVzZW50IGF0IGFsbC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgWklQNjRfRU9DRExfTEVOR1RIID0KKyAgICAgICAgLyogemlwNjQgZW5kIG9mIGNlbnRyYWwgZGlyIGxvY2F0b3Igc2lnICovIFdPUkQKKyAgICAgICAgLyogbnVtYmVyIG9mIHRoZSBkaXNrIHdpdGggdGhlIHN0YXJ0ICAgICovCisgICAgICAgIC8qIHN0YXJ0IG9mIHRoZSB6aXA2NCBlbmQgb2YgICAgICAgICAgICAqLworICAgICAgICAvKiBjZW50cmFsIGRpcmVjdG9yeSAgICAgICAgICAgICAgICAgICAgKi8gKyBXT1JECisgICAgICAgIC8qIHJlbGF0aXZlIG9mZnNldCBvZiB0aGUgemlwNjQgICAgICAgICAqLworICAgICAgICAvKiBlbmQgb2YgY2VudHJhbCBkaXJlY3RvcnkgcmVjb3JkICAgICAgKi8gKyBEV09SRAorICAgICAgICAvKiB0b3RhbCBudW1iZXIgb2YgZGlza3MgICAgICAgICAgICAgICAgKi8gKyBXT1JEOworCisgICAgLyoqCisgICAgICogT2Zmc2V0IG9mIHRoZSBmaWVsZCB0aGF0IGhvbGRzIHRoZSBsb2NhdGlvbiBvZiB0aGUgIlppcDY0IGVuZAorICAgICAqIG9mIGNlbnRyYWwgZGlyZWN0b3J5IHJlY29yZCIgaW5zaWRlIHRoZSAiWmlwNjQgZW5kIG9mIGNlbnRyYWwKKyAgICAgKiBkaXJlY3RvcnkgbG9jYXRvciIgcmVsYXRpdmUgdG8gdGhlIHN0YXJ0IG9mIHRoZSAiWmlwNjQgZW5kIG9mCisgICAgICogY2VudHJhbCBkaXJlY3RvcnkgbG9jYXRvciIuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFpJUDY0X0VPQ0RMX0xPQ0FUT1JfT0ZGU0VUID0KKyAgICAgICAgLyogemlwNjQgZW5kIG9mIGNlbnRyYWwgZGlyIGxvY2F0b3Igc2lnICovIFdPUkQKKyAgICAgICAgLyogbnVtYmVyIG9mIHRoZSBkaXNrIHdpdGggdGhlIHN0YXJ0ICAgICovCisgICAgICAgIC8qIHN0YXJ0IG9mIHRoZSB6aXA2NCBlbmQgb2YgICAgICAgICAgICAqLworICAgICAgICAvKiBjZW50cmFsIGRpcmVjdG9yeSAgICAgICAgICAgICAgICAgICAgKi8gKyBXT1JEOworCisgICAgLyoqCisgICAgICogT2Zmc2V0IG9mIHRoZSBmaWVsZCB0aGF0IGhvbGRzIHRoZSBsb2NhdGlvbiBvZiB0aGUgZmlyc3QKKyAgICAgKiBjZW50cmFsIGRpcmVjdG9yeSBlbnRyeSBpbnNpZGUgdGhlICJaaXA2NCBlbmQgb2YgY2VudHJhbAorICAgICAqIGRpcmVjdG9yeSByZWNvcmQiIHJlbGF0aXZlIHRvIHRoZSBzdGFydCBvZiB0aGUgIlppcDY0IGVuZCBvZgorICAgICAqIGNlbnRyYWwgZGlyZWN0b3J5IHJlY29yZCIuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFpJUDY0X0VPQ0RfQ0ZEX0xPQ0FUT1JfT0ZGU0VUID0KKyAgICAgICAgLyogemlwNjQgZW5kIG9mIGNlbnRyYWwgZGlyICAgICAgICAqLworICAgICAgICAvKiBzaWduYXR1cmUgICAgICAgICAgICAgICAgICAgICAgICovIFdPUkQKKyAgICAgICAgLyogc2l6ZSBvZiB6aXA2NCBlbmQgb2YgY2VudHJhbCAgICAqLworICAgICAgICAvKiBkaXJlY3RvcnkgcmVjb3JkICAgICAgICAgICAgICAgICovICsgRFdPUkQKKyAgICAgICAgLyogdmVyc2lvbiBtYWRlIGJ5ICAgICAgICAgICAgICAgICAqLyArIFNIT1JUCisgICAgICAgIC8qIHZlcnNpb24gbmVlZGVkIHRvIGV4dHJhY3QgICAgICAgKi8gKyBTSE9SVAorICAgICAgICAvKiBudW1iZXIgb2YgdGhpcyBkaXNrICAgICAgICAgICAgICovICsgV09SRAorICAgICAgICAvKiBudW1iZXIgb2YgdGhlIGRpc2sgd2l0aCB0aGUgICAgICovCisgICAgICAgIC8qIHN0YXJ0IG9mIHRoZSBjZW50cmFsIGRpcmVjdG9yeSAgKi8gKyBXT1JECisgICAgICAgIC8qIHRvdGFsIG51bWJlciBvZiBlbnRyaWVzIGluIHRoZSAgKi8KKyAgICAgICAgLyogY2VudHJhbCBkaXJlY3Rvcnkgb24gdGhpcyBkaXNrICAqLyArIERXT1JECisgICAgICAgIC8qIHRvdGFsIG51bWJlciBvZiBlbnRyaWVzIGluIHRoZSAgKi8KKyAgICAgICAgLyogY2VudHJhbCBkaXJlY3RvcnkgICAgICAgICAgICAgICAqLyArIERXT1JECisgICAgICAgIC8qIHNpemUgb2YgdGhlIGNlbnRyYWwgZGlyZWN0b3J5ICAgKi8gKyBEV09SRDsKKworICAgIC8qKgorICAgICAqIFNlYXJjaGVzIGZvciBlaXRoZXIgdGhlICZxdW90O1ppcDY0IGVuZCBvZiBjZW50cmFsIGRpcmVjdG9yeQorICAgICAqIGxvY2F0b3ImcXVvdDsgb3IgdGhlICZxdW90O0VuZCBvZiBjZW50cmFsIGRpciByZWNvcmQmcXVvdDssIHBhcnNlcworICAgICAqIGl0IGFuZCBwb3NpdGlvbnMgdGhlIHN0cmVhbSBhdCB0aGUgZmlyc3QgY2VudHJhbCBkaXJlY3RvcnkKKyAgICAgKiByZWNvcmQuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHBvc2l0aW9uQXRDZW50cmFsRGlyZWN0b3J5KCkKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcG9zaXRpb25BdEVuZE9mQ2VudHJhbERpcmVjdG9yeVJlY29yZCgpOworICAgICAgICBib29sZWFuIGZvdW5kID0gZmFsc2U7CisgICAgICAgIGZpbmFsIGJvb2xlYW4gc2VhcmNoZWRGb3JaaXA2NEVPQ0QgPQorICAgICAgICAgICAgYXJjaGl2ZS5wb3NpdGlvbigpID4gWklQNjRfRU9DRExfTEVOR1RIOworICAgICAgICBpZiAoc2VhcmNoZWRGb3JaaXA2NEVPQ0QpIHsKKyAgICAgICAgICAgIGFyY2hpdmUucG9zaXRpb24oYXJjaGl2ZS5wb3NpdGlvbigpIC0gWklQNjRfRU9DRExfTEVOR1RIKTsKKyAgICAgICAgICAgIHdvcmRCYnVmLnJld2luZCgpOworICAgICAgICAgICAgSU9VdGlscy5yZWFkRnVsbHkoYXJjaGl2ZSwgd29yZEJidWYpOworICAgICAgICAgICAgZm91bmQgPSBBcnJheXMuZXF1YWxzKFppcEFyY2hpdmVPdXRwdXRTdHJlYW0uWklQNjRfRU9DRF9MT0NfU0lHLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdvcmRCdWYpOworICAgICAgICB9CisgICAgICAgIGlmICghZm91bmQpIHsKKyAgICAgICAgICAgIC8vIG5vdCBhIFpJUDY0IGFyY2hpdmUKKyAgICAgICAgICAgIGlmIChzZWFyY2hlZEZvclppcDY0RU9DRCkgeworICAgICAgICAgICAgICAgIHNraXBCeXRlcyhaSVA2NF9FT0NETF9MRU5HVEggLSBXT1JEKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHBvc2l0aW9uQXRDZW50cmFsRGlyZWN0b3J5MzIoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHBvc2l0aW9uQXRDZW50cmFsRGlyZWN0b3J5NjQoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlcyB0aGUgJnF1b3Q7WmlwNjQgZW5kIG9mIGNlbnRyYWwgZGlyZWN0b3J5IGxvY2F0b3ImcXVvdDssCisgICAgICogZmluZHMgdGhlICZxdW90O1ppcDY0IGVuZCBvZiBjZW50cmFsIGRpcmVjdG9yeSByZWNvcmQmcXVvdDsgdXNpbmcgdGhlCisgICAgICogcGFyc2VkIGluZm9ybWF0aW9uLCBwYXJzZXMgdGhhdCBhbmQgcG9zaXRpb25zIHRoZSBzdHJlYW0gYXQgdGhlCisgICAgICogZmlyc3QgY2VudHJhbCBkaXJlY3RvcnkgcmVjb3JkLgorICAgICAqCisgICAgICogRXhwZWN0cyBzdHJlYW0gdG8gYmUgcG9zaXRpb25lZCByaWdodCBiZWhpbmQgdGhlICZxdW90O1ppcDY0CisgICAgICogZW5kIG9mIGNlbnRyYWwgZGlyZWN0b3J5IGxvY2F0b3ImcXVvdDsncyBzaWduYXR1cmUuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHBvc2l0aW9uQXRDZW50cmFsRGlyZWN0b3J5NjQoKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBza2lwQnl0ZXMoWklQNjRfRU9DRExfTE9DQVRPUl9PRkZTRVQKKyAgICAgICAgICAgICAgICAgIC0gV09SRCAvKiBzaWduYXR1cmUgaGFzIGFscmVhZHkgYmVlbiByZWFkICovKTsKKyAgICAgICAgZHdvcmRCYnVmLnJld2luZCgpOworICAgICAgICBJT1V0aWxzLnJlYWRGdWxseShhcmNoaXZlLCBkd29yZEJidWYpOworICAgICAgICBhcmNoaXZlLnBvc2l0aW9uKFppcEVpZ2h0Qnl0ZUludGVnZXIuZ2V0TG9uZ1ZhbHVlKGR3b3JkQnVmKSk7CisgICAgICAgIHdvcmRCYnVmLnJld2luZCgpOworICAgICAgICBJT1V0aWxzLnJlYWRGdWxseShhcmNoaXZlLCB3b3JkQmJ1Zik7CisgICAgICAgIGlmICghQXJyYXlzLmVxdWFscyh3b3JkQnVmLCBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtLlpJUDY0X0VPQ0RfU0lHKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFppcEV4Y2VwdGlvbigiYXJjaGl2ZSdzIFpJUDY0IGVuZCBvZiBjZW50cmFsICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiZGlyZWN0b3J5IGxvY2F0b3IgaXMgY29ycnVwdC4iKTsKKyAgICAgICAgfQorICAgICAgICBza2lwQnl0ZXMoWklQNjRfRU9DRF9DRkRfTE9DQVRPUl9PRkZTRVQKKyAgICAgICAgICAgICAgICAgIC0gV09SRCAvKiBzaWduYXR1cmUgaGFzIGFscmVhZHkgYmVlbiByZWFkICovKTsKKyAgICAgICAgZHdvcmRCYnVmLnJld2luZCgpOworICAgICAgICBJT1V0aWxzLnJlYWRGdWxseShhcmNoaXZlLCBkd29yZEJidWYpOworICAgICAgICBhcmNoaXZlLnBvc2l0aW9uKFppcEVpZ2h0Qnl0ZUludGVnZXIuZ2V0TG9uZ1ZhbHVlKGR3b3JkQnVmKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2VzIHRoZSAmcXVvdDtFbmQgb2YgY2VudHJhbCBkaXIgcmVjb3JkJnF1b3Q7IGFuZCBwb3NpdGlvbnMKKyAgICAgKiB0aGUgc3RyZWFtIGF0IHRoZSBmaXJzdCBjZW50cmFsIGRpcmVjdG9yeSByZWNvcmQuCisgICAgICoKKyAgICAgKiBFeHBlY3RzIHN0cmVhbSB0byBiZSBwb3NpdGlvbmVkIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlCisgICAgICogJnF1b3Q7RW5kIG9mIGNlbnRyYWwgZGlyIHJlY29yZCZxdW90Oy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcG9zaXRpb25BdENlbnRyYWxEaXJlY3RvcnkzMigpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHNraXBCeXRlcyhDRkRfTE9DQVRPUl9PRkZTRVQpOworICAgICAgICB3b3JkQmJ1Zi5yZXdpbmQoKTsKKyAgICAgICAgSU9VdGlscy5yZWFkRnVsbHkoYXJjaGl2ZSwgd29yZEJidWYpOworICAgICAgICBhcmNoaXZlLnBvc2l0aW9uKFppcExvbmcuZ2V0VmFsdWUod29yZEJ1ZikpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNlYXJjaGVzIGZvciB0aGUgYW5kIHBvc2l0aW9ucyB0aGUgc3RyZWFtIGF0IHRoZSBzdGFydCBvZiB0aGUKKyAgICAgKiAmcXVvdDtFbmQgb2YgY2VudHJhbCBkaXIgcmVjb3JkJnF1b3Q7LgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBwb3NpdGlvbkF0RW5kT2ZDZW50cmFsRGlyZWN0b3J5UmVjb3JkKCkKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgYm9vbGVhbiBmb3VuZCA9IHRyeVRvTG9jYXRlU2lnbmF0dXJlKE1JTl9FT0NEX1NJWkUsIE1BWF9FT0NEX1NJWkUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtLkVPQ0RfU0lHKTsKKyAgICAgICAgaWYgKCFmb3VuZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFppcEV4Y2VwdGlvbigiYXJjaGl2ZSBpcyBub3QgYSBaSVAgYXJjaGl2ZSIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2VhcmNoZXMgdGhlIGFyY2hpdmUgYmFja3dhcmRzIGZyb20gbWluRGlzdGFuY2UgdG8gbWF4RGlzdGFuY2UKKyAgICAgKiBmb3IgdGhlIGdpdmVuIHNpZ25hdHVyZSwgcG9zaXRpb25zIHRoZSBSYW5kb21hY2Nlc3NGaWxlIHJpZ2h0CisgICAgICogYXQgdGhlIHNpZ25hdHVyZSBpZiBpdCBoYXMgYmVlbiBmb3VuZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gdHJ5VG9Mb2NhdGVTaWduYXR1cmUoZmluYWwgbG9uZyBtaW5EaXN0YW5jZUZyb21FbmQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGxvbmcgbWF4RGlzdGFuY2VGcm9tRW5kLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBieXRlW10gc2lnKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBib29sZWFuIGZvdW5kID0gZmFsc2U7CisgICAgICAgIGxvbmcgb2ZmID0gYXJjaGl2ZS5zaXplKCkgLSBtaW5EaXN0YW5jZUZyb21FbmQ7CisgICAgICAgIGZpbmFsIGxvbmcgc3RvcFNlYXJjaGluZyA9CisgICAgICAgICAgICBNYXRoLm1heCgwTCwgYXJjaGl2ZS5zaXplKCkgLSBtYXhEaXN0YW5jZUZyb21FbmQpOworICAgICAgICBpZiAob2ZmID49IDApIHsKKyAgICAgICAgICAgIGZvciAoOyBvZmYgPj0gc3RvcFNlYXJjaGluZzsgb2ZmLS0pIHsKKyAgICAgICAgICAgICAgICBhcmNoaXZlLnBvc2l0aW9uKG9mZik7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgd29yZEJidWYucmV3aW5kKCk7CisgICAgICAgICAgICAgICAgICAgIElPVXRpbHMucmVhZEZ1bGx5KGFyY2hpdmUsIHdvcmRCYnVmKTsKKyAgICAgICAgICAgICAgICAgICAgd29yZEJidWYuZmxpcCgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEVPRkV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaW50IGN1cnIgPSB3b3JkQmJ1Zi5nZXQoKTsKKyAgICAgICAgICAgICAgICBpZiAoY3VyciA9PSBzaWdbUE9TXzBdKSB7CisgICAgICAgICAgICAgICAgICAgIGN1cnIgPSB3b3JkQmJ1Zi5nZXQoKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnIgPT0gc2lnW1BPU18xXSkgeworICAgICAgICAgICAgICAgICAgICAgICAgY3VyciA9IHdvcmRCYnVmLmdldCgpOworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnIgPT0gc2lnW1BPU18yXSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnIgPSB3b3JkQmJ1Zi5nZXQoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3VyciA9PSBzaWdbUE9TXzNdKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvdW5kID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChmb3VuZCkgeworICAgICAgICAgICAgYXJjaGl2ZS5wb3NpdGlvbihvZmYpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmb3VuZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTa2lwcyB0aGUgZ2l2ZW4gbnVtYmVyIG9mIGJ5dGVzIG9yIHRocm93cyBhbiBFT0ZFeGNlcHRpb24gaWYKKyAgICAgKiBza2lwcGluZyBmYWlsZWQuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHNraXBCeXRlcyhmaW5hbCBpbnQgY291bnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGxvbmcgY3VycmVudFBvc2l0aW9uID0gYXJjaGl2ZS5wb3NpdGlvbigpOworICAgICAgICBsb25nIG5ld1Bvc2l0aW9uID0gY3VycmVudFBvc2l0aW9uICsgY291bnQ7CisgICAgICAgIGlmIChuZXdQb3NpdGlvbiA+IGFyY2hpdmUuc2l6ZSgpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRU9GRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgYXJjaGl2ZS5wb3NpdGlvbihuZXdQb3NpdGlvbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogTnVtYmVyIG9mIGJ5dGVzIGluIGxvY2FsIGZpbGUgaGVhZGVyIHVwIHRvIHRoZSAmcXVvdDtsZW5ndGggb2YKKyAgICAgKiBmaWxlbmFtZSZxdW90OyBlbnRyeS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIExGSF9PRkZTRVRfRk9SX0ZJTEVOQU1FX0xFTkdUSCA9CisgICAgICAgIC8qIGxvY2FsIGZpbGUgaGVhZGVyIHNpZ25hdHVyZSAgICAgKi8gV09SRAorICAgICAgICAvKiB2ZXJzaW9uIG5lZWRlZCB0byBleHRyYWN0ICAgICAgICovICsgU0hPUlQKKyAgICAgICAgLyogZ2VuZXJhbCBwdXJwb3NlIGJpdCBmbGFnICAgICAgICAqLyArIFNIT1JUCisgICAgICAgIC8qIGNvbXByZXNzaW9uIG1ldGhvZCAgICAgICAgICAgICAgKi8gKyBTSE9SVAorICAgICAgICAvKiBsYXN0IG1vZCBmaWxlIHRpbWUgICAgICAgICAgICAgICovICsgU0hPUlQKKyAgICAgICAgLyogbGFzdCBtb2QgZmlsZSBkYXRlICAgICAgICAgICAgICAqLyArIFNIT1JUCisgICAgICAgIC8qIGNyYy0zMiAgICAgICAgICAgICAgICAgICAgICAgICAgKi8gKyBXT1JECisgICAgICAgIC8qIGNvbXByZXNzZWQgc2l6ZSAgICAgICAgICAgICAgICAgKi8gKyBXT1JECisgICAgICAgIC8qIHVuY29tcHJlc3NlZCBzaXplICAgICAgICAgICAgICAgKi8gKyAobG9uZykgV09SRDsKKworICAgIC8qKgorICAgICAqIFdhbGtzIHRocm91Z2ggYWxsIHJlY29yZGVkIGVudHJpZXMgYW5kIGFkZHMgdGhlIGRhdGEgYXZhaWxhYmxlCisgICAgICogZnJvbSB0aGUgbG9jYWwgZmlsZSBoZWFkZXIuCisgICAgICoKKyAgICAgKiA8cD5BbHNvIHJlY29yZHMgdGhlIG9mZnNldHMgZm9yIHRoZSBkYXRhIHRvIHJlYWQgZnJvbSB0aGUKKyAgICAgKiBlbnRyaWVzLjwvcD4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcmVzb2x2ZUxvY2FsRmlsZUhlYWRlckRhdGEoZmluYWwgTWFwPFppcEFyY2hpdmVFbnRyeSwgTmFtZUFuZENvbW1lbnQ+CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudHJpZXNXaXRob3V0VVRGOEZsYWcpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZvciAoZmluYWwgWmlwQXJjaGl2ZUVudHJ5IHppcEFyY2hpdmVFbnRyeSA6IGVudHJpZXMpIHsKKyAgICAgICAgICAgIC8vIGVudHJpZXMgaXMgZmlsbGVkIGluIHBvcHVsYXRlRnJvbUNlbnRyYWxEaXJlY3RvcnkgYW5kCisgICAgICAgICAgICAvLyBuZXZlciBtb2RpZmllZAorICAgICAgICAgICAgZmluYWwgRW50cnkgemUgPSAoRW50cnkpIHppcEFyY2hpdmVFbnRyeTsKKyAgICAgICAgICAgIGZpbmFsIGxvbmcgb2Zmc2V0ID0gemUuZ2V0TG9jYWxIZWFkZXJPZmZzZXQoKTsKKyAgICAgICAgICAgIGFyY2hpdmUucG9zaXRpb24ob2Zmc2V0ICsgTEZIX09GRlNFVF9GT1JfRklMRU5BTUVfTEVOR1RIKTsKKyAgICAgICAgICAgIHdvcmRCYnVmLnJld2luZCgpOworICAgICAgICAgICAgSU9VdGlscy5yZWFkRnVsbHkoYXJjaGl2ZSwgd29yZEJidWYpOworICAgICAgICAgICAgd29yZEJidWYuZmxpcCgpOworICAgICAgICAgICAgd29yZEJidWYuZ2V0KHNob3J0QnVmKTsKKyAgICAgICAgICAgIGZpbmFsIGludCBmaWxlTmFtZUxlbiA9IFppcFNob3J0LmdldFZhbHVlKHNob3J0QnVmKTsKKyAgICAgICAgICAgIHdvcmRCYnVmLmdldChzaG9ydEJ1Zik7CisgICAgICAgICAgICBmaW5hbCBpbnQgZXh0cmFGaWVsZExlbiA9IFppcFNob3J0LmdldFZhbHVlKHNob3J0QnVmKTsKKyAgICAgICAgICAgIHNraXBCeXRlcyhmaWxlTmFtZUxlbik7CisgICAgICAgICAgICBmaW5hbCBieXRlW10gbG9jYWxFeHRyYURhdGEgPSBuZXcgYnl0ZVtleHRyYUZpZWxkTGVuXTsKKyAgICAgICAgICAgIElPVXRpbHMucmVhZEZ1bGx5KGFyY2hpdmUsIEJ5dGVCdWZmZXIud3JhcChsb2NhbEV4dHJhRGF0YSkpOworICAgICAgICAgICAgemUuc2V0RXh0cmEobG9jYWxFeHRyYURhdGEpOworICAgICAgICAgICAgemUuc2V0RGF0YU9mZnNldChvZmZzZXQgKyBMRkhfT0ZGU0VUX0ZPUl9GSUxFTkFNRV9MRU5HVEgKKyAgICAgICAgICAgICAgICArIFNIT1JUICsgU0hPUlQgKyBmaWxlTmFtZUxlbiArIGV4dHJhRmllbGRMZW4pOworICAgICAgICAgICAgemUuc2V0U3RyZWFtQ29udGlndW91cyh0cnVlKTsKKworICAgICAgICAgICAgaWYgKGVudHJpZXNXaXRob3V0VVRGOEZsYWcuY29udGFpbnNLZXkoemUpKSB7CisgICAgICAgICAgICAgICAgZmluYWwgTmFtZUFuZENvbW1lbnQgbmMgPSBlbnRyaWVzV2l0aG91dFVURjhGbGFnLmdldCh6ZSk7CisgICAgICAgICAgICAgICAgWmlwVXRpbC5zZXROYW1lQW5kQ29tbWVudEZyb21FeHRyYUZpZWxkcyh6ZSwgbmMubmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5jLmNvbW1lbnQpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBmaW5hbCBTdHJpbmcgbmFtZSA9IHplLmdldE5hbWUoKTsKKyAgICAgICAgICAgIExpbmtlZExpc3Q8WmlwQXJjaGl2ZUVudHJ5PiBlbnRyaWVzT2ZUaGF0TmFtZSA9IG5hbWVNYXAuZ2V0KG5hbWUpOworICAgICAgICAgICAgaWYgKGVudHJpZXNPZlRoYXROYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBlbnRyaWVzT2ZUaGF0TmFtZSA9IG5ldyBMaW5rZWRMaXN0PD4oKTsKKyAgICAgICAgICAgICAgICBuYW1lTWFwLnB1dChuYW1lLCBlbnRyaWVzT2ZUaGF0TmFtZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBlbnRyaWVzT2ZUaGF0TmFtZS5hZGRMYXN0KHplKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrcyB3aGV0aGVyIHRoZSBhcmNoaXZlIHN0YXJ0cyB3aXRoIGEgTEZILiAgSWYgaXQgZG9lc24ndCwKKyAgICAgKiBpdCBtYXkgYmUgYW4gZW1wdHkgYXJjaGl2ZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gc3RhcnRzV2l0aExvY2FsRmlsZUhlYWRlcigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGFyY2hpdmUucG9zaXRpb24oMCk7CisgICAgICAgIHdvcmRCYnVmLnJld2luZCgpOworICAgICAgICBJT1V0aWxzLnJlYWRGdWxseShhcmNoaXZlLCB3b3JkQmJ1Zik7CisgICAgICAgIHJldHVybiBBcnJheXMuZXF1YWxzKHdvcmRCdWYsIFppcEFyY2hpdmVPdXRwdXRTdHJlYW0uTEZIX1NJRyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBuZXcgQm91bmRlZElucHV0U3RyZWFtLCBhY2NvcmRpbmcgdG8gaW1wbGVtZW50YXRpb24gb2YKKyAgICAgKiB1bmRlcmx5aW5nIGFyY2hpdmUgY2hhbm5lbC4KKyAgICAgKi8KKyAgICBwcml2YXRlIEJvdW5kZWRJbnB1dFN0cmVhbSBjcmVhdGVCb3VuZGVkSW5wdXRTdHJlYW0obG9uZyBzdGFydCwgbG9uZyByZW1haW5pbmcpIHsKKyAgICAgICAgcmV0dXJuIGFyY2hpdmUgaW5zdGFuY2VvZiBGaWxlQ2hhbm5lbCA/CisgICAgICAgICAgICBuZXcgQm91bmRlZEZpbGVDaGFubmVsSW5wdXRTdHJlYW0oc3RhcnQsIHJlbWFpbmluZykgOgorICAgICAgICAgICAgbmV3IEJvdW5kZWRJbnB1dFN0cmVhbShzdGFydCwgcmVtYWluaW5nKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnB1dFN0cmVhbSB0aGF0IGRlbGVnYXRlcyByZXF1ZXN0cyB0byB0aGUgdW5kZXJseWluZworICAgICAqIFNlZWthYmxlQnl0ZUNoYW5uZWwsIG1ha2luZyBzdXJlIHRoYXQgb25seSBieXRlcyBmcm9tIGEgY2VydGFpbgorICAgICAqIHJhbmdlIGNhbiBiZSByZWFkLgorICAgICAqLworICAgIHByaXZhdGUgY2xhc3MgQm91bmRlZElucHV0U3RyZWFtIGV4dGVuZHMgSW5wdXRTdHJlYW0geworICAgICAgICBwcml2YXRlIEJ5dGVCdWZmZXIgc2luZ2xlQnl0ZUJ1ZmZlcjsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBsb25nIGVuZDsKKyAgICAgICAgcHJpdmF0ZSBsb25nIGxvYzsKKworICAgICAgICBCb3VuZGVkSW5wdXRTdHJlYW0oZmluYWwgbG9uZyBzdGFydCwgZmluYWwgbG9uZyByZW1haW5pbmcpIHsKKyAgICAgICAgICAgIHRoaXMuZW5kID0gc3RhcnQrcmVtYWluaW5nOworICAgICAgICAgICAgaWYgKHRoaXMuZW5kIDwgc3RhcnQpIHsKKyAgICAgICAgICAgICAgICAvLyBjaGVjayBmb3IgcG90ZW50aWFsIHZ1bG5lcmFiaWxpdHkgZHVlIHRvIG92ZXJmbG93CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSW52YWxpZCBsZW5ndGggb2Ygc3RyZWFtIGF0IG9mZnNldD0iK3N0YXJ0KyIsIGxlbmd0aD0iK3JlbWFpbmluZyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBsb2MgPSBzdGFydDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgc3luY2hyb25pemVkIGludCByZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGlmIChsb2MgPj0gZW5kKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHNpbmdsZUJ5dGVCdWZmZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHNpbmdsZUJ5dGVCdWZmZXIgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKDEpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZWxzZSB7CisgICAgICAgICAgICAgICAgc2luZ2xlQnl0ZUJ1ZmZlci5yZXdpbmQoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGludCByZWFkID0gcmVhZChsb2MsIHNpbmdsZUJ5dGVCdWZmZXIpOworICAgICAgICAgICAgaWYgKHJlYWQgPCAwKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHJlYWQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBsb2MrKzsKKyAgICAgICAgICAgIHJldHVybiBzaW5nbGVCeXRlQnVmZmVyLmdldCgpICYgMHhmZjsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgc3luY2hyb25pemVkIGludCByZWFkKGZpbmFsIGJ5dGVbXSBiLCBmaW5hbCBpbnQgb2ZmLCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgaWYgKGxlbiA8PSAwKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChsZW4gPiBlbmQtbG9jKSB7CisgICAgICAgICAgICAgICAgaWYgKGxvYyA+PSBlbmQpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBsZW4gPSAoaW50KShlbmQtbG9jKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQnl0ZUJ1ZmZlciBidWY7CisgICAgICAgICAgICBidWYgPSBCeXRlQnVmZmVyLndyYXAoYiwgb2ZmLCBsZW4pOworICAgICAgICAgICAgaW50IHJldCA9IHJlYWQobG9jLCBidWYpOworICAgICAgICAgICAgaWYgKHJldCA+IDApIHsKKyAgICAgICAgICAgICAgICBsb2MgKz0gcmV0OworICAgICAgICAgICAgICAgIHJldHVybiByZXQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gcmV0OworICAgICAgICB9CisKKyAgICAgICAgcHJvdGVjdGVkIGludCByZWFkKGxvbmcgcG9zLCBCeXRlQnVmZmVyIGJ1ZikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGludCByZWFkOworICAgICAgICAgICAgc3luY2hyb25pemVkIChhcmNoaXZlKSB7CisgICAgICAgICAgICAgICAgYXJjaGl2ZS5wb3NpdGlvbihwb3MpOworICAgICAgICAgICAgICAgIHJlYWQgPSBhcmNoaXZlLnJlYWQoYnVmKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJ1Zi5mbGlwKCk7CisgICAgICAgICAgICByZXR1cm4gcmVhZDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIExvY2stZnJlZSBpbXBsZW1lbnRhdGlvbiBvZiBCb3VuZGVkSW5wdXRTdHJlYW0uIFRoZQorICAgICAqIGltcGxlbWVudGF0aW9uIHVzZXMgcG9zaXRpb25lZCByZWFkcyBvbiB0aGUgdW5kZXJseWluZyBhcmNoaXZlCisgICAgICogZmlsZSBjaGFubmVsIGFuZCB0aGVyZWZvcmUgcGVyZm9ybXMgc2lnbmlmaWNhbnRseSBmYXN0ZXIgaW4KKyAgICAgKiBjb25jdXJyZW50IGVudmlyb25tZW50LgorICAgICAqLworICAgIHByaXZhdGUgY2xhc3MgQm91bmRlZEZpbGVDaGFubmVsSW5wdXRTdHJlYW0gZXh0ZW5kcyBCb3VuZGVkSW5wdXRTdHJlYW0geworICAgICAgICBwcml2YXRlIGZpbmFsIEZpbGVDaGFubmVsIGFyY2hpdmU7CisKKyAgICAgICAgQm91bmRlZEZpbGVDaGFubmVsSW5wdXRTdHJlYW0oZmluYWwgbG9uZyBzdGFydCwgZmluYWwgbG9uZyByZW1haW5pbmcpIHsKKyAgICAgICAgICAgIHN1cGVyKHN0YXJ0LCByZW1haW5pbmcpOworICAgICAgICAgICAgYXJjaGl2ZSA9IChGaWxlQ2hhbm5lbClaaXBGaWxlLnRoaXMuYXJjaGl2ZTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgaW50IHJlYWQobG9uZyBwb3MsIEJ5dGVCdWZmZXIgYnVmKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgaW50IHJlYWQgPSBhcmNoaXZlLnJlYWQoYnVmLCBwb3MpOworICAgICAgICAgICAgYnVmLmZsaXAoKTsKKyAgICAgICAgICAgIHJldHVybiByZWFkOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgTmFtZUFuZENvbW1lbnQgeworICAgICAgICBwcml2YXRlIGZpbmFsIGJ5dGVbXSBuYW1lOworICAgICAgICBwcml2YXRlIGZpbmFsIGJ5dGVbXSBjb21tZW50OworICAgICAgICBwcml2YXRlIE5hbWVBbmRDb21tZW50KGZpbmFsIGJ5dGVbXSBuYW1lLCBmaW5hbCBieXRlW10gY29tbWVudCkgeworICAgICAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKKyAgICAgICAgICAgIHRoaXMuY29tbWVudCA9IGNvbW1lbnQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0d28gWmlwQXJjaGl2ZUVudHJpZXMgYmFzZWQgb24gdGhlaXIgb2Zmc2V0IHdpdGhpbiB0aGUgYXJjaGl2ZS4KKyAgICAgKgorICAgICAqIDxwPldvbid0IHJldHVybiBhbnkgbWVhbmluZ2Z1bCByZXN1bHRzIGlmIG9uZSBvZiB0aGUgZW50cmllcworICAgICAqIGlzbid0IHBhcnQgb2YgdGhlIGFyY2hpdmUgYXQgYWxsLjwvcD4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjEKKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIENvbXBhcmF0b3I8WmlwQXJjaGl2ZUVudHJ5PiBvZmZzZXRDb21wYXJhdG9yID0KKyAgICAgICAgbmV3IENvbXBhcmF0b3I8WmlwQXJjaGl2ZUVudHJ5PigpIHsKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBpbnQgY29tcGFyZShmaW5hbCBaaXBBcmNoaXZlRW50cnkgZTEsIGZpbmFsIFppcEFyY2hpdmVFbnRyeSBlMikgeworICAgICAgICAgICAgaWYgKGUxID09IGUyKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGZpbmFsIEVudHJ5IGVudDEgPSBlMSBpbnN0YW5jZW9mIEVudHJ5ID8gKEVudHJ5KSBlMSA6IG51bGw7CisgICAgICAgICAgICBmaW5hbCBFbnRyeSBlbnQyID0gZTIgaW5zdGFuY2VvZiBFbnRyeSA/IChFbnRyeSkgZTIgOiBudWxsOworICAgICAgICAgICAgaWYgKGVudDEgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybiAxOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGVudDIgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZpbmFsIGxvbmcgdmFsID0gKGVudDEuZ2V0TG9jYWxIZWFkZXJPZmZzZXQoKQorICAgICAgICAgICAgICAgICAgICAgICAgLSBlbnQyLmdldExvY2FsSGVhZGVyT2Zmc2V0KCkpOworICAgICAgICAgICAgcmV0dXJuIHZhbCA9PSAwID8gMCA6IHZhbCA8IDAgPyAtMSA6ICsxOworICAgICAgICB9CisgICAgfTsKKworICAgIC8qKgorICAgICAqIEV4dGVuZHMgWmlwQXJjaGl2ZUVudHJ5IHRvIHN0b3JlIHRoZSBvZmZzZXQgd2l0aGluIHRoZSBhcmNoaXZlLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIEVudHJ5IGV4dGVuZHMgWmlwQXJjaGl2ZUVudHJ5IHsKKworICAgICAgICBFbnRyeSgpIHsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICAgICAgcmV0dXJuIDMgKiBzdXBlci5oYXNoQ29kZSgpCisgICAgICAgICAgICAgICAgKyAoaW50KSBnZXRMb2NhbEhlYWRlck9mZnNldCgpKyhpbnQpKGdldExvY2FsSGVhZGVyT2Zmc2V0KCk+PjMyKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgT2JqZWN0IG90aGVyKSB7CisgICAgICAgICAgICBpZiAoc3VwZXIuZXF1YWxzKG90aGVyKSkgeworICAgICAgICAgICAgICAgIC8vIHN1cGVyLmVxdWFscyB3b3VsZCByZXR1cm4gZmFsc2UgaWYgb3RoZXIgd2VyZSBub3QgYW4gRW50cnkKKyAgICAgICAgICAgICAgICBmaW5hbCBFbnRyeSBvdGhlckVudHJ5ID0gKEVudHJ5KSBvdGhlcjsKKyAgICAgICAgICAgICAgICByZXR1cm4gZ2V0TG9jYWxIZWFkZXJPZmZzZXQoKQorICAgICAgICAgICAgICAgICAgICAgICAgPT0gb3RoZXJFbnRyeS5nZXRMb2NhbEhlYWRlck9mZnNldCgpCisgICAgICAgICAgICAgICAgICAgICYmIGdldERhdGFPZmZzZXQoKQorICAgICAgICAgICAgICAgICAgICAgICAgPT0gb3RoZXJFbnRyeS5nZXREYXRhT2Zmc2V0KCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBTdG9yZWRTdGF0aXN0aWNzU3RyZWFtIGV4dGVuZHMgQ291bnRpbmdJbnB1dFN0cmVhbSBpbXBsZW1lbnRzIElucHV0U3RyZWFtU3RhdGlzdGljcyB7CisgICAgICAgIFN0b3JlZFN0YXRpc3RpY3NTdHJlYW0oSW5wdXRTdHJlYW0gaW4pIHsKKyAgICAgICAgICAgIHN1cGVyKGluKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgbG9uZyBnZXRDb21wcmVzc2VkQ291bnQoKSB7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0Qnl0ZXNSZWFkKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGxvbmcgZ2V0VW5jb21wcmVzc2VkQ291bnQoKSB7CisgICAgICAgICAgICByZXR1cm4gZ2V0Q29tcHJlc3NlZENvdW50KCk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1ppcExvbmcuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvWmlwTG9uZy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjYwNDZjNjEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1ppcExvbmcuamF2YQpAQCAtMCwwICsxLDIxNiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICoKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcDsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5CeXRlVXRpbHM7CisKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKKworaW1wb3J0IHN0YXRpYyBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcC5aaXBDb25zdGFudHMuV09SRDsKKworLyoqCisgKiBVdGlsaXR5IGNsYXNzIHRoYXQgcmVwcmVzZW50cyBhIGZvdXIgYnl0ZSBpbnRlZ2VyIHdpdGggY29udmVyc2lvbgorICogcnVsZXMgZm9yIHRoZSBsaXR0bGUgZW5kaWFuIGJ5dGUgb3JkZXIgb2YgWklQIGZpbGVzLgorICogQEltbXV0YWJsZQorICovCitwdWJsaWMgZmluYWwgY2xhc3MgWmlwTG9uZyBpbXBsZW1lbnRzIENsb25lYWJsZSwgU2VyaWFsaXphYmxlIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxTDsKKworICAgIHByaXZhdGUgZmluYWwgbG9uZyB2YWx1ZTsKKworICAgIC8qKiBDZW50cmFsIEZpbGUgSGVhZGVyIFNpZ25hdHVyZSAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgWmlwTG9uZyBDRkhfU0lHID0gbmV3IFppcExvbmcoMFgwMjAxNEI1MEwpOworCisgICAgLyoqIExvY2FsIEZpbGUgSGVhZGVyIFNpZ25hdHVyZSAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgWmlwTG9uZyBMRkhfU0lHID0gbmV3IFppcExvbmcoMFgwNDAzNEI1MEwpOworCisgICAgLyoqCisgICAgICogRGF0YSBEZXNjcmlwdG9yIHNpZ25hdHVyZS4KKyAgICAgKgorICAgICAqIDxwPkFjdHVhbGx5LCBQS1dBUkUgdXNlcyB0aGlzIGFzIG1hcmtlciBmb3Igc3BsaXQvc3Bhbm5lZAorICAgICAqIGFyY2hpdmVzIGFuZCBvdGhlciBhcmNoaXZlcnMgaGF2ZSBzdGFydGVkIHRvIHVzZSBpdCBhcyBEYXRhCisgICAgICogRGVzY3JpcHRvciBzaWduYXR1cmUgKGFzIHdlbGwpLjwvcD4KKyAgICAgKiBAc2luY2UgMS4xCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBaaXBMb25nIEREX1NJRyA9IG5ldyBaaXBMb25nKDBYMDgwNzRCNTBMKTsKKworICAgIC8qKgorICAgICAqIFZhbHVlIHN0b3JlZCBpbiBzaXplIGFuZCBzaW1pbGFyIGZpZWxkcyBpZiBaSVA2NCBleHRlbnNpb25zIGFyZQorICAgICAqIHVzZWQuCisgICAgICogQHNpbmNlIDEuMworICAgICAqLworICAgIHN0YXRpYyBmaW5hbCBaaXBMb25nIFpJUDY0X01BR0lDID0gbmV3IFppcExvbmcoWmlwQ29uc3RhbnRzLlpJUDY0X01BR0lDKTsKKworICAgIC8qKgorICAgICAqIE1hcmtzIFpJUCBhcmNoaXZlcyB0aGF0IHdlcmUgc3VwcG9zZWQgdG8gYmUgc3BsaXQgb3Igc3Bhbm5lZAorICAgICAqIGJ1dCBvbmx5IG5lZWRlZCBhIHNpbmdsZSBzZWdtZW50IGluIHRoZW4gZW5kIChzbyBhcmUgYWN0dWFsbHkKKyAgICAgKiBuZWl0aGVyIHNwbGl0IG5vciBzcGFubmVkKS4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgaXMgdGhlICJQSzAwIiBwcmVmaXggZm91bmQgaW4gc29tZSBhcmNoaXZlcy48L3A+CisgICAgICogQHNpbmNlIDEuNQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgWmlwTG9uZyBTSU5HTEVfU0VHTUVOVF9TUExJVF9NQVJLRVIgPQorICAgICAgICBuZXcgWmlwTG9uZygwWDMwMzA0QjUwTCk7CisKKyAgICAvKioKKyAgICAgKiBBcmNoaXZlIGV4dHJhIGRhdGEgcmVjb3JkIHNpZ25hdHVyZS4KKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBaaXBMb25nIEFFRF9TSUcgPSBuZXcgWmlwTG9uZygwWDA4MDY0QjUwTCk7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgaW5zdGFuY2UgZnJvbSBhIG51bWJlci4KKyAgICAgKiBAcGFyYW0gdmFsdWUgdGhlIGxvbmcgdG8gc3RvcmUgYXMgYSBaaXBMb25nCisgICAgICovCisgICAgcHVibGljIFppcExvbmcoZmluYWwgbG9uZyB2YWx1ZSkgeworICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogY3JlYXRlIGluc3RhbmNlIGZyb20gYSBqYXZhIGludC4KKyAgICAgKiBAcGFyYW0gdmFsdWUgdGhlIGludCB0byBzdG9yZSBhcyBhIFppcExvbmcKKyAgICAgKiBAc2luY2UgMS4xNQorICAgICAqLworICAgIHB1YmxpYyBaaXBMb25nKGludCB2YWx1ZSkgeworICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlIGluc3RhbmNlIGZyb20gYnl0ZXMuCisgICAgICogQHBhcmFtIGJ5dGVzIHRoZSBieXRlcyB0byBzdG9yZSBhcyBhIFppcExvbmcKKyAgICAgKi8KKyAgICBwdWJsaWMgWmlwTG9uZyAoZmluYWwgYnl0ZVtdIGJ5dGVzKSB7CisgICAgICAgIHRoaXMoYnl0ZXMsIDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZSBpbnN0YW5jZSBmcm9tIHRoZSBmb3VyIGJ5dGVzIHN0YXJ0aW5nIGF0IG9mZnNldC4KKyAgICAgKiBAcGFyYW0gYnl0ZXMgdGhlIGJ5dGVzIHRvIHN0b3JlIGFzIGEgWmlwTG9uZworICAgICAqIEBwYXJhbSBvZmZzZXQgdGhlIG9mZnNldCB0byBzdGFydAorICAgICAqLworICAgIHB1YmxpYyBaaXBMb25nIChmaW5hbCBieXRlW10gYnl0ZXMsIGZpbmFsIGludCBvZmZzZXQpIHsKKyAgICAgICAgdmFsdWUgPSBaaXBMb25nLmdldFZhbHVlKGJ5dGVzLCBvZmZzZXQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB2YWx1ZSBhcyBmb3VyIGJ5dGVzIGluIGJpZyBlbmRpYW4gYnl0ZSBvcmRlci4KKyAgICAgKiBAcmV0dXJuIHZhbHVlIGFzIGZvdXIgYnl0ZXMgaW4gYmlnIGVuZGlhbiBvcmRlcgorICAgICAqLworICAgIHB1YmxpYyBieXRlW10gZ2V0Qnl0ZXMoKSB7CisgICAgICAgIHJldHVybiBaaXBMb25nLmdldEJ5dGVzKHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdmFsdWUgYXMgSmF2YSBsb25nLgorICAgICAqIEByZXR1cm4gdmFsdWUgYXMgYSBsb25nCisgICAgICovCisgICAgcHVibGljIGxvbmcgZ2V0VmFsdWUoKSB7CisgICAgICAgIHJldHVybiB2YWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdmFsdWUgYXMgYSAoc2lnbmVkKSBqYXZhIGludAorICAgICAqIEByZXR1cm4gdmFsdWUgYXMgaW50CisgICAgICogQHNpbmNlIDEuMTUKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldEludFZhbHVlKCkgeyByZXR1cm4gKGludCl2YWx1ZTt9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdmFsdWUgYXMgZm91ciBieXRlcyBpbiBiaWcgZW5kaWFuIGJ5dGUgb3JkZXIuCisgICAgICogQHBhcmFtIHZhbHVlIHRoZSB2YWx1ZSB0byBjb252ZXJ0CisgICAgICogQHJldHVybiB2YWx1ZSBhcyBmb3VyIGJ5dGVzIGluIGJpZyBlbmRpYW4gYnl0ZSBvcmRlcgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYnl0ZVtdIGdldEJ5dGVzKGZpbmFsIGxvbmcgdmFsdWUpIHsKKyAgICAgICAgZmluYWwgYnl0ZVtdIHJlc3VsdCA9IG5ldyBieXRlW1dPUkRdOworICAgICAgICBwdXRMb25nKHZhbHVlLCByZXN1bHQsIDApOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIHB1dCB0aGUgdmFsdWUgYXMgZm91ciBieXRlcyBpbiBiaWcgZW5kaWFuIGJ5dGUgb3JkZXIuCisgICAgICogQHBhcmFtIHZhbHVlIHRoZSBKYXZhIGxvbmcgdG8gY29udmVydCB0byBieXRlcworICAgICAqIEBwYXJhbSBidWYgdGhlIG91dHB1dCBidWZmZXIKKyAgICAgKiBAcGFyYW0gIG9mZnNldAorICAgICAqICAgICAgICAgVGhlIG9mZnNldCB3aXRoaW4gdGhlIG91dHB1dCBidWZmZXIgb2YgdGhlIGZpcnN0IGJ5dGUgdG8gYmUgd3JpdHRlbi4KKyAgICAgKiAgICAgICAgIG11c3QgYmUgbm9uLW5lZ2F0aXZlIGFuZCBubyBsYXJnZXIgdGhhbiA8dHQ+YnVmLmxlbmd0aC00PC90dD4KKyAgICAgKi8KKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBwdXRMb25nKGZpbmFsIGxvbmcgdmFsdWUsIGZpbmFsIGJ5dGVbXSBidWYsIGludCBvZmZzZXQpIHsKKyAgICAgICAgQnl0ZVV0aWxzLnRvTGl0dGxlRW5kaWFuKGJ1ZiwgdmFsdWUsIG9mZnNldCwgNCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcHV0TG9uZyhmaW5hbCBieXRlW10gYnVmLCBmaW5hbCBpbnQgb2Zmc2V0KSB7CisgICAgICAgIHB1dExvbmcodmFsdWUsIGJ1Ziwgb2Zmc2V0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBIZWxwZXIgbWV0aG9kIHRvIGdldCB0aGUgdmFsdWUgYXMgYSBKYXZhIGxvbmcgZnJvbSBmb3VyIGJ5dGVzIHN0YXJ0aW5nIGF0IGdpdmVuIGFycmF5IG9mZnNldAorICAgICAqIEBwYXJhbSBieXRlcyB0aGUgYXJyYXkgb2YgYnl0ZXMKKyAgICAgKiBAcGFyYW0gb2Zmc2V0IHRoZSBvZmZzZXQgdG8gc3RhcnQKKyAgICAgKiBAcmV0dXJuIHRoZSBjb3JyZXNwb25kaW5nIEphdmEgbG9uZyB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbG9uZyBnZXRWYWx1ZShmaW5hbCBieXRlW10gYnl0ZXMsIGZpbmFsIGludCBvZmZzZXQpIHsKKyAgICAgICAgcmV0dXJuIEJ5dGVVdGlscy5mcm9tTGl0dGxlRW5kaWFuKGJ5dGVzLCBvZmZzZXQsIDQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEhlbHBlciBtZXRob2QgdG8gZ2V0IHRoZSB2YWx1ZSBhcyBhIEphdmEgbG9uZyBmcm9tIGEgZm91ci1ieXRlIGFycmF5CisgICAgICogQHBhcmFtIGJ5dGVzIHRoZSBhcnJheSBvZiBieXRlcworICAgICAqIEByZXR1cm4gdGhlIGNvcnJlc3BvbmRpbmcgSmF2YSBsb25nIHZhbHVlCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBsb25nIGdldFZhbHVlKGZpbmFsIGJ5dGVbXSBieXRlcykgeworICAgICAgICByZXR1cm4gZ2V0VmFsdWUoYnl0ZXMsIDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIE92ZXJyaWRlIHRvIG1ha2UgdHdvIGluc3RhbmNlcyB3aXRoIHNhbWUgdmFsdWUgZXF1YWwuCisgICAgICogQHBhcmFtIG8gYW4gb2JqZWN0IHRvIGNvbXBhcmUKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIG9iamVjdHMgYXJlIGVxdWFsCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIE9iamVjdCBvKSB7CisgICAgICAgIGlmIChvID09IG51bGwgfHwgIShvIGluc3RhbmNlb2YgWmlwTG9uZykpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdmFsdWUgPT0gKChaaXBMb25nKSBvKS5nZXRWYWx1ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIE92ZXJyaWRlIHRvIG1ha2UgdHdvIGluc3RhbmNlcyB3aXRoIHNhbWUgdmFsdWUgZXF1YWwuCisgICAgICogQHJldHVybiB0aGUgdmFsdWUgc3RvcmVkIGluIHRoZSBaaXBMb25nCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgcmV0dXJuIChpbnQpIHZhbHVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gY25mZSkgeworICAgICAgICAgICAgLy8gaW1wb3NzaWJsZQorICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oY25mZSk7IC8vTk9TT05BUgorICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuICJaaXBMb25nIHZhbHVlOiAiICsgdmFsdWU7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9aaXBNZXRob2QuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvWmlwTWV0aG9kLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGM5MTEyZAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvWmlwTWV0aG9kLmphdmEKQEAgLTAsMCArMSwyMjMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXA7CisKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLlppcEVudHJ5OworCisvKioKKyAqIExpc3Qgb2Yga25vd24gY29tcHJlc3Npb24gbWV0aG9kcworICoKKyAqIE1hbnkgb2YgdGhlc2UgbWV0aG9kcyBhcmUgY3VycmVudGx5IG5vdCBzdXBwb3J0ZWQgYnkgY29tbW9ucyBjb21wcmVzcworICoKKyAqIEBzaW5jZSAxLjUKKyAqLworcHVibGljIGVudW0gWmlwTWV0aG9kIHsKKworICAgIC8qKgorICAgICAqIENvbXByZXNzaW9uIG1ldGhvZCAwIGZvciB1bmNvbXByZXNzZWQgZW50cmllcy4KKyAgICAgKgorICAgICAqIEBzZWUgWmlwRW50cnkjU1RPUkVECisgICAgICovCisgICAgU1RPUkVEKFppcEVudHJ5LlNUT1JFRCksCisKKyAgICAvKioKKyAgICAgKiBVblNocmlua2luZy4KKyAgICAgKiBkeW5hbWljIExlbXBlbC1aaXYtV2VsY2gtQWxnb3JpdGhtCisgICAgICoKKyAgICAgKiBAc2VlIDxhIGhyZWY9Imh0dHBzOi8vd3d3LnBrd2FyZS5jb20vZG9jdW1lbnRzL2Nhc2VzdHVkaWVzL0FQUE5PVEUuVFhUIj5FeHBsYW5hdGlvbiBvZiBmaWVsZHM6IGNvbXByZXNzaW9uCisgICAgICogICAgICBtZXRob2Q6ICgyIGJ5dGVzKTwvYT4KKyAgICAgKi8KKyAgICBVTlNIUklOS0lORygxKSwKKworICAgIC8qKgorICAgICAqIFJlZHVjZWQgd2l0aCBjb21wcmVzc2lvbiBmYWN0b3IgMS4KKyAgICAgKgorICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cHM6Ly93d3cucGt3YXJlLmNvbS9kb2N1bWVudHMvY2FzZXN0dWRpZXMvQVBQTk9URS5UWFQiPkV4cGxhbmF0aW9uIG9mIGZpZWxkczogY29tcHJlc3Npb24KKyAgICAgKiAgICAgIG1ldGhvZDogKDIgYnl0ZXMpPC9hPgorICAgICAqLworICAgIEVYUEFORElOR19MRVZFTF8xKDIpLAorCisgICAgLyoqCisgICAgICogUmVkdWNlZCB3aXRoIGNvbXByZXNzaW9uIGZhY3RvciAyLgorICAgICAqCisgICAgICogQHNlZSA8YSBocmVmPSJodHRwczovL3d3dy5wa3dhcmUuY29tL2RvY3VtZW50cy9jYXNlc3R1ZGllcy9BUFBOT1RFLlRYVCI+RXhwbGFuYXRpb24gb2YgZmllbGRzOiBjb21wcmVzc2lvbgorICAgICAqICAgICAgbWV0aG9kOiAoMiBieXRlcyk8L2E+CisgICAgICovCisgICAgRVhQQU5ESU5HX0xFVkVMXzIoMyksCisKKyAgICAvKioKKyAgICAgKiBSZWR1Y2VkIHdpdGggY29tcHJlc3Npb24gZmFjdG9yIDMuCisgICAgICoKKyAgICAgKiBAc2VlIDxhIGhyZWY9Imh0dHBzOi8vd3d3LnBrd2FyZS5jb20vZG9jdW1lbnRzL2Nhc2VzdHVkaWVzL0FQUE5PVEUuVFhUIj5FeHBsYW5hdGlvbiBvZiBmaWVsZHM6IGNvbXByZXNzaW9uCisgICAgICogICAgICBtZXRob2Q6ICgyIGJ5dGVzKTwvYT4KKyAgICAgKi8KKyAgICBFWFBBTkRJTkdfTEVWRUxfMyg0KSwKKworICAgIC8qKgorICAgICAqIFJlZHVjZWQgd2l0aCBjb21wcmVzc2lvbiBmYWN0b3IgNC4KKyAgICAgKgorICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cHM6Ly93d3cucGt3YXJlLmNvbS9kb2N1bWVudHMvY2FzZXN0dWRpZXMvQVBQTk9URS5UWFQiPkV4cGxhbmF0aW9uIG9mIGZpZWxkczogY29tcHJlc3Npb24KKyAgICAgKiAgICAgIG1ldGhvZDogKDIgYnl0ZXMpPC9hPgorICAgICAqLworICAgIEVYUEFORElOR19MRVZFTF80KDUpLAorCisgICAgLyoqCisgICAgICogSW1wbG9kaW5nLgorICAgICAqCisgICAgICogQHNlZSA8YSBocmVmPSJodHRwczovL3d3dy5wa3dhcmUuY29tL2RvY3VtZW50cy9jYXNlc3R1ZGllcy9BUFBOT1RFLlRYVCI+RXhwbGFuYXRpb24gb2YgZmllbGRzOiBjb21wcmVzc2lvbgorICAgICAqICAgICAgbWV0aG9kOiAoMiBieXRlcyk8L2E+CisgICAgICovCisgICAgSU1QTE9ESU5HKDYpLAorCisgICAgLyoqCisgICAgICogVG9rZW5pemF0aW9uLgorICAgICAqCisgICAgICogQHNlZSA8YSBocmVmPSJodHRwczovL3d3dy5wa3dhcmUuY29tL2RvY3VtZW50cy9jYXNlc3R1ZGllcy9BUFBOT1RFLlRYVCI+RXhwbGFuYXRpb24gb2YgZmllbGRzOiBjb21wcmVzc2lvbgorICAgICAqICAgICAgbWV0aG9kOiAoMiBieXRlcyk8L2E+CisgICAgICovCisgICAgVE9LRU5JWkFUSU9OKDcpLAorCisgICAgLyoqCisgICAgICogQ29tcHJlc3Npb24gbWV0aG9kIDggZm9yIGNvbXByZXNzZWQgKGRlZmxhdGVkKSBlbnRyaWVzLgorICAgICAqCisgICAgICogQHNlZSBaaXBFbnRyeSNERUZMQVRFRAorICAgICAqLworICAgIERFRkxBVEVEKFppcEVudHJ5LkRFRkxBVEVEKSwKKworICAgIC8qKgorICAgICAqIENvbXByZXNzaW9uIE1ldGhvZCA5IGZvciBlbmhhbmNlZCBkZWZsYXRlLgorICAgICAqCisgICAgICogQHNlZSA8YSBocmVmPSJodHRwczovL3d3dy53aW56aXAuY29tL3d6NTQuaHRtIj5odHRwczovL3d3dy53aW56aXAuY29tL3d6NTQuaHRtPC9hPgorICAgICAqLworICAgIEVOSEFOQ0VEX0RFRkxBVEVEKDkpLAorCisgICAgLyoqCisgICAgICogUEtXQVJFIERhdGEgQ29tcHJlc3Npb24gTGlicmFyeSBJbXBsb2RpbmcuCisgICAgICoKKyAgICAgKiBAc2VlIDxhIGhyZWY9Imh0dHBzOi8vd3d3LndpbnppcC5jb20vd3o1NC5odG0iPmh0dHBzOi8vd3d3LndpbnppcC5jb20vd3o1NC5odG08L2E+CisgICAgICovCisgICAgUEtXQVJFX0lNUExPRElORygxMCksCisKKyAgICAvKioKKyAgICAgKiBDb21wcmVzc2lvbiBNZXRob2QgMTIgZm9yIGJ6aXAyLgorICAgICAqCisgICAgICogQHNlZSA8YSBocmVmPSJodHRwczovL3d3dy53aW56aXAuY29tL3d6NTQuaHRtIj5odHRwczovL3d3dy53aW56aXAuY29tL3d6NTQuaHRtPC9hPgorICAgICAqLworICAgIEJaSVAyKDEyKSwKKworICAgIC8qKgorICAgICAqIENvbXByZXNzaW9uIE1ldGhvZCAxNCBmb3IgTFpNQS4KKyAgICAgKgorICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cHM6Ly93d3cuNy16aXAub3JnL3Nkay5odG1sIj5odHRwczovL3d3dy43LXppcC5vcmcvc2RrLmh0bWw8L2E+CisgICAgICogQHNlZSA8YSBocmVmPSJodHRwczovL3d3dy53aW56aXAuY29tL3d6NTQuaHRtIj5odHRwczovL3d3dy53aW56aXAuY29tL3d6NTQuaHRtPC9hPgorICAgICAqLworICAgIExaTUEoMTQpLAorCisKKyAgICAvKioKKyAgICAgKiBDb21wcmVzc2lvbiBNZXRob2QgOTUgZm9yIFhaLgorICAgICAqCisgICAgICogQHNlZSA8YSBocmVmPSJodHRwczovL3d3dy53aW56aXAuY29tL3d6NTQuaHRtIj5odHRwczovL3d3dy53aW56aXAuY29tL3d6NTQuaHRtPC9hPgorICAgICAqLworICAgIFhaKDk1KSwKKworICAgIC8qKgorICAgICAqIENvbXByZXNzaW9uIE1ldGhvZCA5NiBmb3IgSnBlZyBjb21wcmVzc2lvbi4KKyAgICAgKgorICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cHM6Ly93d3cud2luemlwLmNvbS93ejU0Lmh0bSI+aHR0cHM6Ly93d3cud2luemlwLmNvbS93ejU0Lmh0bTwvYT4KKyAgICAgKi8KKyAgICBKUEVHKDk2KSwKKworICAgIC8qKgorICAgICAqIENvbXByZXNzaW9uIE1ldGhvZCA5NyBmb3IgV2F2UGFjay4KKyAgICAgKgorICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cHM6Ly93d3cud2luemlwLmNvbS93ejU0Lmh0bSI+aHR0cHM6Ly93d3cud2luemlwLmNvbS93ejU0Lmh0bTwvYT4KKyAgICAgKi8KKyAgICBXQVZQQUNLKDk3KSwKKworICAgIC8qKgorICAgICAqIENvbXByZXNzaW9uIE1ldGhvZCA5OCBmb3IgUFBNZC4KKyAgICAgKgorICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cHM6Ly93d3cud2luemlwLmNvbS93ejU0Lmh0bSI+aHR0cHM6Ly93d3cud2luemlwLmNvbS93ejU0Lmh0bTwvYT4KKyAgICAgKi8KKyAgICBQUE1EKDk4KSwKKworCisgICAgLyoqCisgICAgICogQ29tcHJlc3Npb24gTWV0aG9kIDk5IGZvciBBRVMgZW5jcnlwdGlvbi4KKyAgICAgKgorICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cHM6Ly93d3cud2luemlwLmNvbS93ejU0Lmh0bSI+aHR0cHM6Ly93d3cud2luemlwLmNvbS93ejU0Lmh0bTwvYT4KKyAgICAgKi8KKyAgICBBRVNfRU5DUllQVEVEKDk5KSwKKworICAgIC8qKgorICAgICAqIFVua25vd24gY29tcHJlc3Npb24gbWV0aG9kLgorICAgICAqLworICAgIFVOS05PV04oKTsKKworICAgIHN0YXRpYyBmaW5hbCBpbnQgVU5LTk9XTl9DT0RFID0gLTE7CisKKyAgICBwcml2YXRlIGZpbmFsIGludCBjb2RlOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTWFwPEludGVnZXIsIFppcE1ldGhvZD4gY29kZVRvRW51bTsKKworICAgIHN0YXRpYyB7CisgICAgICAgIGZpbmFsIE1hcDxJbnRlZ2VyLCBaaXBNZXRob2Q+IGN0ZSA9IG5ldyBIYXNoTWFwPD4oKTsKKyAgICAgICAgZm9yIChmaW5hbCBaaXBNZXRob2QgbWV0aG9kIDogdmFsdWVzKCkpIHsKKyAgICAgICAgICAgIGN0ZS5wdXQobWV0aG9kLmdldENvZGUoKSwgbWV0aG9kKTsKKyAgICAgICAgfQorICAgICAgICBjb2RlVG9FbnVtID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTWFwKGN0ZSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBaaXBNZXRob2QoKSB7CisgICAgICAgIHRoaXMoVU5LTk9XTl9DT0RFKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBwcml2YXRlIGNvbnN0cnVjdG9yIGZvciBlbnVtIHN0eWxlIGNsYXNzLgorICAgICAqLworICAgIFppcE1ldGhvZChmaW5hbCBpbnQgY29kZSkgeworICAgICAgICB0aGlzLmNvZGUgPSBjb2RlOworICAgIH0KKworICAgIC8qKgorICAgICAqIHRoZSBjb2RlIG9mIHRoZSBjb21wcmVzc2lvbiBtZXRob2QuCisgICAgICoKKyAgICAgKiBAc2VlIFppcEFyY2hpdmVFbnRyeSNnZXRNZXRob2QoKQorICAgICAqCisgICAgICogQHJldHVybiBhbiBpbnRlZ2VyIGNvZGUgZm9yIHRoZSBtZXRob2QKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldENvZGUoKSB7CisgICAgICAgIHJldHVybiBjb2RlOworICAgIH0KKworCisgICAgLyoqCisgICAgICogcmV0dXJucyB0aGUge0BsaW5rIFppcE1ldGhvZH0gZm9yIHRoZSBnaXZlbiBjb2RlIG9yIG51bGwgaWYgdGhlCisgICAgICogbWV0aG9kIGlzIG5vdCBrbm93bi4KKyAgICAgKiBAcGFyYW0gY29kZSB0aGUgY29kZQorICAgICAqIEByZXR1cm4gdGhlIHtAbGluayBaaXBNZXRob2R9IGZvciB0aGUgZ2l2ZW4gY29kZSBvciBudWxsIGlmIHRoZQorICAgICAqIG1ldGhvZCBpcyBub3Qga25vd24uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBaaXBNZXRob2QgZ2V0TWV0aG9kQnlDb2RlKGZpbmFsIGludCBjb2RlKSB7CisgICAgICAgIHJldHVybiBjb2RlVG9FbnVtLmdldChjb2RlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1ppcFNob3J0LmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1ppcFNob3J0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2NiNTA5NAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvWmlwU2hvcnQuamF2YQpAQCAtMCwwICsxLDE2MSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICoKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcDsKKworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLkJ5dGVVdGlsczsKKworLyoqCisgKiBVdGlsaXR5IGNsYXNzIHRoYXQgcmVwcmVzZW50cyBhIHR3byBieXRlIGludGVnZXIgd2l0aCBjb252ZXJzaW9uCisgKiBydWxlcyBmb3IgdGhlIGxpdHRsZSBlbmRpYW4gYnl0ZSBvcmRlciBvZiBaSVAgZmlsZXMuCisgKiBASW1tdXRhYmxlCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBaaXBTaG9ydCBpbXBsZW1lbnRzIENsb25lYWJsZSwgU2VyaWFsaXphYmxlIHsKKyAgICAvKioKKyAgICAgKiBaaXBTaG9ydCB3aXRoIGEgdmFsdWUgb2YgMC4KKyAgICAgKiBAc2luY2UgMS4xNAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgWmlwU2hvcnQgWkVSTyA9IG5ldyBaaXBTaG9ydCgwKTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOworCisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgdmFsdWU7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgaW5zdGFuY2UgZnJvbSBhIG51bWJlci4KKyAgICAgKiBAcGFyYW0gdmFsdWUgdGhlIGludCB0byBzdG9yZSBhcyBhIFppcFNob3J0CisgICAgICovCisgICAgcHVibGljIFppcFNob3J0IChmaW5hbCBpbnQgdmFsdWUpIHsKKyAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZSBpbnN0YW5jZSBmcm9tIGJ5dGVzLgorICAgICAqIEBwYXJhbSBieXRlcyB0aGUgYnl0ZXMgdG8gc3RvcmUgYXMgYSBaaXBTaG9ydAorICAgICAqLworICAgIHB1YmxpYyBaaXBTaG9ydCAoZmluYWwgYnl0ZVtdIGJ5dGVzKSB7CisgICAgICAgIHRoaXMoYnl0ZXMsIDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZSBpbnN0YW5jZSBmcm9tIHRoZSB0d28gYnl0ZXMgc3RhcnRpbmcgYXQgb2Zmc2V0LgorICAgICAqIEBwYXJhbSBieXRlcyB0aGUgYnl0ZXMgdG8gc3RvcmUgYXMgYSBaaXBTaG9ydAorICAgICAqIEBwYXJhbSBvZmZzZXQgdGhlIG9mZnNldCB0byBzdGFydAorICAgICAqLworICAgIHB1YmxpYyBaaXBTaG9ydCAoZmluYWwgYnl0ZVtdIGJ5dGVzLCBmaW5hbCBpbnQgb2Zmc2V0KSB7CisgICAgICAgIHZhbHVlID0gWmlwU2hvcnQuZ2V0VmFsdWUoYnl0ZXMsIG9mZnNldCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHZhbHVlIGFzIHR3byBieXRlcyBpbiBiaWcgZW5kaWFuIGJ5dGUgb3JkZXIuCisgICAgICogQHJldHVybiB0aGUgdmFsdWUgYXMgYSBhIHR3byBieXRlIGFycmF5IGluIGJpZyBlbmRpYW4gYnl0ZSBvcmRlcgorICAgICAqLworICAgIHB1YmxpYyBieXRlW10gZ2V0Qnl0ZXMoKSB7CisgICAgICAgIGZpbmFsIGJ5dGVbXSByZXN1bHQgPSBuZXcgYnl0ZVsyXTsKKyAgICAgICAgQnl0ZVV0aWxzLnRvTGl0dGxlRW5kaWFuKHJlc3VsdCwgdmFsdWUsIDAsIDIpOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB2YWx1ZSBhcyBKYXZhIGludC4KKyAgICAgKiBAcmV0dXJuIHZhbHVlIGFzIGEgSmF2YSBpbnQKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFZhbHVlKCkgeworICAgICAgICByZXR1cm4gdmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHZhbHVlIGFzIHR3byBieXRlcyBpbiBiaWcgZW5kaWFuIGJ5dGUgb3JkZXIuCisgICAgICogQHBhcmFtIHZhbHVlIHRoZSBKYXZhIGludCB0byBjb252ZXJ0IHRvIGJ5dGVzCisgICAgICogQHJldHVybiB0aGUgY29udmVydGVkIGludCBhcyBhIGJ5dGUgYXJyYXkgaW4gYmlnIGVuZGlhbiBieXRlIG9yZGVyCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBieXRlW10gZ2V0Qnl0ZXMoZmluYWwgaW50IHZhbHVlKSB7CisgICAgICAgIGZpbmFsIGJ5dGVbXSByZXN1bHQgPSBuZXcgYnl0ZVsyXTsKKyAgICAgICAgcHV0U2hvcnQodmFsdWUsIHJlc3VsdCwgMCk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogcHV0IHRoZSB2YWx1ZSBhcyB0d28gYnl0ZXMgaW4gYmlnIGVuZGlhbiBieXRlIG9yZGVyLgorICAgICAqIEBwYXJhbSB2YWx1ZSB0aGUgSmF2YSBpbnQgdG8gY29udmVydCB0byBieXRlcworICAgICAqIEBwYXJhbSBidWYgdGhlIG91dHB1dCBidWZmZXIKKyAgICAgKiBAcGFyYW0gIG9mZnNldAorICAgICAqICAgICAgICAgVGhlIG9mZnNldCB3aXRoaW4gdGhlIG91dHB1dCBidWZmZXIgb2YgdGhlIGZpcnN0IGJ5dGUgdG8gYmUgd3JpdHRlbi4KKyAgICAgKiAgICAgICAgIG11c3QgYmUgbm9uLW5lZ2F0aXZlIGFuZCBubyBsYXJnZXIgdGhhbiA8dHQ+YnVmLmxlbmd0aC0yPC90dD4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgcHV0U2hvcnQoZmluYWwgaW50IHZhbHVlLCBmaW5hbCBieXRlW10gYnVmLCBmaW5hbCBpbnQgb2Zmc2V0KSB7CisgICAgICAgIEJ5dGVVdGlscy50b0xpdHRsZUVuZGlhbihidWYsIHZhbHVlLCBvZmZzZXQsIDIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEhlbHBlciBtZXRob2QgdG8gZ2V0IHRoZSB2YWx1ZSBhcyBhIGphdmEgaW50IGZyb20gdHdvIGJ5dGVzIHN0YXJ0aW5nIGF0IGdpdmVuIGFycmF5IG9mZnNldAorICAgICAqIEBwYXJhbSBieXRlcyB0aGUgYXJyYXkgb2YgYnl0ZXMKKyAgICAgKiBAcGFyYW0gb2Zmc2V0IHRoZSBvZmZzZXQgdG8gc3RhcnQKKyAgICAgKiBAcmV0dXJuIHRoZSBjb3JyZXNwb25kaW5nIGphdmEgaW50IHZhbHVlCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgZ2V0VmFsdWUoZmluYWwgYnl0ZVtdIGJ5dGVzLCBmaW5hbCBpbnQgb2Zmc2V0KSB7CisgICAgICAgIHJldHVybiAoaW50KSBCeXRlVXRpbHMuZnJvbUxpdHRsZUVuZGlhbihieXRlcywgb2Zmc2V0LCAyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBIZWxwZXIgbWV0aG9kIHRvIGdldCB0aGUgdmFsdWUgYXMgYSBqYXZhIGludCBmcm9tIGEgdHdvLWJ5dGUgYXJyYXkKKyAgICAgKiBAcGFyYW0gYnl0ZXMgdGhlIGFycmF5IG9mIGJ5dGVzCisgICAgICogQHJldHVybiB0aGUgY29ycmVzcG9uZGluZyBqYXZhIGludCB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IGdldFZhbHVlKGZpbmFsIGJ5dGVbXSBieXRlcykgeworICAgICAgICByZXR1cm4gZ2V0VmFsdWUoYnl0ZXMsIDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIE92ZXJyaWRlIHRvIG1ha2UgdHdvIGluc3RhbmNlcyB3aXRoIHNhbWUgdmFsdWUgZXF1YWwuCisgICAgICogQHBhcmFtIG8gYW4gb2JqZWN0IHRvIGNvbXBhcmUKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIG9iamVjdHMgYXJlIGVxdWFsCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIE9iamVjdCBvKSB7CisgICAgICAgIGlmIChvID09IG51bGwgfHwgIShvIGluc3RhbmNlb2YgWmlwU2hvcnQpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHZhbHVlID09ICgoWmlwU2hvcnQpIG8pLmdldFZhbHVlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogT3ZlcnJpZGUgdG8gbWFrZSB0d28gaW5zdGFuY2VzIHdpdGggc2FtZSB2YWx1ZSBlcXVhbC4KKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBzdG9yZWQgaW4gdGhlIFppcFNob3J0CisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgcmV0dXJuIHZhbHVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gY25mZSkgeworICAgICAgICAgICAgLy8gaW1wb3NzaWJsZQorICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oY25mZSk7IC8vTk9TT05BUgorICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuICJaaXBTaG9ydCB2YWx1ZTogIiArIHZhbHVlOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvWmlwVXRpbC5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9aaXBVdGlsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGNjM2U2YQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvWmlwVXRpbC5qYXZhCkBAIC0wLDAgKzEsMzYwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBqYXZhLnV0aWwuQ2FsZW5kYXI7CitpbXBvcnQgamF2YS51dGlsLkRhdGU7CitpbXBvcnQgamF2YS51dGlsLnppcC5DUkMzMjsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLlppcEVudHJ5OworCisvKioKKyAqIFV0aWxpdHkgY2xhc3MgZm9yIGhhbmRsaW5nIERPUyBhbmQgSmF2YSB0aW1lIGNvbnZlcnNpb25zLgorICogQEltbXV0YWJsZQorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgWmlwVXRpbCB7CisgICAgLyoqCisgICAgICogU21hbGxlc3QgZGF0ZS90aW1lIFpJUCBjYW4gaGFuZGxlLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBET1NfVElNRV9NSU4gPSBaaXBMb25nLmdldEJ5dGVzKDB4MDAwMDIxMDBMKTsKKworICAgIC8qKgorICAgICAqIENvbnZlcnQgYSBEYXRlIG9iamVjdCB0byBhIERPUyBkYXRlL3RpbWUgZmllbGQuCisgICAgICogQHBhcmFtIHRpbWUgdGhlIDxjb2RlPkRhdGU8L2NvZGU+IHRvIGNvbnZlcnQKKyAgICAgKiBAcmV0dXJuIHRoZSBkYXRlIGFzIGEgPGNvZGU+WmlwTG9uZzwvY29kZT4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFppcExvbmcgdG9Eb3NUaW1lKGZpbmFsIERhdGUgdGltZSkgeworICAgICAgICByZXR1cm4gbmV3IFppcExvbmcodG9Eb3NUaW1lKHRpbWUuZ2V0VGltZSgpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydCBhIERhdGUgb2JqZWN0IHRvIGEgRE9TIGRhdGUvdGltZSBmaWVsZC4KKyAgICAgKgorICAgICAqIDxwPlN0b2xlbiBmcm9tIEluZm9aaXAncyA8Y29kZT5maWxlaW8uYzwvY29kZT48L3A+CisgICAgICogQHBhcmFtIHQgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBzaW5jZSB0aGUgZXBvY2gKKyAgICAgKiBAcmV0dXJuIHRoZSBkYXRlIGFzIGEgYnl0ZSBhcnJheQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYnl0ZVtdIHRvRG9zVGltZShmaW5hbCBsb25nIHQpIHsKKyAgICAgICAgZmluYWwgYnl0ZVtdIHJlc3VsdCA9IG5ldyBieXRlWzRdOworICAgICAgICB0b0Rvc1RpbWUodCwgcmVzdWx0LCAwKTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZXJ0IGEgRGF0ZSBvYmplY3QgdG8gYSBET1MgZGF0ZS90aW1lIGZpZWxkLgorICAgICAqCisgICAgICogPHA+U3RvbGVuIGZyb20gSW5mb1ppcCdzIDxjb2RlPmZpbGVpby5jPC9jb2RlPjwvcD4KKyAgICAgKiBAcGFyYW0gdCBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIHNpbmNlIHRoZSBlcG9jaAorICAgICAqIEBwYXJhbSBidWYgdGhlIG91dHB1dCBidWZmZXIKKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICBUaGUgb2Zmc2V0IHdpdGhpbiB0aGUgb3V0cHV0IGJ1ZmZlciBvZiB0aGUgZmlyc3QgYnl0ZSB0byBiZSB3cml0dGVuLgorICAgICAqICAgICAgICAgbXVzdCBiZSBub24tbmVnYXRpdmUgYW5kIG5vIGxhcmdlciB0aGFuIDx0dD5idWYubGVuZ3RoLTQ8L3R0PgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCB0b0Rvc1RpbWUoZmluYWwgbG9uZyB0LCBmaW5hbCBieXRlW10gYnVmLCBmaW5hbCBpbnQgb2Zmc2V0KSB7CisgICAgICAgIHRvRG9zVGltZShDYWxlbmRhci5nZXRJbnN0YW5jZSgpLCB0LCBidWYsIG9mZnNldCk7CisgICAgfQorCisgICAgc3RhdGljIHZvaWQgdG9Eb3NUaW1lKGZpbmFsIENhbGVuZGFyIGMsIGZpbmFsIGxvbmcgdCwgZmluYWwgYnl0ZVtdIGJ1ZiwgZmluYWwgaW50IG9mZnNldCkgeworICAgICAgICBjLnNldFRpbWVJbk1pbGxpcyh0KTsKKworICAgICAgICBmaW5hbCBpbnQgeWVhciA9IGMuZ2V0KENhbGVuZGFyLllFQVIpOworICAgICAgICBpZiAoeWVhciA8IDE5ODApIHsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoRE9TX1RJTUVfTUlOLCAwLCBidWYsIG9mZnNldCwgRE9TX1RJTUVfTUlOLmxlbmd0aCk7Ly8gc3RvcCBjYWxsZXJzIGZyb20gY2hhbmdpbmcgdGhlIGFycmF5CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgZmluYWwgaW50IG1vbnRoID0gYy5nZXQoQ2FsZW5kYXIuTU9OVEgpICsgMTsKKyAgICAgICAgZmluYWwgbG9uZyB2YWx1ZSA9ICAoKHllYXIgLSAxOTgwKSA8PCAyNSkKKyAgICAgICAgICAgICAgICB8ICAgICAgICAgKG1vbnRoIDw8IDIxKQorICAgICAgICAgICAgICAgIHwgICAgICAgICAoYy5nZXQoQ2FsZW5kYXIuREFZX09GX01PTlRIKSA8PCAxNikKKyAgICAgICAgICAgICAgICB8ICAgICAgICAgKGMuZ2V0KENhbGVuZGFyLkhPVVJfT0ZfREFZKSA8PCAxMSkKKyAgICAgICAgICAgICAgICB8ICAgICAgICAgKGMuZ2V0KENhbGVuZGFyLk1JTlVURSkgPDwgNSkKKyAgICAgICAgICAgICAgICB8ICAgICAgICAgKGMuZ2V0KENhbGVuZGFyLlNFQ09ORCkgPj4gMSk7CisgICAgICAgIFppcExvbmcucHV0TG9uZyh2YWx1ZSwgYnVmLCBvZmZzZXQpOworICAgIH0KKworCisgICAgLyoqCisgICAgICogQXNzdW1lcyBhIG5lZ2F0aXZlIGludGVnZXIgcmVhbGx5IGlzIGEgcG9zaXRpdmUgaW50ZWdlciB0aGF0CisgICAgICogaGFzIHdyYXBwZWQgYXJvdW5kIGFuZCByZS1jcmVhdGVzIHRoZSBvcmlnaW5hbCB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpIHRoZSB2YWx1ZSB0byB0cmVhdCBhcyB1bnNpZ25lZCBpbnQuCisgICAgICogQHJldHVybiB0aGUgdW5zaWduZWQgaW50IGFzIGEgbG9uZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGxvbmcgYWRqdXN0VG9Mb25nKGZpbmFsIGludCBpKSB7CisgICAgICAgIGlmIChpIDwgMCkgeworICAgICAgICAgICAgcmV0dXJuIDIgKiAoKGxvbmcpIEludGVnZXIuTUFYX1ZBTFVFKSArIDIgKyBpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldmVyc2VzIGEgYnl0ZVtdIGFycmF5LiAgUmV2ZXJzZXMgaW4tcGxhY2UgKHRodXMgcHJvdmlkZWQgYXJyYXkgaXMKKyAgICAgKiBtdXRhdGVkKSwgYnV0IGFsc28gcmV0dXJucyBzYW1lIGZvciBjb252ZW5pZW5jZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheSB0byByZXZlcnNlIChtdXRhdGVkIGluLXBsYWNlLCBidXQgYWxzbyByZXR1cm5lZCBmb3IKKyAgICAgKiAgICAgICAgY29udmVuaWVuY2UpLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcmV2ZXJzZWQgYXJyYXkgKG11dGF0ZWQgaW4tcGxhY2UsIGJ1dCBhbHNvIHJldHVybmVkIGZvcgorICAgICAqICAgICAgICBjb252ZW5pZW5jZSkuCisgICAgICogQHNpbmNlIDEuNQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYnl0ZVtdIHJldmVyc2UoZmluYWwgYnl0ZVtdIGFycmF5KSB7CisgICAgICAgIGZpbmFsIGludCB6ID0gYXJyYXkubGVuZ3RoIC0gMTsgLy8gcG9zaXRpb24gb2YgbGFzdCBlbGVtZW50CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXJyYXkubGVuZ3RoIC8gMjsgaSsrKSB7CisgICAgICAgICAgICBmaW5hbCBieXRlIHggPSBhcnJheVtpXTsKKyAgICAgICAgICAgIGFycmF5W2ldID0gYXJyYXlbeiAtIGldOworICAgICAgICAgICAgYXJyYXlbeiAtIGldID0geDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYXJyYXk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydHMgYSBCaWdJbnRlZ2VyIGludG8gYSBsb25nLCBhbmQgYmxvd3MgdXAKKyAgICAgKiAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uKSBpZiB0aGUgQmlnSW50ZWdlciBpcyB0b28gYmlnLgorICAgICAqCisgICAgICogQHBhcmFtIGJpZyBCaWdJbnRlZ2VyIHRvIGNvbnZlcnQuCisgICAgICogQHJldHVybiBsb25nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBCaWdJbnRlZ2VyLgorICAgICAqLworICAgIHN0YXRpYyBsb25nIGJpZ1RvTG9uZyhmaW5hbCBCaWdJbnRlZ2VyIGJpZykgeworICAgICAgICBpZiAoYmlnLmJpdExlbmd0aCgpIDw9IDYzKSB7IC8vIGJpdExlbmd0aCgpIGRvZXNuJ3QgY291bnQgdGhlIHNpZ24gYml0LgorICAgICAgICAgICAgcmV0dXJuIGJpZy5sb25nVmFsdWUoKTsKKyAgICAgICAgfQorICAgICAgICB0aHJvdyBuZXcgTnVtYmVyRm9ybWF0RXhjZXB0aW9uKCJUaGUgQmlnSW50ZWdlciBjYW5ub3QgZml0IGluc2lkZSBhIDY0IGJpdCBqYXZhIGxvbmc6IFsiICsgYmlnICsgIl0iKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8cD4KKyAgICAgKiBDb252ZXJ0cyBhIGxvbmcgaW50byBhIEJpZ0ludGVnZXIuICBOZWdhdGl2ZSBudW1iZXJzIGJldHdlZW4gLTEgYW5kCisgICAgICogLTJeMzEgYXJlIHRyZWF0ZWQgYXMgdW5zaWduZWQgMzIgYml0IChlLmcuLCBwb3NpdGl2ZSkgaW50ZWdlcnMuCisgICAgICogTmVnYXRpdmUgbnVtYmVycyBiZWxvdyAtMl4zMSBjYXVzZSBhbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiB0byBiZSB0aHJvd24uCisgICAgICogPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGwgbG9uZyB0byBjb252ZXJ0IHRvIEJpZ0ludGVnZXIuCisgICAgICogQHJldHVybiBCaWdJbnRlZ2VyIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBwcm92aWRlZCBsb25nLgorICAgICAqLworICAgIHN0YXRpYyBCaWdJbnRlZ2VyIGxvbmdUb0JpZyhsb25nIGwpIHsKKyAgICAgICAgaWYgKGwgPCBJbnRlZ2VyLk1JTl9WQUxVRSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiTmVnYXRpdmUgbG9uZ3MgPCAtMl4zMSBub3QgcGVybWl0dGVkOiBbIiArIGwgKyAiXSIpOworICAgICAgICB9IGVsc2UgaWYgKGwgPCAwICYmIGwgPj0gSW50ZWdlci5NSU5fVkFMVUUpIHsKKyAgICAgICAgICAgIC8vIElmIHNvbWVvbmUgcGFzc2VzIGluIGEgLTIsIHRoZXkgcHJvYmFibHkgbWVhbiA0Mjk0OTY3Mjk0CisgICAgICAgICAgICAvLyAoRm9yIGV4YW1wbGUsIFVuaXggVUlEL0dJRCdzIGFyZSAzMiBiaXQgdW5zaWduZWQuKQorICAgICAgICAgICAgbCA9IFppcFV0aWwuYWRqdXN0VG9Mb25nKChpbnQpIGwpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBCaWdJbnRlZ2VyLnZhbHVlT2YobCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydHMgYSBzaWduZWQgYnl0ZSBpbnRvIGFuIHVuc2lnbmVkIGludGVnZXIgcmVwcmVzZW50YXRpb24KKyAgICAgKiAoZS5nLiwgLTEgYmVjb21lcyAyNTUpLgorICAgICAqCisgICAgICogQHBhcmFtIGIgYnl0ZSB0byBjb252ZXJ0IHRvIGludAorICAgICAqIEByZXR1cm4gaW50IHJlcHJlc2VudGF0aW9uIG9mIHRoZSBwcm92aWRlZCBieXRlCisgICAgICogQHNpbmNlIDEuNQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IHNpZ25lZEJ5dGVUb1Vuc2lnbmVkSW50KGZpbmFsIGJ5dGUgYikgeworICAgICAgICBpZiAoYiA+PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gYjsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gMjU2ICsgYjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZXJ0cyBhbiB1bnNpZ25lZCBpbnRlZ2VyIHRvIGEgc2lnbmVkIGJ5dGUgKGUuZy4sIDI1NSBiZWNvbWVzIC0xKS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpIGludGVnZXIgdG8gY29udmVydCB0byBieXRlCisgICAgICogQHJldHVybiBieXRlIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBwcm92aWRlZCBpbnQKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgcHJvdmlkZWQgaW50ZWdlciBpcyBub3QgaW5zaWRlIHRoZSByYW5nZSBbMCwyNTVdLgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJ5dGUgdW5zaWduZWRJbnRUb1NpZ25lZEJ5dGUoZmluYWwgaW50IGkpIHsKKyAgICAgICAgaWYgKGkgPiAyNTUgfHwgaSA8IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkNhbiBvbmx5IGNvbnZlcnQgbm9uLW5lZ2F0aXZlIGludGVnZXJzIGJldHdlZW4gWzAsMjU1XSB0byBieXRlOiBbIiArIGkgKyAiXSIpOworICAgICAgICB9CisgICAgICAgIGlmIChpIDwgMTI4KSB7CisgICAgICAgICAgICByZXR1cm4gKGJ5dGUpIGk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIChieXRlKSAoaSAtIDI1Nik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydCBhIERPUyBkYXRlL3RpbWUgZmllbGQgdG8gYSBEYXRlIG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB6aXBEb3NUaW1lIGNvbnRhaW5zIHRoZSBzdG9yZWQgRE9TIHRpbWUuCisgICAgICogQHJldHVybiBhIERhdGUgaW5zdGFuY2UgY29ycmVzcG9uZGluZyB0byB0aGUgZ2l2ZW4gdGltZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIERhdGUgZnJvbURvc1RpbWUoZmluYWwgWmlwTG9uZyB6aXBEb3NUaW1lKSB7CisgICAgICAgIGZpbmFsIGxvbmcgZG9zVGltZSA9IHppcERvc1RpbWUuZ2V0VmFsdWUoKTsKKyAgICAgICAgcmV0dXJuIG5ldyBEYXRlKGRvc1RvSmF2YVRpbWUoZG9zVGltZSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlcnRzIERPUyB0aW1lIHRvIEphdmEgdGltZSAobnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBzaW5jZQorICAgICAqIGVwb2NoKS4KKyAgICAgKiBAcGFyYW0gZG9zVGltZSB0aW1lIHRvIGNvbnZlcnQKKyAgICAgKiBAcmV0dXJuIGNvbnZlcnRlZCB0aW1lCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBsb25nIGRvc1RvSmF2YVRpbWUoZmluYWwgbG9uZyBkb3NUaW1lKSB7CisgICAgICAgIGZpbmFsIENhbGVuZGFyIGNhbCA9IENhbGVuZGFyLmdldEluc3RhbmNlKCk7CisgICAgICAgIC8vIENoZWNrU3R5bGU6TWFnaWNOdW1iZXJDaGVjayBPRkYgLSBubyBwb2ludAorICAgICAgICBjYWwuc2V0KENhbGVuZGFyLllFQVIsIChpbnQpICgoZG9zVGltZSA+PiAyNSkgJiAweDdmKSArIDE5ODApOworICAgICAgICBjYWwuc2V0KENhbGVuZGFyLk1PTlRILCAoaW50KSAoKGRvc1RpbWUgPj4gMjEpICYgMHgwZikgLSAxKTsKKyAgICAgICAgY2FsLnNldChDYWxlbmRhci5EQVRFLCAoaW50KSAoZG9zVGltZSA+PiAxNikgJiAweDFmKTsKKyAgICAgICAgY2FsLnNldChDYWxlbmRhci5IT1VSX09GX0RBWSwgKGludCkgKGRvc1RpbWUgPj4gMTEpICYgMHgxZik7CisgICAgICAgIGNhbC5zZXQoQ2FsZW5kYXIuTUlOVVRFLCAoaW50KSAoZG9zVGltZSA+PiA1KSAmIDB4M2YpOworICAgICAgICBjYWwuc2V0KENhbGVuZGFyLlNFQ09ORCwgKGludCkgKGRvc1RpbWUgPDwgMSkgJiAweDNlKTsKKyAgICAgICAgY2FsLnNldChDYWxlbmRhci5NSUxMSVNFQ09ORCwgMCk7CisgICAgICAgIC8vIENoZWNrU3R5bGU6TWFnaWNOdW1iZXJDaGVjayBPTgorICAgICAgICByZXR1cm4gY2FsLmdldFRpbWUoKS5nZXRUaW1lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSWYgdGhlIGVudHJ5IGhhcyBVbmljb2RlKkV4dHJhRmllbGRzIGFuZCB0aGUgQ1JDcyBvZiB0aGUKKyAgICAgKiBuYW1lcy9jb21tZW50cyBtYXRjaCB0aG9zZSBvZiB0aGUgZXh0cmEgZmllbGRzLCB0cmFuc2ZlciB0aGUKKyAgICAgKiBrbm93biBVbmljb2RlIHZhbHVlcyBmcm9tIHRoZSBleHRyYSBmaWVsZC4KKyAgICAgKi8KKyAgICBzdGF0aWMgdm9pZCBzZXROYW1lQW5kQ29tbWVudEZyb21FeHRyYUZpZWxkcyhmaW5hbCBaaXBBcmNoaXZlRW50cnkgemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgYnl0ZVtdIG9yaWdpbmFsTmFtZUJ5dGVzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBjb21tZW50Qnl0ZXMpIHsKKyAgICAgICAgZmluYWwgVW5pY29kZVBhdGhFeHRyYUZpZWxkIG5hbWUgPSAoVW5pY29kZVBhdGhFeHRyYUZpZWxkKQorICAgICAgICAgICAgemUuZ2V0RXh0cmFGaWVsZChVbmljb2RlUGF0aEV4dHJhRmllbGQuVVBBVEhfSUQpOworICAgICAgICBmaW5hbCBTdHJpbmcgbmV3TmFtZSA9IGdldFVuaWNvZGVTdHJpbmdJZk9yaWdpbmFsTWF0Y2hlcyhuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmlnaW5hbE5hbWVCeXRlcyk7CisgICAgICAgIGlmIChuZXdOYW1lICE9IG51bGwpIHsKKyAgICAgICAgICAgIHplLnNldE5hbWUobmV3TmFtZSk7CisgICAgICAgICAgICB6ZS5zZXROYW1lU291cmNlKFppcEFyY2hpdmVFbnRyeS5OYW1lU291cmNlLlVOSUNPREVfRVhUUkFfRklFTEQpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGNvbW1lbnRCeXRlcyAhPSBudWxsICYmIGNvbW1lbnRCeXRlcy5sZW5ndGggPiAwKSB7CisgICAgICAgICAgICBmaW5hbCBVbmljb2RlQ29tbWVudEV4dHJhRmllbGQgY210ID0gKFVuaWNvZGVDb21tZW50RXh0cmFGaWVsZCkKKyAgICAgICAgICAgICAgICB6ZS5nZXRFeHRyYUZpZWxkKFVuaWNvZGVDb21tZW50RXh0cmFGaWVsZC5VQ09NX0lEKTsKKyAgICAgICAgICAgIGZpbmFsIFN0cmluZyBuZXdDb21tZW50ID0KKyAgICAgICAgICAgICAgICBnZXRVbmljb2RlU3RyaW5nSWZPcmlnaW5hbE1hdGNoZXMoY210LCBjb21tZW50Qnl0ZXMpOworICAgICAgICAgICAgaWYgKG5ld0NvbW1lbnQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHplLnNldENvbW1lbnQobmV3Q29tbWVudCk7CisgICAgICAgICAgICAgICAgemUuc2V0Q29tbWVudFNvdXJjZShaaXBBcmNoaXZlRW50cnkuQ29tbWVudFNvdXJjZS5VTklDT0RFX0VYVFJBX0ZJRUxEKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIElmIHRoZSBzdG9yZWQgQ1JDIG1hdGNoZXMgdGhlIG9uZSBvZiB0aGUgZ2l2ZW4gbmFtZSwgcmV0dXJuIHRoZQorICAgICAqIFVuaWNvZGUgbmFtZSBvZiB0aGUgZ2l2ZW4gZmllbGQuCisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgZmllbGQgaXMgbnVsbCBvciB0aGUgQ1JDcyBkb24ndCBtYXRjaCwgcmV0dXJuIG51bGwKKyAgICAgKiBpbnN0ZWFkLjwvcD4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYworICAgICAgICBTdHJpbmcgZ2V0VW5pY29kZVN0cmluZ0lmT3JpZ2luYWxNYXRjaGVzKGZpbmFsIEFic3RyYWN0VW5pY29kZUV4dHJhRmllbGQgZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBieXRlW10gb3JpZykgeworICAgICAgICBpZiAoZiAhPSBudWxsKSB7CisgICAgICAgICAgICBmaW5hbCBDUkMzMiBjcmMzMiA9IG5ldyBDUkMzMigpOworICAgICAgICAgICAgY3JjMzIudXBkYXRlKG9yaWcpOworICAgICAgICAgICAgZmluYWwgbG9uZyBvcmlnQ1JDMzIgPSBjcmMzMi5nZXRWYWx1ZSgpOworCisgICAgICAgICAgICBpZiAob3JpZ0NSQzMyID09IGYuZ2V0TmFtZUNSQzMyKCkpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gWmlwRW5jb2RpbmdIZWxwZXIKKyAgICAgICAgICAgICAgICAgICAgICAgIC5VVEY4X1pJUF9FTkNPRElORy5kZWNvZGUoZi5nZXRVbmljb2RlTmFtZSgpKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChmaW5hbCBJT0V4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgICAgICAvLyBVVEYtOCB1bnN1cHBvcnRlZD8gIHNob3VsZCBiZSBpbXBvc3NpYmxlIHRoZQorICAgICAgICAgICAgICAgICAgICAvLyBVbmljb2RlKkV4dHJhRmllbGQgbXVzdCBjb250YWluIHNvbWUgYmFkIGJ5dGVzCisKKyAgICAgICAgICAgICAgICAgICAgLy8gVE9ETyBsb2cgdGhpcyBhbnl3aGVyZT8KKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIGNvcHkgb2YgdGhlIGdpdmVuIGFycmF5IC0gb3IgcmV0dXJuIG51bGwgaWYgdGhlCisgICAgICogYXJndW1lbnQgaXMgbnVsbC4KKyAgICAgKi8KKyAgICBzdGF0aWMgYnl0ZVtdIGNvcHkoZmluYWwgYnl0ZVtdIGZyb20pIHsKKyAgICAgICAgaWYgKGZyb20gIT0gbnVsbCkgeworICAgICAgICAgICAgZmluYWwgYnl0ZVtdIHRvID0gbmV3IGJ5dGVbZnJvbS5sZW5ndGhdOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShmcm9tLCAwLCB0bywgMCwgdG8ubGVuZ3RoKTsKKyAgICAgICAgICAgIHJldHVybiB0bzsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBzdGF0aWMgdm9pZCBjb3B5KGZpbmFsIGJ5dGVbXSBmcm9tLCBmaW5hbCBieXRlW10gdG8sIGZpbmFsIGludCBvZmZzZXQpIHsKKyAgICAgICAgaWYgKGZyb20gIT0gbnVsbCkgeworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShmcm9tLCAwLCB0bywgb2Zmc2V0LCBmcm9tLmxlbmd0aCk7CisgICAgICAgIH0KKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFdoZXRoZXIgdGhpcyBsaWJyYXJ5IGlzIGFibGUgdG8gcmVhZCBvciB3cml0ZSB0aGUgZ2l2ZW4gZW50cnkuCisgICAgICovCisgICAgc3RhdGljIGJvb2xlYW4gY2FuSGFuZGxlRW50cnlEYXRhKGZpbmFsIFppcEFyY2hpdmVFbnRyeSBlbnRyeSkgeworICAgICAgICByZXR1cm4gc3VwcG9ydHNFbmNyeXB0aW9uT2YoZW50cnkpICYmIHN1cHBvcnRzTWV0aG9kT2YoZW50cnkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdoZXRoZXIgdGhpcyBsaWJyYXJ5IHN1cHBvcnRzIHRoZSBlbmNyeXB0aW9uIHVzZWQgYnkgdGhlIGdpdmVuCisgICAgICogZW50cnkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGVudHJ5IGlzbid0IGVuY3J5cHRlZCBhdCBhbGwKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIHN1cHBvcnRzRW5jcnlwdGlvbk9mKGZpbmFsIFppcEFyY2hpdmVFbnRyeSBlbnRyeSkgeworICAgICAgICByZXR1cm4gIWVudHJ5LmdldEdlbmVyYWxQdXJwb3NlQml0KCkudXNlc0VuY3J5cHRpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXaGV0aGVyIHRoaXMgbGlicmFyeSBzdXBwb3J0cyB0aGUgY29tcHJlc3Npb24gbWV0aG9kIHVzZWQgYnkKKyAgICAgKiB0aGUgZ2l2ZW4gZW50cnkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGNvbXByZXNzaW9uIG1ldGhvZCBpcyBzdXBwb3J0ZWQKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIHN1cHBvcnRzTWV0aG9kT2YoZmluYWwgWmlwQXJjaGl2ZUVudHJ5IGVudHJ5KSB7CisgICAgICAgIHJldHVybiBlbnRyeS5nZXRNZXRob2QoKSA9PSBaaXBFbnRyeS5TVE9SRUQKKyAgICAgICAgICAgIHx8IGVudHJ5LmdldE1ldGhvZCgpID09IFppcE1ldGhvZC5VTlNIUklOS0lORy5nZXRDb2RlKCkKKyAgICAgICAgICAgIHx8IGVudHJ5LmdldE1ldGhvZCgpID09IFppcE1ldGhvZC5JTVBMT0RJTkcuZ2V0Q29kZSgpCisgICAgICAgICAgICB8fCBlbnRyeS5nZXRNZXRob2QoKSA9PSBaaXBFbnRyeS5ERUZMQVRFRAorICAgICAgICAgICAgfHwgZW50cnkuZ2V0TWV0aG9kKCkgPT0gWmlwTWV0aG9kLkVOSEFOQ0VEX0RFRkxBVEVELmdldENvZGUoKQorICAgICAgICAgICAgfHwgZW50cnkuZ2V0TWV0aG9kKCkgPT0gWmlwTWV0aG9kLkJaSVAyLmdldENvZGUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3Mgd2hldGhlciB0aGUgZW50cnkgcmVxdWlyZXMgZmVhdHVyZXMgbm90ICh5ZXQpIHN1cHBvcnRlZAorICAgICAqIGJ5IHRoZSBsaWJyYXJ5IGFuZCB0aHJvd3MgYW4gZXhjZXB0aW9uIGlmIGl0IGRvZXMuCisgICAgICovCisgICAgc3RhdGljIHZvaWQgY2hlY2tSZXF1ZXN0ZWRGZWF0dXJlcyhmaW5hbCBaaXBBcmNoaXZlRW50cnkgemUpCisgICAgICAgIHRocm93cyBVbnN1cHBvcnRlZFppcEZlYXR1cmVFeGNlcHRpb24geworICAgICAgICBpZiAoIXN1cHBvcnRzRW5jcnlwdGlvbk9mKHplKSkgeworICAgICAgICAgICAgdGhyb3cKKyAgICAgICAgICAgICAgICBuZXcgVW5zdXBwb3J0ZWRaaXBGZWF0dXJlRXhjZXB0aW9uKFVuc3VwcG9ydGVkWmlwRmVhdHVyZUV4Y2VwdGlvbgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLkZlYXR1cmUuRU5DUllQVElPTiwgemUpOworICAgICAgICB9CisgICAgICAgIGlmICghc3VwcG9ydHNNZXRob2RPZih6ZSkpIHsKKyAgICAgICAgICAgIGZpbmFsIFppcE1ldGhvZCBtID0gWmlwTWV0aG9kLmdldE1ldGhvZEJ5Q29kZSh6ZS5nZXRNZXRob2QoKSk7CisgICAgICAgICAgICBpZiAobSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhyb3cKKyAgICAgICAgICAgICAgICAgICAgbmV3IFVuc3VwcG9ydGVkWmlwRmVhdHVyZUV4Y2VwdGlvbihVbnN1cHBvcnRlZFppcEZlYXR1cmVFeGNlcHRpb24KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuRmVhdHVyZS5NRVRIT0QsIHplKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZFppcEZlYXR1cmVFeGNlcHRpb24obSwgemUpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9wYWNrYWdlLmh0bWwgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL3BhY2thZ2UuaHRtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MjE2ODdiCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9wYWNrYWdlLmh0bWwKQEAgLTAsMCArMSwyNCBAQAorPGh0bWw+Cis8IS0tCisKKyAgIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAgIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisKKyAgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKworICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAgIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisKKy0tPgorICA8Ym9keT4KKyAgICA8cD5Qcm92aWRlcyBzdHJlYW0gY2xhc3NlcyBmb3IgcmVhZGluZyBhbmQgd3JpdGluZyBhcmNoaXZlcyB1c2luZworICAgICAgdGhlIFpJUCBmb3JtYXQuPC9wPgorICA8L2JvZHk+Cis8L2h0bWw+CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jaGFuZ2VzL0NoYW5nZS5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY2hhbmdlcy9DaGFuZ2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mYjkwMWJkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY2hhbmdlcy9DaGFuZ2UuamF2YQpAQCAtMCwwICsxLDk2IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNoYW5nZXM7CisKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5BcmNoaXZlRW50cnk7CisKKy8qKgorICogQ2hhbmdlIGhvbGRzIG1ldGEgaW5mb3JtYXRpb24gYWJvdXQgYSBjaGFuZ2UuCisgKgorICogQEltbXV0YWJsZQorICovCitjbGFzcyBDaGFuZ2UgeworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIHRhcmdldEZpbGU7IC8vIGVudHJ5IG5hbWUgdG8gZGVsZXRlCisgICAgcHJpdmF0ZSBmaW5hbCBBcmNoaXZlRW50cnkgZW50cnk7IC8vIG5ldyBlbnRyeSB0byBhZGQKKyAgICBwcml2YXRlIGZpbmFsIElucHV0U3RyZWFtIGlucHV0OyAvLyBzb3VyY2UgZm9yIG5ldyBlbnRyeQorICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiByZXBsYWNlTW9kZTsgLy8gY2hhbmdlIHNob3VsZCByZXBsYWNlTW9kZSBleGlzdGluZyBlbnRyaWVzCisKKyAgICAvLyBUeXBlIG9mIGNoYW5nZQorICAgIHByaXZhdGUgZmluYWwgaW50IHR5cGU7CisgICAgLy8gUG9zc2libGUgdHlwZSB2YWx1ZXMKKyAgICBzdGF0aWMgZmluYWwgaW50IFRZUEVfREVMRVRFID0gMTsKKyAgICBzdGF0aWMgZmluYWwgaW50IFRZUEVfQUREID0gMjsKKyAgICBzdGF0aWMgZmluYWwgaW50IFRZUEVfTU9WRSA9IDM7IC8vIE5PVCBVU0VECisgICAgc3RhdGljIGZpbmFsIGludCBUWVBFX0RFTEVURV9ESVIgPSA0OworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IuIFRha2VzIHRoZSBmaWxlbmFtZSBvZiB0aGUgZmlsZSB0byBiZSBkZWxldGVkCisgICAgICogZnJvbSB0aGUgc3RyZWFtIGFzIGFyZ3VtZW50LgorICAgICAqIEBwYXJhbSBwRmlsZW5hbWUgdGhlIGZpbGVuYW1lIG9mIHRoZSBmaWxlIHRvIGRlbGV0ZQorICAgICAqLworICAgIENoYW5nZShmaW5hbCBTdHJpbmcgcEZpbGVuYW1lLCBmaW5hbCBpbnQgdHlwZSkgeworICAgICAgICBpZihwRmlsZW5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy50YXJnZXRGaWxlID0gcEZpbGVuYW1lOworICAgICAgICB0aGlzLnR5cGUgPSB0eXBlOworICAgICAgICB0aGlzLmlucHV0ID0gbnVsbDsKKyAgICAgICAgdGhpcy5lbnRyeSA9IG51bGw7CisgICAgICAgIHRoaXMucmVwbGFjZU1vZGUgPSB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdCBhIGNoYW5nZSB3aGljaCBhZGRzIGFuIGVudHJ5LgorICAgICAqCisgICAgICogQHBhcmFtIHBFbnRyeSB0aGUgZW50cnkgZGV0YWlscworICAgICAqIEBwYXJhbSBwSW5wdXQgdGhlIElucHV0U3RyZWFtIGZvciB0aGUgZW50cnkgZGF0YQorICAgICAqLworICAgIENoYW5nZShmaW5hbCBBcmNoaXZlRW50cnkgcEVudHJ5LCBmaW5hbCBJbnB1dFN0cmVhbSBwSW5wdXQsIGZpbmFsIGJvb2xlYW4gcmVwbGFjZSkgeworICAgICAgICBpZihwRW50cnkgPT0gbnVsbCB8fCBwSW5wdXQgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5lbnRyeSA9IHBFbnRyeTsKKyAgICAgICAgdGhpcy5pbnB1dCA9IHBJbnB1dDsKKyAgICAgICAgdHlwZSA9IFRZUEVfQUREOworICAgICAgICB0YXJnZXRGaWxlID0gbnVsbDsKKyAgICAgICAgdGhpcy5yZXBsYWNlTW9kZSA9IHJlcGxhY2U7CisgICAgfQorCisgICAgQXJjaGl2ZUVudHJ5IGdldEVudHJ5KCkgeworICAgICAgICByZXR1cm4gZW50cnk7CisgICAgfQorCisgICAgSW5wdXRTdHJlYW0gZ2V0SW5wdXQoKSB7CisgICAgICAgIHJldHVybiBpbnB1dDsKKyAgICB9CisKKyAgICBTdHJpbmcgdGFyZ2V0RmlsZSgpIHsKKyAgICAgICAgcmV0dXJuIHRhcmdldEZpbGU7CisgICAgfQorCisgICAgaW50IHR5cGUoKSB7CisgICAgICAgIHJldHVybiB0eXBlOworICAgIH0KKworICAgIGJvb2xlYW4gaXNSZXBsYWNlTW9kZSgpIHsKKyAgICAgICAgcmV0dXJuIHJlcGxhY2VNb2RlOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NoYW5nZXMvQ2hhbmdlU2V0LmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jaGFuZ2VzL0NoYW5nZVNldC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMwZjhjNjEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jaGFuZ2VzL0NoYW5nZVNldC5qYXZhCkBAIC0wLDAgKzEsMTY0IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNoYW5nZXM7CisKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlua2VkSGFzaFNldDsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5BcmNoaXZlRW50cnk7CisKKy8qKgorICogQ2hhbmdlU2V0IGNvbGxlY3RzIGFuZCBwZXJmb3JtcyBjaGFuZ2VzIHRvIGFuIGFyY2hpdmUuCisgKiBQdXR0aW5nIGRlbGV0ZSBjaGFuZ2VzIGluIHRoaXMgQ2hhbmdlU2V0IGZyb20gbXVsdGlwbGUgdGhyZWFkcyBjYW4KKyAqIGNhdXNlIGNvbmZsaWN0cy4KKyAqCisgKiBATm90VGhyZWFkU2FmZQorICovCitwdWJsaWMgZmluYWwgY2xhc3MgQ2hhbmdlU2V0IHsKKworICAgIHByaXZhdGUgZmluYWwgU2V0PENoYW5nZT4gY2hhbmdlcyA9IG5ldyBMaW5rZWRIYXNoU2V0PD4oKTsKKworICAgIC8qKgorICAgICAqIERlbGV0ZXMgdGhlIGZpbGUgd2l0aCB0aGUgZmlsZW5hbWUgZnJvbSB0aGUgYXJjaGl2ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmaWxlbmFtZQorICAgICAqICAgICAgICAgICAgdGhlIGZpbGVuYW1lIG9mIHRoZSBmaWxlIHRvIGRlbGV0ZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGRlbGV0ZShmaW5hbCBTdHJpbmcgZmlsZW5hbWUpIHsKKyAgICAgICAgYWRkRGVsZXRpb24obmV3IENoYW5nZShmaWxlbmFtZSwgQ2hhbmdlLlRZUEVfREVMRVRFKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRGVsZXRlcyB0aGUgZGlyZWN0b3J5IHRyZWUgZnJvbSB0aGUgYXJjaGl2ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkaXJOYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgZGlyZWN0b3J5IHRyZWUgdG8gZGVsZXRlCisgICAgICovCisgICAgcHVibGljIHZvaWQgZGVsZXRlRGlyKGZpbmFsIFN0cmluZyBkaXJOYW1lKSB7CisgICAgICAgIGFkZERlbGV0aW9uKG5ldyBDaGFuZ2UoZGlyTmFtZSwgQ2hhbmdlLlRZUEVfREVMRVRFX0RJUikpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgYSBuZXcgYXJjaGl2ZSBlbnRyeSB0byB0aGUgYXJjaGl2ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwRW50cnkKKyAgICAgKiAgICAgICAgICAgIHRoZSBlbnRyeSB0byBhZGQKKyAgICAgKiBAcGFyYW0gcElucHV0CisgICAgICogICAgICAgICAgICB0aGUgZGF0YXN0cmVhbSB0byBhZGQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGQoZmluYWwgQXJjaGl2ZUVudHJ5IHBFbnRyeSwgZmluYWwgSW5wdXRTdHJlYW0gcElucHV0KSB7CisgICAgICAgIHRoaXMuYWRkKHBFbnRyeSwgcElucHV0LCB0cnVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIGEgbmV3IGFyY2hpdmUgZW50cnkgdG8gdGhlIGFyY2hpdmUuCisgICAgICogSWYgcmVwbGFjZSBpcyBzZXQgdG8gdHJ1ZSwgdGhpcyBjaGFuZ2Ugd2lsbCByZXBsYWNlIGFsbCBvdGhlciBhZGRpdGlvbnMKKyAgICAgKiBkb25lIGluIHRoaXMgQ2hhbmdlU2V0IGFuZCBhbGwgZXhpc3RpbmcgZW50cmllcyBpbiB0aGUgb3JpZ2luYWwgc3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtIHBFbnRyeQorICAgICAqICAgICAgICAgICAgdGhlIGVudHJ5IHRvIGFkZAorICAgICAqIEBwYXJhbSBwSW5wdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXRhc3RyZWFtIHRvIGFkZAorICAgICAqIEBwYXJhbSByZXBsYWNlCisgICAgICogICAgICAgICAgICBpbmRpY2F0ZXMgdGhlIHRoaXMgY2hhbmdlIHNob3VsZCByZXBsYWNlIGV4aXN0aW5nIGVudHJpZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGQoZmluYWwgQXJjaGl2ZUVudHJ5IHBFbnRyeSwgZmluYWwgSW5wdXRTdHJlYW0gcElucHV0LCBmaW5hbCBib29sZWFuIHJlcGxhY2UpIHsKKyAgICAgICAgYWRkQWRkaXRpb24obmV3IENoYW5nZShwRW50cnksIHBJbnB1dCwgcmVwbGFjZSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgYW4gYWRkaXRpb24gY2hhbmdlLgorICAgICAqCisgICAgICogQHBhcmFtIHBDaGFuZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFuZ2Ugd2hpY2ggc2hvdWxkIHJlc3VsdCBpbiBhbiBhZGRpdGlvbgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBhZGRBZGRpdGlvbihmaW5hbCBDaGFuZ2UgcENoYW5nZSkgeworICAgICAgICBpZiAoQ2hhbmdlLlRZUEVfQUREICE9IHBDaGFuZ2UudHlwZSgpIHx8CisgICAgICAgICAgICBwQ2hhbmdlLmdldElucHV0KCkgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgaWYgKCFjaGFuZ2VzLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgZm9yIChmaW5hbCBJdGVyYXRvcjxDaGFuZ2U+IGl0ID0gY2hhbmdlcy5pdGVyYXRvcigpOyBpdC5oYXNOZXh0KCk7KSB7CisgICAgICAgICAgICAgICAgZmluYWwgQ2hhbmdlIGNoYW5nZSA9IGl0Lm5leHQoKTsKKyAgICAgICAgICAgICAgICBpZiAoY2hhbmdlLnR5cGUoKSA9PSBDaGFuZ2UuVFlQRV9BREQKKyAgICAgICAgICAgICAgICAgICAgICAgICYmIGNoYW5nZS5nZXRFbnRyeSgpICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgQXJjaGl2ZUVudHJ5IGVudHJ5ID0gY2hhbmdlLmdldEVudHJ5KCk7CisKKyAgICAgICAgICAgICAgICAgICAgaWYoZW50cnkuZXF1YWxzKHBDaGFuZ2UuZ2V0RW50cnkoKSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmKHBDaGFuZ2UuaXNSZXBsYWNlTW9kZSgpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXQucmVtb3ZlKCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbmdlcy5hZGQocENoYW5nZSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgLy8gZG8gbm90IGFkZCB0aGlzIGNoYW5nZQorICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGNoYW5nZXMuYWRkKHBDaGFuZ2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgYW4gZGVsZXRlIGNoYW5nZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwQ2hhbmdlCisgICAgICogICAgICAgICAgICB0aGUgY2hhbmdlIHdoaWNoIHNob3VsZCByZXN1bHQgaW4gYSBkZWxldGlvbgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBhZGREZWxldGlvbihmaW5hbCBDaGFuZ2UgcENoYW5nZSkgeworICAgICAgICBpZiAoKENoYW5nZS5UWVBFX0RFTEVURSAhPSBwQ2hhbmdlLnR5cGUoKSAmJgorICAgICAgICAgICAgQ2hhbmdlLlRZUEVfREVMRVRFX0RJUiAhPSBwQ2hhbmdlLnR5cGUoKSkgfHwKKyAgICAgICAgICAgIHBDaGFuZ2UudGFyZ2V0RmlsZSgpID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBmaW5hbCBTdHJpbmcgc291cmNlID0gcENoYW5nZS50YXJnZXRGaWxlKCk7CisKKyAgICAgICAgaWYgKHNvdXJjZSAhPSBudWxsICYmICFjaGFuZ2VzLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgZm9yIChmaW5hbCBJdGVyYXRvcjxDaGFuZ2U+IGl0ID0gY2hhbmdlcy5pdGVyYXRvcigpOyBpdC5oYXNOZXh0KCk7KSB7CisgICAgICAgICAgICAgICAgZmluYWwgQ2hhbmdlIGNoYW5nZSA9IGl0Lm5leHQoKTsKKyAgICAgICAgICAgICAgICBpZiAoY2hhbmdlLnR5cGUoKSA9PSBDaGFuZ2UuVFlQRV9BREQKKyAgICAgICAgICAgICAgICAgICAgICAgICYmIGNoYW5nZS5nZXRFbnRyeSgpICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIHRhcmdldCA9IGNoYW5nZS5nZXRFbnRyeSgpLmdldE5hbWUoKTsKKworICAgICAgICAgICAgICAgICAgICBpZiAodGFyZ2V0ID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgaWYgKENoYW5nZS5UWVBFX0RFTEVURSA9PSBwQ2hhbmdlLnR5cGUoKSAmJiBzb3VyY2UuZXF1YWxzKHRhcmdldCkgfHwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoQ2hhbmdlLlRZUEVfREVMRVRFX0RJUiA9PSBwQ2hhbmdlLnR5cGUoKSAmJiB0YXJnZXQubWF0Y2hlcyhzb3VyY2UgKyAiLy4qIikpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpdC5yZW1vdmUoKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBjaGFuZ2VzLmFkZChwQ2hhbmdlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsaXN0IG9mIGNoYW5nZXMgYXMgYSBjb3B5LiBDaGFuZ2VzIG9uIHRoaXMgc2V0CisgICAgICogYXJlIG5vdCByZWZsZWN0ZWQgb24gdGhpcyBDaGFuZ2VTZXQgYW5kIHZpY2UgdmVyc2EuCisgICAgICogQHJldHVybiB0aGUgY2hhbmdlcyBhcyBhIGNvcHkKKyAgICAgKi8KKyAgICBTZXQ8Q2hhbmdlPiBnZXRDaGFuZ2VzKCkgeworICAgICAgICByZXR1cm4gbmV3IExpbmtlZEhhc2hTZXQ8PihjaGFuZ2VzKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jaGFuZ2VzL0NoYW5nZVNldFBlcmZvcm1lci5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY2hhbmdlcy9DaGFuZ2VTZXRQZXJmb3JtZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iZWM2YjY0Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY2hhbmdlcy9DaGFuZ2VTZXRQZXJmb3JtZXIuamF2YQpAQCAtMCwwICsxLDI4NCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jaGFuZ2VzOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLkxpbmtlZEhhc2hTZXQ7CitpbXBvcnQgamF2YS51dGlsLlNldDsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZUVudHJ5OworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZUlucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcC5aaXBBcmNoaXZlRW50cnk7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXAuWmlwRmlsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuSU9VdGlsczsKKworLyoqCisgKiBQZXJmb3JtcyBDaGFuZ2VTZXQgb3BlcmF0aW9ucyBvbiBhIHN0cmVhbS4KKyAqIFRoaXMgY2xhc3MgaXMgdGhyZWFkIHNhZmUgYW5kIGNhbiBiZSB1c2VkIG11bHRpcGxlIHRpbWVzLgorICogSXQgb3BlcmF0ZXMgb24gYSBjb3B5IG9mIHRoZSBDaGFuZ2VTZXQuIElmIHRoZSBDaGFuZ2VTZXQgY2hhbmdlcywKKyAqIGEgbmV3IFBlcmZvcm1lciBtdXN0IGJlIGNyZWF0ZWQuCisgKgorICogQFRocmVhZFNhZmUKKyAqIEBJbW11dGFibGUKKyAqLworcHVibGljIGNsYXNzIENoYW5nZVNldFBlcmZvcm1lciB7CisgICAgcHJpdmF0ZSBmaW5hbCBTZXQ8Q2hhbmdlPiBjaGFuZ2VzOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIENoYW5nZVNldFBlcmZvcm1lciB3aXRoIHRoZSBjaGFuZ2VzIGZyb20gdGhpcyBDaGFuZ2VTZXQKKyAgICAgKiBAcGFyYW0gY2hhbmdlU2V0IHRoZSBDaGFuZ2VTZXQgd2hpY2ggb3BlcmF0aW9ucyBhcmUgdXNlZCBmb3IgcGVyZm9ybWluZworICAgICAqLworICAgIHB1YmxpYyBDaGFuZ2VTZXRQZXJmb3JtZXIoZmluYWwgQ2hhbmdlU2V0IGNoYW5nZVNldCkgeworICAgICAgICBjaGFuZ2VzID0gY2hhbmdlU2V0LmdldENoYW5nZXMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtcyBhbGwgY2hhbmdlcyBjb2xsZWN0ZWQgaW4gdGhpcyBDaGFuZ2VTZXQgb24gdGhlIGlucHV0IHN0cmVhbSBhbmQKKyAgICAgKiBzdHJlYW1zIHRoZSByZXN1bHQgdG8gdGhlIG91dHB1dCBzdHJlYW0uIFBlcmZvcm0gbWF5IGJlIGNhbGxlZCBtb3JlIHRoYW4gb25jZS4KKyAgICAgKgorICAgICAqIFRoaXMgbWV0aG9kIGZpbmlzaGVzIHRoZSBzdHJlYW0sIG5vIG90aGVyIGVudHJpZXMgc2hvdWxkIGJlIGFkZGVkCisgICAgICogYWZ0ZXIgdGhhdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbgorICAgICAqICAgICAgICAgICAgdGhlIElucHV0U3RyZWFtIHRvIHBlcmZvcm0gdGhlIGNoYW5nZXMgb24KKyAgICAgKiBAcGFyYW0gb3V0CisgICAgICogICAgICAgICAgICB0aGUgcmVzdWx0aW5nIE91dHB1dFN0cmVhbSB3aXRoIGFsbCBtb2RpZmljYXRpb25zCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIHJlYWQvd3JpdGUgZXJyb3Igb2NjdXJzCisgICAgICogQHJldHVybiB0aGUgcmVzdWx0cyBvZiB0aGlzIG9wZXJhdGlvbgorICAgICAqLworICAgIHB1YmxpYyBDaGFuZ2VTZXRSZXN1bHRzIHBlcmZvcm0oZmluYWwgQXJjaGl2ZUlucHV0U3RyZWFtIGluLCBmaW5hbCBBcmNoaXZlT3V0cHV0U3RyZWFtIG91dCkKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBwZXJmb3JtKG5ldyBBcmNoaXZlSW5wdXRTdHJlYW1JdGVyYXRvcihpbiksIG91dCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGVyZm9ybXMgYWxsIGNoYW5nZXMgY29sbGVjdGVkIGluIHRoaXMgQ2hhbmdlU2V0IG9uIHRoZSBaaXBGaWxlIGFuZAorICAgICAqIHN0cmVhbXMgdGhlIHJlc3VsdCB0byB0aGUgb3V0cHV0IHN0cmVhbS4gUGVyZm9ybSBtYXkgYmUgY2FsbGVkIG1vcmUgdGhhbiBvbmNlLgorICAgICAqCisgICAgICogVGhpcyBtZXRob2QgZmluaXNoZXMgdGhlIHN0cmVhbSwgbm8gb3RoZXIgZW50cmllcyBzaG91bGQgYmUgYWRkZWQKKyAgICAgKiBhZnRlciB0aGF0LgorICAgICAqCisgICAgICogQHBhcmFtIGluCisgICAgICogICAgICAgICAgICB0aGUgWmlwRmlsZSB0byBwZXJmb3JtIHRoZSBjaGFuZ2VzIG9uCisgICAgICogQHBhcmFtIG91dAorICAgICAqICAgICAgICAgICAgdGhlIHJlc3VsdGluZyBPdXRwdXRTdHJlYW0gd2l0aCBhbGwgbW9kaWZpY2F0aW9ucworICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiByZWFkL3dyaXRlIGVycm9yIG9jY3VycworICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdHMgb2YgdGhpcyBvcGVyYXRpb24KKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIENoYW5nZVNldFJlc3VsdHMgcGVyZm9ybShmaW5hbCBaaXBGaWxlIGluLCBmaW5hbCBBcmNoaXZlT3V0cHV0U3RyZWFtIG91dCkKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBwZXJmb3JtKG5ldyBaaXBGaWxlSXRlcmF0b3IoaW4pLCBvdXQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIGFsbCBjaGFuZ2VzIGNvbGxlY3RlZCBpbiB0aGlzIENoYW5nZVNldCBvbiB0aGUgaW5wdXQgZW50cmllcyBhbmQKKyAgICAgKiBzdHJlYW1zIHRoZSByZXN1bHQgdG8gdGhlIG91dHB1dCBzdHJlYW0uCisgICAgICoKKyAgICAgKiBUaGlzIG1ldGhvZCBmaW5pc2hlcyB0aGUgc3RyZWFtLCBubyBvdGhlciBlbnRyaWVzIHNob3VsZCBiZSBhZGRlZAorICAgICAqIGFmdGVyIHRoYXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZW50cnlJdGVyYXRvcgorICAgICAqICAgICAgICAgICAgdGhlIGVudHJpZXMgdG8gcGVyZm9ybSB0aGUgY2hhbmdlcyBvbgorICAgICAqIEBwYXJhbSBvdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSByZXN1bHRpbmcgT3V0cHV0U3RyZWFtIHdpdGggYWxsIG1vZGlmaWNhdGlvbnMKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gcmVhZC93cml0ZSBlcnJvciBvY2N1cnMKKyAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHRzIG9mIHRoaXMgb3BlcmF0aW9uCisgICAgICovCisgICAgcHJpdmF0ZSBDaGFuZ2VTZXRSZXN1bHRzIHBlcmZvcm0oZmluYWwgQXJjaGl2ZUVudHJ5SXRlcmF0b3IgZW50cnlJdGVyYXRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBBcmNoaXZlT3V0cHV0U3RyZWFtIG91dCkKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIENoYW5nZVNldFJlc3VsdHMgcmVzdWx0cyA9IG5ldyBDaGFuZ2VTZXRSZXN1bHRzKCk7CisKKyAgICAgICAgZmluYWwgU2V0PENoYW5nZT4gd29ya2luZ1NldCA9IG5ldyBMaW5rZWRIYXNoU2V0PD4oY2hhbmdlcyk7CisKKyAgICAgICAgZm9yIChmaW5hbCBJdGVyYXRvcjxDaGFuZ2U+IGl0ID0gd29ya2luZ1NldC5pdGVyYXRvcigpOyBpdC5oYXNOZXh0KCk7KSB7CisgICAgICAgICAgICBmaW5hbCBDaGFuZ2UgY2hhbmdlID0gaXQubmV4dCgpOworCisgICAgICAgICAgICBpZiAoY2hhbmdlLnR5cGUoKSA9PSBDaGFuZ2UuVFlQRV9BREQgJiYgY2hhbmdlLmlzUmVwbGFjZU1vZGUoKSkgeworICAgICAgICAgICAgICAgIGNvcHlTdHJlYW0oY2hhbmdlLmdldElucHV0KCksIG91dCwgY2hhbmdlLmdldEVudHJ5KCkpOworICAgICAgICAgICAgICAgIGl0LnJlbW92ZSgpOworICAgICAgICAgICAgICAgIHJlc3VsdHMuYWRkZWRGcm9tQ2hhbmdlU2V0KGNoYW5nZS5nZXRFbnRyeSgpLmdldE5hbWUoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB3aGlsZSAoZW50cnlJdGVyYXRvci5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgIGZpbmFsIEFyY2hpdmVFbnRyeSBlbnRyeSA9IGVudHJ5SXRlcmF0b3IubmV4dCgpOworICAgICAgICAgICAgYm9vbGVhbiBjb3B5ID0gdHJ1ZTsKKworICAgICAgICAgICAgZm9yIChmaW5hbCBJdGVyYXRvcjxDaGFuZ2U+IGl0ID0gd29ya2luZ1NldC5pdGVyYXRvcigpOyBpdC5oYXNOZXh0KCk7KSB7CisgICAgICAgICAgICAgICAgZmluYWwgQ2hhbmdlIGNoYW5nZSA9IGl0Lm5leHQoKTsKKworICAgICAgICAgICAgICAgIGZpbmFsIGludCB0eXBlID0gY2hhbmdlLnR5cGUoKTsKKyAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgbmFtZSA9IGVudHJ5LmdldE5hbWUoKTsKKyAgICAgICAgICAgICAgICBpZiAodHlwZSA9PSBDaGFuZ2UuVFlQRV9ERUxFVEUgJiYgbmFtZSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChuYW1lLmVxdWFscyhjaGFuZ2UudGFyZ2V0RmlsZSgpKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgY29weSA9IGZhbHNlOworICAgICAgICAgICAgICAgICAgICAgICAgaXQucmVtb3ZlKCk7CisgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRzLmRlbGV0ZWQobmFtZSk7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSBDaGFuZ2UuVFlQRV9ERUxFVEVfRElSICYmIG5hbWUgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAvLyBkb24ndCBjb21iaW5lIGlmcyB0byBtYWtlIGZ1dHVyZSBleHRlbnNpb25zIG1vcmUgZWFzeQorICAgICAgICAgICAgICAgICAgICBpZiAobmFtZS5zdGFydHNXaXRoKGNoYW5nZS50YXJnZXRGaWxlKCkgKyAiLyIpKSB7IC8vIE5PUE1ECisgICAgICAgICAgICAgICAgICAgICAgICBjb3B5ID0gZmFsc2U7CisgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRzLmRlbGV0ZWQobmFtZSk7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKGNvcHkKKyAgICAgICAgICAgICAgICAmJiAhaXNEZWxldGVkTGF0ZXIod29ya2luZ1NldCwgZW50cnkpCisgICAgICAgICAgICAgICAgJiYgIXJlc3VsdHMuaGFzQmVlbkFkZGVkKGVudHJ5LmdldE5hbWUoKSkpIHsKKyAgICAgICAgICAgICAgICBjb3B5U3RyZWFtKGVudHJ5SXRlcmF0b3IuZ2V0SW5wdXRTdHJlYW0oKSwgb3V0LCBlbnRyeSk7CisgICAgICAgICAgICAgICAgcmVzdWx0cy5hZGRlZEZyb21TdHJlYW0oZW50cnkuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIEFkZHMgZmlsZXMgd2hpY2ggaGFzbid0IGJlZW4gYWRkZWQgZnJvbSB0aGUgb3JpZ2luYWwgYW5kIGRvIG5vdCBoYXZlIHJlcGxhY2UgbW9kZSBvbgorICAgICAgICBmb3IgKGZpbmFsIEl0ZXJhdG9yPENoYW5nZT4gaXQgPSB3b3JraW5nU2V0Lml0ZXJhdG9yKCk7IGl0Lmhhc05leHQoKTspIHsKKyAgICAgICAgICAgIGZpbmFsIENoYW5nZSBjaGFuZ2UgPSBpdC5uZXh0KCk7CisKKyAgICAgICAgICAgIGlmIChjaGFuZ2UudHlwZSgpID09IENoYW5nZS5UWVBFX0FERCAmJgorICAgICAgICAgICAgICAgICFjaGFuZ2UuaXNSZXBsYWNlTW9kZSgpICYmCisgICAgICAgICAgICAgICAgIXJlc3VsdHMuaGFzQmVlbkFkZGVkKGNoYW5nZS5nZXRFbnRyeSgpLmdldE5hbWUoKSkpIHsKKyAgICAgICAgICAgICAgICBjb3B5U3RyZWFtKGNoYW5nZS5nZXRJbnB1dCgpLCBvdXQsIGNoYW5nZS5nZXRFbnRyeSgpKTsKKyAgICAgICAgICAgICAgICBpdC5yZW1vdmUoKTsKKyAgICAgICAgICAgICAgICByZXN1bHRzLmFkZGVkRnJvbUNoYW5nZVNldChjaGFuZ2UuZ2V0RW50cnkoKS5nZXROYW1lKCkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIG91dC5maW5pc2goKTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIGFuIEFyY2hpdmVFbnRyeSBpcyBkZWxldGVkIGxhdGVyIGluIHRoZSBDaGFuZ2VTZXQuIFRoaXMgaXMKKyAgICAgKiBuZWNlc3NhcnkgaWYgYW4gZmlsZSBpcyBhZGRlZCB3aXRoIHRoaXMgQ2hhbmdlU2V0LCBidXQgbGF0ZXIgYmVjYW1lCisgICAgICogZGVsZXRlZCBpbiB0aGUgc2FtZSBzZXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZW50cnkKKyAgICAgKiAgICAgICAgICAgIHRoZSBlbnRyeSB0byBjaGVjaworICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhpcyBlbnRyeSBoYXMgYW4gZGVsZXRpb24gY2hhbmdlIGxhdGVyLCBmYWxzZSBvdGhlcndpc2UKKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gaXNEZWxldGVkTGF0ZXIoZmluYWwgU2V0PENoYW5nZT4gd29ya2luZ1NldCwgZmluYWwgQXJjaGl2ZUVudHJ5IGVudHJ5KSB7CisgICAgICAgIGZpbmFsIFN0cmluZyBzb3VyY2UgPSBlbnRyeS5nZXROYW1lKCk7CisKKyAgICAgICAgaWYgKCF3b3JraW5nU2V0LmlzRW1wdHkoKSkgeworICAgICAgICAgICAgZm9yIChmaW5hbCBDaGFuZ2UgY2hhbmdlIDogd29ya2luZ1NldCkgeworICAgICAgICAgICAgICAgIGZpbmFsIGludCB0eXBlID0gY2hhbmdlLnR5cGUoKTsKKyAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgdGFyZ2V0ID0gY2hhbmdlLnRhcmdldEZpbGUoKTsKKyAgICAgICAgICAgICAgICBpZiAodHlwZSA9PSBDaGFuZ2UuVFlQRV9ERUxFVEUgJiYgc291cmNlLmVxdWFscyh0YXJnZXQpKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGlmICh0eXBlID09IENoYW5nZS5UWVBFX0RFTEVURV9ESVIgJiYgc291cmNlLnN0YXJ0c1dpdGgodGFyZ2V0ICsgIi8iKSl7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29waWVzIHRoZSBBcmNoaXZlRW50cnkgdG8gdGhlIE91dHB1dCBzdHJlYW0KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmVhbSB0byByZWFkIHRoZSBkYXRhIGZyb20KKyAgICAgKiBAcGFyYW0gb3V0CisgICAgICogICAgICAgICAgICB0aGUgc3RyZWFtIHRvIHdyaXRlIHRoZSBkYXRhIHRvCisgICAgICogQHBhcmFtIGVudHJ5CisgICAgICogICAgICAgICAgICB0aGUgZW50cnkgdG8gd3JpdGUKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgZGF0YSBjYW5ub3QgYmUgcmVhZCBvciB3cml0dGVuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGNvcHlTdHJlYW0oZmluYWwgSW5wdXRTdHJlYW0gaW4sIGZpbmFsIEFyY2hpdmVPdXRwdXRTdHJlYW0gb3V0LAorICAgICAgICAgICAgZmluYWwgQXJjaGl2ZUVudHJ5IGVudHJ5KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvdXQucHV0QXJjaGl2ZUVudHJ5KGVudHJ5KTsKKyAgICAgICAgSU9VdGlscy5jb3B5KGluLCBvdXQpOworICAgICAgICBvdXQuY2xvc2VBcmNoaXZlRW50cnkoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVc2VkIGluIHBlcmZvcm0gdG8gYWJzdHJhY3Qgb3V0IGdldHRpbmcgZW50cmllcyBhbmQgc3RyZWFtcyBmb3IKKyAgICAgKiB0aG9zZSBlbnRyaWVzLgorICAgICAqCisgICAgICogPHA+SXRlcmF0b3IjaGFzTmV4dCBpcyBub3QgYWxsb3dlZCB0byB0aHJvdyBleGNlcHRpb25zIHRoYXQncworICAgICAqIHdoeSB3ZSBjYW4ndCB1c2UgSXRlcmF0b3ImbHQ7QXJjaGl2ZUVudHJ5Jmd0OyBkaXJlY3RseSAtCisgICAgICogb3RoZXJ3aXNlIHdlJ2QgbmVlZCB0byBjb252ZXJ0IGV4Y2VwdGlvbnMgdGhyb3duIGluCisgICAgICogQXJjaGl2ZUlucHV0U3RyZWFtI2dldE5leHRFbnRyeS48L3A+CisgICAgICovCisgICAgaW50ZXJmYWNlIEFyY2hpdmVFbnRyeUl0ZXJhdG9yIHsKKyAgICAgICAgYm9vbGVhbiBoYXNOZXh0KCkgdGhyb3dzIElPRXhjZXB0aW9uOworICAgICAgICBBcmNoaXZlRW50cnkgbmV4dCgpOworICAgICAgICBJbnB1dFN0cmVhbSBnZXRJbnB1dFN0cmVhbSgpIHRocm93cyBJT0V4Y2VwdGlvbjsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBBcmNoaXZlSW5wdXRTdHJlYW1JdGVyYXRvcgorICAgICAgICBpbXBsZW1lbnRzIEFyY2hpdmVFbnRyeUl0ZXJhdG9yIHsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBBcmNoaXZlSW5wdXRTdHJlYW0gaW47CisgICAgICAgIHByaXZhdGUgQXJjaGl2ZUVudHJ5IG5leHQ7CisgICAgICAgIEFyY2hpdmVJbnB1dFN0cmVhbUl0ZXJhdG9yKGZpbmFsIEFyY2hpdmVJbnB1dFN0cmVhbSBpbikgeworICAgICAgICAgICAgdGhpcy5pbiA9IGluOworICAgICAgICB9CisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZXh0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiAobmV4dCA9IGluLmdldE5leHRFbnRyeSgpKSAhPSBudWxsOworICAgICAgICB9CisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgQXJjaGl2ZUVudHJ5IG5leHQoKSB7CisgICAgICAgICAgICByZXR1cm4gbmV4dDsKKyAgICAgICAgfQorICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIElucHV0U3RyZWFtIGdldElucHV0U3RyZWFtKCkgeworICAgICAgICAgICAgcmV0dXJuIGluOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgWmlwRmlsZUl0ZXJhdG9yCisgICAgICAgIGltcGxlbWVudHMgQXJjaGl2ZUVudHJ5SXRlcmF0b3IgeworICAgICAgICBwcml2YXRlIGZpbmFsIFppcEZpbGUgaW47CisgICAgICAgIHByaXZhdGUgZmluYWwgRW51bWVyYXRpb248WmlwQXJjaGl2ZUVudHJ5PiBuZXN0ZWRFbnVtOworICAgICAgICBwcml2YXRlIFppcEFyY2hpdmVFbnRyeSBjdXJyZW50OworICAgICAgICBaaXBGaWxlSXRlcmF0b3IoZmluYWwgWmlwRmlsZSBpbikgeworICAgICAgICAgICAgdGhpcy5pbiA9IGluOworICAgICAgICAgICAgbmVzdGVkRW51bSA9IGluLmdldEVudHJpZXNJblBoeXNpY2FsT3JkZXIoKTsKKyAgICAgICAgfQorICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzTmV4dCgpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXN0ZWRFbnVtLmhhc01vcmVFbGVtZW50cygpOworICAgICAgICB9CisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgQXJjaGl2ZUVudHJ5IG5leHQoKSB7CisgICAgICAgICAgICBjdXJyZW50ID0gbmVzdGVkRW51bS5uZXh0RWxlbWVudCgpOworICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnQ7CisgICAgICAgIH0KKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBJbnB1dFN0cmVhbSBnZXRJbnB1dFN0cmVhbSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gaW4uZ2V0SW5wdXRTdHJlYW0oY3VycmVudCk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jaGFuZ2VzL0NoYW5nZVNldFJlc3VsdHMuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NoYW5nZXMvQ2hhbmdlU2V0UmVzdWx0cy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc4OGRjY2YKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jaGFuZ2VzL0NoYW5nZVNldFJlc3VsdHMuamF2YQpAQCAtMCwwICsxLDkwIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNoYW5nZXM7CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworCisvKioKKyAqIFN0b3JlcyB0aGUgcmVzdWx0cyBvZiBhbiBwZXJmb3JtZWQgQ2hhbmdlU2V0IG9wZXJhdGlvbi4KKyAqLworcHVibGljIGNsYXNzIENoYW5nZVNldFJlc3VsdHMgeworICAgIHByaXZhdGUgZmluYWwgTGlzdDxTdHJpbmc+IGFkZGVkRnJvbUNoYW5nZVNldCA9IG5ldyBBcnJheUxpc3Q8PigpOworICAgIHByaXZhdGUgZmluYWwgTGlzdDxTdHJpbmc+IGFkZGVkRnJvbVN0cmVhbSA9IG5ldyBBcnJheUxpc3Q8PigpOworICAgIHByaXZhdGUgZmluYWwgTGlzdDxTdHJpbmc+IGRlbGV0ZWQgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKworICAgIC8qKgorICAgICAqIEFkZHMgdGhlIGZpbGVuYW1lIG9mIGEgcmVjZW50bHkgZGVsZXRlZCBmaWxlIHRvIHRoZSByZXN1bHQgbGlzdC4KKyAgICAgKiBAcGFyYW0gZmlsZU5hbWUgdGhlIGZpbGUgd2hpY2ggaGFzIGJlZW4gZGVsZXRlZAorICAgICAqLworICAgIHZvaWQgZGVsZXRlZChmaW5hbCBTdHJpbmcgZmlsZU5hbWUpIHsKKyAgICAgICAgZGVsZXRlZC5hZGQoZmlsZU5hbWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgdGhlIG5hbWUgb2YgYSBmaWxlIHRvIHRoZSByZXN1bHQgbGlzdCB3aGljaCBoYXMgYmVlbgorICAgICAqIGNvcGllZCBmcm9tIHRoZSBzb3VyY2Ugc3RyZWFtIHRvIHRoZSB0YXJnZXQgc3RyZWFtLgorICAgICAqIEBwYXJhbSBmaWxlTmFtZSB0aGUgZmlsZSBuYW1lIHdoaWNoIGhhcyBiZWVuIGFkZGVkIGZyb20gdGhlIG9yaWdpbmFsIHN0cmVhbQorICAgICAqLworICAgIHZvaWQgYWRkZWRGcm9tU3RyZWFtKGZpbmFsIFN0cmluZyBmaWxlTmFtZSkgeworICAgICAgICBhZGRlZEZyb21TdHJlYW0uYWRkKGZpbGVOYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoZSBuYW1lIG9mIGEgZmlsZSB0byB0aGUgcmVzdWx0IGxpc3Qgd2hpY2ggaGFzIGJlZW4KKyAgICAgKiBjb3BpZWQgZnJvbSB0aGUgY2hhbmdlc2V0IHRvIHRoZSB0YXJnZXQgc3RyZWFtCisgICAgICogQHBhcmFtIGZpbGVOYW1lIHRoZSBuYW1lIG9mIHRoZSBmaWxlCisgICAgICovCisgICAgdm9pZCBhZGRlZEZyb21DaGFuZ2VTZXQoZmluYWwgU3RyaW5nIGZpbGVOYW1lKSB7CisgICAgICAgIGFkZGVkRnJvbUNoYW5nZVNldC5hZGQoZmlsZU5hbWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBsaXN0IG9mIGZpbGVuYW1lcyB3aGljaCBoYXMgYmVlbiBhZGRlZCBmcm9tIHRoZSBjaGFuZ2VzZXQKKyAgICAgKiBAcmV0dXJuIHRoZSBsaXN0IG9mIGZpbGVuYW1lcworICAgICAqLworICAgIHB1YmxpYyBMaXN0PFN0cmluZz4gZ2V0QWRkZWRGcm9tQ2hhbmdlU2V0KCkgeworICAgICAgICByZXR1cm4gYWRkZWRGcm9tQ2hhbmdlU2V0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBsaXN0IG9mIGZpbGVuYW1lcyB3aGljaCBoYXMgYmVlbiBhZGRlZCBmcm9tIHRoZSBvcmlnaW5hbCBzdHJlYW0KKyAgICAgKiBAcmV0dXJuIHRoZSBsaXN0IG9mIGZpbGVuYW1lcworICAgICAqLworICAgIHB1YmxpYyBMaXN0PFN0cmluZz4gZ2V0QWRkZWRGcm9tU3RyZWFtKCkgeworICAgICAgICByZXR1cm4gYWRkZWRGcm9tU3RyZWFtOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBsaXN0IG9mIGZpbGVuYW1lcyB3aGljaCBoYXMgYmVlbiBkZWxldGVkCisgICAgICogQHJldHVybiB0aGUgbGlzdCBvZiBmaWxlbmFtZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgTGlzdDxTdHJpbmc+IGdldERlbGV0ZWQoKSB7CisgICAgICAgIHJldHVybiBkZWxldGVkOworICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrcyBpZiBhbiBmaWxlbmFtZSBhbHJlYWR5IGhhcyBiZWVuIGFkZGVkIHRvIHRoZSByZXN1bHQgbGlzdAorICAgICAqIEBwYXJhbSBmaWxlbmFtZSB0aGUgZmlsZW5hbWUgdG8gY2hlY2sKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoaXMgZmlsZW5hbWUgYWxyZWFkeSBoYXMgYmVlbiBhZGRlZAorICAgICAqLworICAgIGJvb2xlYW4gaGFzQmVlbkFkZGVkKGZpbmFsIFN0cmluZyBmaWxlbmFtZSkgeworICAgICAgICByZXR1cm4gYWRkZWRGcm9tQ2hhbmdlU2V0LmNvbnRhaW5zKGZpbGVuYW1lKSB8fCBhZGRlZEZyb21TdHJlYW0uY29udGFpbnMoZmlsZW5hbWUpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NoYW5nZXMvcGFja2FnZS5odG1sIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY2hhbmdlcy9wYWNrYWdlLmh0bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGJhM2U4NwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NoYW5nZXMvcGFja2FnZS5odG1sCkBAIC0wLDAgKzEsMjcgQEAKKzxodG1sPgorPCEtLQorCisgICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAgIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAgICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorCisgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisKKyAgIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAgIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAgIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAgIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorCistLT4KKyAgPGJvZHk+CisgICAgPHA+PGI+RVhQRVJJTUVOVEFMPC9iPiBzdXBwb3J0IGZvciBjaGFuZ2VzZXRzIHRoYXQgYXJlIGFwcGxpZWQgdG8KKyAgICAgIGFyY2hpdmVzLjwvcD4KKworICAgIDxwPlRoaXMgQVBJIGlzIGNvbnNpZGVyZWQgdW5zdGFibGUgYW5kIG1heSBiZSBtb2RpZmllZCBvciBldmVuCisgICAgICByZW1vdmVkIGluIGZ1dHVyZSByZWxlYXNlcy48L3A+CisgIDwvYm9keT4KKzwvaHRtbD4KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL0NvbXByZXNzb3JFeGNlcHRpb24uamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL0NvbXByZXNzb3JFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45YWYzZTY5Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvQ29tcHJlc3NvckV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNTEgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnM7CisKKy8qKgorICogQ29tcHJlc3NvciByZWxhdGVkIGV4Y2VwdGlvbgorICovCitwdWJsaWMgY2xhc3MgQ29tcHJlc3NvckV4Y2VwdGlvbiBleHRlbmRzIEV4Y2VwdGlvbiB7CisKKyAgICAvKiogU2VyaWFsICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTI5MzI5MDEzMTAyNTU5MDg4MTRMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBleGNlcHRpb24gd2l0aCB0aGUgc3BlY2lmaWVkIGRldGFpbCBtZXNzYWdlLiBUaGUgY2F1c2UKKyAgICAgKiBpcyBub3QgaW5pdGlhbGl6ZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWVzc2FnZQorICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlCisgICAgICovCisgICAgcHVibGljIENvbXByZXNzb3JFeGNlcHRpb24oZmluYWwgU3RyaW5nIG1lc3NhZ2UpIHsKKyAgICAgICAgc3VwZXIobWVzc2FnZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBleGNlcHRpb24gd2l0aCB0aGUgc3BlY2lmaWVkIGRldGFpbCBtZXNzYWdlIGFuZCBjYXVzZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtZXNzYWdlCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UKKyAgICAgKiBAcGFyYW0gY2F1c2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBjYXVzZQorICAgICAqLworICAgIHB1YmxpYyBDb21wcmVzc29yRXhjZXB0aW9uKGZpbmFsIFN0cmluZyBtZXNzYWdlLCBmaW5hbCBUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIobWVzc2FnZSwgY2F1c2UpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL0NvbXByZXNzb3JJbnB1dFN0cmVhbS5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvQ29tcHJlc3NvcklucHV0U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjdkZTcwNQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL0NvbXByZXNzb3JJbnB1dFN0cmVhbS5qYXZhCkBAIC0wLDAgKzEsOTYgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnM7CisKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQ29tcHJlc3NvcklucHV0U3RyZWFtIGV4dGVuZHMgSW5wdXRTdHJlYW0geworICAgIHByaXZhdGUgbG9uZyBieXRlc1JlYWQgPSAwOworCisgICAgLyoqCisgICAgICogSW5jcmVtZW50cyB0aGUgY291bnRlciBvZiBhbHJlYWR5IHJlYWQgYnl0ZXMuCisgICAgICogRG9lc24ndCBpbmNyZW1lbnQgaWYgdGhlIEVPRiBoYXMgYmVlbiBoaXQgKHJlYWQgPT0gLTEpCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVhZCB0aGUgbnVtYmVyIG9mIGJ5dGVzIHJlYWQKKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjEKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBjb3VudChmaW5hbCBpbnQgcmVhZCkgeworICAgICAgICBjb3VudCgobG9uZykgcmVhZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5jcmVtZW50cyB0aGUgY291bnRlciBvZiBhbHJlYWR5IHJlYWQgYnl0ZXMuCisgICAgICogRG9lc24ndCBpbmNyZW1lbnQgaWYgdGhlIEVPRiBoYXMgYmVlbiBoaXQgKHJlYWQgPT0gLTEpCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVhZCB0aGUgbnVtYmVyIG9mIGJ5dGVzIHJlYWQKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBjb3VudChmaW5hbCBsb25nIHJlYWQpIHsKKyAgICAgICAgaWYgKHJlYWQgIT0gLTEpIHsKKyAgICAgICAgICAgIGJ5dGVzUmVhZCA9IGJ5dGVzUmVhZCArIHJlYWQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZWNyZW1lbnRzIHRoZSBjb3VudGVyIG9mIGFscmVhZHkgcmVhZCBieXRlcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwdXNoZWRCYWNrIHRoZSBudW1iZXIgb2YgYnl0ZXMgcHVzaGVkIGJhY2suCisgICAgICogQHNpbmNlIDEuNworICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHB1c2hlZEJhY2tCeXRlcyhmaW5hbCBsb25nIHB1c2hlZEJhY2spIHsKKyAgICAgICAgYnl0ZXNSZWFkIC09IHB1c2hlZEJhY2s7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY3VycmVudCBudW1iZXIgb2YgYnl0ZXMgcmVhZCBmcm9tIHRoaXMgc3RyZWFtLgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiByZWFkIGJ5dGVzCisgICAgICogQGRlcHJlY2F0ZWQgdGhpcyBtZXRob2QgbWF5IHlpZWxkIHdyb25nIHJlc3VsdHMgZm9yIGxhcmdlCisgICAgICogYXJjaGl2ZXMsIHVzZSAjZ2V0Qnl0ZXNSZWFkIGluc3RlYWQKKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBpbnQgZ2V0Q291bnQoKSB7CisgICAgICAgIHJldHVybiAoaW50KSBieXRlc1JlYWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY3VycmVudCBudW1iZXIgb2YgYnl0ZXMgcmVhZCBmcm9tIHRoaXMgc3RyZWFtLgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiByZWFkIGJ5dGVzCisgICAgICoKKyAgICAgKiBAc2luY2UgMS4xCisgICAgICovCisgICAgcHVibGljIGxvbmcgZ2V0Qnl0ZXNSZWFkKCkgeworICAgICAgICByZXR1cm4gYnl0ZXNSZWFkOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGFtb3VudCBvZiByYXcgb3IgY29tcHJlc3NlZCBieXRlcyByZWFkIGJ5IHRoZSBzdHJlYW0uCisgICAgICoKKyAgICAgKiA8cD5UaGlzIGltcGxlbWVudGF0aW9uIGludm9rZXMge0BsaW5rICNnZXRCeXRlc1JlYWR9LjwvcD4KKyAgICAgKgorICAgICAqIDxwPlByb3ZpZGVzIGhhbGYgb2Yge0BsaW5rCisgICAgICogb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLklucHV0U3RyZWFtU3RhdGlzdGljc30KKyAgICAgKiB3aXRob3V0IGZvcmNpbmcgc3ViY2xhc3NlcyB0byBpbXBsZW1lbnQgdGhlIG90aGVyIGhhbGYuPC9wPgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgYW1vdW50IG9mIGRlY29tcHJlc3NlZCBieXRlcyByZXR1cm5lZCBieSB0aGUgc3RyZWFtCisgICAgICogQHNpbmNlIDEuMTcKKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBnZXRVbmNvbXByZXNzZWRDb3VudCgpIHsKKyAgICAgICAgcmV0dXJuIGdldEJ5dGVzUmVhZCgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL0NvbXByZXNzb3JPdXRwdXRTdHJlYW0uamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL0NvbXByZXNzb3JPdXRwdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MWVlZTljCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvQ29tcHJlc3Nvck91dHB1dFN0cmVhbS5qYXZhCkBAIC0wLDAgKzEsMjUgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnM7CisKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKKworcHVibGljIGFic3RyYWN0IGNsYXNzIENvbXByZXNzb3JPdXRwdXRTdHJlYW0gZXh0ZW5kcyBPdXRwdXRTdHJlYW0geworICAgIC8vIFRPRE8KK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL0NvbXByZXNzb3JTdHJlYW1GYWN0b3J5LmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9Db21wcmVzc29yU3RyZWFtRmFjdG9yeS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ3MzBiOWQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9Db21wcmVzc29yU3RyZWFtRmFjdG9yeS5qYXZhCkBAIC0wLDAgKzEsNzk3IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuc2VjdXJpdHkuQWNjZXNzQ29udHJvbGxlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByaXZpbGVnZWRBY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CitpbXBvcnQgamF2YS51dGlsLlNldDsKK2ltcG9ydCBqYXZhLnV0aWwuU29ydGVkTWFwOworaW1wb3J0IGphdmEudXRpbC5UcmVlTWFwOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLmJyb3RsaS5Ccm90bGlDb21wcmVzc29ySW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLmJyb3RsaS5Ccm90bGlVdGlsczsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuYnppcDIuQlppcDJDb21wcmVzc29ySW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLmJ6aXAyLkJaaXAyQ29tcHJlc3Nvck91dHB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuZGVmbGF0ZS5EZWZsYXRlQ29tcHJlc3NvcklucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5kZWZsYXRlLkRlZmxhdGVDb21wcmVzc29yT3V0cHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5kZWZsYXRlNjQuRGVmbGF0ZTY0Q29tcHJlc3NvcklucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5nemlwLkd6aXBDb21wcmVzc29ySW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLmd6aXAuR3ppcENvbXByZXNzb3JPdXRwdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLmx6NC5CbG9ja0xaNENvbXByZXNzb3JJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMubHo0LkJsb2NrTFo0Q29tcHJlc3Nvck91dHB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMubHo0LkZyYW1lZExaNENvbXByZXNzb3JJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMubHo0LkZyYW1lZExaNENvbXByZXNzb3JPdXRwdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLmx6bWEuTFpNQUNvbXByZXNzb3JJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMubHptYS5MWk1BQ29tcHJlc3Nvck91dHB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMubHptYS5MWk1BVXRpbHM7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLnBhY2syMDAuUGFjazIwMENvbXByZXNzb3JJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMucGFjazIwMC5QYWNrMjAwQ29tcHJlc3Nvck91dHB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuc25hcHB5LkZyYW1lZFNuYXBweUNvbXByZXNzb3JJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuc25hcHB5LkZyYW1lZFNuYXBweUNvbXByZXNzb3JPdXRwdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLnNuYXBweS5TbmFwcHlDb21wcmVzc29ySW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLnh6LlhaQ29tcHJlc3NvcklucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy54ei5YWkNvbXByZXNzb3JPdXRwdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLnh6LlhaVXRpbHM7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLnouWkNvbXByZXNzb3JJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuenN0YW5kYXJkLlpzdGRDb21wcmVzc29ySW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLnpzdGFuZGFyZC5ac3RkQ29tcHJlc3Nvck91dHB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuenN0YW5kYXJkLlpzdGRVdGlsczsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuSU9VdGlsczsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuTGlzdHM7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLlNlcnZpY2VMb2FkZXJJdGVyYXRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuU2V0czsKKworLyoqCisgKiA8cD4KKyAqIEZhY3RvcnkgdG8gY3JlYXRlIENvbXByZXNzb3JbSW58T3V0XXB1dFN0cmVhbXMgZnJvbSBuYW1lcy4gVG8gYWRkIG90aGVyCisgKiBpbXBsZW1lbnRhdGlvbnMgeW91IHNob3VsZCBleHRlbmQgQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkgYW5kIG92ZXJyaWRlIHRoZQorICogYXBwcm9wcmlhdGUgbWV0aG9kcyAoYW5kIGNhbGwgdGhlaXIgaW1wbGVtZW50YXRpb24gZnJvbSBzdXBlciBvZiBjb3Vyc2UpLgorICogPC9wPgorICoKKyAqIEV4YW1wbGUgKENvbXByZXNzaW5nIGEgZmlsZSk6CisgKgorICogPHByZT4KKyAqIGZpbmFsIE91dHB1dFN0cmVhbSBvdXQgPSBGaWxlcy5uZXdPdXRwdXRTdHJlYW0ob3V0cHV0LnRvUGF0aCgpKTsKKyAqIENvbXByZXNzb3JPdXRwdXRTdHJlYW0gY29zID0gbmV3IENvbXByZXNzb3JTdHJlYW1GYWN0b3J5KCkKKyAqICAgICAgICAgLmNyZWF0ZUNvbXByZXNzb3JPdXRwdXRTdHJlYW0oQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkuQlpJUDIsIG91dCk7CisgKiBJT1V0aWxzLmNvcHkoRmlsZXMubmV3SW5wdXRTdHJlYW0oaW5wdXQudG9QYXRoKCkpLCBjb3MpOworICogY29zLmNsb3NlKCk7CisgKiA8L3ByZT4KKyAqCisgKiBFeGFtcGxlIChEZWNvbXByZXNzaW5nIGEgZmlsZSk6CisgKgorICogPHByZT4KKyAqIGZpbmFsIElucHV0U3RyZWFtIGlzID0gRmlsZXMubmV3SW5wdXRTdHJlYW0oaW5wdXQudG9QYXRoKCkpOworICogQ29tcHJlc3NvcklucHV0U3RyZWFtIGluID0gbmV3IENvbXByZXNzb3JTdHJlYW1GYWN0b3J5KCkuY3JlYXRlQ29tcHJlc3NvcklucHV0U3RyZWFtKENvbXByZXNzb3JTdHJlYW1GYWN0b3J5LkJaSVAyLAorICogICAgICAgICBpcyk7CisgKiBJT1V0aWxzLmNvcHkoaW4sIEZpbGVzLm5ld091dHB1dFN0cmVhbShvdXRwdXQudG9QYXRoKCkpKTsKKyAqIGluLmNsb3NlKCk7CisgKiA8L3ByZT4KKyAqCisgKiBASW1tdXRhYmxlIHByb3ZpZGVkIHRoYXQgdGhlIGRlcHJlY2F0ZWQgbWV0aG9kIHNldERlY29tcHJlc3NDb25jYXRlbmF0ZWQgaXMKKyAqICAgICAgICAgICAgbm90IHVzZWQuCisgKiBAVGhyZWFkU2FmZSBldmVuIGlmIHRoZSBkZXByZWNhdGVkIG1ldGhvZCBzZXREZWNvbXByZXNzQ29uY2F0ZW5hdGVkIGlzIHVzZWQKKyAqLworcHVibGljIGNsYXNzIENvbXByZXNzb3JTdHJlYW1GYWN0b3J5IGltcGxlbWVudHMgQ29tcHJlc3NvclN0cmVhbVByb3ZpZGVyIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIENvbXByZXNzb3JTdHJlYW1GYWN0b3J5IFNJTkdMRVRPTiA9IG5ldyBDb21wcmVzc29yU3RyZWFtRmFjdG9yeSgpOworCisKKworICAgIC8qKgorICAgICAqIENvbnN0YW50ICh2YWx1ZSB7QHZhbHVlfSkgdXNlZCB0byBpZGVudGlmeSB0aGUgQlJPVExJIGNvbXByZXNzaW9uCisgICAgICogYWxnb3JpdGhtLgorICAgICAqCisgICAgICogQHNpbmNlIDEuMTQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBCUk9UTEkgPSAiYnIiOworCisgICAgLyoqCisgICAgICogQ29uc3RhbnQgKHZhbHVlIHtAdmFsdWV9KSB1c2VkIHRvIGlkZW50aWZ5IHRoZSBCWklQMiBjb21wcmVzc2lvbgorICAgICAqIGFsZ29yaXRobS4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjEKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBCWklQMiA9ICJiemlwMiI7CisKKyAgICAvKioKKyAgICAgKiBDb25zdGFudCAodmFsdWUge0B2YWx1ZX0pIHVzZWQgdG8gaWRlbnRpZnkgdGhlIEdaSVAgY29tcHJlc3Npb24KKyAgICAgKiBhbGdvcml0aG0uCisgICAgICoKKyAgICAgKiBAc2luY2UgMS4xCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgR1pJUCA9ICJneiI7CisKKyAgICAvKioKKyAgICAgKiBDb25zdGFudCAodmFsdWUge0B2YWx1ZX0pIHVzZWQgdG8gaWRlbnRpZnkgdGhlIFBBQ0syMDAgY29tcHJlc3Npb24KKyAgICAgKiBhbGdvcml0aG0uCisgICAgICoKKyAgICAgKiBAc2luY2UgMS4zCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgUEFDSzIwMCA9ICJwYWNrMjAwIjsKKworICAgIC8qKgorICAgICAqIENvbnN0YW50ICh2YWx1ZSB7QHZhbHVlfSkgdXNlZCB0byBpZGVudGlmeSB0aGUgWFogY29tcHJlc3Npb24gbWV0aG9kLgorICAgICAqCisgICAgICogQHNpbmNlIDEuNAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhaID0gInh6IjsKKworICAgIC8qKgorICAgICAqIENvbnN0YW50ICh2YWx1ZSB7QHZhbHVlfSkgdXNlZCB0byBpZGVudGlmeSB0aGUgTFpNQSBjb21wcmVzc2lvbiBtZXRob2QuCisgICAgICoKKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTFpNQSA9ICJsem1hIjsKKworICAgIC8qKgorICAgICAqIENvbnN0YW50ICh2YWx1ZSB7QHZhbHVlfSkgdXNlZCB0byBpZGVudGlmeSB0aGUgImZyYW1lZCIgU25hcHB5CisgICAgICogY29tcHJlc3Npb24gbWV0aG9kLgorICAgICAqCisgICAgICogQHNpbmNlIDEuNworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNOQVBQWV9GUkFNRUQgPSAic25hcHB5LWZyYW1lZCI7CisKKyAgICAvKioKKyAgICAgKiBDb25zdGFudCAodmFsdWUge0B2YWx1ZX0pIHVzZWQgdG8gaWRlbnRpZnkgdGhlICJyYXciIFNuYXBweSBjb21wcmVzc2lvbgorICAgICAqIG1ldGhvZC4gTm90IHN1cHBvcnRlZCBhcyBhbiBvdXRwdXQgc3RyZWFtIHR5cGUuCisgICAgICoKKyAgICAgKiBAc2luY2UgMS43CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU05BUFBZX1JBVyA9ICJzbmFwcHktcmF3IjsKKworICAgIC8qKgorICAgICAqIENvbnN0YW50ICh2YWx1ZSB7QHZhbHVlfSkgdXNlZCB0byBpZGVudGlmeSB0aGUgdHJhZGl0aW9uYWwgVW5peCBjb21wcmVzcworICAgICAqIG1ldGhvZC4gTm90IHN1cHBvcnRlZCBhcyBhbiBvdXRwdXQgc3RyZWFtIHR5cGUuCisgICAgICoKKyAgICAgKiBAc2luY2UgMS43CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWiA9ICJ6IjsKKworICAgIC8qKgorICAgICAqIENvbnN0YW50ICh2YWx1ZSB7QHZhbHVlfSkgdXNlZCB0byBpZGVudGlmeSB0aGUgRGVmbGF0ZSBjb21wcmVzcyBtZXRob2QuCisgICAgICoKKyAgICAgKiBAc2luY2UgMS45CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgREVGTEFURSA9ICJkZWZsYXRlIjsKKworICAgIC8qKgorICAgICAqIENvbnN0YW50ICh2YWx1ZSB7QHZhbHVlfSkgdXNlZCB0byBpZGVudGlmeSB0aGUgRGVmbGF0ZTY0IGNvbXByZXNzIG1ldGhvZC4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjE2CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgREVGTEFURTY0ID0gImRlZmxhdGU2NCI7CisKKyAgICAvKioKKyAgICAgKiBDb25zdGFudCAodmFsdWUge0B2YWx1ZX0pIHVzZWQgdG8gaWRlbnRpZnkgdGhlIGJsb2NrIExaNAorICAgICAqIGNvbXByZXNzaW9uIG1ldGhvZC4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjE0CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTFo0X0JMT0NLID0gImx6NC1ibG9jayI7CisKKyAgICAvKioKKyAgICAgKiBDb25zdGFudCAodmFsdWUge0B2YWx1ZX0pIHVzZWQgdG8gaWRlbnRpZnkgdGhlIGZyYW1lIExaNAorICAgICAqIGNvbXByZXNzaW9uIG1ldGhvZC4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjE0CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTFo0X0ZSQU1FRCA9ICJsejQtZnJhbWVkIjsKKworICAgIC8qKgorICAgICAqIENvbnN0YW50ICh2YWx1ZSB7QHZhbHVlfSkgdXNlZCB0byBpZGVudGlmeSB0aGUgWnN0YW5kYXJkIGNvbXByZXNzaW9uCisgICAgICogYWxnb3JpdGhtLiBOb3Qgc3VwcG9ydGVkIGFzIGFuIG91dHB1dCBzdHJlYW0gdHlwZS4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjE2CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWlNUQU5EQVJEID0gInpzdGQiOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFlPVV9ORUVEX0JST1RMSV9ERUMgPSB5b3VOZWVkKCJHb29nbGUgQnJvdGxpIERlYyIsICJodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2Jyb3RsaS8iKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgWU9VX05FRURfWFpfSkFWQSA9IHlvdU5lZWQoIlhaIGZvciBKYXZhIiwgImh0dHBzOi8vdHVrYWFuaS5vcmcveHovamF2YS5odG1sIik7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFlPVV9ORUVEX1pTVERfSk5JID0geW91TmVlZCgiWnN0ZCBKTkkiLCAiaHR0cHM6Ly9naXRodWIuY29tL2x1YmVuL3pzdGQtam5pIik7CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgeW91TmVlZChTdHJpbmcgbmFtZSwgU3RyaW5nIHVybCkgeworICAgICAgICByZXR1cm4gIiBJbiBhZGRpdGlvbiB0byBBcGFjaGUgQ29tbW9ucyBDb21wcmVzcyB5b3UgbmVlZCB0aGUgIiArIG5hbWUgKyAiIGxpYnJhcnkgLSBzZWUgIiArIHVybDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHNvcnRlZCBtYXAgZnJvbSBpbnB1dCBzdHJlYW0gcHJvdmlkZXIgbmFtZXMgdG8gcHJvdmlkZXIKKyAgICAgKiBvYmplY3RzLgorICAgICAqCisgICAgICogPHA+CisgICAgICogVGhlIG1hcCByZXR1cm5lZCBieSB0aGlzIG1ldGhvZCB3aWxsIGhhdmUgb25lIGVudHJ5IGZvciBlYWNoIHByb3ZpZGVyIGZvcgorICAgICAqIHdoaWNoIHN1cHBvcnQgaXMgYXZhaWxhYmxlIGluIHRoZSBjdXJyZW50IEphdmEgdmlydHVhbCBtYWNoaW5lLiBJZiB0d28gb3IKKyAgICAgKiBtb3JlIHN1cHBvcnRlZCBwcm92aWRlciBoYXZlIHRoZSBzYW1lIG5hbWUgdGhlbiB0aGUgcmVzdWx0aW5nIG1hcCB3aWxsCisgICAgICogY29udGFpbiBqdXN0IG9uZSBvZiB0aGVtOyB3aGljaCBvbmUgaXQgd2lsbCBjb250YWluIGlzIG5vdCBzcGVjaWZpZWQuCisgICAgICogPC9wPgorICAgICAqCisgICAgICogPHA+CisgICAgICogVGhlIGludm9jYXRpb24gb2YgdGhpcyBtZXRob2QsIGFuZCB0aGUgc3Vic2VxdWVudCB1c2Ugb2YgdGhlIHJlc3VsdGluZworICAgICAqIG1hcCwgbWF5IGNhdXNlIHRpbWUtY29uc3VtaW5nIGRpc2sgb3IgbmV0d29yayBJL08gb3BlcmF0aW9ucyB0byBvY2N1ci4KKyAgICAgKiBUaGlzIG1ldGhvZCBpcyBwcm92aWRlZCBmb3IgYXBwbGljYXRpb25zIHRoYXQgbmVlZCB0byBlbnVtZXJhdGUgYWxsIG9mCisgICAgICogdGhlIGF2YWlsYWJsZSBwcm92aWRlcnMsIGZvciBleGFtcGxlIHRvIGFsbG93IHVzZXIgcHJvdmlkZXIgc2VsZWN0aW9uLgorICAgICAqIDwvcD4KKyAgICAgKgorICAgICAqIDxwPgorICAgICAqIFRoaXMgbWV0aG9kIG1heSByZXR1cm4gZGlmZmVyZW50IHJlc3VsdHMgYXQgZGlmZmVyZW50IHRpbWVzIGlmIG5ldworICAgICAqIHByb3ZpZGVycyBhcmUgZHluYW1pY2FsbHkgbWFkZSBhdmFpbGFibGUgdG8gdGhlIGN1cnJlbnQgSmF2YSB2aXJ0dWFsCisgICAgICogbWFjaGluZS4KKyAgICAgKiA8L3A+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIEFuIGltbXV0YWJsZSwgbWFwIGZyb20gbmFtZXMgdG8gcHJvdmlkZXIgb2JqZWN0cworICAgICAqIEBzaW5jZSAxLjEzCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTb3J0ZWRNYXA8U3RyaW5nLCBDb21wcmVzc29yU3RyZWFtUHJvdmlkZXI+IGZpbmRBdmFpbGFibGVDb21wcmVzc29ySW5wdXRTdHJlYW1Qcm92aWRlcnMoKSB7CisgICAgICAgIHJldHVybiBBY2Nlc3NDb250cm9sbGVyLmRvUHJpdmlsZWdlZChuZXcgUHJpdmlsZWdlZEFjdGlvbjxTb3J0ZWRNYXA8U3RyaW5nLCBDb21wcmVzc29yU3RyZWFtUHJvdmlkZXI+PigpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIFNvcnRlZE1hcDxTdHJpbmcsIENvbXByZXNzb3JTdHJlYW1Qcm92aWRlcj4gcnVuKCkgeworICAgICAgICAgICAgICAgIGZpbmFsIFRyZWVNYXA8U3RyaW5nLCBDb21wcmVzc29yU3RyZWFtUHJvdmlkZXI+IG1hcCA9IG5ldyBUcmVlTWFwPD4oKTsKKyAgICAgICAgICAgICAgICBwdXRBbGwoU0lOR0xFVE9OLmdldElucHV0U3RyZWFtQ29tcHJlc3Nvck5hbWVzKCksIFNJTkdMRVRPTiwgbWFwKTsKKyAgICAgICAgICAgICAgICBmb3IgKGZpbmFsIENvbXByZXNzb3JTdHJlYW1Qcm92aWRlciBwcm92aWRlciA6IGZpbmRDb21wcmVzc29yU3RyZWFtUHJvdmlkZXJzKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgcHV0QWxsKHByb3ZpZGVyLmdldElucHV0U3RyZWFtQ29tcHJlc3Nvck5hbWVzKCksIHByb3ZpZGVyLCBtYXApOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gbWFwOworICAgICAgICAgICAgfQorICAgICAgICB9KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHNvcnRlZCBtYXAgZnJvbSBvdXRwdXQgc3RyZWFtIHByb3ZpZGVyIG5hbWVzIHRvIHByb3ZpZGVyCisgICAgICogb2JqZWN0cy4KKyAgICAgKgorICAgICAqIDxwPgorICAgICAqIFRoZSBtYXAgcmV0dXJuZWQgYnkgdGhpcyBtZXRob2Qgd2lsbCBoYXZlIG9uZSBlbnRyeSBmb3IgZWFjaCBwcm92aWRlciBmb3IKKyAgICAgKiB3aGljaCBzdXBwb3J0IGlzIGF2YWlsYWJsZSBpbiB0aGUgY3VycmVudCBKYXZhIHZpcnR1YWwgbWFjaGluZS4gSWYgdHdvIG9yCisgICAgICogbW9yZSBzdXBwb3J0ZWQgcHJvdmlkZXIgaGF2ZSB0aGUgc2FtZSBuYW1lIHRoZW4gdGhlIHJlc3VsdGluZyBtYXAgd2lsbAorICAgICAqIGNvbnRhaW4ganVzdCBvbmUgb2YgdGhlbTsgd2hpY2ggb25lIGl0IHdpbGwgY29udGFpbiBpcyBub3Qgc3BlY2lmaWVkLgorICAgICAqIDwvcD4KKyAgICAgKgorICAgICAqIDxwPgorICAgICAqIFRoZSBpbnZvY2F0aW9uIG9mIHRoaXMgbWV0aG9kLCBhbmQgdGhlIHN1YnNlcXVlbnQgdXNlIG9mIHRoZSByZXN1bHRpbmcKKyAgICAgKiBtYXAsIG1heSBjYXVzZSB0aW1lLWNvbnN1bWluZyBkaXNrIG9yIG5ldHdvcmsgSS9PIG9wZXJhdGlvbnMgdG8gb2NjdXIuCisgICAgICogVGhpcyBtZXRob2QgaXMgcHJvdmlkZWQgZm9yIGFwcGxpY2F0aW9ucyB0aGF0IG5lZWQgdG8gZW51bWVyYXRlIGFsbCBvZgorICAgICAqIHRoZSBhdmFpbGFibGUgcHJvdmlkZXJzLCBmb3IgZXhhbXBsZSB0byBhbGxvdyB1c2VyIHByb3ZpZGVyIHNlbGVjdGlvbi4KKyAgICAgKiA8L3A+CisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIG1ldGhvZCBtYXkgcmV0dXJuIGRpZmZlcmVudCByZXN1bHRzIGF0IGRpZmZlcmVudCB0aW1lcyBpZiBuZXcKKyAgICAgKiBwcm92aWRlcnMgYXJlIGR5bmFtaWNhbGx5IG1hZGUgYXZhaWxhYmxlIHRvIHRoZSBjdXJyZW50IEphdmEgdmlydHVhbAorICAgICAqIG1hY2hpbmUuCisgICAgICogPC9wPgorICAgICAqCisgICAgICogQHJldHVybiBBbiBpbW11dGFibGUsIG1hcCBmcm9tIG5hbWVzIHRvIHByb3ZpZGVyIG9iamVjdHMKKyAgICAgKiBAc2luY2UgMS4xMworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU29ydGVkTWFwPFN0cmluZywgQ29tcHJlc3NvclN0cmVhbVByb3ZpZGVyPiBmaW5kQXZhaWxhYmxlQ29tcHJlc3Nvck91dHB1dFN0cmVhbVByb3ZpZGVycygpIHsKKyAgICAgICAgcmV0dXJuIEFjY2Vzc0NvbnRyb2xsZXIuZG9Qcml2aWxlZ2VkKG5ldyBQcml2aWxlZ2VkQWN0aW9uPFNvcnRlZE1hcDxTdHJpbmcsIENvbXByZXNzb3JTdHJlYW1Qcm92aWRlcj4+KCkgeworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgU29ydGVkTWFwPFN0cmluZywgQ29tcHJlc3NvclN0cmVhbVByb3ZpZGVyPiBydW4oKSB7CisgICAgICAgICAgICAgICAgZmluYWwgVHJlZU1hcDxTdHJpbmcsIENvbXByZXNzb3JTdHJlYW1Qcm92aWRlcj4gbWFwID0gbmV3IFRyZWVNYXA8PigpOworICAgICAgICAgICAgICAgIHB1dEFsbChTSU5HTEVUT04uZ2V0T3V0cHV0U3RyZWFtQ29tcHJlc3Nvck5hbWVzKCksIFNJTkdMRVRPTiwgbWFwKTsKKyAgICAgICAgICAgICAgICBmb3IgKGZpbmFsIENvbXByZXNzb3JTdHJlYW1Qcm92aWRlciBwcm92aWRlciA6IGZpbmRDb21wcmVzc29yU3RyZWFtUHJvdmlkZXJzKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgcHV0QWxsKHByb3ZpZGVyLmdldE91dHB1dFN0cmVhbUNvbXByZXNzb3JOYW1lcygpLCBwcm92aWRlciwgbWFwKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIG1hcDsKKyAgICAgICAgICAgIH0KKworICAgICAgICB9KTsKKyAgICB9CisgICAgcHJpdmF0ZSBzdGF0aWMgQXJyYXlMaXN0PENvbXByZXNzb3JTdHJlYW1Qcm92aWRlcj4gZmluZENvbXByZXNzb3JTdHJlYW1Qcm92aWRlcnMoKSB7CisgICAgICAgIHJldHVybiBMaXN0cy5uZXdBcnJheUxpc3Qoc2VydmljZUxvYWRlckl0ZXJhdG9yKCkpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldEJyb3RsaSgpIHsKKyAgICAgICAgcmV0dXJuIEJST1RMSTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRCemlwMigpIHsKKyAgICAgICAgcmV0dXJuIEJaSVAyOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldERlZmxhdGUoKSB7CisgICAgICAgIHJldHVybiBERUZMQVRFOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzaW5jZSAxLjE2CisgICAgICogQHJldHVybiB0aGUgY29uc3RhbnQge0BsaW5rICNERUZMQVRFNjR9CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0RGVmbGF0ZTY0KCkgeworICAgICAgICByZXR1cm4gREVGTEFURTY0OworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldEd6aXAoKSB7CisgICAgICAgIHJldHVybiBHWklQOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldEx6bWEoKSB7CisgICAgICAgIHJldHVybiBMWk1BOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldFBhY2syMDAoKSB7CisgICAgICAgIHJldHVybiBQQUNLMjAwOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkgZ2V0U2luZ2xldG9uKCkgeworICAgICAgICByZXR1cm4gU0lOR0xFVE9OOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldFNuYXBweUZyYW1lZCgpIHsKKyAgICAgICAgcmV0dXJuIFNOQVBQWV9GUkFNRUQ7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0U25hcHB5UmF3KCkgeworICAgICAgICByZXR1cm4gU05BUFBZX1JBVzsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRYeigpIHsKKyAgICAgICAgcmV0dXJuIFhaOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldFooKSB7CisgICAgICAgIHJldHVybiBaOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldExaNEZyYW1lZCgpIHsKKyAgICAgICAgcmV0dXJuIExaNF9GUkFNRUQ7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0TFo0QmxvY2soKSB7CisgICAgICAgIHJldHVybiBMWjRfQkxPQ0s7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0WnN0YW5kYXJkKCkgeworICAgICAgICByZXR1cm4gWlNUQU5EQVJEOworICAgIH0KKworICAgIHN0YXRpYyB2b2lkIHB1dEFsbChmaW5hbCBTZXQ8U3RyaW5nPiBuYW1lcywgZmluYWwgQ29tcHJlc3NvclN0cmVhbVByb3ZpZGVyIHByb3ZpZGVyLAorICAgICAgICAgICAgZmluYWwgVHJlZU1hcDxTdHJpbmcsIENvbXByZXNzb3JTdHJlYW1Qcm92aWRlcj4gbWFwKSB7CisgICAgICAgIGZvciAoZmluYWwgU3RyaW5nIG5hbWUgOiBuYW1lcykgeworICAgICAgICAgICAgbWFwLnB1dCh0b0tleShuYW1lKSwgcHJvdmlkZXIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgSXRlcmF0b3I8Q29tcHJlc3NvclN0cmVhbVByb3ZpZGVyPiBzZXJ2aWNlTG9hZGVySXRlcmF0b3IoKSB7CisgICAgICAgIHJldHVybiBuZXcgU2VydmljZUxvYWRlckl0ZXJhdG9yPD4oQ29tcHJlc3NvclN0cmVhbVByb3ZpZGVyLmNsYXNzKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgdG9LZXkoZmluYWwgU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgcmV0dXJuIG5hbWUudG9VcHBlckNhc2UoTG9jYWxlLlJPT1QpOworICAgIH0KKworICAgIC8qKgorICAgICAqIElmIHRydWUsIGRlY29tcHJlc3MgdW50aWwgdGhlIGVuZCBvZiB0aGUgaW5wdXQuIElmIGZhbHNlLCBzdG9wIGFmdGVyIHRoZQorICAgICAqIGZpcnN0IHN0cmVhbSBhbmQgbGVhdmUgdGhlIGlucHV0IHBvc2l0aW9uIHRvIHBvaW50IHRvIHRoZSBuZXh0IGJ5dGUgYWZ0ZXIKKyAgICAgKiB0aGUgc3RyZWFtCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBCb29sZWFuIGRlY29tcHJlc3NVbnRpbEVPRjsKKyAgICAvLyBUaGlzIGlzIEJvb2xlYW4gc28gc2V0RGVjb21wcmVzc0NvbmNhdGVuYXRlZCBjYW4gZGV0ZXJtaW5lIHdoZXRoZXIgaXQgaGFzCisgICAgLy8gYmVlbiBzZXQgYnkgdGhlIGN0b3IKKyAgICAvLyBvbmNlIHRoZSBzZXREZWNvbXByZXNzQ29uY2F0ZW5hdGVkIG1ldGhvZCBoYXMgYmVlbiByZW1vdmVkLCBpdCBjYW4gcmV2ZXJ0CisgICAgLy8gdG8gYm9vbGVhbgorCisgICAgcHJpdmF0ZSBTb3J0ZWRNYXA8U3RyaW5nLCBDb21wcmVzc29yU3RyZWFtUHJvdmlkZXI+IGNvbXByZXNzb3JJbnB1dFN0cmVhbVByb3ZpZGVyczsKKworICAgIHByaXZhdGUgU29ydGVkTWFwPFN0cmluZywgQ29tcHJlc3NvclN0cmVhbVByb3ZpZGVyPiBjb21wcmVzc29yT3V0cHV0U3RyZWFtUHJvdmlkZXJzOworCisgICAgLyoqCisgICAgICogSWYgdHJ1ZSwgZGVjb21wcmVzcyB1bnRpbCB0aGUgZW5kIG9mIHRoZSBpbnB1dC4gSWYgZmFsc2UsIHN0b3AgYWZ0ZXIgdGhlCisgICAgICogZmlyc3Qgc3RyZWFtIGFuZCBsZWF2ZSB0aGUgaW5wdXQgcG9zaXRpb24gdG8gcG9pbnQgdG8gdGhlIG5leHQgYnl0ZSBhZnRlcgorICAgICAqIHRoZSBzdHJlYW0KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvbGF0aWxlIGJvb2xlYW4gZGVjb21wcmVzc0NvbmNhdGVuYXRlZCA9IGZhbHNlOworCisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgbWVtb3J5TGltaXRJbktiOworICAgIC8qKgorICAgICAqIENyZWF0ZSBhbiBpbnN0YW5jZSB3aXRoIHRoZSBkZWNvbXByZXNzIENvbmNhdGVuYXRlZCBvcHRpb24gc2V0IHRvIGZhbHNlLgorICAgICAqLworICAgIHB1YmxpYyBDb21wcmVzc29yU3RyZWFtRmFjdG9yeSgpIHsKKyAgICAgICAgdGhpcy5kZWNvbXByZXNzVW50aWxFT0YgPSBudWxsOworICAgICAgICB0aGlzLm1lbW9yeUxpbWl0SW5LYiA9IC0xOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhbiBpbnN0YW5jZSB3aXRoIHRoZSBwcm92aWRlZCBkZWNvbXByZXNzIENvbmNhdGVuYXRlZCBvcHRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGVjb21wcmVzc1VudGlsRU9GCisgICAgICogICAgICAgICAgICBpZiB0cnVlLCBkZWNvbXByZXNzIHVudGlsIHRoZSBlbmQgb2YgdGhlIGlucHV0OyBpZiBmYWxzZSwgc3RvcAorICAgICAqICAgICAgICAgICAgYWZ0ZXIgdGhlIGZpcnN0IHN0cmVhbSBhbmQgbGVhdmUgdGhlIGlucHV0IHBvc2l0aW9uIHRvIHBvaW50CisgICAgICogICAgICAgICAgICB0byB0aGUgbmV4dCBieXRlIGFmdGVyIHRoZSBzdHJlYW0uIFRoaXMgc2V0dGluZyBhcHBsaWVzIHRvIHRoZQorICAgICAqICAgICAgICAgICAgZ3ppcCwgYnppcDIgYW5kIHh6IGZvcm1hdHMgb25seS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtZW1vcnlMaW1pdEluS2IKKyAgICAgKiAgICAgICAgICAgIFNvbWUgc3RyZWFtcyByZXF1aXJlIGFsbG9jYXRpb24gb2YgcG90ZW50aWFsbHkgc2lnbmlmaWNhbnQKKyAgICAgKiAgICAgICAgICAgIGJ5dGUgYXJyYXlzL3RhYmxlcywgYW5kIHRoZXkgY2FuIG9mZmVyIGNoZWNrcyB0byBwcmV2ZW50IE9PTXMKKyAgICAgKiAgICAgICAgICAgIG9uIGNvcnJ1cHQgZmlsZXMuICBTZXQgdGhlIG1heGltdW0gYWxsb3dlZCBtZW1vcnkgYWxsb2NhdGlvbiBpbiBLQnMuCisgICAgICoKKyAgICAgKiBAc2luY2UgMS4xNAorICAgICAqLworICAgIHB1YmxpYyBDb21wcmVzc29yU3RyZWFtRmFjdG9yeShmaW5hbCBib29sZWFuIGRlY29tcHJlc3NVbnRpbEVPRiwgZmluYWwgaW50IG1lbW9yeUxpbWl0SW5LYikgeworICAgICAgICB0aGlzLmRlY29tcHJlc3NVbnRpbEVPRiA9IGRlY29tcHJlc3NVbnRpbEVPRjsKKyAgICAgICAgLy8gQWxzbyBjb3B5IHRvIGV4aXN0aW5nIHZhcmlhYmxlIHNvIGNhbiBjb250aW51ZSB0byB1c2UgdGhhdCBhcyB0aGUKKyAgICAgICAgLy8gY3VycmVudCB2YWx1ZQorICAgICAgICB0aGlzLmRlY29tcHJlc3NDb25jYXRlbmF0ZWQgPSBkZWNvbXByZXNzVW50aWxFT0Y7CisgICAgICAgIHRoaXMubWVtb3J5TGltaXRJbktiID0gbWVtb3J5TGltaXRJbktiOworICAgIH0KKworCisgICAgLyoqCisgICAgICogQ3JlYXRlIGFuIGluc3RhbmNlIHdpdGggdGhlIHByb3ZpZGVkIGRlY29tcHJlc3MgQ29uY2F0ZW5hdGVkIG9wdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZWNvbXByZXNzVW50aWxFT0YKKyAgICAgKiAgICAgICAgICAgIGlmIHRydWUsIGRlY29tcHJlc3MgdW50aWwgdGhlIGVuZCBvZiB0aGUgaW5wdXQ7IGlmIGZhbHNlLCBzdG9wCisgICAgICogICAgICAgICAgICBhZnRlciB0aGUgZmlyc3Qgc3RyZWFtIGFuZCBsZWF2ZSB0aGUgaW5wdXQgcG9zaXRpb24gdG8gcG9pbnQKKyAgICAgKiAgICAgICAgICAgIHRvIHRoZSBuZXh0IGJ5dGUgYWZ0ZXIgdGhlIHN0cmVhbS4gVGhpcyBzZXR0aW5nIGFwcGxpZXMgdG8gdGhlCisgICAgICogICAgICAgICAgICBnemlwLCBiemlwMiBhbmQgeHogZm9ybWF0cyBvbmx5LgorICAgICAqIEBzaW5jZSAxLjEwCisgICAgICovCisgICAgcHVibGljIENvbXByZXNzb3JTdHJlYW1GYWN0b3J5KGZpbmFsIGJvb2xlYW4gZGVjb21wcmVzc1VudGlsRU9GKSB7CisgICAgICAgIHRoaXMoZGVjb21wcmVzc1VudGlsRU9GLCAtMSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVHJ5IHRvIGRldGVjdCB0aGUgdHlwZSBvZiBjb21wcmVzc29yIHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbiBpbnB1dCBzdHJlYW0KKyAgICAgKiBAcmV0dXJuIHR5cGUgb2YgY29tcHJlc3NvciBzdHJlYW0gZGV0ZWN0ZWQKKyAgICAgKiBAdGhyb3dzIENvbXByZXNzb3JFeGNlcHRpb24gaWYgbm8gY29tcHJlc3NvciBzdHJlYW0gdHlwZSB3YXMgZGV0ZWN0ZWQKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3IgaWYgc29tZXRoaW5nIGVsc2Ugd2VudCB3cm9uZworICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHN0cmVhbSBpcyBudWxsIG9yIGRvZXMgbm90IHN1cHBvcnQgbWFyaworICAgICAqCisgICAgICogQHNpbmNlIDEuMTQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBkZXRlY3QoZmluYWwgSW5wdXRTdHJlYW0gaW4pIHRocm93cyBDb21wcmVzc29yRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGluID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlN0cmVhbSBtdXN0IG5vdCBiZSBudWxsLiIpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKCFpbi5tYXJrU3VwcG9ydGVkKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIk1hcmsgaXMgbm90IHN1cHBvcnRlZC4iKTsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIGJ5dGVbXSBzaWduYXR1cmUgPSBuZXcgYnl0ZVsxMl07CisgICAgICAgIGluLm1hcmsoc2lnbmF0dXJlLmxlbmd0aCk7CisgICAgICAgIGludCBzaWduYXR1cmVMZW5ndGggPSAtMTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNpZ25hdHVyZUxlbmd0aCA9IElPVXRpbHMucmVhZEZ1bGx5KGluLCBzaWduYXR1cmUpOworICAgICAgICAgICAgaW4ucmVzZXQoKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IENvbXByZXNzb3JFeGNlcHRpb24oIklPRXhjZXB0aW9uIHdoaWxlIHJlYWRpbmcgc2lnbmF0dXJlLiIsIGUpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKEJaaXAyQ29tcHJlc3NvcklucHV0U3RyZWFtLm1hdGNoZXMoc2lnbmF0dXJlLCBzaWduYXR1cmVMZW5ndGgpKSB7CisgICAgICAgICAgICByZXR1cm4gQlpJUDI7CisgICAgICAgIH0KKworICAgICAgICBpZiAoR3ppcENvbXByZXNzb3JJbnB1dFN0cmVhbS5tYXRjaGVzKHNpZ25hdHVyZSwgc2lnbmF0dXJlTGVuZ3RoKSkgeworICAgICAgICAgICAgcmV0dXJuIEdaSVA7CisgICAgICAgIH0KKworICAgICAgICBpZiAoUGFjazIwMENvbXByZXNzb3JJbnB1dFN0cmVhbS5tYXRjaGVzKHNpZ25hdHVyZSwgc2lnbmF0dXJlTGVuZ3RoKSkgeworICAgICAgICAgICAgcmV0dXJuIFBBQ0syMDA7CisgICAgICAgIH0KKworICAgICAgICBpZiAoRnJhbWVkU25hcHB5Q29tcHJlc3NvcklucHV0U3RyZWFtLm1hdGNoZXMoc2lnbmF0dXJlLCBzaWduYXR1cmVMZW5ndGgpKSB7CisgICAgICAgICAgICByZXR1cm4gU05BUFBZX0ZSQU1FRDsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChaQ29tcHJlc3NvcklucHV0U3RyZWFtLm1hdGNoZXMoc2lnbmF0dXJlLCBzaWduYXR1cmVMZW5ndGgpKSB7CisgICAgICAgICAgICByZXR1cm4gWjsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChEZWZsYXRlQ29tcHJlc3NvcklucHV0U3RyZWFtLm1hdGNoZXMoc2lnbmF0dXJlLCBzaWduYXR1cmVMZW5ndGgpKSB7CisgICAgICAgICAgICByZXR1cm4gREVGTEFURTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChYWlV0aWxzLm1hdGNoZXMoc2lnbmF0dXJlLCBzaWduYXR1cmVMZW5ndGgpKSB7CisgICAgICAgICAgICByZXR1cm4gWFo7CisgICAgICAgIH0KKworICAgICAgICBpZiAoTFpNQVV0aWxzLm1hdGNoZXMoc2lnbmF0dXJlLCBzaWduYXR1cmVMZW5ndGgpKSB7CisgICAgICAgICAgICByZXR1cm4gTFpNQTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChGcmFtZWRMWjRDb21wcmVzc29ySW5wdXRTdHJlYW0ubWF0Y2hlcyhzaWduYXR1cmUsIHNpZ25hdHVyZUxlbmd0aCkpIHsKKyAgICAgICAgICAgIHJldHVybiBMWjRfRlJBTUVEOworICAgICAgICB9CisKKyAgICAgICAgaWYgKFpzdGRVdGlscy5tYXRjaGVzKHNpZ25hdHVyZSwgc2lnbmF0dXJlTGVuZ3RoKSkgeworICAgICAgICAgICAgcmV0dXJuIFpTVEFOREFSRDsKKyAgICAgICAgfQorCisgICAgICAgIHRocm93IG5ldyBDb21wcmVzc29yRXhjZXB0aW9uKCJObyBDb21wcmVzc29yIGZvdW5kIGZvciB0aGUgc3RyZWFtIHNpZ25hdHVyZS4iKTsKKyAgICB9CisgICAgLyoqCisgICAgICogQ3JlYXRlIGFuIGNvbXByZXNzb3IgaW5wdXQgc3RyZWFtIGZyb20gYW4gaW5wdXQgc3RyZWFtLCBhdXRvZGV0ZWN0aW5nIHRoZQorICAgICAqIGNvbXByZXNzb3IgdHlwZSBmcm9tIHRoZSBmaXJzdCBmZXcgYnl0ZXMgb2YgdGhlIHN0cmVhbS4gVGhlIElucHV0U3RyZWFtCisgICAgICogbXVzdCBzdXBwb3J0IG1hcmtzLCBsaWtlIEJ1ZmZlcmVkSW5wdXRTdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW4KKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnB1dCBzdHJlYW0KKyAgICAgKiBAcmV0dXJuIHRoZSBjb21wcmVzc29yIGlucHV0IHN0cmVhbQorICAgICAqIEB0aHJvd3MgQ29tcHJlc3NvckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBjb21wcmVzc29yIG5hbWUgaXMgbm90IGtub3duCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3RyZWFtIGlzIG51bGwgb3IgZG9lcyBub3Qgc3VwcG9ydCBtYXJrCisgICAgICogQHNpbmNlIDEuMQorICAgICAqLworICAgIHB1YmxpYyBDb21wcmVzc29ySW5wdXRTdHJlYW0gY3JlYXRlQ29tcHJlc3NvcklucHV0U3RyZWFtKGZpbmFsIElucHV0U3RyZWFtIGluKSB0aHJvd3MgQ29tcHJlc3NvckV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBjcmVhdGVDb21wcmVzc29ySW5wdXRTdHJlYW0oZGV0ZWN0KGluKSwgaW4pOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBjb21wcmVzc29yIGlucHV0IHN0cmVhbSBmcm9tIGEgY29tcHJlc3NvciBuYW1lIGFuZCBhbiBpbnB1dAorICAgICAqIHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICBvZiB0aGUgY29tcHJlc3NvciwgaS5lLiB7QHZhbHVlICNHWklQfSwge0B2YWx1ZSAjQlpJUDJ9LAorICAgICAqICAgICAgICAgICAge0B2YWx1ZSAjWFp9LCB7QHZhbHVlICNMWk1BfSwge0B2YWx1ZSAjUEFDSzIwMH0sCisgICAgICogICAgICAgICAgICB7QHZhbHVlICNTTkFQUFlfUkFXfSwge0B2YWx1ZSAjU05BUFBZX0ZSQU1FRH0sIHtAdmFsdWUgI1p9LAorICAgICAqICAgICAgICAgICAge0B2YWx1ZSAjTFo0X0JMT0NLfSwge0B2YWx1ZSAjTFo0X0ZSQU1FRH0sIHtAdmFsdWUgI1pTVEFOREFSRH0sCisgICAgICogICAgICAgICAgICB7QHZhbHVlICNERUZMQVRFNjR9CisgICAgICogICAgICAgICAgICBvciB7QHZhbHVlICNERUZMQVRFfQorICAgICAqIEBwYXJhbSBpbgorICAgICAqICAgICAgICAgICAgdGhlIGlucHV0IHN0cmVhbQorICAgICAqIEByZXR1cm4gY29tcHJlc3NvciBpbnB1dCBzdHJlYW0KKyAgICAgKiBAdGhyb3dzIENvbXByZXNzb3JFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY29tcHJlc3NvciBuYW1lIGlzIG5vdCBrbm93biBvciBub3QgYXZhaWxhYmxlLAorICAgICAqICAgICAgICAgICAgIG9yIGlmIHRoZXJlJ3MgYW4gSU9FeGNlcHRpb24gb3IgTWVtb3J5TGltaXRFeGNlcHRpb24gdGhyb3duCisgICAgICogICAgICAgICAgICAgZHVyaW5nIGluaXRpYWxpemF0aW9uCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgbmFtZSBvciBpbnB1dCBzdHJlYW0gaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBDb21wcmVzc29ySW5wdXRTdHJlYW0gY3JlYXRlQ29tcHJlc3NvcklucHV0U3RyZWFtKGZpbmFsIFN0cmluZyBuYW1lLCBmaW5hbCBJbnB1dFN0cmVhbSBpbikKKyAgICAgICAgICAgIHRocm93cyBDb21wcmVzc29yRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGNyZWF0ZUNvbXByZXNzb3JJbnB1dFN0cmVhbShuYW1lLCBpbiwgZGVjb21wcmVzc0NvbmNhdGVuYXRlZCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIENvbXByZXNzb3JJbnB1dFN0cmVhbSBjcmVhdGVDb21wcmVzc29ySW5wdXRTdHJlYW0oZmluYWwgU3RyaW5nIG5hbWUsIGZpbmFsIElucHV0U3RyZWFtIGluLAorICAgICAgICAgICAgZmluYWwgYm9vbGVhbiBhY3R1YWxEZWNvbXByZXNzQ29uY2F0ZW5hdGVkKSB0aHJvd3MgQ29tcHJlc3NvckV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChuYW1lID09IG51bGwgfHwgaW4gPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiQ29tcHJlc3NvciBuYW1lIGFuZCBzdHJlYW0gbXVzdCBub3QgYmUgbnVsbC4iKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisKKyAgICAgICAgICAgIGlmIChHWklQLmVxdWFsc0lnbm9yZUNhc2UobmFtZSkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEd6aXBDb21wcmVzc29ySW5wdXRTdHJlYW0oaW4sIGFjdHVhbERlY29tcHJlc3NDb25jYXRlbmF0ZWQpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoQlpJUDIuZXF1YWxzSWdub3JlQ2FzZShuYW1lKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQlppcDJDb21wcmVzc29ySW5wdXRTdHJlYW0oaW4sIGFjdHVhbERlY29tcHJlc3NDb25jYXRlbmF0ZWQpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoQlJPVExJLmVxdWFsc0lnbm9yZUNhc2UobmFtZSkpIHsKKyAgICAgICAgICAgICAgICBpZiAoIUJyb3RsaVV0aWxzLmlzQnJvdGxpQ29tcHJlc3Npb25BdmFpbGFibGUoKSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ29tcHJlc3NvckV4Y2VwdGlvbigiQnJvdGxpIGNvbXByZXNzaW9uIGlzIG5vdCBhdmFpbGFibGUuIiArIFlPVV9ORUVEX0JST1RMSV9ERUMpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEJyb3RsaUNvbXByZXNzb3JJbnB1dFN0cmVhbShpbik7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChYWi5lcXVhbHNJZ25vcmVDYXNlKG5hbWUpKSB7CisgICAgICAgICAgICAgICAgaWYgKCFYWlV0aWxzLmlzWFpDb21wcmVzc2lvbkF2YWlsYWJsZSgpKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBDb21wcmVzc29yRXhjZXB0aW9uKCJYWiBjb21wcmVzc2lvbiBpcyBub3QgYXZhaWxhYmxlLiIgKyBZT1VfTkVFRF9YWl9KQVZBKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBYWkNvbXByZXNzb3JJbnB1dFN0cmVhbShpbiwgYWN0dWFsRGVjb21wcmVzc0NvbmNhdGVuYXRlZCwgbWVtb3J5TGltaXRJbktiKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKFpTVEFOREFSRC5lcXVhbHNJZ25vcmVDYXNlKG5hbWUpKSB7CisgICAgICAgICAgICAgICAgaWYgKCFac3RkVXRpbHMuaXNac3RkQ29tcHJlc3Npb25BdmFpbGFibGUoKSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ29tcHJlc3NvckV4Y2VwdGlvbigiWnN0YW5kYXJkIGNvbXByZXNzaW9uIGlzIG5vdCBhdmFpbGFibGUuIiArIFlPVV9ORUVEX1pTVERfSk5JKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBac3RkQ29tcHJlc3NvcklucHV0U3RyZWFtKGluKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKExaTUEuZXF1YWxzSWdub3JlQ2FzZShuYW1lKSkgeworICAgICAgICAgICAgICAgIGlmICghTFpNQVV0aWxzLmlzTFpNQUNvbXByZXNzaW9uQXZhaWxhYmxlKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENvbXByZXNzb3JFeGNlcHRpb24oIkxaTUEgY29tcHJlc3Npb24gaXMgbm90IGF2YWlsYWJsZSIgKyBZT1VfTkVFRF9YWl9KQVZBKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBMWk1BQ29tcHJlc3NvcklucHV0U3RyZWFtKGluLCBtZW1vcnlMaW1pdEluS2IpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoUEFDSzIwMC5lcXVhbHNJZ25vcmVDYXNlKG5hbWUpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBQYWNrMjAwQ29tcHJlc3NvcklucHV0U3RyZWFtKGluKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKFNOQVBQWV9SQVcuZXF1YWxzSWdub3JlQ2FzZShuYW1lKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU25hcHB5Q29tcHJlc3NvcklucHV0U3RyZWFtKGluKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKFNOQVBQWV9GUkFNRUQuZXF1YWxzSWdub3JlQ2FzZShuYW1lKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgRnJhbWVkU25hcHB5Q29tcHJlc3NvcklucHV0U3RyZWFtKGluKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKFouZXF1YWxzSWdub3JlQ2FzZShuYW1lKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgWkNvbXByZXNzb3JJbnB1dFN0cmVhbShpbiwgbWVtb3J5TGltaXRJbktiKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKERFRkxBVEUuZXF1YWxzSWdub3JlQ2FzZShuYW1lKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgRGVmbGF0ZUNvbXByZXNzb3JJbnB1dFN0cmVhbShpbik7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChERUZMQVRFNjQuZXF1YWxzSWdub3JlQ2FzZShuYW1lKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgRGVmbGF0ZTY0Q29tcHJlc3NvcklucHV0U3RyZWFtKGluKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKExaNF9CTE9DSy5lcXVhbHNJZ25vcmVDYXNlKG5hbWUpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBCbG9ja0xaNENvbXByZXNzb3JJbnB1dFN0cmVhbShpbik7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChMWjRfRlJBTUVELmVxdWFsc0lnbm9yZUNhc2UobmFtZSkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEZyYW1lZExaNENvbXByZXNzb3JJbnB1dFN0cmVhbShpbiwgYWN0dWFsRGVjb21wcmVzc0NvbmNhdGVuYXRlZCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IENvbXByZXNzb3JFeGNlcHRpb24oIkNvdWxkIG5vdCBjcmVhdGUgQ29tcHJlc3NvcklucHV0U3RyZWFtLiIsIGUpOworICAgICAgICB9CisgICAgICAgIGZpbmFsIENvbXByZXNzb3JTdHJlYW1Qcm92aWRlciBjb21wcmVzc29yU3RyZWFtUHJvdmlkZXIgPSBnZXRDb21wcmVzc29ySW5wdXRTdHJlYW1Qcm92aWRlcnMoKS5nZXQodG9LZXkobmFtZSkpOworICAgICAgICBpZiAoY29tcHJlc3NvclN0cmVhbVByb3ZpZGVyICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBjb21wcmVzc29yU3RyZWFtUHJvdmlkZXIuY3JlYXRlQ29tcHJlc3NvcklucHV0U3RyZWFtKG5hbWUsIGluLCBhY3R1YWxEZWNvbXByZXNzQ29uY2F0ZW5hdGVkKTsKKyAgICAgICAgfQorCisgICAgICAgIHRocm93IG5ldyBDb21wcmVzc29yRXhjZXB0aW9uKCJDb21wcmVzc29yOiAiICsgbmFtZSArICIgbm90IGZvdW5kLiIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gY29tcHJlc3NvciBvdXRwdXQgc3RyZWFtIGZyb20gYW4gY29tcHJlc3NvciBuYW1lIGFuZCBhbiBvdXRwdXQKKyAgICAgKiBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgdGhlIGNvbXByZXNzb3IgbmFtZSwgaS5lLiB7QHZhbHVlICNHWklQfSwge0B2YWx1ZSAjQlpJUDJ9LAorICAgICAqICAgICAgICAgICAge0B2YWx1ZSAjWFp9LCB7QHZhbHVlICNQQUNLMjAwfSwge0B2YWx1ZSAjU05BUFBZX0ZSQU1FRH0sCisgICAgICogICAgICAgICAgICB7QHZhbHVlICNMWjRfQkxPQ0t9LCB7QHZhbHVlICNMWjRfRlJBTUVEfSwge0B2YWx1ZSAjWlNUQU5EQVJEfQorICAgICAqICAgICAgICAgICAgb3Ige0B2YWx1ZSAjREVGTEFURX0KKyAgICAgKiBAcGFyYW0gb3V0CisgICAgICogICAgICAgICAgICB0aGUgb3V0cHV0IHN0cmVhbQorICAgICAqIEByZXR1cm4gdGhlIGNvbXByZXNzb3Igb3V0cHV0IHN0cmVhbQorICAgICAqIEB0aHJvd3MgQ29tcHJlc3NvckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBhcmNoaXZlciBuYW1lIGlzIG5vdCBrbm93bgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGFyY2hpdmVyIG5hbWUgb3Igc3RyZWFtIGlzIG51bGwKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQ29tcHJlc3Nvck91dHB1dFN0cmVhbSBjcmVhdGVDb21wcmVzc29yT3V0cHV0U3RyZWFtKGZpbmFsIFN0cmluZyBuYW1lLCBmaW5hbCBPdXRwdXRTdHJlYW0gb3V0KQorICAgICAgICAgICAgdGhyb3dzIENvbXByZXNzb3JFeGNlcHRpb24geworICAgICAgICBpZiAobmFtZSA9PSBudWxsIHx8IG91dCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJDb21wcmVzc29yIG5hbWUgYW5kIHN0cmVhbSBtdXN0IG5vdCBiZSBudWxsLiIpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKworICAgICAgICAgICAgaWYgKEdaSVAuZXF1YWxzSWdub3JlQ2FzZShuYW1lKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgR3ppcENvbXByZXNzb3JPdXRwdXRTdHJlYW0ob3V0KTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKEJaSVAyLmVxdWFsc0lnbm9yZUNhc2UobmFtZSkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEJaaXAyQ29tcHJlc3Nvck91dHB1dFN0cmVhbShvdXQpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoWFouZXF1YWxzSWdub3JlQ2FzZShuYW1lKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgWFpDb21wcmVzc29yT3V0cHV0U3RyZWFtKG91dCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChQQUNLMjAwLmVxdWFsc0lnbm9yZUNhc2UobmFtZSkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFBhY2syMDBDb21wcmVzc29yT3V0cHV0U3RyZWFtKG91dCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChMWk1BLmVxdWFsc0lnbm9yZUNhc2UobmFtZSkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IExaTUFDb21wcmVzc29yT3V0cHV0U3RyZWFtKG91dCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChERUZMQVRFLmVxdWFsc0lnbm9yZUNhc2UobmFtZSkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IERlZmxhdGVDb21wcmVzc29yT3V0cHV0U3RyZWFtKG91dCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChTTkFQUFlfRlJBTUVELmVxdWFsc0lnbm9yZUNhc2UobmFtZSkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEZyYW1lZFNuYXBweUNvbXByZXNzb3JPdXRwdXRTdHJlYW0ob3V0KTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKExaNF9CTE9DSy5lcXVhbHNJZ25vcmVDYXNlKG5hbWUpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBCbG9ja0xaNENvbXByZXNzb3JPdXRwdXRTdHJlYW0ob3V0KTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKExaNF9GUkFNRUQuZXF1YWxzSWdub3JlQ2FzZShuYW1lKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgRnJhbWVkTFo0Q29tcHJlc3Nvck91dHB1dFN0cmVhbShvdXQpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoWlNUQU5EQVJELmVxdWFsc0lnbm9yZUNhc2UobmFtZSkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFpzdGRDb21wcmVzc29yT3V0cHV0U3RyZWFtKG91dCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBDb21wcmVzc29yRXhjZXB0aW9uKCJDb3VsZCBub3QgY3JlYXRlIENvbXByZXNzb3JPdXRwdXRTdHJlYW0iLCBlKTsKKyAgICAgICAgfQorICAgICAgICBmaW5hbCBDb21wcmVzc29yU3RyZWFtUHJvdmlkZXIgY29tcHJlc3NvclN0cmVhbVByb3ZpZGVyID0gZ2V0Q29tcHJlc3Nvck91dHB1dFN0cmVhbVByb3ZpZGVycygpLmdldCh0b0tleShuYW1lKSk7CisgICAgICAgIGlmIChjb21wcmVzc29yU3RyZWFtUHJvdmlkZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGNvbXByZXNzb3JTdHJlYW1Qcm92aWRlci5jcmVhdGVDb21wcmVzc29yT3V0cHV0U3RyZWFtKG5hbWUsIG91dCk7CisgICAgICAgIH0KKyAgICAgICAgdGhyb3cgbmV3IENvbXByZXNzb3JFeGNlcHRpb24oIkNvbXByZXNzb3I6ICIgKyBuYW1lICsgIiBub3QgZm91bmQuIik7CisgICAgfQorCisgICAgcHVibGljIFNvcnRlZE1hcDxTdHJpbmcsIENvbXByZXNzb3JTdHJlYW1Qcm92aWRlcj4gZ2V0Q29tcHJlc3NvcklucHV0U3RyZWFtUHJvdmlkZXJzKCkgeworICAgICAgICBpZiAoY29tcHJlc3NvcklucHV0U3RyZWFtUHJvdmlkZXJzID09IG51bGwpIHsKKyAgICAgICAgICAgIGNvbXByZXNzb3JJbnB1dFN0cmVhbVByb3ZpZGVycyA9IENvbGxlY3Rpb25zCisgICAgICAgICAgICAgICAgICAgIC51bm1vZGlmaWFibGVTb3J0ZWRNYXAoZmluZEF2YWlsYWJsZUNvbXByZXNzb3JJbnB1dFN0cmVhbVByb3ZpZGVycygpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY29tcHJlc3NvcklucHV0U3RyZWFtUHJvdmlkZXJzOworICAgIH0KKworICAgIHB1YmxpYyBTb3J0ZWRNYXA8U3RyaW5nLCBDb21wcmVzc29yU3RyZWFtUHJvdmlkZXI+IGdldENvbXByZXNzb3JPdXRwdXRTdHJlYW1Qcm92aWRlcnMoKSB7CisgICAgICAgIGlmIChjb21wcmVzc29yT3V0cHV0U3RyZWFtUHJvdmlkZXJzID09IG51bGwpIHsKKyAgICAgICAgICAgIGNvbXByZXNzb3JPdXRwdXRTdHJlYW1Qcm92aWRlcnMgPSBDb2xsZWN0aW9ucworICAgICAgICAgICAgICAgICAgICAudW5tb2RpZmlhYmxlU29ydGVkTWFwKGZpbmRBdmFpbGFibGVDb21wcmVzc29yT3V0cHV0U3RyZWFtUHJvdmlkZXJzKCkpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBjb21wcmVzc29yT3V0cHV0U3RyZWFtUHJvdmlkZXJzOworICAgIH0KKworICAgIC8vIEZvciBVbml0IHRlc3RzCisgICAgYm9vbGVhbiBnZXREZWNvbXByZXNzQ29uY2F0ZW5hdGVkKCkgeworICAgICAgICByZXR1cm4gZGVjb21wcmVzc0NvbmNhdGVuYXRlZDsKKyAgICB9CisKKyAgICBwdWJsaWMgQm9vbGVhbiBnZXREZWNvbXByZXNzVW50aWxFT0YoKSB7CisgICAgICAgIHJldHVybiBkZWNvbXByZXNzVW50aWxFT0Y7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNldDxTdHJpbmc+IGdldElucHV0U3RyZWFtQ29tcHJlc3Nvck5hbWVzKCkgeworICAgICAgICByZXR1cm4gU2V0cy5uZXdIYXNoU2V0KEdaSVAsIEJST1RMSSwgQlpJUDIsIFhaLCBMWk1BLCBQQUNLMjAwLCBERUZMQVRFLCBTTkFQUFlfUkFXLCBTTkFQUFlfRlJBTUVELCBaLCBMWjRfQkxPQ0ssCisgICAgICAgICAgICBMWjRfRlJBTUVELCBaU1RBTkRBUkQsIERFRkxBVEU2NCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNldDxTdHJpbmc+IGdldE91dHB1dFN0cmVhbUNvbXByZXNzb3JOYW1lcygpIHsKKyAgICAgICAgcmV0dXJuIFNldHMubmV3SGFzaFNldChHWklQLCBCWklQMiwgWFosIExaTUEsIFBBQ0syMDAsIERFRkxBVEUsIFNOQVBQWV9GUkFNRUQsIExaNF9CTE9DSywgTFo0X0ZSQU1FRCwgWlNUQU5EQVJEKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXaGV0aGVyIHRvIGRlY29tcHJlc3MgdGhlIGZ1bGwgaW5wdXQgb3Igb25seSB0aGUgZmlyc3Qgc3RyZWFtIGluIGZvcm1hdHMKKyAgICAgKiBzdXBwb3J0aW5nIG11bHRpcGxlIGNvbmNhdGVuYXRlZCBpbnB1dCBzdHJlYW1zLgorICAgICAqCisgICAgICogPHA+CisgICAgICogVGhpcyBzZXR0aW5nIGFwcGxpZXMgdG8gdGhlIGd6aXAsIGJ6aXAyIGFuZCB4eiBmb3JtYXRzIG9ubHkuCisgICAgICogPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGRlY29tcHJlc3NDb25jYXRlbmF0ZWQKKyAgICAgKiAgICAgICAgICAgIGlmIHRydWUsIGRlY29tcHJlc3MgdW50aWwgdGhlIGVuZCBvZiB0aGUgaW5wdXQ7IGlmIGZhbHNlLCBzdG9wCisgICAgICogICAgICAgICAgICBhZnRlciB0aGUgZmlyc3Qgc3RyZWFtIGFuZCBsZWF2ZSB0aGUgaW5wdXQgcG9zaXRpb24gdG8gcG9pbnQKKyAgICAgKiAgICAgICAgICAgIHRvIHRoZSBuZXh0IGJ5dGUgYWZ0ZXIgdGhlIHN0cmVhbQorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKiBAZGVwcmVjYXRlZCAxLjEwIHVzZSB0aGUge0BsaW5rICNDb21wcmVzc29yU3RyZWFtRmFjdG9yeShib29sZWFuKX0KKyAgICAgKiAgICAgICAgICAgICBjb25zdHJ1Y3RvciBpbnN0ZWFkCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY29uc3RydWN0b3Ige0BsaW5rICNDb21wcmVzc29yU3RyZWFtRmFjdG9yeShib29sZWFuKX0KKyAgICAgKiAgICAgICAgICAgICB3YXMgdXNlZCB0byBjcmVhdGUgdGhlIGZhY3RvcnkKKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyB2b2lkIHNldERlY29tcHJlc3NDb25jYXRlbmF0ZWQoZmluYWwgYm9vbGVhbiBkZWNvbXByZXNzQ29uY2F0ZW5hdGVkKSB7CisgICAgICAgIGlmICh0aGlzLmRlY29tcHJlc3NVbnRpbEVPRiAhPSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJDYW5ub3Qgb3ZlcnJpZGUgdGhlIHNldHRpbmcgZGVmaW5lZCBieSB0aGUgY29uc3RydWN0b3IiKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmRlY29tcHJlc3NDb25jYXRlbmF0ZWQgPSBkZWNvbXByZXNzQ29uY2F0ZW5hdGVkOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvQ29tcHJlc3NvclN0cmVhbVByb3ZpZGVyLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9Db21wcmVzc29yU3RyZWFtUHJvdmlkZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iMGM4NDMxCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvQ29tcHJlc3NvclN0cmVhbVByb3ZpZGVyLmphdmEKQEAgLTAsMCArMSwxMDMgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29yczsKKworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLlNldDsKKworLyoqCisgKiBDcmVhdGVzIENvbXByZXNzb3Ige0BsaW5rIENvbXByZXNzb3JJbnB1dFN0cmVhbX1zIGFuZAorICoge0BsaW5rIENvbXByZXNzb3JPdXRwdXRTdHJlYW19cy4KKyAqCisgKiBAc2luY2UgMS4xMworICovCitwdWJsaWMgaW50ZXJmYWNlIENvbXByZXNzb3JTdHJlYW1Qcm92aWRlciB7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgY29tcHJlc3NvciBpbnB1dCBzdHJlYW0gZnJvbSBhIGNvbXByZXNzb3IgbmFtZSBhbmQgYW4gaW5wdXQKKyAgICAgKiBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgb2YgdGhlIGNvbXByZXNzb3IsIGkuZS4KKyAgICAgKiAgICAgICAgICAgIHtAdmFsdWUgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLkNvbXByZXNzb3JTdHJlYW1GYWN0b3J5I0daSVB9LAorICAgICAqICAgICAgICAgICAge0B2YWx1ZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkjQlpJUDJ9LAorICAgICAqICAgICAgICAgICAge0B2YWx1ZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkjWFp9LAorICAgICAqICAgICAgICAgICAge0B2YWx1ZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkjTFpNQX0sCisgICAgICogICAgICAgICAgICB7QHZhbHVlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5Db21wcmVzc29yU3RyZWFtRmFjdG9yeSNQQUNLMjAwfSwKKyAgICAgKiAgICAgICAgICAgIHtAdmFsdWUgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLkNvbXByZXNzb3JTdHJlYW1GYWN0b3J5I1NOQVBQWV9SQVd9LAorICAgICAqICAgICAgICAgICAge0B2YWx1ZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkjU05BUFBZX0ZSQU1FRH0sCisgICAgICogICAgICAgICAgICB7QHZhbHVlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5Db21wcmVzc29yU3RyZWFtRmFjdG9yeSNafQorICAgICAqICAgICAgICAgICAgb3IKKyAgICAgKiAgICAgICAgICAgIHtAdmFsdWUgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLkNvbXByZXNzb3JTdHJlYW1GYWN0b3J5I0RFRkxBVEV9CisgICAgICogQHBhcmFtIGluCisgICAgICogICAgICAgICAgICB0aGUgaW5wdXQgc3RyZWFtCisgICAgICogQHBhcmFtIGRlY29tcHJlc3NVbnRpbEVPRgorICAgICAqICAgICAgICAgICAgaWYgdHJ1ZSwgZGVjb21wcmVzcyB1bnRpbCB0aGUgZW5kIG9mIHRoZSBpbnB1dDsgaWYgZmFsc2UsIHN0b3AKKyAgICAgKiAgICAgICAgICAgIGFmdGVyIHRoZSBmaXJzdCBzdHJlYW0gYW5kIGxlYXZlIHRoZSBpbnB1dCBwb3NpdGlvbiB0byBwb2ludAorICAgICAqICAgICAgICAgICAgdG8gdGhlIG5leHQgYnl0ZSBhZnRlciB0aGUgc3RyZWFtLiBUaGlzIHNldHRpbmcgYXBwbGllcyB0byB0aGUKKyAgICAgKiAgICAgICAgICAgIGd6aXAsIGJ6aXAyIGFuZCB4eiBmb3JtYXRzIG9ubHkuCisgICAgICogQHJldHVybiBjb21wcmVzc29yIGlucHV0IHN0cmVhbQorICAgICAqIEB0aHJvd3MgQ29tcHJlc3NvckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBjb21wcmVzc29yIG5hbWUgaXMgbm90IGtub3duCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgbmFtZSBvciBpbnB1dCBzdHJlYW0gaXMgbnVsbAorICAgICAqLworICAgIENvbXByZXNzb3JJbnB1dFN0cmVhbSBjcmVhdGVDb21wcmVzc29ySW5wdXRTdHJlYW0oZmluYWwgU3RyaW5nIG5hbWUsIGZpbmFsIElucHV0U3RyZWFtIGluLAorICAgICAgICAgICAgZmluYWwgYm9vbGVhbiBkZWNvbXByZXNzVW50aWxFT0YpIHRocm93cyBDb21wcmVzc29yRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIGNvbXByZXNzb3Igb3V0cHV0IHN0cmVhbSBmcm9tIGFuIGNvbXByZXNzb3IgbmFtZSBhbmQgYW4gb3V0cHV0CisgICAgICogc3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBjb21wcmVzc29yIG5hbWUsIGkuZS4KKyAgICAgKiAgICAgICAgICAgIHtAdmFsdWUgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLkNvbXByZXNzb3JTdHJlYW1GYWN0b3J5I0daSVB9LAorICAgICAqICAgICAgICAgICAge0B2YWx1ZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkjQlpJUDJ9LAorICAgICAqICAgICAgICAgICAge0B2YWx1ZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkjWFp9LAorICAgICAqICAgICAgICAgICAge0B2YWx1ZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkjUEFDSzIwMH0KKyAgICAgKiAgICAgICAgICAgIG9yCisgICAgICogICAgICAgICAgICB7QHZhbHVlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5Db21wcmVzc29yU3RyZWFtRmFjdG9yeSNERUZMQVRFfQorICAgICAqIEBwYXJhbSBvdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBvdXRwdXQgc3RyZWFtCisgICAgICogQHJldHVybiB0aGUgY29tcHJlc3NvciBvdXRwdXQgc3RyZWFtCisgICAgICogQHRocm93cyBDb21wcmVzc29yRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGFyY2hpdmVyIG5hbWUgaXMgbm90IGtub3duCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgYXJjaGl2ZXIgbmFtZSBvciBzdHJlYW0gaXMgbnVsbAorICAgICAqLworICAgIENvbXByZXNzb3JPdXRwdXRTdHJlYW0gY3JlYXRlQ29tcHJlc3Nvck91dHB1dFN0cmVhbShmaW5hbCBTdHJpbmcgbmFtZSwgZmluYWwgT3V0cHV0U3RyZWFtIG91dCkKKyAgICAgICAgICAgIHRocm93cyBDb21wcmVzc29yRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyBhbGwgdGhlIGlucHV0IHN0cmVhbSBjb21wcmVzc29yIG5hbWVzIGZvciB0aGlzIHByb3ZpZGVyCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFsbCB0aGUgaW5wdXQgY29tcHJlc3NvciBuYW1lcyBmb3IgdGhpcyBwcm92aWRlcgorICAgICAqLworICAgIFNldDxTdHJpbmc+IGdldElucHV0U3RyZWFtQ29tcHJlc3Nvck5hbWVzKCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGFsbCB0aGUgb3V0cHV0IHN0cmVhbSBjb21wcmVzc29yIG5hbWVzIGZvciB0aGlzIHByb3ZpZGVyCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFsbCB0aGUgb3V0cHV0IGNvbXByZXNzb3IgbmFtZXMgZm9yIHRoaXMgcHJvdmlkZXIKKyAgICAgKi8KKyAgICBTZXQ8U3RyaW5nPiBnZXRPdXRwdXRTdHJlYW1Db21wcmVzc29yTmFtZXMoKTsKKworfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvRmlsZU5hbWVVdGlsLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9GaWxlTmFtZVV0aWwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mOTdiYjhlCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvRmlsZU5hbWVVdGlsLmphdmEKQEAgLTAsMCArMSwxOTYgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnM7CisKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworCisvKioKKyAqIEZpbGUgbmFtZSBtYXBwaW5nIGNvZGUgZm9yIHRoZSBjb21wcmVzc2lvbiBmb3JtYXRzLgorICogQFRocmVhZFNhZmUKKyAqIEBzaW5jZSAxLjQKKyAqLworcHVibGljIGNsYXNzIEZpbGVOYW1lVXRpbCB7CisKKyAgICAvKioKKyAgICAgKiBNYXAgZnJvbSBjb21tb24gZmlsZW5hbWUgc3VmZml4ZXMgdG8gdGhlIHN1ZmZpeGVzIHRoYXQgaWRlbnRpZnkgY29tcHJlc3NlZAorICAgICAqIHZlcnNpb25zIG9mIHRob3NlIGZpbGUgdHlwZXMuIEZvciBleGFtcGxlOiBmcm9tICIudGFyIiB0byAiLnRneiIuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBNYXA8U3RyaW5nLCBTdHJpbmc+IGNvbXByZXNzU3VmZml4ID0KKyAgICAgICAgbmV3IEhhc2hNYXA8PigpOworCisgICAgLyoqCisgICAgICogTWFwIGZyb20gY29tbW9uIGZpbGVuYW1lIHN1ZmZpeGVzIG9mIGNvbXByZXNzZWQgZmlsZXMgdG8gdGhlCisgICAgICogY29ycmVzcG9uZGluZyBzdWZmaXhlcyBvZiB1bmNvbXByZXNzZWQgZmlsZXMuIEZvciBleGFtcGxlOiBmcm9tCisgICAgICogIi50Z3oiIHRvICIudGFyIi4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIG1hcCBhbHNvIGNvbnRhaW5zIGZvcm1hdC1zcGVjaWZpYyBzdWZmaXhlcyBsaWtlICIuZ3oiIGFuZCAiLXoiLgorICAgICAqIFRoZXNlIHN1ZmZpeGVzIGFyZSBtYXBwZWQgdG8gdGhlIGVtcHR5IHN0cmluZywgYXMgdGhleSBzaG91bGQgc2ltcGx5CisgICAgICogYmUgcmVtb3ZlZCBmcm9tIHRoZSBmaWxlbmFtZSB3aGVuIHRoZSBmaWxlIGlzIHVuY29tcHJlc3NlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIE1hcDxTdHJpbmcsIFN0cmluZz4gdW5jb21wcmVzc1N1ZmZpeDsKKworICAgIC8qKgorICAgICAqIExlbmd0aCBvZiB0aGUgbG9uZ2VzdCBjb21wcmVzc2VkIHN1ZmZpeC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIGludCBsb25nZXN0Q29tcHJlc3NlZFN1ZmZpeDsKKworICAgIC8qKgorICAgICAqIExlbmd0aCBvZiB0aGUgc2hvcnRlc3QgY29tcHJlc3NlZCBzdWZmaXguCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgc2hvcnRlc3RDb21wcmVzc2VkU3VmZml4OworCisgICAgLyoqCisgICAgICogTGVuZ3RoIG9mIHRoZSBsb25nZXN0IHVuY29tcHJlc3NlZCBzdWZmaXguCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgbG9uZ2VzdFVuY29tcHJlc3NlZFN1ZmZpeDsKKworICAgIC8qKgorICAgICAqIExlbmd0aCBvZiB0aGUgc2hvcnRlc3QgdW5jb21wcmVzc2VkIHN1ZmZpeCBsb25nZXIgdGhhbiB0aGUKKyAgICAgKiBlbXB0eSBzdHJpbmcuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgc2hvcnRlc3RVbmNvbXByZXNzZWRTdWZmaXg7CisKKyAgICAvKioKKyAgICAgKiBUaGUgZm9ybWF0J3MgZGVmYXVsdCBleHRlbnNpb24uCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgZGVmYXVsdEV4dGVuc2lvbjsKKworICAgIC8qKgorICAgICAqIHNldHMgdXAgdGhlIHV0aWxpdHkgd2l0aCBhIG1hcCBvZiBrbm93biBjb21wcmVzc2VkIHRvCisgICAgICogdW5jb21wcmVzc2VkIHN1ZmZpeCBtYXBwaW5ncyBhbmQgdGhlIGRlZmF1bHQgZXh0ZW5zaW9uIG9mIHRoZQorICAgICAqIGZvcm1hdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB1bmNvbXByZXNzU3VmZml4IE1hcCBmcm9tIGNvbW1vbiBmaWxlbmFtZSBzdWZmaXhlcyBvZgorICAgICAqIGNvbXByZXNzZWQgZmlsZXMgdG8gdGhlIGNvcnJlc3BvbmRpbmcgc3VmZml4ZXMgb2YgdW5jb21wcmVzc2VkCisgICAgICogZmlsZXMuIEZvciBleGFtcGxlOiBmcm9tICIudGd6IiB0byAiLnRhciIuICBUaGlzIG1hcCBhbHNvCisgICAgICogY29udGFpbnMgZm9ybWF0LXNwZWNpZmljIHN1ZmZpeGVzIGxpa2UgIi5neiIgYW5kICIteiIuICBUaGVzZQorICAgICAqIHN1ZmZpeGVzIGFyZSBtYXBwZWQgdG8gdGhlIGVtcHR5IHN0cmluZywgYXMgdGhleSBzaG91bGQgc2ltcGx5CisgICAgICogYmUgcmVtb3ZlZCBmcm9tIHRoZSBmaWxlbmFtZSB3aGVuIHRoZSBmaWxlIGlzIHVuY29tcHJlc3NlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZWZhdWx0RXh0ZW5zaW9uIHRoZSBmb3JtYXQncyBkZWZhdWx0IGV4dGVuc2lvbiBsaWtlICIuZ3oiCisgICAgICovCisgICAgcHVibGljIEZpbGVOYW1lVXRpbChmaW5hbCBNYXA8U3RyaW5nLCBTdHJpbmc+IHVuY29tcHJlc3NTdWZmaXgsCisgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgZGVmYXVsdEV4dGVuc2lvbikgeworICAgICAgICB0aGlzLnVuY29tcHJlc3NTdWZmaXggPSBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVNYXAodW5jb21wcmVzc1N1ZmZpeCk7CisgICAgICAgIGludCBsYyA9IEludGVnZXIuTUlOX1ZBTFVFLCBzYyA9IEludGVnZXIuTUFYX1ZBTFVFOworICAgICAgICBpbnQgbHUgPSBJbnRlZ2VyLk1JTl9WQUxVRSwgc3UgPSBJbnRlZ2VyLk1BWF9WQUxVRTsKKyAgICAgICAgZm9yIChmaW5hbCBNYXAuRW50cnk8U3RyaW5nLCBTdHJpbmc+IGVudCA6IHVuY29tcHJlc3NTdWZmaXguZW50cnlTZXQoKSkgeworICAgICAgICAgICAgZmluYWwgaW50IGNsID0gZW50LmdldEtleSgpLmxlbmd0aCgpOworICAgICAgICAgICAgaWYgKGNsID4gbGMpIHsKKyAgICAgICAgICAgICAgICBsYyA9IGNsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGNsIDwgc2MpIHsKKyAgICAgICAgICAgICAgICBzYyA9IGNsOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBmaW5hbCBTdHJpbmcgdSA9IGVudC5nZXRWYWx1ZSgpOworICAgICAgICAgICAgZmluYWwgaW50IHVsID0gdS5sZW5ndGgoKTsKKyAgICAgICAgICAgIGlmICh1bCA+IDApIHsKKyAgICAgICAgICAgICAgICBpZiAoIWNvbXByZXNzU3VmZml4LmNvbnRhaW5zS2V5KHUpKSB7CisgICAgICAgICAgICAgICAgICAgIGNvbXByZXNzU3VmZml4LnB1dCh1LCBlbnQuZ2V0S2V5KCkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAodWwgPiBsdSkgeworICAgICAgICAgICAgICAgICAgICBsdSA9IHVsOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAodWwgPCBzdSkgeworICAgICAgICAgICAgICAgICAgICBzdSA9IHVsOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBsb25nZXN0Q29tcHJlc3NlZFN1ZmZpeCA9IGxjOworICAgICAgICBsb25nZXN0VW5jb21wcmVzc2VkU3VmZml4ID0gbHU7CisgICAgICAgIHNob3J0ZXN0Q29tcHJlc3NlZFN1ZmZpeCA9IHNjOworICAgICAgICBzaG9ydGVzdFVuY29tcHJlc3NlZFN1ZmZpeCA9IHN1OworICAgICAgICB0aGlzLmRlZmF1bHRFeHRlbnNpb24gPSBkZWZhdWx0RXh0ZW5zaW9uOworICAgIH0KKworICAgIC8qKgorICAgICAqIERldGVjdHMgY29tbW9uIGZvcm1hdCBzdWZmaXhlcyBpbiB0aGUgZ2l2ZW4gZmlsZW5hbWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmlsZW5hbWUgbmFtZSBvZiBhIGZpbGUKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgZmlsZW5hbWUgaGFzIGEgY29tbW9uIGZvcm1hdCBzdWZmaXgsCisgICAgICogICAgICAgICB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzQ29tcHJlc3NlZEZpbGVuYW1lKGZpbmFsIFN0cmluZyBmaWxlbmFtZSkgeworICAgICAgICBmaW5hbCBTdHJpbmcgbG93ZXIgPSBmaWxlbmFtZS50b0xvd2VyQ2FzZShMb2NhbGUuRU5HTElTSCk7CisgICAgICAgIGZpbmFsIGludCBuID0gbG93ZXIubGVuZ3RoKCk7CisgICAgICAgIGZvciAoaW50IGkgPSBzaG9ydGVzdENvbXByZXNzZWRTdWZmaXg7CisgICAgICAgICAgICAgaSA8PSBsb25nZXN0Q29tcHJlc3NlZFN1ZmZpeCAmJiBpIDwgbjsgaSsrKSB7CisgICAgICAgICAgICBpZiAodW5jb21wcmVzc1N1ZmZpeC5jb250YWluc0tleShsb3dlci5zdWJzdHJpbmcobiAtIGkpKSkgeworICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBNYXBzIHRoZSBnaXZlbiBuYW1lIG9mIGEgY29tcHJlc3NlZCBmaWxlIHRvIHRoZSBuYW1lIHRoYXQgdGhlCisgICAgICogZmlsZSBzaG91bGQgaGF2ZSBhZnRlciB1bmNvbXByZXNzaW9uLiBDb21tb25seSB1c2VkIGZpbGUgdHlwZSBzcGVjaWZpYworICAgICAqIHN1ZmZpeGVzIGxpa2UgIi50Z3oiIG9yICIuc3ZneiIgYXJlIGF1dG9tYXRpY2FsbHkgZGV0ZWN0ZWQgYW5kCisgICAgICogY29ycmVjdGx5IG1hcHBlZC4gRm9yIGV4YW1wbGUgdGhlIG5hbWUgInBhY2thZ2UudGd6IiBpcyBtYXBwZWQgdG8KKyAgICAgKiAicGFja2FnZS50YXIiLiBBbmQgYW55IGZpbGVuYW1lcyB3aXRoIHRoZSBnZW5lcmljICIuZ3oiIHN1ZmZpeAorICAgICAqIChvciBhbnkgb3RoZXIgZ2VuZXJpYyBnemlwIHN1ZmZpeCkgaXMgbWFwcGVkIHRvIGEgbmFtZSB3aXRob3V0IHRoYXQKKyAgICAgKiBzdWZmaXguIElmIG5vIGZvcm1hdCBzdWZmaXggaXMgZGV0ZWN0ZWQsIHRoZW4gdGhlIGZpbGVuYW1lIGlzIHJldHVybmVkCisgICAgICogdW5tYXBwZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmlsZW5hbWUgbmFtZSBvZiBhIGZpbGUKKyAgICAgKiBAcmV0dXJuIG5hbWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgdW5jb21wcmVzc2VkIGZpbGUKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFVuY29tcHJlc3NlZEZpbGVuYW1lKGZpbmFsIFN0cmluZyBmaWxlbmFtZSkgeworICAgICAgICBmaW5hbCBTdHJpbmcgbG93ZXIgPSBmaWxlbmFtZS50b0xvd2VyQ2FzZShMb2NhbGUuRU5HTElTSCk7CisgICAgICAgIGZpbmFsIGludCBuID0gbG93ZXIubGVuZ3RoKCk7CisgICAgICAgIGZvciAoaW50IGkgPSBzaG9ydGVzdENvbXByZXNzZWRTdWZmaXg7CisgICAgICAgICAgICAgaSA8PSBsb25nZXN0Q29tcHJlc3NlZFN1ZmZpeCAmJiBpIDwgbjsgaSsrKSB7CisgICAgICAgICAgICBmaW5hbCBTdHJpbmcgc3VmZml4ID0gdW5jb21wcmVzc1N1ZmZpeC5nZXQobG93ZXIuc3Vic3RyaW5nKG4gLSBpKSk7CisgICAgICAgICAgICBpZiAoc3VmZml4ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmlsZW5hbWUuc3Vic3RyaW5nKDAsIG4gLSBpKSArIHN1ZmZpeDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmlsZW5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogTWFwcyB0aGUgZ2l2ZW4gZmlsZW5hbWUgdG8gdGhlIG5hbWUgdGhhdCB0aGUgZmlsZSBzaG91bGQgaGF2ZSBhZnRlcgorICAgICAqIGNvbXByZXNzaW9uLiBDb21tb24gZmlsZSB0eXBlcyB3aXRoIGN1c3RvbSBzdWZmaXhlcyBmb3IKKyAgICAgKiBjb21wcmVzc2VkIHZlcnNpb25zIGFyZSBhdXRvbWF0aWNhbGx5IGRldGVjdGVkIGFuZCBjb3JyZWN0bHkgbWFwcGVkLgorICAgICAqIEZvciBleGFtcGxlIHRoZSBuYW1lICJwYWNrYWdlLnRhciIgaXMgbWFwcGVkIHRvICJwYWNrYWdlLnRneiIuIElmIG5vCisgICAgICogY3VzdG9tIG1hcHBpbmcgaXMgYXBwbGljYWJsZSwgdGhlbiB0aGUgZGVmYXVsdCAiLmd6IiBzdWZmaXggaXMgYXBwZW5kZWQKKyAgICAgKiB0byB0aGUgZmlsZW5hbWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmlsZW5hbWUgbmFtZSBvZiBhIGZpbGUKKyAgICAgKiBAcmV0dXJuIG5hbWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgY29tcHJlc3NlZCBmaWxlCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRDb21wcmVzc2VkRmlsZW5hbWUoZmluYWwgU3RyaW5nIGZpbGVuYW1lKSB7CisgICAgICAgIGZpbmFsIFN0cmluZyBsb3dlciA9IGZpbGVuYW1lLnRvTG93ZXJDYXNlKExvY2FsZS5FTkdMSVNIKTsKKyAgICAgICAgZmluYWwgaW50IG4gPSBsb3dlci5sZW5ndGgoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IHNob3J0ZXN0VW5jb21wcmVzc2VkU3VmZml4OworICAgICAgICAgICAgIGkgPD0gbG9uZ2VzdFVuY29tcHJlc3NlZFN1ZmZpeCAmJiBpIDwgbjsgaSsrKSB7CisgICAgICAgICAgICBmaW5hbCBTdHJpbmcgc3VmZml4ID0gY29tcHJlc3NTdWZmaXguZ2V0KGxvd2VyLnN1YnN0cmluZyhuIC0gaSkpOworICAgICAgICAgICAgaWYgKHN1ZmZpeCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZpbGVuYW1lLnN1YnN0cmluZygwLCBuIC0gaSkgKyBzdWZmaXg7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgLy8gTm8gY3VzdG9tIHN1ZmZpeCBmb3VuZCwganVzdCBhcHBlbmQgdGhlIGRlZmF1bHQKKyAgICAgICAgcmV0dXJuIGZpbGVuYW1lICsgZGVmYXVsdEV4dGVuc2lvbjsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2Jyb3RsaS9Ccm90bGlDb21wcmVzc29ySW5wdXRTdHJlYW0uamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2Jyb3RsaS9Ccm90bGlDb21wcmVzc29ySW5wdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41Njc0Y2IyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvYnJvdGxpL0Jyb3RsaUNvbXByZXNzb3JJbnB1dFN0cmVhbS5qYXZhCkBAIC0wLDAgKzEsMTA2IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLmJyb3RsaTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5Db21wcmVzc29ySW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLkNvdW50aW5nSW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLklPVXRpbHM7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLklucHV0U3RyZWFtU3RhdGlzdGljczsKK2ltcG9ydCBvcmcuYnJvdGxpLmRlYy5Ccm90bGlJbnB1dFN0cmVhbTsKKworLyoqCisgKiB7QGxpbmsgQ29tcHJlc3NvcklucHV0U3RyZWFtfSBpbXBsZW1lbnRhdGlvbiB0byBkZWNvZGUgQnJvdGxpIGVuY29kZWQgc3RyZWFtLgorICogTGlicmFyeSByZWxpZXMgb24gPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9icm90bGkiPkdvb2dsZSBicm90bGk8L2E+CisgKgorICogQHNpbmNlIDEuMTQKKyAqLworcHVibGljIGNsYXNzIEJyb3RsaUNvbXByZXNzb3JJbnB1dFN0cmVhbSBleHRlbmRzIENvbXByZXNzb3JJbnB1dFN0cmVhbQorICAgIGltcGxlbWVudHMgSW5wdXRTdHJlYW1TdGF0aXN0aWNzIHsKKworICAgIHByaXZhdGUgZmluYWwgQ291bnRpbmdJbnB1dFN0cmVhbSBjb3VudGluZ1N0cmVhbTsKKyAgICBwcml2YXRlIGZpbmFsIEJyb3RsaUlucHV0U3RyZWFtIGRlY0lTOworCisgICAgcHVibGljIEJyb3RsaUNvbXByZXNzb3JJbnB1dFN0cmVhbShmaW5hbCBJbnB1dFN0cmVhbSBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZGVjSVMgPSBuZXcgQnJvdGxpSW5wdXRTdHJlYW0oY291bnRpbmdTdHJlYW0gPSBuZXcgQ291bnRpbmdJbnB1dFN0cmVhbShpbikpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgYXZhaWxhYmxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGRlY0lTLmF2YWlsYWJsZSgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZGVjSVMuY2xvc2UoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHJlYWQoZmluYWwgYnl0ZVtdIGIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBkZWNJUy5yZWFkKGIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBsb25nIHNraXAoZmluYWwgbG9uZyBuKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gSU9VdGlscy5za2lwKGRlY0lTLCBuKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBtYXJrKGZpbmFsIGludCByZWFkbGltaXQpIHsKKyAgICAgICAgZGVjSVMubWFyayhyZWFkbGltaXQpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIG1hcmtTdXBwb3J0ZWQoKSB7CisgICAgICAgIHJldHVybiBkZWNJUy5tYXJrU3VwcG9ydGVkKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCByZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgaW50IHJldCA9IGRlY0lTLnJlYWQoKTsKKyAgICAgICAgY291bnQocmV0ID09IC0xID8gMCA6IDEpOworICAgICAgICByZXR1cm4gcmV0OworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZChmaW5hbCBieXRlW10gYnVmLCBmaW5hbCBpbnQgb2ZmLCBmaW5hbCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBpbnQgcmV0ID0gZGVjSVMucmVhZChidWYsIG9mZiwgbGVuKTsKKyAgICAgICAgY291bnQocmV0KTsKKyAgICAgICAgcmV0dXJuIHJldDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICByZXR1cm4gZGVjSVMudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCByZXNldCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGRlY0lTLnJlc2V0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNpbmNlIDEuMTcKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgbG9uZyBnZXRDb21wcmVzc2VkQ291bnQoKSB7CisgICAgICAgIHJldHVybiBjb3VudGluZ1N0cmVhbS5nZXRCeXRlc1JlYWQoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9icm90bGkvQnJvdGxpVXRpbHMuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2Jyb3RsaS9Ccm90bGlVdGlscy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE1YTIxMzkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9icm90bGkvQnJvdGxpVXRpbHMuamF2YQpAQCAtMCwwICsxLDg5IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLmJyb3RsaTsKKworLyoqCisgKiBVdGlsaXR5IGNvZGUgZm9yIHRoZSBCcm90bGkgY29tcHJlc3Npb24gZm9ybWF0LgorICogQFRocmVhZFNhZmUKKyAqIEBzaW5jZSAxLjE0CisgKi8KK3B1YmxpYyBjbGFzcyBCcm90bGlVdGlscyB7CisKKyAgICBlbnVtIENhY2hlZEF2YWlsYWJpbGl0eSB7CisgICAgICAgIERPTlRfQ0FDSEUsIENBQ0hFRF9BVkFJTEFCTEUsIENBQ0hFRF9VTkFWQUlMQUJMRQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvbGF0aWxlIENhY2hlZEF2YWlsYWJpbGl0eSBjYWNoZWRCcm90bGlBdmFpbGFiaWxpdHk7CisKKyAgICBzdGF0aWMgeworICAgICAgICBjYWNoZWRCcm90bGlBdmFpbGFiaWxpdHkgPSBDYWNoZWRBdmFpbGFiaWxpdHkuRE9OVF9DQUNIRTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENsYXNzLmZvck5hbWUoIm9yZy5vc2dpLmZyYW1ld29yay5CdW5kbGVFdmVudCIpOworICAgICAgICB9IGNhdGNoIChmaW5hbCBFeGNlcHRpb24gZXgpIHsgLy8gTk9TT05BUgorICAgICAgICAgICAgc2V0Q2FjaGVCcm90bGlBdmFpbGFibGl0eSh0cnVlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKiBQcml2YXRlIGNvbnN0cnVjdG9yIHRvIHByZXZlbnQgaW5zdGFudGlhdGlvbiBvZiB0aGlzIHV0aWxpdHkgY2xhc3MuICovCisgICAgcHJpdmF0ZSBCcm90bGlVdGlscygpIHsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIEFyZSB0aGUgY2xhc3NlcyByZXF1aXJlZCB0byBzdXBwb3J0IEJyb3RsaSBjb21wcmVzc2lvbiBhdmFpbGFibGU/CisgICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBjbGFzc2VzIHJlcXVpcmVkIHRvIHN1cHBvcnQgQnJvdGxpIGNvbXByZXNzaW9uIGFyZSBhdmFpbGFibGUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNCcm90bGlDb21wcmVzc2lvbkF2YWlsYWJsZSgpIHsKKyAgICAgICAgZmluYWwgQ2FjaGVkQXZhaWxhYmlsaXR5IGNhY2hlZFJlc3VsdCA9IGNhY2hlZEJyb3RsaUF2YWlsYWJpbGl0eTsKKyAgICAgICAgaWYgKGNhY2hlZFJlc3VsdCAhPSBDYWNoZWRBdmFpbGFiaWxpdHkuRE9OVF9DQUNIRSkgeworICAgICAgICAgICAgcmV0dXJuIGNhY2hlZFJlc3VsdCA9PSBDYWNoZWRBdmFpbGFiaWxpdHkuQ0FDSEVEX0FWQUlMQUJMRTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaW50ZXJuYWxJc0Jyb3RsaUNvbXByZXNzaW9uQXZhaWxhYmxlKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpbnRlcm5hbElzQnJvdGxpQ29tcHJlc3Npb25BdmFpbGFibGUoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDbGFzcy5mb3JOYW1lKCJvcmcuYnJvdGxpLmRlYy5Ccm90bGlJbnB1dFN0cmVhbSIpOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0gY2F0Y2ggKE5vQ2xhc3NEZWZGb3VuZEVycm9yIHwgRXhjZXB0aW9uIGVycm9yKSB7IC8vIE5PU09OQVIKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFdoZXRoZXIgdG8gY2FjaGUgdGhlIHJlc3VsdCBvZiB0aGUgQnJvdGxpIGZvciBKYXZhIGNoZWNrLgorICAgICAqCisgICAgICogPHA+VGhpcyBkZWZhdWx0cyB0byB7QGNvZGUgZmFsc2V9IGluIGFuIE9TR2kgZW52aXJvbm1lbnQgYW5kIHtAY29kZSB0cnVlfSBvdGhlcndpc2UuPC9wPgorICAgICAqIEBwYXJhbSBkb0NhY2hlIHdoZXRoZXIgdG8gY2FjaGUgdGhlIHJlc3VsdAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXRDYWNoZUJyb3RsaUF2YWlsYWJsaXR5KGZpbmFsIGJvb2xlYW4gZG9DYWNoZSkgeworICAgICAgICBpZiAoIWRvQ2FjaGUpIHsKKyAgICAgICAgICAgIGNhY2hlZEJyb3RsaUF2YWlsYWJpbGl0eSA9IENhY2hlZEF2YWlsYWJpbGl0eS5ET05UX0NBQ0hFOworICAgICAgICB9IGVsc2UgaWYgKGNhY2hlZEJyb3RsaUF2YWlsYWJpbGl0eSA9PSBDYWNoZWRBdmFpbGFiaWxpdHkuRE9OVF9DQUNIRSkgeworICAgICAgICAgICAgZmluYWwgYm9vbGVhbiBoYXNCcm90bGkgPSBpbnRlcm5hbElzQnJvdGxpQ29tcHJlc3Npb25BdmFpbGFibGUoKTsKKyAgICAgICAgICAgIGNhY2hlZEJyb3RsaUF2YWlsYWJpbGl0eSA9IGhhc0Jyb3RsaSA/IENhY2hlZEF2YWlsYWJpbGl0eS5DQUNIRURfQVZBSUxBQkxFCisgICAgICAgICAgICAgICAgOiBDYWNoZWRBdmFpbGFiaWxpdHkuQ0FDSEVEX1VOQVZBSUxBQkxFOworICAgICAgICB9CisgICAgfQorCisgICAgLy8gb25seSBleGlzdHMgdG8gc3VwcG9ydCB1bml0IHRlc3RzCisgICAgc3RhdGljIENhY2hlZEF2YWlsYWJpbGl0eSBnZXRDYWNoZWRCcm90bGlBdmFpbGFiaWxpdHkoKSB7CisgICAgICAgIHJldHVybiBjYWNoZWRCcm90bGlBdmFpbGFiaWxpdHk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvYnJvdGxpL3BhY2thZ2UuaHRtbCBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2Jyb3RsaS9wYWNrYWdlLmh0bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzY1NGNmNgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2Jyb3RsaS9wYWNrYWdlLmh0bWwKQEAgLTAsMCArMSwyNiBAQAorPGh0bWw+Cis8IS0tCisKKyAgIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAgIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisKKyAgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKworICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAgIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisKKy0tPgorICA8Ym9keT4KKyAgICA8cD5Qcm92aWRlcyBzdHJlYW0gY2xhc3MgZm9yIGRlY29tcHJlc3Npbmcgc3RyZWFtcyB1c2luZyB0aGUKKyAgICAgIEJyb3RsaSBhbGdvcml0aG0gYmFzZWQKKyAgICAgIG9uIDxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvYnJvdGxpIj5Hb29nbGUncyBCcm90bGkKKyAgICAgIGRlY29kZXI8L2E+LjwvcD4KKyAgPC9ib2R5PgorPC9odG1sPgpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvYnppcDIvQlppcDJDb21wcmVzc29ySW5wdXRTdHJlYW0uamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2J6aXAyL0JaaXAyQ29tcHJlc3NvcklucHV0U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjc3YmJiZAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2J6aXAyL0JaaXAyQ29tcHJlc3NvcklucHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSw5NzAgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKgorICogVGhpcyBwYWNrYWdlIGlzIGJhc2VkIG9uIHRoZSB3b3JrIGRvbmUgYnkgS2Vpcm9uIExpZGRsZSwgQWZ0ZXggU29mdHdhcmUKKyAqIDxrZWlyb25AYWZ0ZXhzdy5jb20+IHRvIHdob20gdGhlIEFudCBwcm9qZWN0IGlzIHZlcnkgZ3JhdGVmdWwgZm9yIGhpcworICogZ3JlYXQgY29kZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuYnppcDI7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5uaW8uQnl0ZU9yZGVyOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuQ29tcHJlc3NvcklucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5CaXRJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuQ2xvc2VTaGllbGRGaWx0ZXJJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuSW5wdXRTdHJlYW1TdGF0aXN0aWNzOworCisvKioKKyAqIEFuIGlucHV0IHN0cmVhbSB0aGF0IGRlY29tcHJlc3NlcyBmcm9tIHRoZSBCWmlwMiBmb3JtYXQgdG8gYmUgcmVhZCBhcyBhbnkgb3RoZXIgc3RyZWFtLgorICoKKyAqIEBOb3RUaHJlYWRTYWZlCisgKi8KK3B1YmxpYyBjbGFzcyBCWmlwMkNvbXByZXNzb3JJbnB1dFN0cmVhbSBleHRlbmRzIENvbXByZXNzb3JJbnB1dFN0cmVhbQorICAgIGltcGxlbWVudHMgQlppcDJDb25zdGFudHMsIElucHV0U3RyZWFtU3RhdGlzdGljcyB7CisKKyAgICAvKioKKyAgICAgKiBJbmRleCBvZiB0aGUgbGFzdCBjaGFyIGluIHRoZSBibG9jaywgc28gdGhlIGJsb2NrIHNpemUgPT0gbGFzdCArIDEuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgbGFzdDsKKworICAgIC8qKgorICAgICAqIEluZGV4IGluIHpwdHJbXSBvZiBvcmlnaW5hbCBzdHJpbmcgYWZ0ZXIgc29ydGluZy4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBvcmlnUHRyOworCisgICAgLyoqCisgICAgICogYWx3YXlzOiBpbiB0aGUgcmFuZ2UgMCAuLiA5LiBUaGUgY3VycmVudCBibG9jayBzaXplIGlzIDEwMDAwMCAqIHRoaXMKKyAgICAgKiBudW1iZXIuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgYmxvY2tTaXplMTAwazsKKworICAgIHByaXZhdGUgYm9vbGVhbiBibG9ja1JhbmRvbWlzZWQ7CisKKyAgICBwcml2YXRlIGZpbmFsIENSQyBjcmMgPSBuZXcgQ1JDKCk7CisKKyAgICBwcml2YXRlIGludCBuSW5Vc2U7CisKKyAgICBwcml2YXRlIEJpdElucHV0U3RyZWFtIGJpbjsKKyAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gZGVjb21wcmVzc0NvbmNhdGVuYXRlZDsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBFT0YgPSAwOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBTVEFSVF9CTE9DS19TVEFURSA9IDE7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFJBTkRfUEFSVF9BX1NUQVRFID0gMjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgUkFORF9QQVJUX0JfU1RBVEUgPSAzOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBSQU5EX1BBUlRfQ19TVEFURSA9IDQ7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE5PX1JBTkRfUEFSVF9BX1NUQVRFID0gNTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTk9fUkFORF9QQVJUX0JfU1RBVEUgPSA2OworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBOT19SQU5EX1BBUlRfQ19TVEFURSA9IDc7CisKKyAgICBwcml2YXRlIGludCBjdXJyZW50U3RhdGUgPSBTVEFSVF9CTE9DS19TVEFURTsKKworICAgIHByaXZhdGUgaW50IHN0b3JlZEJsb2NrQ1JDLCBzdG9yZWRDb21iaW5lZENSQzsKKyAgICBwcml2YXRlIGludCBjb21wdXRlZEJsb2NrQ1JDLCBjb21wdXRlZENvbWJpbmVkQ1JDOworCisgICAgLy8gVmFyaWFibGVzIHVzZWQgYnkgc2V0dXAqIG1ldGhvZHMgZXhjbHVzaXZlbHkKKworICAgIHByaXZhdGUgaW50IHN1X2NvdW50OworICAgIHByaXZhdGUgaW50IHN1X2NoMjsKKyAgICBwcml2YXRlIGludCBzdV9jaFByZXY7CisgICAgcHJpdmF0ZSBpbnQgc3VfaTI7CisgICAgcHJpdmF0ZSBpbnQgc3VfajI7CisgICAgcHJpdmF0ZSBpbnQgc3Vfck5Ub0dvOworICAgIHByaXZhdGUgaW50IHN1X3JUUG9zOworICAgIHByaXZhdGUgaW50IHN1X3RQb3M7CisgICAgcHJpdmF0ZSBjaGFyIHN1X3o7CisKKyAgICAvKioKKyAgICAgKiBBbGwgbWVtb3J5IGludGVuc2l2ZSBzdHVmZi4gVGhpcyBmaWVsZCBpcyBpbml0aWFsaXplZCBieSBpbml0QmxvY2soKS4KKyAgICAgKi8KKyAgICBwcml2YXRlIEJaaXAyQ29tcHJlc3NvcklucHV0U3RyZWFtLkRhdGEgZGF0YTsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgQlppcDJDb21wcmVzc29ySW5wdXRTdHJlYW0gd2hpY2ggZGVjb21wcmVzc2VzIGJ5dGVzCisgICAgICogcmVhZCBmcm9tIHRoZSBzcGVjaWZpZWQgc3RyZWFtLiBUaGlzIGRvZXNuJ3Qgc3VwcHBydCBkZWNvbXByZXNzaW5nCisgICAgICogY29uY2F0ZW5hdGVkIC5iejIgZmlsZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW4gdGhlIElucHV0U3RyZWFtIGZyb20gd2hpY2ggdGhpcyBvYmplY3Qgc2hvdWxkIGJlIGNyZWF0ZWQKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHN0cmVhbSBjb250ZW50IGlzIG1hbGZvcm1lZCBvciBhbiBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgaW4gPT0gbnVsbH0KKyAgICAgKi8KKyAgICBwdWJsaWMgQlppcDJDb21wcmVzc29ySW5wdXRTdHJlYW0oZmluYWwgSW5wdXRTdHJlYW0gaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMoaW4sIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IEJaaXAyQ29tcHJlc3NvcklucHV0U3RyZWFtIHdoaWNoIGRlY29tcHJlc3NlcyBieXRlcworICAgICAqIHJlYWQgZnJvbSB0aGUgc3BlY2lmaWVkIHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbiB0aGUgSW5wdXRTdHJlYW0gZnJvbSB3aGljaCB0aGlzIG9iamVjdCBzaG91bGQgYmUgY3JlYXRlZAorICAgICAqIEBwYXJhbSBkZWNvbXByZXNzQ29uY2F0ZW5hdGVkCisgICAgICogICAgICAgICAgICAgICAgICAgICBpZiB0cnVlLCBkZWNvbXByZXNzIHVudGlsIHRoZSBlbmQgb2YgdGhlIGlucHV0OworICAgICAqICAgICAgICAgICAgICAgICAgICAgaWYgZmFsc2UsIHN0b3AgYWZ0ZXIgdGhlIGZpcnN0IC5iejIgc3RyZWFtIGFuZAorICAgICAqICAgICAgICAgICAgICAgICAgICAgbGVhdmUgdGhlIGlucHV0IHBvc2l0aW9uIHRvIHBvaW50IHRvIHRoZSBuZXh0CisgICAgICogICAgICAgICAgICAgICAgICAgICBieXRlIGFmdGVyIHRoZSAuYnoyIHN0cmVhbQorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBpbiA9PSBudWxsfSwgdGhlIHN0cmVhbSBjb250ZW50IGlzIG1hbGZvcm1lZCwgb3IgYW4gSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgQlppcDJDb21wcmVzc29ySW5wdXRTdHJlYW0oZmluYWwgSW5wdXRTdHJlYW0gaW4sIGZpbmFsIGJvb2xlYW4gZGVjb21wcmVzc0NvbmNhdGVuYXRlZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcy5iaW4gPSBuZXcgQml0SW5wdXRTdHJlYW0oaW4gPT0gU3lzdGVtLmluID8gbmV3IENsb3NlU2hpZWxkRmlsdGVySW5wdXRTdHJlYW0oaW4pIDogaW4sCisgICAgICAgICAgICBCeXRlT3JkZXIuQklHX0VORElBTik7CisgICAgICAgIHRoaXMuZGVjb21wcmVzc0NvbmNhdGVuYXRlZCA9IGRlY29tcHJlc3NDb25jYXRlbmF0ZWQ7CisKKyAgICAgICAgaW5pdCh0cnVlKTsKKyAgICAgICAgaW5pdEJsb2NrKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCByZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHRoaXMuYmluICE9IG51bGwpIHsKKyAgICAgICAgICAgIGZpbmFsIGludCByID0gcmVhZDAoKTsKKyAgICAgICAgICAgIGNvdW50KHIgPCAwID8gLTEgOiAxKTsKKyAgICAgICAgICAgIHJldHVybiByOworICAgICAgICB9CisgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigic3RyZWFtIGNsb3NlZCIpOworICAgIH0KKworICAgIC8qCisgICAgICogKG5vbi1KYXZhZG9jKQorICAgICAqCisgICAgICogQHNlZSBqYXZhLmlvLklucHV0U3RyZWFtI3JlYWQoYnl0ZVtdLCBpbnQsIGludCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHJlYWQoZmluYWwgYnl0ZVtdIGRlc3QsIGZpbmFsIGludCBvZmZzLCBmaW5hbCBpbnQgbGVuKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAob2ZmcyA8IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCJvZmZzKCIgKyBvZmZzICsgIikgPCAwLiIpOworICAgICAgICB9CisgICAgICAgIGlmIChsZW4gPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigibGVuKCIgKyBsZW4gKyAiKSA8IDAuIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG9mZnMgKyBsZW4gPiBkZXN0Lmxlbmd0aCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oIm9mZnMoIiArIG9mZnMgKyAiKSArIGxlbigiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGxlbiArICIpID4gZGVzdC5sZW5ndGgoIiArIGRlc3QubGVuZ3RoICsgIikuIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHRoaXMuYmluID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigic3RyZWFtIGNsb3NlZCIpOworICAgICAgICB9CisgICAgICAgIGlmIChsZW4gPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICBmaW5hbCBpbnQgaGkgPSBvZmZzICsgbGVuOworICAgICAgICBpbnQgZGVzdE9mZnMgPSBvZmZzOworICAgICAgICBpbnQgYjsKKyAgICAgICAgd2hpbGUgKGRlc3RPZmZzIDwgaGkgJiYgKChiID0gcmVhZDAoKSkgPj0gMCkpIHsKKyAgICAgICAgICAgIGRlc3RbZGVzdE9mZnMrK10gPSAoYnl0ZSkgYjsKKyAgICAgICAgICAgIGNvdW50KDEpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIChkZXN0T2ZmcyA9PSBvZmZzKSA/IC0xIDogKGRlc3RPZmZzIC0gb2Zmcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNpbmNlIDEuMTcKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgbG9uZyBnZXRDb21wcmVzc2VkQ291bnQoKSB7CisgICAgICAgIHJldHVybiBiaW4uZ2V0Qnl0ZXNSZWFkKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIG1ha2VNYXBzKCkgeworICAgICAgICBmaW5hbCBib29sZWFuW10gaW5Vc2UgPSB0aGlzLmRhdGEuaW5Vc2U7CisgICAgICAgIGZpbmFsIGJ5dGVbXSBzZXFUb1Vuc2VxID0gdGhpcy5kYXRhLnNlcVRvVW5zZXE7CisKKyAgICAgICAgaW50IG5JblVzZVNoYWRvdyA9IDA7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAyNTY7IGkrKykgeworICAgICAgICAgICAgaWYgKGluVXNlW2ldKSB7CisgICAgICAgICAgICAgICAgc2VxVG9VbnNlcVtuSW5Vc2VTaGFkb3crK10gPSAoYnl0ZSkgaTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHRoaXMubkluVXNlID0gbkluVXNlU2hhZG93OworICAgIH0KKworICAgIHByaXZhdGUgaW50IHJlYWQwKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3dpdGNoIChjdXJyZW50U3RhdGUpIHsKKyAgICAgICAgY2FzZSBFT0Y6CisgICAgICAgICAgICByZXR1cm4gLTE7CisKKyAgICAgICAgY2FzZSBTVEFSVF9CTE9DS19TVEFURToKKyAgICAgICAgICAgIHJldHVybiBzZXR1cEJsb2NrKCk7CisKKyAgICAgICAgY2FzZSBSQU5EX1BBUlRfQV9TVEFURToKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKKworICAgICAgICBjYXNlIFJBTkRfUEFSVF9CX1NUQVRFOgorICAgICAgICAgICAgcmV0dXJuIHNldHVwUmFuZFBhcnRCKCk7CisKKyAgICAgICAgY2FzZSBSQU5EX1BBUlRfQ19TVEFURToKKyAgICAgICAgICAgIHJldHVybiBzZXR1cFJhbmRQYXJ0QygpOworCisgICAgICAgIGNhc2UgTk9fUkFORF9QQVJUX0FfU1RBVEU6CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7CisKKyAgICAgICAgY2FzZSBOT19SQU5EX1BBUlRfQl9TVEFURToKKyAgICAgICAgICAgIHJldHVybiBzZXR1cE5vUmFuZFBhcnRCKCk7CisKKyAgICAgICAgY2FzZSBOT19SQU5EX1BBUlRfQ19TVEFURToKKyAgICAgICAgICAgIHJldHVybiBzZXR1cE5vUmFuZFBhcnRDKCk7CisKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgaW50IHJlYWROZXh0Qnl0ZShCaXRJbnB1dFN0cmVhbSBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgbG9uZyBiID0gaW4ucmVhZEJpdHMoOCk7CisgICAgICAgIHJldHVybiAoaW50KSBiOworICAgIH0KKworICAgIHByaXZhdGUgYm9vbGVhbiBpbml0KGZpbmFsIGJvb2xlYW4gaXNGaXJzdFN0cmVhbSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKG51bGwgPT0gYmluKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIk5vIElucHV0U3RyZWFtIik7CisgICAgICAgIH0KKworICAgICAgICBpZiAoIWlzRmlyc3RTdHJlYW0pIHsKKyAgICAgICAgICAgIGJpbi5jbGVhckJpdENhY2hlKCk7CisgICAgICAgIH0KKworICAgICAgICBmaW5hbCBpbnQgbWFnaWMwID0gcmVhZE5leHRCeXRlKHRoaXMuYmluKTsKKyAgICAgICAgaWYgKG1hZ2ljMCA9PSAtMSAmJiAhaXNGaXJzdFN0cmVhbSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIGZpbmFsIGludCBtYWdpYzEgPSByZWFkTmV4dEJ5dGUodGhpcy5iaW4pOworICAgICAgICBmaW5hbCBpbnQgbWFnaWMyID0gcmVhZE5leHRCeXRlKHRoaXMuYmluKTsKKworICAgICAgICBpZiAobWFnaWMwICE9ICdCJyB8fCBtYWdpYzEgIT0gJ1onIHx8IG1hZ2ljMiAhPSAnaCcpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihpc0ZpcnN0U3RyZWFtCisgICAgICAgICAgICAgICAgICAgID8gIlN0cmVhbSBpcyBub3QgaW4gdGhlIEJaaXAyIGZvcm1hdCIKKyAgICAgICAgICAgICAgICAgICAgOiAiR2FyYmFnZSBhZnRlciBhIHZhbGlkIEJaaXAyIHN0cmVhbSIpOworICAgICAgICB9CisKKyAgICAgICAgZmluYWwgaW50IGJsb2NrU2l6ZSA9IHJlYWROZXh0Qnl0ZSh0aGlzLmJpbik7CisgICAgICAgIGlmICgoYmxvY2tTaXplIDwgJzEnKSB8fCAoYmxvY2tTaXplID4gJzknKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJCWmlwMiBibG9jayBzaXplIGlzIGludmFsaWQiKTsKKyAgICAgICAgfQorCisgICAgICAgIHRoaXMuYmxvY2tTaXplMTAwayA9IGJsb2NrU2l6ZSAtICcwJzsKKworICAgICAgICB0aGlzLmNvbXB1dGVkQ29tYmluZWRDUkMgPSAwOworCisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBpbml0QmxvY2soKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBCaXRJbnB1dFN0cmVhbSBiaW4gPSB0aGlzLmJpbjsKKyAgICAgICAgY2hhciBtYWdpYzA7CisgICAgICAgIGNoYXIgbWFnaWMxOworICAgICAgICBjaGFyIG1hZ2ljMjsKKyAgICAgICAgY2hhciBtYWdpYzM7CisgICAgICAgIGNoYXIgbWFnaWM0OworICAgICAgICBjaGFyIG1hZ2ljNTsKKworICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgLy8gR2V0IHRoZSBibG9jayBtYWdpYyBieXRlcy4KKyAgICAgICAgICAgIG1hZ2ljMCA9IGJzR2V0VUJ5dGUoYmluKTsKKyAgICAgICAgICAgIG1hZ2ljMSA9IGJzR2V0VUJ5dGUoYmluKTsKKyAgICAgICAgICAgIG1hZ2ljMiA9IGJzR2V0VUJ5dGUoYmluKTsKKyAgICAgICAgICAgIG1hZ2ljMyA9IGJzR2V0VUJ5dGUoYmluKTsKKyAgICAgICAgICAgIG1hZ2ljNCA9IGJzR2V0VUJ5dGUoYmluKTsKKyAgICAgICAgICAgIG1hZ2ljNSA9IGJzR2V0VUJ5dGUoYmluKTsKKworICAgICAgICAgICAgLy8gSWYgaXNuJ3QgZW5kIG9mIHN0cmVhbSBtYWdpYywgYnJlYWsgb3V0IG9mIHRoZSBsb29wLgorICAgICAgICAgICAgaWYgKG1hZ2ljMCAhPSAweDE3IHx8IG1hZ2ljMSAhPSAweDcyIHx8IG1hZ2ljMiAhPSAweDQ1CisgICAgICAgICAgICAgICAgICAgIHx8IG1hZ2ljMyAhPSAweDM4IHx8IG1hZ2ljNCAhPSAweDUwIHx8IG1hZ2ljNSAhPSAweDkwKSB7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIEVuZCBvZiBzdHJlYW0gd2FzIHJlYWNoZWQuIENoZWNrIHRoZSBjb21iaW5lZCBDUkMgYW5kCisgICAgICAgICAgICAvLyBhZHZhbmNlIHRvIHRoZSBuZXh0IC5iejIgc3RyZWFtIGlmIGRlY29kaW5nIGNvbmNhdGVuYXRlZAorICAgICAgICAgICAgLy8gc3RyZWFtcy4KKyAgICAgICAgICAgIGlmIChjb21wbGV0ZSgpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgaWYgKG1hZ2ljMCAhPSAweDMxIHx8IC8vICcxJworICAgICAgICAgICAgbWFnaWMxICE9IDB4NDEgfHwgLy8gJyknCisgICAgICAgICAgICBtYWdpYzIgIT0gMHg1OSB8fCAvLyAnWScKKyAgICAgICAgICAgIG1hZ2ljMyAhPSAweDI2IHx8IC8vICcmJworICAgICAgICAgICAgbWFnaWM0ICE9IDB4NTMgfHwgLy8gJ1MnCisgICAgICAgICAgICBtYWdpYzUgIT0gMHg1OSAvLyAnWScKKyAgICAgICAgICAgICkgeworICAgICAgICAgICAgdGhpcy5jdXJyZW50U3RhdGUgPSBFT0Y7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oImJhZCBibG9jayBoZWFkZXIiKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLnN0b3JlZEJsb2NrQ1JDID0gYnNHZXRJbnQoYmluKTsKKyAgICAgICAgdGhpcy5ibG9ja1JhbmRvbWlzZWQgPSBic1IoYmluLCAxKSA9PSAxOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBBbGxvY2F0ZSBkYXRhIGhlcmUgaW5zdGVhZCBpbiBjb25zdHJ1Y3Rvciwgc28gd2UgZG8gbm90IGFsbG9jYXRlCisgICAgICAgICAqIGl0IGlmIHRoZSBpbnB1dCBmaWxlIGlzIGVtcHR5LgorICAgICAgICAgKi8KKyAgICAgICAgaWYgKHRoaXMuZGF0YSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aGlzLmRhdGEgPSBuZXcgRGF0YSh0aGlzLmJsb2NrU2l6ZTEwMGspOworICAgICAgICB9CisKKyAgICAgICAgLy8gY3VyckJsb2NrTm8rKzsKKyAgICAgICAgZ2V0QW5kTW92ZVRvRnJvbnREZWNvZGUoKTsKKworICAgICAgICB0aGlzLmNyYy5pbml0aWFsaXNlQ1JDKCk7CisgICAgICAgIHRoaXMuY3VycmVudFN0YXRlID0gU1RBUlRfQkxPQ0tfU1RBVEU7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGVuZEJsb2NrKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcy5jb21wdXRlZEJsb2NrQ1JDID0gdGhpcy5jcmMuZ2V0RmluYWxDUkMoKTsKKworICAgICAgICAvLyBBIGJhZCBDUkMgaXMgY29uc2lkZXJlZCBhIGZhdGFsIGVycm9yLgorICAgICAgICBpZiAodGhpcy5zdG9yZWRCbG9ja0NSQyAhPSB0aGlzLmNvbXB1dGVkQmxvY2tDUkMpIHsKKyAgICAgICAgICAgIC8vIG1ha2UgbmV4dCBibG9ja3MgcmVhZGFibGUgd2l0aG91dCBlcnJvcgorICAgICAgICAgICAgLy8gKHJlcGFpciBmZWF0dXJlLCBub3QgeWV0IGRvY3VtZW50ZWQsIG5vdCB0ZXN0ZWQpCisgICAgICAgICAgICB0aGlzLmNvbXB1dGVkQ29tYmluZWRDUkMgPSAodGhpcy5zdG9yZWRDb21iaW5lZENSQyA8PCAxKQorICAgICAgICAgICAgICAgIHwgKHRoaXMuc3RvcmVkQ29tYmluZWRDUkMgPj4+IDMxKTsKKyAgICAgICAgICAgIHRoaXMuY29tcHV0ZWRDb21iaW5lZENSQyBePSB0aGlzLnN0b3JlZEJsb2NrQ1JDOworCisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkJaaXAyIENSQyBlcnJvciIpOworICAgICAgICB9CisKKyAgICAgICAgdGhpcy5jb21wdXRlZENvbWJpbmVkQ1JDID0gKHRoaXMuY29tcHV0ZWRDb21iaW5lZENSQyA8PCAxKQorICAgICAgICAgICAgfCAodGhpcy5jb21wdXRlZENvbWJpbmVkQ1JDID4+PiAzMSk7CisgICAgICAgIHRoaXMuY29tcHV0ZWRDb21iaW5lZENSQyBePSB0aGlzLmNvbXB1dGVkQmxvY2tDUkM7CisgICAgfQorCisgICAgcHJpdmF0ZSBib29sZWFuIGNvbXBsZXRlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcy5zdG9yZWRDb21iaW5lZENSQyA9IGJzR2V0SW50KGJpbik7CisgICAgICAgIHRoaXMuY3VycmVudFN0YXRlID0gRU9GOworICAgICAgICB0aGlzLmRhdGEgPSBudWxsOworCisgICAgICAgIGlmICh0aGlzLnN0b3JlZENvbWJpbmVkQ1JDICE9IHRoaXMuY29tcHV0ZWRDb21iaW5lZENSQykgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJCWmlwMiBDUkMgZXJyb3IiKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIExvb2sgZm9yIHRoZSBuZXh0IC5iejIgc3RyZWFtIGlmIGRlY29tcHJlc3NpbmcKKyAgICAgICAgLy8gY29uY2F0ZW5hdGVkIGZpbGVzLgorICAgICAgICByZXR1cm4gIWRlY29tcHJlc3NDb25jYXRlbmF0ZWQgfHwgIWluaXQoZmFsc2UpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgQml0SW5wdXRTdHJlYW0gaW5TaGFkb3cgPSB0aGlzLmJpbjsKKyAgICAgICAgaWYgKGluU2hhZG93ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaW5TaGFkb3cuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgdGhpcy5kYXRhID0gbnVsbDsKKyAgICAgICAgICAgICAgICB0aGlzLmJpbiA9IG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiByZWFkIGJpdHMgZnJvbSB0aGUgaW5wdXQgc3RyZWFtCisgICAgICogQHBhcmFtIG4gdGhlIG51bWJlciBvZiBiaXRzIHRvIHJlYWQsIG11c3Qgbm90IGV4Y2VlZCAzMj8KKyAgICAgKiBAcmV0dXJuIHRoZSByZXF1ZXN0ZWQgYml0cyBjb21iaW5lZCBpbnRvIGFuIGludAorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBpbnQgYnNSKEJpdElucHV0U3RyZWFtIGJpbiwgZmluYWwgaW50IG4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGxvbmcgdGhlY2ggPSBiaW4ucmVhZEJpdHMobik7CisgICAgICAgIGlmICh0aGVjaCA8IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigidW5leHBlY3RlZCBlbmQgb2Ygc3RyZWFtIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIChpbnQpIHRoZWNoOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gYnNHZXRCaXQoQml0SW5wdXRTdHJlYW0gYmluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gYnNSKGJpbiwgMSkgIT0gMDsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBjaGFyIGJzR2V0VUJ5dGUoQml0SW5wdXRTdHJlYW0gYmluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gKGNoYXIpIGJzUihiaW4sIDgpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGludCBic0dldEludChCaXRJbnB1dFN0cmVhbSBiaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBic1IoYmluLCAzMik7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBjaGVja0JvdW5kcyhmaW5hbCBpbnQgY2hlY2tWYWwsIGZpbmFsIGludCBsaW1pdEV4Y2x1c2l2ZSwgU3RyaW5nIG5hbWUpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChjaGVja1ZhbCA8IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiQ29ycnVwdGVkIGlucHV0LCAiICsgbmFtZSArICIgdmFsdWUgbmVnYXRpdmUiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoY2hlY2tWYWwgPj0gbGltaXRFeGNsdXNpdmUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiQ29ycnVwdGVkIGlucHV0LCAiICsgbmFtZSArICIgdmFsdWUgdG9vIGJpZyIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2FsbGVkIGJ5IGNyZWF0ZUh1ZmZtYW5EZWNvZGluZ1RhYmxlcygpIGV4Y2x1c2l2ZWx5LgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgaGJDcmVhdGVEZWNvZGVUYWJsZXMoZmluYWwgaW50W10gbGltaXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnRbXSBiYXNlLCBmaW5hbCBpbnRbXSBwZXJtLCBmaW5hbCBjaGFyW10gbGVuZ3RoLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IG1pbkxlbiwgZmluYWwgaW50IG1heExlbiwgZmluYWwgaW50IGFscGhhU2l6ZSkKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZm9yIChpbnQgaSA9IG1pbkxlbiwgcHAgPSAwOyBpIDw9IG1heExlbjsgaSsrKSB7CisgICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IGFscGhhU2l6ZTsgaisrKSB7CisgICAgICAgICAgICAgICAgaWYgKGxlbmd0aFtqXSA9PSBpKSB7CisgICAgICAgICAgICAgICAgICAgIHBlcm1bcHArK10gPSBqOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGZvciAoaW50IGkgPSBNQVhfQ09ERV9MRU47IC0taSA+IDA7KSB7CisgICAgICAgICAgICBiYXNlW2ldID0gMDsKKyAgICAgICAgICAgIGxpbWl0W2ldID0gMDsKKyAgICAgICAgfQorCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYWxwaGFTaXplOyBpKyspIHsKKyAgICAgICAgICAgIGZpbmFsIGludCBsID0gbGVuZ3RoW2ldOworICAgICAgICAgICAgY2hlY2tCb3VuZHMobCwgTUFYX0FMUEhBX1NJWkUsICJsZW5ndGgiKTsKKyAgICAgICAgICAgIGJhc2VbbCArIDFdKys7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKGludCBpID0gMSwgYiA9IGJhc2VbMF07IGkgPCBNQVhfQ09ERV9MRU47IGkrKykgeworICAgICAgICAgICAgYiArPSBiYXNlW2ldOworICAgICAgICAgICAgYmFzZVtpXSA9IGI7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKGludCBpID0gbWluTGVuLCB2ZWMgPSAwLCBiID0gYmFzZVtpXTsgaSA8PSBtYXhMZW47IGkrKykgeworICAgICAgICAgICAgZmluYWwgaW50IG5iID0gYmFzZVtpICsgMV07CisgICAgICAgICAgICB2ZWMgKz0gbmIgLSBiOworICAgICAgICAgICAgYiA9IG5iOworICAgICAgICAgICAgbGltaXRbaV0gPSB2ZWMgLSAxOworICAgICAgICAgICAgdmVjIDw8PSAxOworICAgICAgICB9CisKKyAgICAgICAgZm9yIChpbnQgaSA9IG1pbkxlbiArIDE7IGkgPD0gbWF4TGVuOyBpKyspIHsKKyAgICAgICAgICAgIGJhc2VbaV0gPSAoKGxpbWl0W2kgLSAxXSArIDEpIDw8IDEpIC0gYmFzZVtpXTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByZWN2RGVjb2RpbmdUYWJsZXMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBCaXRJbnB1dFN0cmVhbSBiaW4gPSB0aGlzLmJpbjsKKyAgICAgICAgZmluYWwgRGF0YSBkYXRhU2hhZG93ID0gdGhpcy5kYXRhOworICAgICAgICBmaW5hbCBib29sZWFuW10gaW5Vc2UgPSBkYXRhU2hhZG93LmluVXNlOworICAgICAgICBmaW5hbCBieXRlW10gcG9zID0gZGF0YVNoYWRvdy5yZWN2RGVjb2RpbmdUYWJsZXNfcG9zOworICAgICAgICBmaW5hbCBieXRlW10gc2VsZWN0b3IgPSBkYXRhU2hhZG93LnNlbGVjdG9yOworICAgICAgICBmaW5hbCBieXRlW10gc2VsZWN0b3JNdGYgPSBkYXRhU2hhZG93LnNlbGVjdG9yTXRmOworCisgICAgICAgIGludCBpblVzZTE2ID0gMDsKKworICAgICAgICAvKiBSZWNlaXZlIHRoZSBtYXBwaW5nIHRhYmxlICovCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTY7IGkrKykgeworICAgICAgICAgICAgaWYgKGJzR2V0Qml0KGJpbikpIHsKKyAgICAgICAgICAgICAgICBpblVzZTE2IHw9IDEgPDwgaTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIEFycmF5cy5maWxsKGluVXNlLCBmYWxzZSk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTY7IGkrKykgeworICAgICAgICAgICAgaWYgKChpblVzZTE2ICYgKDEgPDwgaSkpICE9IDApIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBpbnQgaTE2ID0gaSA8PCA0OworICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgMTY7IGorKykgeworICAgICAgICAgICAgICAgICAgICBpZiAoYnNHZXRCaXQoYmluKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgaW5Vc2VbaTE2ICsgal0gPSB0cnVlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgbWFrZU1hcHMoKTsKKyAgICAgICAgZmluYWwgaW50IGFscGhhU2l6ZSA9IHRoaXMubkluVXNlICsgMjsKKyAgICAgICAgLyogTm93IHRoZSBzZWxlY3RvcnMgKi8KKyAgICAgICAgZmluYWwgaW50IG5Hcm91cHMgPSBic1IoYmluLCAzKTsKKyAgICAgICAgZmluYWwgaW50IG5TZWxlY3RvcnMgPSBic1IoYmluLCAxNSk7CisgICAgICAgIGNoZWNrQm91bmRzKGFscGhhU2l6ZSwgTUFYX0FMUEhBX1NJWkUgKyAxLCAiYWxwaGFTaXplIik7CisgICAgICAgIGNoZWNrQm91bmRzKG5Hcm91cHMsIE5fR1JPVVBTICsgMSwgIm5Hcm91cHMiKTsKKyAgICAgICAgY2hlY2tCb3VuZHMoblNlbGVjdG9ycywgTUFYX1NFTEVDVE9SUyArIDEsICJuU2VsZWN0b3JzIik7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuU2VsZWN0b3JzOyBpKyspIHsKKyAgICAgICAgICAgIGludCBqID0gMDsKKyAgICAgICAgICAgIHdoaWxlIChic0dldEJpdChiaW4pKSB7CisgICAgICAgICAgICAgICAgaisrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgc2VsZWN0b3JNdGZbaV0gPSAoYnl0ZSkgajsKKyAgICAgICAgfQorCisgICAgICAgIC8qIFVuZG8gdGhlIE1URiB2YWx1ZXMgZm9yIHRoZSBzZWxlY3RvcnMuICovCisgICAgICAgIGZvciAoaW50IHYgPSBuR3JvdXBzOyAtLXYgPj0gMDspIHsKKyAgICAgICAgICAgIHBvc1t2XSA9IChieXRlKSB2OworICAgICAgICB9CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuU2VsZWN0b3JzOyBpKyspIHsKKyAgICAgICAgICAgIGludCB2ID0gc2VsZWN0b3JNdGZbaV0gJiAweGZmOworICAgICAgICAgICAgY2hlY2tCb3VuZHModiwgTl9HUk9VUFMsICJzZWxlY3Rvck10ZiIpOworICAgICAgICAgICAgZmluYWwgYnl0ZSB0bXAgPSBwb3Nbdl07CisgICAgICAgICAgICB3aGlsZSAodiA+IDApIHsKKyAgICAgICAgICAgICAgICAvLyBuZWFybHkgYWxsIHRpbWVzIHYgaXMgemVybywgNCBpbiBtb3N0IG90aGVyIGNhc2VzCisgICAgICAgICAgICAgICAgcG9zW3ZdID0gcG9zW3YgLSAxXTsKKyAgICAgICAgICAgICAgICB2LS07CisgICAgICAgICAgICB9CisgICAgICAgICAgICBwb3NbMF0gPSB0bXA7CisgICAgICAgICAgICBzZWxlY3RvcltpXSA9IHRtcDsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIGNoYXJbXVtdIGxlbiA9IGRhdGFTaGFkb3cudGVtcF9jaGFyQXJyYXkyZDsKKworICAgICAgICAvKiBOb3cgdGhlIGNvZGluZyB0YWJsZXMgKi8KKyAgICAgICAgZm9yIChpbnQgdCA9IDA7IHQgPCBuR3JvdXBzOyB0KyspIHsKKyAgICAgICAgICAgIGludCBjdXJyID0gYnNSKGJpbiwgNSk7CisgICAgICAgICAgICBmaW5hbCBjaGFyW10gbGVuX3QgPSBsZW5bdF07CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFscGhhU2l6ZTsgaSsrKSB7CisgICAgICAgICAgICAgICAgd2hpbGUgKGJzR2V0Qml0KGJpbikpIHsKKyAgICAgICAgICAgICAgICAgICAgY3VyciArPSBic0dldEJpdChiaW4pID8gLTEgOiAxOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBsZW5fdFtpXSA9IChjaGFyKSBjdXJyOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gZmluYWxseSBjcmVhdGUgdGhlIEh1ZmZtYW4gdGFibGVzCisgICAgICAgIGNyZWF0ZUh1ZmZtYW5EZWNvZGluZ1RhYmxlcyhhbHBoYVNpemUsIG5Hcm91cHMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENhbGxlZCBieSByZWN2RGVjb2RpbmdUYWJsZXMoKSBleGNsdXNpdmVseS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgY3JlYXRlSHVmZm1hbkRlY29kaW5nVGFibGVzKGZpbmFsIGludCBhbHBoYVNpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgbkdyb3VwcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgRGF0YSBkYXRhU2hhZG93ID0gdGhpcy5kYXRhOworICAgICAgICBmaW5hbCBjaGFyW11bXSBsZW4gPSBkYXRhU2hhZG93LnRlbXBfY2hhckFycmF5MmQ7CisgICAgICAgIGZpbmFsIGludFtdIG1pbkxlbnMgPSBkYXRhU2hhZG93Lm1pbkxlbnM7CisgICAgICAgIGZpbmFsIGludFtdW10gbGltaXQgPSBkYXRhU2hhZG93LmxpbWl0OworICAgICAgICBmaW5hbCBpbnRbXVtdIGJhc2UgPSBkYXRhU2hhZG93LmJhc2U7CisgICAgICAgIGZpbmFsIGludFtdW10gcGVybSA9IGRhdGFTaGFkb3cucGVybTsKKworICAgICAgICBmb3IgKGludCB0ID0gMDsgdCA8IG5Hcm91cHM7IHQrKykgeworICAgICAgICAgICAgaW50IG1pbkxlbiA9IDMyOworICAgICAgICAgICAgaW50IG1heExlbiA9IDA7CisgICAgICAgICAgICBmaW5hbCBjaGFyW10gbGVuX3QgPSBsZW5bdF07CisgICAgICAgICAgICBmb3IgKGludCBpID0gYWxwaGFTaXplOyAtLWkgPj0gMDspIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBjaGFyIGxlbnQgPSBsZW5fdFtpXTsKKyAgICAgICAgICAgICAgICBpZiAobGVudCA+IG1heExlbikgeworICAgICAgICAgICAgICAgICAgICBtYXhMZW4gPSBsZW50OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAobGVudCA8IG1pbkxlbikgeworICAgICAgICAgICAgICAgICAgICBtaW5MZW4gPSBsZW50OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGhiQ3JlYXRlRGVjb2RlVGFibGVzKGxpbWl0W3RdLCBiYXNlW3RdLCBwZXJtW3RdLCBsZW5bdF0sIG1pbkxlbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heExlbiwgYWxwaGFTaXplKTsKKyAgICAgICAgICAgIG1pbkxlbnNbdF0gPSBtaW5MZW47CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgZ2V0QW5kTW92ZVRvRnJvbnREZWNvZGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBCaXRJbnB1dFN0cmVhbSBiaW4gPSB0aGlzLmJpbjsKKyAgICAgICAgdGhpcy5vcmlnUHRyID0gYnNSKGJpbiwgMjQpOworICAgICAgICByZWN2RGVjb2RpbmdUYWJsZXMoKTsKKworICAgICAgICBmaW5hbCBEYXRhIGRhdGFTaGFkb3cgPSB0aGlzLmRhdGE7CisgICAgICAgIGZpbmFsIGJ5dGVbXSBsbDggPSBkYXRhU2hhZG93LmxsODsKKyAgICAgICAgZmluYWwgaW50W10gdW56ZnRhYiA9IGRhdGFTaGFkb3cudW56ZnRhYjsKKyAgICAgICAgZmluYWwgYnl0ZVtdIHNlbGVjdG9yID0gZGF0YVNoYWRvdy5zZWxlY3RvcjsKKyAgICAgICAgZmluYWwgYnl0ZVtdIHNlcVRvVW5zZXEgPSBkYXRhU2hhZG93LnNlcVRvVW5zZXE7CisgICAgICAgIGZpbmFsIGNoYXJbXSB5eSA9IGRhdGFTaGFkb3cuZ2V0QW5kTW92ZVRvRnJvbnREZWNvZGVfeXk7CisgICAgICAgIGZpbmFsIGludFtdIG1pbkxlbnMgPSBkYXRhU2hhZG93Lm1pbkxlbnM7CisgICAgICAgIGZpbmFsIGludFtdW10gbGltaXQgPSBkYXRhU2hhZG93LmxpbWl0OworICAgICAgICBmaW5hbCBpbnRbXVtdIGJhc2UgPSBkYXRhU2hhZG93LmJhc2U7CisgICAgICAgIGZpbmFsIGludFtdW10gcGVybSA9IGRhdGFTaGFkb3cucGVybTsKKyAgICAgICAgZmluYWwgaW50IGxpbWl0TGFzdCA9IHRoaXMuYmxvY2tTaXplMTAwayAqIDEwMDAwMDsKKworICAgICAgICAvKgorICAgICAgICAgKiBTZXR0aW5nIHVwIHRoZSB1bnpmdGFiIGVudHJpZXMgaGVyZSBpcyBub3Qgc3RyaWN0bHkgbmVjZXNzYXJ5LCBidXQgaXQKKyAgICAgICAgICogZG9lcyBzYXZlIGhhdmluZyB0byBkbyBpdCBsYXRlciBpbiBhIHNlcGFyYXRlIHBhc3MsIGFuZCBzbyBzYXZlcyBhCisgICAgICAgICAqIGJsb2NrJ3Mgd29ydGggb2YgY2FjaGUgbWlzc2VzLgorICAgICAgICAgKi8KKyAgICAgICAgZm9yIChpbnQgaSA9IDI1NjsgLS1pID49IDA7KSB7CisgICAgICAgICAgICB5eVtpXSA9IChjaGFyKSBpOworICAgICAgICAgICAgdW56ZnRhYltpXSA9IDA7CisgICAgICAgIH0KKworICAgICAgICBpbnQgZ3JvdXBObyA9IDA7CisgICAgICAgIGludCBncm91cFBvcyA9IEdfU0laRSAtIDE7CisgICAgICAgIGZpbmFsIGludCBlb2IgPSB0aGlzLm5JblVzZSArIDE7CisgICAgICAgIGludCBuZXh0U3ltID0gZ2V0QW5kTW92ZVRvRnJvbnREZWNvZGUwKCk7CisgICAgICAgIGludCBsYXN0U2hhZG93ID0gLTE7CisgICAgICAgIGludCB6dCA9IHNlbGVjdG9yW2dyb3VwTm9dICYgMHhmZjsKKyAgICAgICAgY2hlY2tCb3VuZHMoenQsIE5fR1JPVVBTLCAienQiKTsKKyAgICAgICAgaW50W10gYmFzZV96dCA9IGJhc2VbenRdOworICAgICAgICBpbnRbXSBsaW1pdF96dCA9IGxpbWl0W3p0XTsKKyAgICAgICAgaW50W10gcGVybV96dCA9IHBlcm1benRdOworICAgICAgICBpbnQgbWluTGVuc196dCA9IG1pbkxlbnNbenRdOworCisgICAgICAgIHdoaWxlIChuZXh0U3ltICE9IGVvYikgeworICAgICAgICAgICAgaWYgKChuZXh0U3ltID09IFJVTkEpIHx8IChuZXh0U3ltID09IFJVTkIpKSB7CisgICAgICAgICAgICAgICAgaW50IHMgPSAtMTsKKworICAgICAgICAgICAgICAgIGZvciAoaW50IG4gPSAxOyB0cnVlOyBuIDw8PSAxKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChuZXh0U3ltID09IFJVTkEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHMgKz0gbjsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChuZXh0U3ltID09IFJVTkIpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHMgKz0gbiA8PCAxOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBpZiAoZ3JvdXBQb3MgPT0gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXBQb3MgPSBHX1NJWkUgLSAxOworICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tCb3VuZHMoKytncm91cE5vLCBNQVhfU0VMRUNUT1JTLCAiZ3JvdXBObyIpOworICAgICAgICAgICAgICAgICAgICAgICAgenQgPSBzZWxlY3Rvcltncm91cE5vXSAmIDB4ZmY7CisgICAgICAgICAgICAgICAgICAgICAgICBjaGVja0JvdW5kcyh6dCwgTl9HUk9VUFMsICJ6dCIpOworICAgICAgICAgICAgICAgICAgICAgICAgYmFzZV96dCA9IGJhc2VbenRdOworICAgICAgICAgICAgICAgICAgICAgICAgbGltaXRfenQgPSBsaW1pdFt6dF07CisgICAgICAgICAgICAgICAgICAgICAgICBwZXJtX3p0ID0gcGVybVt6dF07CisgICAgICAgICAgICAgICAgICAgICAgICBtaW5MZW5zX3p0ID0gbWluTGVuc1t6dF07CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICBncm91cFBvcy0tOworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgaW50IHpuID0gbWluTGVuc196dDsKKyAgICAgICAgICAgICAgICAgICAgY2hlY2tCb3VuZHMoem4sIE1BWF9BTFBIQV9TSVpFLCAiem4iKTsKKyAgICAgICAgICAgICAgICAgICAgaW50IHp2ZWMgPSBic1IoYmluLCB6bik7CisgICAgICAgICAgICAgICAgICAgIHdoaWxlKHp2ZWMgPiBsaW1pdF96dFt6bl0pIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrQm91bmRzKCsrem4sIE1BWF9BTFBIQV9TSVpFLCAiem4iKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHp2ZWMgPSAoenZlYyA8PCAxKSB8IGJzUihiaW4sIDEpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCB0bXAgPSB6dmVjIC0gYmFzZV96dFt6bl07CisgICAgICAgICAgICAgICAgICAgIGNoZWNrQm91bmRzKHRtcCwgTUFYX0FMUEhBX1NJWkUsICJ6dmVjIik7CisgICAgICAgICAgICAgICAgICAgIG5leHRTeW0gPSBwZXJtX3p0W3RtcF07CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgZmluYWwgaW50IHl5MCA9IHl5WzBdOworICAgICAgICAgICAgICAgIGNoZWNrQm91bmRzKHl5MCwgMjU2LCAieXkiKTsKKyAgICAgICAgICAgICAgICBmaW5hbCBieXRlIGNoID0gc2VxVG9VbnNlcVt5eTBdOworICAgICAgICAgICAgICAgIHVuemZ0YWJbY2ggJiAweGZmXSArPSBzICsgMTsKKworICAgICAgICAgICAgICAgIGZpbmFsIGludCBmcm9tID0gKytsYXN0U2hhZG93OworICAgICAgICAgICAgICAgIGxhc3RTaGFkb3cgKz0gczsKKyAgICAgICAgICAgICAgICBBcnJheXMuZmlsbChsbDgsIGZyb20sIGxhc3RTaGFkb3cgKyAxLCBjaCk7CisKKyAgICAgICAgICAgICAgICBpZiAobGFzdFNoYWRvdyA+PSBsaW1pdExhc3QpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJibG9jayBvdmVycnVuIHdoaWxlIGV4cGFuZGluZyBSTEUgaW4gTVRGLCAiCisgICAgICAgICAgICAgICAgICAgICAgICArIGxhc3RTaGFkb3cgKyAiIGV4Y2VlZHMgIiArIGxpbWl0TGFzdCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBpZiAoKytsYXN0U2hhZG93ID49IGxpbWl0TGFzdCkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oImJsb2NrIG92ZXJydW4gaW4gTVRGLCAiCisgICAgICAgICAgICAgICAgICAgICAgICArIGxhc3RTaGFkb3cgKyAiIGV4Y2VlZHMgIiArIGxpbWl0TGFzdCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGNoZWNrQm91bmRzKG5leHRTeW0sIDI1NiArIDEsICJuZXh0U3ltIik7CisKKyAgICAgICAgICAgICAgICBmaW5hbCBjaGFyIHRtcCA9IHl5W25leHRTeW0gLSAxXTsKKyAgICAgICAgICAgICAgICBjaGVja0JvdW5kcyh0bXAsIDI1NiwgInl5Iik7CisgICAgICAgICAgICAgICAgdW56ZnRhYltzZXFUb1Vuc2VxW3RtcF0gJiAweGZmXSsrOworICAgICAgICAgICAgICAgIGxsOFtsYXN0U2hhZG93XSA9IHNlcVRvVW5zZXFbdG1wXTsKKworICAgICAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgICAgICogVGhpcyBsb29wIGlzIGhhbW1lcmVkIGR1cmluZyBkZWNvbXByZXNzaW9uLCBoZW5jZSBhdm9pZAorICAgICAgICAgICAgICAgICAqIG5hdGl2ZSBtZXRob2QgY2FsbCBvdmVyaGVhZCBvZiBTeXN0ZW0uYXJyYXljb3B5IGZvciB2ZXJ5CisgICAgICAgICAgICAgICAgICogc21hbGwgcmFuZ2VzIHRvIGNvcHkuCisgICAgICAgICAgICAgICAgICovCisgICAgICAgICAgICAgICAgaWYgKG5leHRTeW0gPD0gMTYpIHsKKyAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaiA9IG5leHRTeW0gLSAxOyBqID4gMDspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHl5W2pdID0geXlbLS1qXTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoeXksIDAsIHl5LCAxLCBuZXh0U3ltIC0gMSk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgeXlbMF0gPSB0bXA7CisKKyAgICAgICAgICAgICAgICBpZiAoZ3JvdXBQb3MgPT0gMCkgeworICAgICAgICAgICAgICAgICAgICBncm91cFBvcyA9IEdfU0laRSAtIDE7CisgICAgICAgICAgICAgICAgICAgIGNoZWNrQm91bmRzKCsrZ3JvdXBObywgTUFYX1NFTEVDVE9SUywgImdyb3VwTm8iKTsKKyAgICAgICAgICAgICAgICAgICAgenQgPSBzZWxlY3Rvcltncm91cE5vXSAmIDB4ZmY7CisgICAgICAgICAgICAgICAgICAgIGNoZWNrQm91bmRzKHp0LCBOX0dST1VQUywgInp0Iik7CisgICAgICAgICAgICAgICAgICAgIGJhc2VfenQgPSBiYXNlW3p0XTsKKyAgICAgICAgICAgICAgICAgICAgbGltaXRfenQgPSBsaW1pdFt6dF07CisgICAgICAgICAgICAgICAgICAgIHBlcm1fenQgPSBwZXJtW3p0XTsKKyAgICAgICAgICAgICAgICAgICAgbWluTGVuc196dCA9IG1pbkxlbnNbenRdOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGdyb3VwUG9zLS07CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgaW50IHpuID0gbWluTGVuc196dDsKKyAgICAgICAgICAgICAgICBjaGVja0JvdW5kcyh6biwgTUFYX0FMUEhBX1NJWkUsICJ6biIpOworICAgICAgICAgICAgICAgIGludCB6dmVjID0gYnNSKGJpbiwgem4pOworICAgICAgICAgICAgICAgIHdoaWxlKHp2ZWMgPiBsaW1pdF96dFt6bl0pIHsKKyAgICAgICAgICAgICAgICAgICAgY2hlY2tCb3VuZHMoKyt6biwgTUFYX0FMUEhBX1NJWkUsICJ6biIpOworICAgICAgICAgICAgICAgICAgICB6dmVjID0gKHp2ZWMgPDwgMSkgfCBic1IoYmluLCAxKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZmluYWwgaW50IGlkeCA9IHp2ZWMgLSBiYXNlX3p0W3puXTsKKyAgICAgICAgICAgICAgICBjaGVja0JvdW5kcyhpZHgsIE1BWF9BTFBIQV9TSVpFLCAienZlYyIpOworICAgICAgICAgICAgICAgIG5leHRTeW0gPSBwZXJtX3p0W2lkeF07CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB0aGlzLmxhc3QgPSBsYXN0U2hhZG93OworICAgIH0KKworICAgIHByaXZhdGUgaW50IGdldEFuZE1vdmVUb0Zyb250RGVjb2RlMCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIERhdGEgZGF0YVNoYWRvdyA9IHRoaXMuZGF0YTsKKyAgICAgICAgZmluYWwgaW50IHp0ID0gZGF0YVNoYWRvdy5zZWxlY3RvclswXSAmIDB4ZmY7CisgICAgICAgIGNoZWNrQm91bmRzKHp0LCBOX0dST1VQUywgInp0Iik7CisgICAgICAgIGZpbmFsIGludFtdIGxpbWl0X3p0ID0gZGF0YVNoYWRvdy5saW1pdFt6dF07CisgICAgICAgIGludCB6biA9IGRhdGFTaGFkb3cubWluTGVuc1t6dF07CisgICAgICAgIGNoZWNrQm91bmRzKHpuLCBNQVhfQUxQSEFfU0laRSwgInpuIik7CisgICAgICAgIGludCB6dmVjID0gYnNSKGJpbiwgem4pOworICAgICAgICB3aGlsZSAoenZlYyA+IGxpbWl0X3p0W3puXSkgeworICAgICAgICAgICAgY2hlY2tCb3VuZHMoKyt6biwgTUFYX0FMUEhBX1NJWkUsICJ6biIpOworICAgICAgICAgICAgenZlYyA9ICh6dmVjIDw8IDEpIHwgYnNSKGJpbiwgMSk7CisgICAgICAgIH0KKyAgICAgICAgZmluYWwgaW50IHRtcCA9IHp2ZWMgLSBkYXRhU2hhZG93LmJhc2VbenRdW3puXTsKKyAgICAgICAgY2hlY2tCb3VuZHModG1wLCBNQVhfQUxQSEFfU0laRSwgInp2ZWMiKTsKKworICAgICAgICByZXR1cm4gZGF0YVNoYWRvdy5wZXJtW3p0XVt0bXBdOworICAgIH0KKworICAgIHByaXZhdGUgaW50IHNldHVwQmxvY2soKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoY3VycmVudFN0YXRlID09IEVPRiB8fCB0aGlzLmRhdGEgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisKKyAgICAgICAgZmluYWwgaW50W10gY2Z0YWIgPSB0aGlzLmRhdGEuY2Z0YWI7CisgICAgICAgIGZpbmFsIGludCB0dExlbiA9IHRoaXMubGFzdCArIDE7CisgICAgICAgIGZpbmFsIGludFtdIHR0ID0gdGhpcy5kYXRhLmluaXRUVCh0dExlbik7CisgICAgICAgIGZpbmFsIGJ5dGVbXSBsbDggPSB0aGlzLmRhdGEubGw4OworICAgICAgICBjZnRhYlswXSA9IDA7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkodGhpcy5kYXRhLnVuemZ0YWIsIDAsIGNmdGFiLCAxLCAyNTYpOworCisgICAgICAgIGZvciAoaW50IGkgPSAxLCBjID0gY2Z0YWJbMF07IGkgPD0gMjU2OyBpKyspIHsKKyAgICAgICAgICAgIGMgKz0gY2Z0YWJbaV07CisgICAgICAgICAgICBjZnRhYltpXSA9IGM7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKGludCBpID0gMCwgbGFzdFNoYWRvdyA9IHRoaXMubGFzdDsgaSA8PSBsYXN0U2hhZG93OyBpKyspIHsKKyAgICAgICAgICAgIGZpbmFsIGludCB0bXAgPSBjZnRhYltsbDhbaV0gJiAweGZmXSsrOworICAgICAgICAgICAgY2hlY2tCb3VuZHModG1wLCB0dExlbiwgInR0IGluZGV4Iik7CisgICAgICAgICAgICB0dFt0bXBdID0gaTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICgodGhpcy5vcmlnUHRyIDwgMCkgfHwgKHRoaXMub3JpZ1B0ciA+PSB0dC5sZW5ndGgpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oInN0cmVhbSBjb3JydXB0ZWQiKTsKKyAgICAgICAgfQorCisgICAgICAgIHRoaXMuc3VfdFBvcyA9IHR0W3RoaXMub3JpZ1B0cl07CisgICAgICAgIHRoaXMuc3VfY291bnQgPSAwOworICAgICAgICB0aGlzLnN1X2kyID0gMDsKKyAgICAgICAgdGhpcy5zdV9jaDIgPSAyNTY7IC8qIG5vdCBhIGNoYXIgYW5kIG5vdCBFT0YgKi8KKworICAgICAgICBpZiAodGhpcy5ibG9ja1JhbmRvbWlzZWQpIHsKKyAgICAgICAgICAgIHRoaXMuc3Vfck5Ub0dvID0gMDsKKyAgICAgICAgICAgIHRoaXMuc3VfclRQb3MgPSAwOworICAgICAgICAgICAgcmV0dXJuIHNldHVwUmFuZFBhcnRBKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHNldHVwTm9SYW5kUGFydEEoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIGludCBzZXR1cFJhbmRQYXJ0QSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICh0aGlzLnN1X2kyIDw9IHRoaXMubGFzdCkgeworICAgICAgICAgICAgdGhpcy5zdV9jaFByZXYgPSB0aGlzLnN1X2NoMjsKKyAgICAgICAgICAgIGludCBzdV9jaDJTaGFkb3cgPSB0aGlzLmRhdGEubGw4W3RoaXMuc3VfdFBvc10gJiAweGZmOworICAgICAgICAgICAgY2hlY2tCb3VuZHModGhpcy5zdV90UG9zLCB0aGlzLmRhdGEudHQubGVuZ3RoLCAic3VfdFBvcyIpOworICAgICAgICAgICAgdGhpcy5zdV90UG9zID0gdGhpcy5kYXRhLnR0W3RoaXMuc3VfdFBvc107CisgICAgICAgICAgICBpZiAodGhpcy5zdV9yTlRvR28gPT0gMCkgeworICAgICAgICAgICAgICAgIHRoaXMuc3Vfck5Ub0dvID0gUmFuZC5yTnVtcyh0aGlzLnN1X3JUUG9zKSAtIDE7CisgICAgICAgICAgICAgICAgaWYgKCsrdGhpcy5zdV9yVFBvcyA9PSA1MTIpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhpcy5zdV9yVFBvcyA9IDA7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB0aGlzLnN1X3JOVG9Hby0tOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhpcy5zdV9jaDIgPSBzdV9jaDJTaGFkb3cgXj0gKHRoaXMuc3Vfck5Ub0dvID09IDEpID8gMSA6IDA7CisgICAgICAgICAgICB0aGlzLnN1X2kyKys7CisgICAgICAgICAgICB0aGlzLmN1cnJlbnRTdGF0ZSA9IFJBTkRfUEFSVF9CX1NUQVRFOworICAgICAgICAgICAgdGhpcy5jcmMudXBkYXRlQ1JDKHN1X2NoMlNoYWRvdyk7CisgICAgICAgICAgICByZXR1cm4gc3VfY2gyU2hhZG93OworICAgICAgICB9CisgICAgICAgIGVuZEJsb2NrKCk7CisgICAgICAgIGluaXRCbG9jaygpOworICAgICAgICByZXR1cm4gc2V0dXBCbG9jaygpOworICAgIH0KKworICAgIHByaXZhdGUgaW50IHNldHVwTm9SYW5kUGFydEEoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAodGhpcy5zdV9pMiA8PSB0aGlzLmxhc3QpIHsKKyAgICAgICAgICAgIHRoaXMuc3VfY2hQcmV2ID0gdGhpcy5zdV9jaDI7CisgICAgICAgICAgICBmaW5hbCBpbnQgc3VfY2gyU2hhZG93ID0gdGhpcy5kYXRhLmxsOFt0aGlzLnN1X3RQb3NdICYgMHhmZjsKKyAgICAgICAgICAgIHRoaXMuc3VfY2gyID0gc3VfY2gyU2hhZG93OworICAgICAgICAgICAgY2hlY2tCb3VuZHModGhpcy5zdV90UG9zLCB0aGlzLmRhdGEudHQubGVuZ3RoLCAic3VfdFBvcyIpOworICAgICAgICAgICAgdGhpcy5zdV90UG9zID0gdGhpcy5kYXRhLnR0W3RoaXMuc3VfdFBvc107CisgICAgICAgICAgICB0aGlzLnN1X2kyKys7CisgICAgICAgICAgICB0aGlzLmN1cnJlbnRTdGF0ZSA9IE5PX1JBTkRfUEFSVF9CX1NUQVRFOworICAgICAgICAgICAgdGhpcy5jcmMudXBkYXRlQ1JDKHN1X2NoMlNoYWRvdyk7CisgICAgICAgICAgICByZXR1cm4gc3VfY2gyU2hhZG93OworICAgICAgICB9CisgICAgICAgIHRoaXMuY3VycmVudFN0YXRlID0gTk9fUkFORF9QQVJUX0FfU1RBVEU7CisgICAgICAgIGVuZEJsb2NrKCk7CisgICAgICAgIGluaXRCbG9jaygpOworICAgICAgICByZXR1cm4gc2V0dXBCbG9jaygpOworICAgIH0KKworICAgIHByaXZhdGUgaW50IHNldHVwUmFuZFBhcnRCKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHRoaXMuc3VfY2gyICE9IHRoaXMuc3VfY2hQcmV2KSB7CisgICAgICAgICAgICB0aGlzLmN1cnJlbnRTdGF0ZSA9IFJBTkRfUEFSVF9BX1NUQVRFOworICAgICAgICAgICAgdGhpcy5zdV9jb3VudCA9IDE7CisgICAgICAgICAgICByZXR1cm4gc2V0dXBSYW5kUGFydEEoKTsKKyAgICAgICAgfSBlbHNlIGlmICgrK3RoaXMuc3VfY291bnQgPj0gNCkgeworICAgICAgICAgICAgdGhpcy5zdV96ID0gKGNoYXIpICh0aGlzLmRhdGEubGw4W3RoaXMuc3VfdFBvc10gJiAweGZmKTsKKyAgICAgICAgICAgIGNoZWNrQm91bmRzKHRoaXMuc3VfdFBvcywgdGhpcy5kYXRhLnR0Lmxlbmd0aCwgInN1X3RQb3MiKTsKKyAgICAgICAgICAgIHRoaXMuc3VfdFBvcyA9IHRoaXMuZGF0YS50dFt0aGlzLnN1X3RQb3NdOworICAgICAgICAgICAgaWYgKHRoaXMuc3Vfck5Ub0dvID09IDApIHsKKyAgICAgICAgICAgICAgICB0aGlzLnN1X3JOVG9HbyA9IFJhbmQuck51bXModGhpcy5zdV9yVFBvcykgLSAxOworICAgICAgICAgICAgICAgIGlmICgrK3RoaXMuc3VfclRQb3MgPT0gNTEyKSB7CisgICAgICAgICAgICAgICAgICAgIHRoaXMuc3VfclRQb3MgPSAwOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdGhpcy5zdV9yTlRvR28tLTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRoaXMuc3VfajIgPSAwOworICAgICAgICAgICAgdGhpcy5jdXJyZW50U3RhdGUgPSBSQU5EX1BBUlRfQ19TVEFURTsKKyAgICAgICAgICAgIGlmICh0aGlzLnN1X3JOVG9HbyA9PSAxKSB7CisgICAgICAgICAgICAgICAgdGhpcy5zdV96IF49IDE7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gc2V0dXBSYW5kUGFydEMoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRoaXMuY3VycmVudFN0YXRlID0gUkFORF9QQVJUX0FfU1RBVEU7CisgICAgICAgICAgICByZXR1cm4gc2V0dXBSYW5kUGFydEEoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgaW50IHNldHVwUmFuZFBhcnRDKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHRoaXMuc3VfajIgPCB0aGlzLnN1X3opIHsKKyAgICAgICAgICAgIHRoaXMuY3JjLnVwZGF0ZUNSQyh0aGlzLnN1X2NoMik7CisgICAgICAgICAgICB0aGlzLnN1X2oyKys7CisgICAgICAgICAgICByZXR1cm4gdGhpcy5zdV9jaDI7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5jdXJyZW50U3RhdGUgPSBSQU5EX1BBUlRfQV9TVEFURTsKKyAgICAgICAgdGhpcy5zdV9pMisrOworICAgICAgICB0aGlzLnN1X2NvdW50ID0gMDsKKyAgICAgICAgcmV0dXJuIHNldHVwUmFuZFBhcnRBKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnQgc2V0dXBOb1JhbmRQYXJ0QigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICh0aGlzLnN1X2NoMiAhPSB0aGlzLnN1X2NoUHJldikgeworICAgICAgICAgICAgdGhpcy5zdV9jb3VudCA9IDE7CisgICAgICAgICAgICByZXR1cm4gc2V0dXBOb1JhbmRQYXJ0QSgpOworICAgICAgICB9IGVsc2UgaWYgKCsrdGhpcy5zdV9jb3VudCA+PSA0KSB7CisgICAgICAgICAgICBjaGVja0JvdW5kcyh0aGlzLnN1X3RQb3MsIHRoaXMuZGF0YS5sbDgubGVuZ3RoLCAic3VfdFBvcyIpOworICAgICAgICAgICAgdGhpcy5zdV96ID0gKGNoYXIpICh0aGlzLmRhdGEubGw4W3RoaXMuc3VfdFBvc10gJiAweGZmKTsKKyAgICAgICAgICAgIHRoaXMuc3VfdFBvcyA9IHRoaXMuZGF0YS50dFt0aGlzLnN1X3RQb3NdOworICAgICAgICAgICAgdGhpcy5zdV9qMiA9IDA7CisgICAgICAgICAgICByZXR1cm4gc2V0dXBOb1JhbmRQYXJ0QygpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIHNldHVwTm9SYW5kUGFydEEoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgaW50IHNldHVwTm9SYW5kUGFydEMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAodGhpcy5zdV9qMiA8IHRoaXMuc3VfeikgeworICAgICAgICAgICAgZmluYWwgaW50IHN1X2NoMlNoYWRvdyA9IHRoaXMuc3VfY2gyOworICAgICAgICAgICAgdGhpcy5jcmMudXBkYXRlQ1JDKHN1X2NoMlNoYWRvdyk7CisgICAgICAgICAgICB0aGlzLnN1X2oyKys7CisgICAgICAgICAgICB0aGlzLmN1cnJlbnRTdGF0ZSA9IE5PX1JBTkRfUEFSVF9DX1NUQVRFOworICAgICAgICAgICAgcmV0dXJuIHN1X2NoMlNoYWRvdzsKKyAgICAgICAgfQorICAgICAgICB0aGlzLnN1X2kyKys7CisgICAgICAgIHRoaXMuc3VfY291bnQgPSAwOworICAgICAgICByZXR1cm4gc2V0dXBOb1JhbmRQYXJ0QSgpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIERhdGEgeworCisgICAgICAgIC8vICh3aXRoIGJsb2NrU2l6ZSA5MDBrKQorICAgICAgICBmaW5hbCBib29sZWFuW10gaW5Vc2UgPSBuZXcgYm9vbGVhblsyNTZdOyAvLyAyNTYgYnl0ZQorCisgICAgICAgIGZpbmFsIGJ5dGVbXSBzZXFUb1Vuc2VxID0gbmV3IGJ5dGVbMjU2XTsgLy8gMjU2IGJ5dGUKKyAgICAgICAgZmluYWwgYnl0ZVtdIHNlbGVjdG9yID0gbmV3IGJ5dGVbTUFYX1NFTEVDVE9SU107IC8vIDE4MDAyIGJ5dGUKKyAgICAgICAgZmluYWwgYnl0ZVtdIHNlbGVjdG9yTXRmID0gbmV3IGJ5dGVbTUFYX1NFTEVDVE9SU107IC8vIDE4MDAyIGJ5dGUKKworICAgICAgICAvKioKKyAgICAgICAgICogRnJlcSB0YWJsZSBjb2xsZWN0ZWQgdG8gc2F2ZSBhIHBhc3Mgb3ZlciB0aGUgZGF0YSBkdXJpbmcKKyAgICAgICAgICogZGVjb21wcmVzc2lvbi4KKyAgICAgICAgICovCisgICAgICAgIGZpbmFsIGludFtdIHVuemZ0YWIgPSBuZXcgaW50WzI1Nl07IC8vIDEwMjQgYnl0ZQorCisgICAgICAgIGZpbmFsIGludFtdW10gbGltaXQgPSBuZXcgaW50W05fR1JPVVBTXVtNQVhfQUxQSEFfU0laRV07IC8vIDYxOTIgYnl0ZQorICAgICAgICBmaW5hbCBpbnRbXVtdIGJhc2UgPSBuZXcgaW50W05fR1JPVVBTXVtNQVhfQUxQSEFfU0laRV07IC8vIDYxOTIgYnl0ZQorICAgICAgICBmaW5hbCBpbnRbXVtdIHBlcm0gPSBuZXcgaW50W05fR1JPVVBTXVtNQVhfQUxQSEFfU0laRV07IC8vIDYxOTIgYnl0ZQorICAgICAgICBmaW5hbCBpbnRbXSBtaW5MZW5zID0gbmV3IGludFtOX0dST1VQU107IC8vIDI0IGJ5dGUKKworICAgICAgICBmaW5hbCBpbnRbXSBjZnRhYiA9IG5ldyBpbnRbMjU3XTsgLy8gMTAyOCBieXRlCisgICAgICAgIGZpbmFsIGNoYXJbXSBnZXRBbmRNb3ZlVG9Gcm9udERlY29kZV95eSA9IG5ldyBjaGFyWzI1Nl07IC8vIDUxMiBieXRlCisgICAgICAgIGZpbmFsIGNoYXJbXVtdIHRlbXBfY2hhckFycmF5MmQgPSBuZXcgY2hhcltOX0dST1VQU11bTUFYX0FMUEhBX1NJWkVdOyAvLyAzMDk2CisgICAgICAgIC8vIGJ5dGUKKyAgICAgICAgZmluYWwgYnl0ZVtdIHJlY3ZEZWNvZGluZ1RhYmxlc19wb3MgPSBuZXcgYnl0ZVtOX0dST1VQU107IC8vIDYgYnl0ZQorICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0KKyAgICAgICAgLy8gNjA3OTggYnl0ZQorCisgICAgICAgIGludFtdIHR0OyAvLyAzNjAwMDAwIGJ5dGUKKyAgICAgICAgYnl0ZVtdIGxsODsgLy8gOTAwMDAwIGJ5dGUKKworICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0KKyAgICAgICAgLy8gNDU2MDc4MiBieXRlCisgICAgICAgIC8vID09PT09PT09PT09PT09PQorCisgICAgICAgIERhdGEoZmluYWwgaW50IGJsb2NrU2l6ZTEwMGspIHsKKyAgICAgICAgICAgIHRoaXMubGw4ID0gbmV3IGJ5dGVbYmxvY2tTaXplMTAwayAqIEJaaXAyQ29uc3RhbnRzLkJBU0VCTE9DS1NJWkVdOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEluaXRpYWxpemVzIHRoZSB7QGxpbmsgI3R0fSBhcnJheS4KKyAgICAgICAgICoKKyAgICAgICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIHdoZW4gdGhlIHJlcXVpcmVkIGxlbmd0aCBvZiB0aGUgYXJyYXkgaXMga25vd24uCisgICAgICAgICAqIEkgZG9uJ3QgaW5pdGlhbGl6ZSBpdCBhdCBjb25zdHJ1Y3Rpb24gdGltZSB0byBhdm9pZCB1bm5lY2Nlc3NhcnkKKyAgICAgICAgICogbWVtb3J5IGFsbG9jYXRpb24gd2hlbiBjb21wcmVzc2luZyBzbWFsbCBmaWxlcy4KKyAgICAgICAgICovCisgICAgICAgIGludFtdIGluaXRUVChmaW5hbCBpbnQgbGVuZ3RoKSB7CisgICAgICAgICAgICBpbnRbXSB0dFNoYWRvdyA9IHRoaXMudHQ7CisKKyAgICAgICAgICAgIC8vIHR0Lmxlbmd0aCBzaG91bGQgYWx3YXlzIGJlID49IGxlbmd0aCwgYnV0IHRoZW9yZXRpY2FsbHkKKyAgICAgICAgICAgIC8vIGl0IGNhbiBoYXBwZW4sIGlmIHRoZSBjb21wcmVzc29yIG1peGVkIHNtYWxsIGFuZCBsYXJnZQorICAgICAgICAgICAgLy8gYmxvY2tzLiBOb3JtYWxseSBvbmx5IHRoZSBsYXN0IGJsb2NrIHdpbGwgYmUgc21hbGxlcgorICAgICAgICAgICAgLy8gdGhhbiBvdGhlcnMuCisgICAgICAgICAgICBpZiAoKHR0U2hhZG93ID09IG51bGwpIHx8ICh0dFNoYWRvdy5sZW5ndGggPCBsZW5ndGgpKSB7CisgICAgICAgICAgICAgICAgdGhpcy50dCA9IHR0U2hhZG93ID0gbmV3IGludFtsZW5ndGhdOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICByZXR1cm4gdHRTaGFkb3c7CisgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrcyBpZiB0aGUgc2lnbmF0dXJlIG1hdGNoZXMgd2hhdCBpcyBleHBlY3RlZCBmb3IgYSBiemlwMiBmaWxlLgorICAgICAqCisgICAgICogQHBhcmFtIHNpZ25hdHVyZQorICAgICAqICAgICAgICAgICAgdGhlIGJ5dGVzIHRvIGNoZWNrCisgICAgICogQHBhcmFtIGxlbmd0aAorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBieXRlcyB0byBjaGVjaworICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhpcyBzdHJlYW0gaXMgYSBiemlwMiBjb21wcmVzc2VkIHN0cmVhbSwgZmFsc2Ugb3RoZXJ3aXNlCisgICAgICoKKyAgICAgKiBAc2luY2UgMS4xCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIG1hdGNoZXMoZmluYWwgYnl0ZVtdIHNpZ25hdHVyZSwgZmluYWwgaW50IGxlbmd0aCkgeworICAgICAgICByZXR1cm4gbGVuZ3RoID49IDMgJiYgc2lnbmF0dXJlWzBdID09ICdCJyAmJgorICAgICAgICAgICAgICAgIHNpZ25hdHVyZVsxXSA9PSAnWicgJiYgc2lnbmF0dXJlWzJdID09ICdoJzsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9iemlwMi9CWmlwMkNvbXByZXNzb3JPdXRwdXRTdHJlYW0uamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2J6aXAyL0JaaXAyQ29tcHJlc3Nvck91dHB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNjY2YzOGQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9iemlwMi9CWmlwMkNvbXByZXNzb3JPdXRwdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDEzMzcgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuYnppcDI7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLkNvbXByZXNzb3JPdXRwdXRTdHJlYW07CisKKy8qKgorICogQW4gb3V0cHV0IHN0cmVhbSB0aGF0IGNvbXByZXNzZXMgaW50byB0aGUgQlppcDIgZm9ybWF0IGludG8gYW5vdGhlciBzdHJlYW0uCisgKgorICogPHA+CisgKiBUaGUgY29tcHJlc3Npb24gcmVxdWlyZXMgbGFyZ2UgYW1vdW50cyBvZiBtZW1vcnkuIFRodXMgeW91IHNob3VsZCBjYWxsIHRoZQorICoge0BsaW5rICNjbG9zZSgpIGNsb3NlKCl9IG1ldGhvZCBhcyBzb29uIGFzIHBvc3NpYmxlLCB0byBmb3JjZQorICoge0Bjb2RlIEJaaXAyQ29tcHJlc3Nvck91dHB1dFN0cmVhbX0gdG8gcmVsZWFzZSB0aGUgYWxsb2NhdGVkIG1lbW9yeS4KKyAqIDwvcD4KKyAqCisgKiA8cD4gWW91IGNhbiBzaHJpbmsgdGhlIGFtb3VudCBvZiBhbGxvY2F0ZWQgbWVtb3J5IGFuZCBtYXliZSByYWlzZQorICogdGhlIGNvbXByZXNzaW9uIHNwZWVkIGJ5IGNob29zaW5nIGEgbG93ZXIgYmxvY2tzaXplLCB3aGljaCBpbiB0dXJuCisgKiBtYXkgY2F1c2UgYSBsb3dlciBjb21wcmVzc2lvbiByYXRpby4gWW91IGNhbiBhdm9pZCB1bm5lY2Vzc2FyeQorICogbWVtb3J5IGFsbG9jYXRpb24gYnkgYXZvaWRpbmcgdXNpbmcgYSBibG9ja3NpemUgd2hpY2ggaXMgYmlnZ2VyCisgKiB0aGFuIHRoZSBzaXplIG9mIHRoZSBpbnB1dC4gIDwvcD4KKyAqCisgKiA8cD4gWW91IGNhbiBjb21wdXRlIHRoZSBtZW1vcnkgdXNhZ2UgZm9yIGNvbXByZXNzaW5nIGJ5IHRoZQorICogZm9sbG93aW5nIGZvcm11bGE6IDwvcD4KKyAqCisgKiA8cHJlPgorICogJmx0O2NvZGUmZ3Q7NDAwayArICg5ICogYmxvY2tzaXplKSZsdDsvY29kZSZndDsuCisgKiA8L3ByZT4KKyAqCisgKiA8cD4gVG8gZ2V0IHRoZSBtZW1vcnkgcmVxdWlyZWQgZm9yIGRlY29tcHJlc3Npb24gYnkge0BsaW5rCisgKiBCWmlwMkNvbXByZXNzb3JJbnB1dFN0cmVhbX0gdXNlIDwvcD4KKyAqCisgKiA8cHJlPgorICogJmx0O2NvZGUmZ3Q7NjVrICsgKDUgKiBibG9ja3NpemUpJmx0Oy9jb2RlJmd0Oy4KKyAqIDwvcHJlPgorICoKKyAqIDx0YWJsZSB3aWR0aD0iMTAwJSIgYm9yZGVyPSIxIiBzdW1tYXJ5PSJNZW1vcnkgdXNhZ2UgYnkgYmxvY2tzaXplIj4KKyAqIDx0cj4KKyAqIDx0aCBjb2xzcGFuPSIzIj5NZW1vcnkgdXNhZ2UgYnkgYmxvY2tzaXplPC90aD4KKyAqIDwvdHI+CisgKiA8dHI+CisgKiA8dGggYWxpZ249InJpZ2h0Ij5CbG9ja3NpemU8L3RoPiA8dGggYWxpZ249InJpZ2h0Ij5Db21wcmVzc2lvbjxicj4KKyAqIG1lbW9yeSB1c2FnZTwvdGg+IDx0aCBhbGlnbj0icmlnaHQiPkRlY29tcHJlc3Npb248YnI+CisgKiBtZW1vcnkgdXNhZ2U8L3RoPgorICogPC90cj4KKyAqIDx0cj4KKyAqIDx0ZCBhbGlnbj0icmlnaHQiPjEwMGs8L3RkPgorICogPHRkIGFsaWduPSJyaWdodCI+MTMwMGs8L3RkPgorICogPHRkIGFsaWduPSJyaWdodCI+NTY1azwvdGQ+CisgKiA8L3RyPgorICogPHRyPgorICogPHRkIGFsaWduPSJyaWdodCI+MjAwazwvdGQ+CisgKiA8dGQgYWxpZ249InJpZ2h0Ij4yMjAwazwvdGQ+CisgKiA8dGQgYWxpZ249InJpZ2h0Ij4xMDY1azwvdGQ+CisgKiA8L3RyPgorICogPHRyPgorICogPHRkIGFsaWduPSJyaWdodCI+MzAwazwvdGQ+CisgKiA8dGQgYWxpZ249InJpZ2h0Ij4zMTAwazwvdGQ+CisgKiA8dGQgYWxpZ249InJpZ2h0Ij4xNTY1azwvdGQ+CisgKiA8L3RyPgorICogPHRyPgorICogPHRkIGFsaWduPSJyaWdodCI+NDAwazwvdGQ+CisgKiA8dGQgYWxpZ249InJpZ2h0Ij40MDAwazwvdGQ+CisgKiA8dGQgYWxpZ249InJpZ2h0Ij4yMDY1azwvdGQ+CisgKiA8L3RyPgorICogPHRyPgorICogPHRkIGFsaWduPSJyaWdodCI+NTAwazwvdGQ+CisgKiA8dGQgYWxpZ249InJpZ2h0Ij40OTAwazwvdGQ+CisgKiA8dGQgYWxpZ249InJpZ2h0Ij4yNTY1azwvdGQ+CisgKiA8L3RyPgorICogPHRyPgorICogPHRkIGFsaWduPSJyaWdodCI+NjAwazwvdGQ+CisgKiA8dGQgYWxpZ249InJpZ2h0Ij41ODAwazwvdGQ+CisgKiA8dGQgYWxpZ249InJpZ2h0Ij4zMDY1azwvdGQ+CisgKiA8L3RyPgorICogPHRyPgorICogPHRkIGFsaWduPSJyaWdodCI+NzAwazwvdGQ+CisgKiA8dGQgYWxpZ249InJpZ2h0Ij42NzAwazwvdGQ+CisgKiA8dGQgYWxpZ249InJpZ2h0Ij4zNTY1azwvdGQ+CisgKiA8L3RyPgorICogPHRyPgorICogPHRkIGFsaWduPSJyaWdodCI+ODAwazwvdGQ+CisgKiA8dGQgYWxpZ249InJpZ2h0Ij43NjAwazwvdGQ+CisgKiA8dGQgYWxpZ249InJpZ2h0Ij40MDY1azwvdGQ+CisgKiA8L3RyPgorICogPHRyPgorICogPHRkIGFsaWduPSJyaWdodCI+OTAwazwvdGQ+CisgKiA8dGQgYWxpZ249InJpZ2h0Ij44NTAwazwvdGQ+CisgKiA8dGQgYWxpZ249InJpZ2h0Ij40NTY1azwvdGQ+CisgKiA8L3RyPgorICogPC90YWJsZT4KKyAqCisgKiA8cD4KKyAqIEZvciBkZWNvbXByZXNzaW9uIHtAY29kZSBCWmlwMkNvbXByZXNzb3JJbnB1dFN0cmVhbX0gYWxsb2NhdGVzIGxlc3MgbWVtb3J5IGlmIHRoZQorICogYnppcHBlZCBpbnB1dCBpcyBzbWFsbGVyIHRoYW4gb25lIGJsb2NrLgorICogPC9wPgorICoKKyAqIDxwPgorICogSW5zdGFuY2VzIG9mIHRoaXMgY2xhc3MgYXJlIG5vdCB0aHJlYWRzYWZlLgorICogPC9wPgorICoKKyAqIDxwPgorICogVE9ETzogVXBkYXRlIHRvIEJaaXAyIDEuMC4xCisgKiA8L3A+CisgKiBATm90VGhyZWFkU2FmZQorICovCitwdWJsaWMgY2xhc3MgQlppcDJDb21wcmVzc29yT3V0cHV0U3RyZWFtIGV4dGVuZHMgQ29tcHJlc3Nvck91dHB1dFN0cmVhbQorICAgIGltcGxlbWVudHMgQlppcDJDb25zdGFudHMgeworCisgICAgLyoqCisgICAgICogVGhlIG1pbmltdW0gc3VwcG9ydGVkIGJsb2Nrc2l6ZSB7QGNvZGUgID09IDF9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1JTl9CTE9DS1NJWkUgPSAxOworCisgICAgLyoqCisgICAgICogVGhlIG1heGltdW0gc3VwcG9ydGVkIGJsb2Nrc2l6ZSB7QGNvZGUgID09IDl9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BWF9CTE9DS1NJWkUgPSA5OworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEdSRUFURVJfSUNPU1QgPSAxNTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTEVTU0VSX0lDT1NUID0gMDsKKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgaGJNYWtlQ29kZUxlbmd0aHMoZmluYWwgYnl0ZVtdIGxlbiwgZmluYWwgaW50W10gZnJlcSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIERhdGEgZGF0LCBmaW5hbCBpbnQgYWxwaGFTaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IG1heExlbikgeworICAgICAgICAvKgorICAgICAgICAgKiBOb2RlcyBhbmQgaGVhcCBlbnRyaWVzIHJ1biBmcm9tIDEuIEVudHJ5IDAgZm9yIGJvdGggdGhlIGhlYXAgYW5kCisgICAgICAgICAqIG5vZGVzIGlzIGEgc2VudGluZWwuCisgICAgICAgICAqLworICAgICAgICBmaW5hbCBpbnRbXSBoZWFwID0gZGF0LmhlYXA7CisgICAgICAgIGZpbmFsIGludFtdIHdlaWdodCA9IGRhdC53ZWlnaHQ7CisgICAgICAgIGZpbmFsIGludFtdIHBhcmVudCA9IGRhdC5wYXJlbnQ7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IGFscGhhU2l6ZTsgLS1pID49IDA7KSB7CisgICAgICAgICAgICB3ZWlnaHRbaSArIDFdID0gKGZyZXFbaV0gPT0gMCA/IDEgOiBmcmVxW2ldKSA8PCA4OworICAgICAgICB9CisKKyAgICAgICAgZm9yIChib29sZWFuIHRvb0xvbmcgPSB0cnVlOyB0b29Mb25nOykgeworICAgICAgICAgICAgdG9vTG9uZyA9IGZhbHNlOworCisgICAgICAgICAgICBpbnQgbk5vZGVzID0gYWxwaGFTaXplOworICAgICAgICAgICAgaW50IG5IZWFwID0gMDsKKyAgICAgICAgICAgIGhlYXBbMF0gPSAwOworICAgICAgICAgICAgd2VpZ2h0WzBdID0gMDsKKyAgICAgICAgICAgIHBhcmVudFswXSA9IC0yOworCisgICAgICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8PSBhbHBoYVNpemU7IGkrKykgeworICAgICAgICAgICAgICAgIHBhcmVudFtpXSA9IC0xOworICAgICAgICAgICAgICAgIG5IZWFwKys7CisgICAgICAgICAgICAgICAgaGVhcFtuSGVhcF0gPSBpOworCisgICAgICAgICAgICAgICAgaW50IHp6ID0gbkhlYXA7CisgICAgICAgICAgICAgICAgZmluYWwgaW50IHRtcCA9IGhlYXBbenpdOworICAgICAgICAgICAgICAgIHdoaWxlICh3ZWlnaHRbdG1wXSA8IHdlaWdodFtoZWFwW3p6ID4+IDFdXSkgeworICAgICAgICAgICAgICAgICAgICBoZWFwW3p6XSA9IGhlYXBbenogPj4gMV07CisgICAgICAgICAgICAgICAgICAgIHp6ID4+PSAxOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBoZWFwW3p6XSA9IHRtcDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgd2hpbGUgKG5IZWFwID4gMSkgeworICAgICAgICAgICAgICAgIGZpbmFsIGludCBuMSA9IGhlYXBbMV07CisgICAgICAgICAgICAgICAgaGVhcFsxXSA9IGhlYXBbbkhlYXBdOworICAgICAgICAgICAgICAgIG5IZWFwLS07CisKKyAgICAgICAgICAgICAgICBpbnQgeXkgPSAwOworICAgICAgICAgICAgICAgIGludCB6eiA9IDE7CisgICAgICAgICAgICAgICAgaW50IHRtcCA9IGhlYXBbMV07CisKKyAgICAgICAgICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgICAgICAgICB5eSA9IHp6IDw8IDE7CisKKyAgICAgICAgICAgICAgICAgICAgaWYgKHl5ID4gbkhlYXApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgaWYgKCh5eSA8IG5IZWFwKQorICAgICAgICAgICAgICAgICAgICAgICAgJiYgKHdlaWdodFtoZWFwW3l5ICsgMV1dIDwgd2VpZ2h0W2hlYXBbeXldXSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHl5Kys7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBpZiAod2VpZ2h0W3RtcF0gPCB3ZWlnaHRbaGVhcFt5eV1dKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIGhlYXBbenpdID0gaGVhcFt5eV07CisgICAgICAgICAgICAgICAgICAgIHp6ID0geXk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgaGVhcFt6el0gPSB0bXA7CisKKyAgICAgICAgICAgICAgICBmaW5hbCBpbnQgbjIgPSBoZWFwWzFdOworICAgICAgICAgICAgICAgIGhlYXBbMV0gPSBoZWFwW25IZWFwXTsKKyAgICAgICAgICAgICAgICBuSGVhcC0tOworCisgICAgICAgICAgICAgICAgeXkgPSAwOworICAgICAgICAgICAgICAgIHp6ID0gMTsKKyAgICAgICAgICAgICAgICB0bXAgPSBoZWFwWzFdOworCisgICAgICAgICAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgICAgICAgICAgeXkgPSB6eiA8PCAxOworCisgICAgICAgICAgICAgICAgICAgIGlmICh5eSA+IG5IZWFwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIGlmICgoeXkgPCBuSGVhcCkKKyAgICAgICAgICAgICAgICAgICAgICAgICYmICh3ZWlnaHRbaGVhcFt5eSArIDFdXSA8IHdlaWdodFtoZWFwW3l5XV0pKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB5eSsrOworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgaWYgKHdlaWdodFt0bXBdIDwgd2VpZ2h0W2hlYXBbeXldXSkgeworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBoZWFwW3p6XSA9IGhlYXBbeXldOworICAgICAgICAgICAgICAgICAgICB6eiA9IHl5OworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGhlYXBbenpdID0gdG1wOworICAgICAgICAgICAgICAgIG5Ob2RlcysrOworICAgICAgICAgICAgICAgIHBhcmVudFtuMV0gPSBwYXJlbnRbbjJdID0gbk5vZGVzOworCisgICAgICAgICAgICAgICAgZmluYWwgaW50IHdlaWdodF9uMSA9IHdlaWdodFtuMV07CisgICAgICAgICAgICAgICAgZmluYWwgaW50IHdlaWdodF9uMiA9IHdlaWdodFtuMl07CisgICAgICAgICAgICAgICAgd2VpZ2h0W25Ob2Rlc10gPSAoKHdlaWdodF9uMSAmIDB4ZmZmZmZmMDApCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAod2VpZ2h0X24yICYgMHhmZmZmZmYwMCkpCisgICAgICAgICAgICAgICAgICAgIHwgKDEgKyAoKCh3ZWlnaHRfbjEgJiAweDAwMDAwMGZmKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+ICh3ZWlnaHRfbjIgJiAweDAwMDAwMGZmKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICA/ICh3ZWlnaHRfbjEgJiAweDAwMDAwMGZmKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogKHdlaWdodF9uMiAmIDB4MDAwMDAwZmYpKSk7CisKKyAgICAgICAgICAgICAgICBwYXJlbnRbbk5vZGVzXSA9IC0xOworICAgICAgICAgICAgICAgIG5IZWFwKys7CisgICAgICAgICAgICAgICAgaGVhcFtuSGVhcF0gPSBuTm9kZXM7CisKKyAgICAgICAgICAgICAgICB0bXAgPSAwOworICAgICAgICAgICAgICAgIHp6ID0gbkhlYXA7CisgICAgICAgICAgICAgICAgdG1wID0gaGVhcFt6el07CisgICAgICAgICAgICAgICAgZmluYWwgaW50IHdlaWdodF90bXAgPSB3ZWlnaHRbdG1wXTsKKyAgICAgICAgICAgICAgICB3aGlsZSAod2VpZ2h0X3RtcCA8IHdlaWdodFtoZWFwW3p6ID4+IDFdXSkgeworICAgICAgICAgICAgICAgICAgICBoZWFwW3p6XSA9IGhlYXBbenogPj4gMV07CisgICAgICAgICAgICAgICAgICAgIHp6ID4+PSAxOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBoZWFwW3p6XSA9IHRtcDsKKworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8PSBhbHBoYVNpemU7IGkrKykgeworICAgICAgICAgICAgICAgIGludCBqID0gMDsKKyAgICAgICAgICAgICAgICBpbnQgayA9IGk7CisKKyAgICAgICAgICAgICAgICBmb3IgKGludCBwYXJlbnRfazsgKHBhcmVudF9rID0gcGFyZW50W2tdKSA+PSAwOykgeworICAgICAgICAgICAgICAgICAgICBrID0gcGFyZW50X2s7CisgICAgICAgICAgICAgICAgICAgIGorKzsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBsZW5baSAtIDFdID0gKGJ5dGUpIGo7CisgICAgICAgICAgICAgICAgaWYgKGogPiBtYXhMZW4pIHsKKyAgICAgICAgICAgICAgICAgICAgdG9vTG9uZyA9IHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAodG9vTG9uZykgeworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAxOyBpIDwgYWxwaGFTaXplOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgaW50IGogPSB3ZWlnaHRbaV0gPj4gODsKKyAgICAgICAgICAgICAgICAgICAgaiA9IDEgKyAoaiA+PiAxKTsKKyAgICAgICAgICAgICAgICAgICAgd2VpZ2h0W2ldID0gaiA8PCA4OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGV4IG9mIHRoZSBsYXN0IGNoYXIgaW4gdGhlIGJsb2NrLCBzbyB0aGUgYmxvY2sgc2l6ZSA9PSBsYXN0ICsgMS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBsYXN0OworCisgICAgLyoqCisgICAgICogQWx3YXlzOiBpbiB0aGUgcmFuZ2UgMCAuLiA5LiBUaGUgY3VycmVudCBibG9jayBzaXplIGlzIDEwMDAwMCAqIHRoaXMKKyAgICAgKiBudW1iZXIuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgYmxvY2tTaXplMTAwazsKKworICAgIHByaXZhdGUgaW50IGJzQnVmZjsKKyAgICBwcml2YXRlIGludCBic0xpdmU7CisgICAgcHJpdmF0ZSBmaW5hbCBDUkMgY3JjID0gbmV3IENSQygpOworCisgICAgcHJpdmF0ZSBpbnQgbkluVXNlOworCisgICAgcHJpdmF0ZSBpbnQgbk1URjsKKworICAgIHByaXZhdGUgaW50IGN1cnJlbnRDaGFyID0gLTE7CisgICAgcHJpdmF0ZSBpbnQgcnVuTGVuZ3RoID0gMDsKKworICAgIHByaXZhdGUgaW50IGJsb2NrQ1JDOworICAgIHByaXZhdGUgaW50IGNvbWJpbmVkQ1JDOworICAgIHByaXZhdGUgZmluYWwgaW50IGFsbG93YWJsZUJsb2NrU2l6ZTsKKworICAgIC8qKgorICAgICAqIEFsbCBtZW1vcnkgaW50ZW5zaXZlIHN0dWZmLgorICAgICAqLworICAgIHByaXZhdGUgRGF0YSBkYXRhOworICAgIHByaXZhdGUgQmxvY2tTb3J0IGJsb2NrU29ydGVyOworCisgICAgcHJpdmF0ZSBPdXRwdXRTdHJlYW0gb3V0OworICAgIHByaXZhdGUgdm9sYXRpbGUgYm9vbGVhbiBjbG9zZWQ7CisKKyAgICAvKioKKyAgICAgKiBDaG9vc2VzIGEgYmxvY2tzaXplIGJhc2VkIG9uIHRoZSBnaXZlbiBsZW5ndGggb2YgdGhlIGRhdGEgdG8gY29tcHJlc3MuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoZSBibG9ja3NpemUsIGJldHdlZW4ge0BsaW5rICNNSU5fQkxPQ0tTSVpFfSBhbmQKKyAgICAgKiAgICAgICAgIHtAbGluayAjTUFYX0JMT0NLU0laRX0gYm90aCBpbmNsdXNpdmUuIEZvciBhIG5lZ2F0aXZlCisgICAgICogICAgICAgICB7QGNvZGUgaW5wdXRMZW5ndGh9IHRoaXMgbWV0aG9kIHJldHVybnMge0Bjb2RlIE1BWF9CTE9DS1NJWkV9CisgICAgICogICAgICAgICBhbHdheXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5wdXRMZW5ndGgKKyAgICAgKiAgICAgICAgICAgIFRoZSBsZW5ndGggb2YgdGhlIGRhdGEgd2hpY2ggd2lsbCBiZSBjb21wcmVzc2VkIGJ5CisgICAgICogICAgICAgICAgICB7QGNvZGUgQlppcDJDb21wcmVzc29yT3V0cHV0U3RyZWFtfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBjaG9vc2VCbG9ja1NpemUoZmluYWwgbG9uZyBpbnB1dExlbmd0aCkgeworICAgICAgICByZXR1cm4gKGlucHV0TGVuZ3RoID4gMCkgPyAoaW50KSBNYXRoCisgICAgICAgICAgICAubWluKChpbnB1dExlbmd0aCAvIDEzMjAwMCkgKyAxLCA5KSA6IE1BWF9CTE9DS1NJWkU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgQlppcDJDb21wcmVzc29yT3V0cHV0U3RyZWFtfSB3aXRoIGEgYmxvY2tzaXplIG9mIDkwMGsuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3V0CisgICAgICogICAgICAgICAgICB0aGUgZGVzdGluYXRpb24gc3RyZWFtLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMgaW4gdGhlIHNwZWNpZmllZCBzdHJlYW0uCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIDxjb2RlPm91dCA9PSBudWxsPC9jb2RlPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgQlppcDJDb21wcmVzc29yT3V0cHV0U3RyZWFtKGZpbmFsIE91dHB1dFN0cmVhbSBvdXQpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMob3V0LCBNQVhfQkxPQ0tTSVpFKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBCWmlwMkNvbXByZXNzb3JPdXRwdXRTdHJlYW19IHdpdGggc3BlY2lmaWVkIGJsb2Nrc2l6ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXN0aW5hdGlvbiBzdHJlYW0uCisgICAgICogQHBhcmFtIGJsb2NrU2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIGJsb2NrU2l6ZSBhcyAxMDBrIHVuaXRzLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMgaW4gdGhlIHNwZWNpZmllZCBzdHJlYW0uCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiA8Y29kZT4oYmxvY2tTaXplICZsdDsgMSkgfHwgKGJsb2NrU2l6ZSAmZ3Q7IDkpPC9jb2RlPi4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgPGNvZGU+b3V0ID09IG51bGw8L2NvZGU+LgorICAgICAqCisgICAgICogQHNlZSAjTUlOX0JMT0NLU0laRQorICAgICAqIEBzZWUgI01BWF9CTE9DS1NJWkUKKyAgICAgKi8KKyAgICBwdWJsaWMgQlppcDJDb21wcmVzc29yT3V0cHV0U3RyZWFtKGZpbmFsIE91dHB1dFN0cmVhbSBvdXQsIGZpbmFsIGludCBibG9ja1NpemUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChibG9ja1NpemUgPCAxKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJibG9ja1NpemUoIiArIGJsb2NrU2l6ZSArICIpIDwgMSIpOworICAgICAgICB9CisgICAgICAgIGlmIChibG9ja1NpemUgPiA5KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJibG9ja1NpemUoIiArIGJsb2NrU2l6ZSArICIpID4gOSIpOworICAgICAgICB9CisKKyAgICAgICAgdGhpcy5ibG9ja1NpemUxMDBrID0gYmxvY2tTaXplOworICAgICAgICB0aGlzLm91dCA9IG91dDsKKworICAgICAgICAvKiAyMCBpcyBqdXN0IGEgcGFyYW5vaWEgY29uc3RhbnQgKi8KKyAgICAgICAgdGhpcy5hbGxvd2FibGVCbG9ja1NpemUgPSAodGhpcy5ibG9ja1NpemUxMDBrICogQlppcDJDb25zdGFudHMuQkFTRUJMT0NLU0laRSkgLSAyMDsKKyAgICAgICAgaW5pdCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGZpbmFsIGludCBiKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoIWNsb3NlZCkgeworICAgICAgICAgICAgd3JpdGUwKGIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJjbG9zZWQiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyB0aGUgY3VycmVudCBieXRlIHRvIHRoZSBidWZmZXIsIHJ1bi1sZW5ndGggZW5jb2RpbmcgaXQKKyAgICAgKiBpZiBpdCBoYXMgYmVlbiByZXBlYXRlZCBhdCBsZWFzdCBmb3VyIHRpbWVzICh0aGUgZmlyc3Qgc3RlcAorICAgICAqIFJMRXMgc2VxdWVuY2VzIG9mIGZvdXIgaWRlbnRpY2FsIGJ5dGVzKS4KKyAgICAgKgorICAgICAqIDxwPkZsdXNoZXMgdGhlIGN1cnJlbnQgYmxvY2sgYmVmb3JlIHdyaXRpbmcgZGF0YSBpZiBpdCBpcworICAgICAqIGZ1bGwuPC9wPgorICAgICAqCisgICAgICogPHA+IndyaXRlIHRvIHRoZSBidWZmZXIiIG1lYW5zIGFkZGluZyB0byBkYXRhLmJ1ZmZlciBzdGFydGluZworICAgICAqIHR3byBzdGVwcyAiYWZ0ZXIiIHRoaXMubGFzdCAtIGluaXRpYWxseSBzdGFydGluZyBhdCBpbmRleCAxCisgICAgICogKG5vdCAwKSAtIGFuZCB1cGRhdGluZyB0aGlzLmxhc3QgdG8gcG9pbnQgdG8gdGhlIGxhc3QgaW5kZXgKKyAgICAgKiB3cml0dGVuIG1pbnVzIDEuPC9wPgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCB3cml0ZVJ1bigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIGludCBsYXN0U2hhZG93ID0gdGhpcy5sYXN0OworCisgICAgICAgIGlmIChsYXN0U2hhZG93IDwgdGhpcy5hbGxvd2FibGVCbG9ja1NpemUpIHsKKyAgICAgICAgICAgIGZpbmFsIGludCBjdXJyZW50Q2hhclNoYWRvdyA9IHRoaXMuY3VycmVudENoYXI7CisgICAgICAgICAgICBmaW5hbCBEYXRhIGRhdGFTaGFkb3cgPSB0aGlzLmRhdGE7CisgICAgICAgICAgICBkYXRhU2hhZG93LmluVXNlW2N1cnJlbnRDaGFyU2hhZG93XSA9IHRydWU7CisgICAgICAgICAgICBmaW5hbCBieXRlIGNoID0gKGJ5dGUpIGN1cnJlbnRDaGFyU2hhZG93OworCisgICAgICAgICAgICBpbnQgcnVuTGVuZ3RoU2hhZG93ID0gdGhpcy5ydW5MZW5ndGg7CisgICAgICAgICAgICB0aGlzLmNyYy51cGRhdGVDUkMoY3VycmVudENoYXJTaGFkb3csIHJ1bkxlbmd0aFNoYWRvdyk7CisKKyAgICAgICAgICAgIHN3aXRjaCAocnVuTGVuZ3RoU2hhZG93KSB7CisgICAgICAgICAgICBjYXNlIDE6CisgICAgICAgICAgICAgICAgZGF0YVNoYWRvdy5ibG9ja1tsYXN0U2hhZG93ICsgMl0gPSBjaDsKKyAgICAgICAgICAgICAgICB0aGlzLmxhc3QgPSBsYXN0U2hhZG93ICsgMTsKKyAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgY2FzZSAyOgorICAgICAgICAgICAgICAgIGRhdGFTaGFkb3cuYmxvY2tbbGFzdFNoYWRvdyArIDJdID0gY2g7CisgICAgICAgICAgICAgICAgZGF0YVNoYWRvdy5ibG9ja1tsYXN0U2hhZG93ICsgM10gPSBjaDsKKyAgICAgICAgICAgICAgICB0aGlzLmxhc3QgPSBsYXN0U2hhZG93ICsgMjsKKyAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgY2FzZSAzOiB7CisgICAgICAgICAgICAgICAgZmluYWwgYnl0ZVtdIGJsb2NrID0gZGF0YVNoYWRvdy5ibG9jazsKKyAgICAgICAgICAgICAgICBibG9ja1tsYXN0U2hhZG93ICsgMl0gPSBjaDsKKyAgICAgICAgICAgICAgICBibG9ja1tsYXN0U2hhZG93ICsgM10gPSBjaDsKKyAgICAgICAgICAgICAgICBibG9ja1tsYXN0U2hhZG93ICsgNF0gPSBjaDsKKyAgICAgICAgICAgICAgICB0aGlzLmxhc3QgPSBsYXN0U2hhZG93ICsgMzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgZGVmYXVsdDogeworICAgICAgICAgICAgICAgIHJ1bkxlbmd0aFNoYWRvdyAtPSA0OworICAgICAgICAgICAgICAgIGRhdGFTaGFkb3cuaW5Vc2VbcnVuTGVuZ3RoU2hhZG93XSA9IHRydWU7CisgICAgICAgICAgICAgICAgZmluYWwgYnl0ZVtdIGJsb2NrID0gZGF0YVNoYWRvdy5ibG9jazsKKyAgICAgICAgICAgICAgICBibG9ja1tsYXN0U2hhZG93ICsgMl0gPSBjaDsKKyAgICAgICAgICAgICAgICBibG9ja1tsYXN0U2hhZG93ICsgM10gPSBjaDsKKyAgICAgICAgICAgICAgICBibG9ja1tsYXN0U2hhZG93ICsgNF0gPSBjaDsKKyAgICAgICAgICAgICAgICBibG9ja1tsYXN0U2hhZG93ICsgNV0gPSBjaDsKKyAgICAgICAgICAgICAgICBibG9ja1tsYXN0U2hhZG93ICsgNl0gPSAoYnl0ZSkgcnVuTGVuZ3RoU2hhZG93OworICAgICAgICAgICAgICAgIHRoaXMubGFzdCA9IGxhc3RTaGFkb3cgKyA1OworICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBlbmRCbG9jaygpOworICAgICAgICAgICAgaW5pdEJsb2NrKCk7CisgICAgICAgICAgICB3cml0ZVJ1bigpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogT3ZlcnJpZGVuIHRvIHdhcm4gYWJvdXQgYW4gdW5jbG9zZWQgc3RyZWFtLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIGZpbmFsaXplKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIGlmICghY2xvc2VkKSB7CisgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIlVuY2xvc2VkIEJaaXAyQ29tcHJlc3Nvck91dHB1dFN0cmVhbSBkZXRlY3RlZCwgd2lsbCAqbm90KiBjbG9zZSBpdCIpOworICAgICAgICB9CisgICAgICAgIHN1cGVyLmZpbmFsaXplKCk7CisgICAgfQorCisKKyAgICBwdWJsaWMgdm9pZCBmaW5pc2goKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoIWNsb3NlZCkgeworICAgICAgICAgICAgY2xvc2VkID0gdHJ1ZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaWYgKHRoaXMucnVuTGVuZ3RoID4gMCkgeworICAgICAgICAgICAgICAgICAgICB3cml0ZVJ1bigpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRDaGFyID0gLTE7CisgICAgICAgICAgICAgICAgZW5kQmxvY2soKTsKKyAgICAgICAgICAgICAgICBlbmRDb21wcmVzc2lvbigpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICB0aGlzLm91dCA9IG51bGw7CisgICAgICAgICAgICAgICAgdGhpcy5ibG9ja1NvcnRlciA9IG51bGw7CisgICAgICAgICAgICAgICAgdGhpcy5kYXRhID0gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFjbG9zZWQpIHsKKyAgICAgICAgICAgIGZpbmFsIE91dHB1dFN0cmVhbSBvdXRTaGFkb3cgPSB0aGlzLm91dDsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZmluaXNoKCk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIG91dFNoYWRvdy5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZmx1c2goKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBPdXRwdXRTdHJlYW0gb3V0U2hhZG93ID0gdGhpcy5vdXQ7CisgICAgICAgIGlmIChvdXRTaGFkb3cgIT0gbnVsbCkgeworICAgICAgICAgICAgb3V0U2hhZG93LmZsdXNoKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgbWFnaWMgYnl0ZXMgbGlrZSBCWiBvbiB0aGUgZmlyc3QgcG9zaXRpb24gb2YgdGhlIHN0cmVhbQorICAgICAqIGFuZCBieXRlcyBpbmRpY2lhdGluZyB0aGUgZmlsZS1mb3JtYXQsIHdoaWNoIGlzCisgICAgICogaHVmZm1hbmlzZWQsIGZvbGxvd2VkIGJ5IGEgZGlnaXQgaW5kaWNhdGluZyBibG9ja1NpemUxMDBrLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgdGhlIG1hZ2ljIGJ5dGVzIGNvdWxkIG5vdCBiZWVuIHdyaXR0ZW4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgaW5pdCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJzUHV0VUJ5dGUoJ0InKTsKKyAgICAgICAgYnNQdXRVQnl0ZSgnWicpOworCisgICAgICAgIHRoaXMuZGF0YSA9IG5ldyBEYXRhKHRoaXMuYmxvY2tTaXplMTAwayk7CisgICAgICAgIHRoaXMuYmxvY2tTb3J0ZXIgPSBuZXcgQmxvY2tTb3J0KHRoaXMuZGF0YSk7CisKKyAgICAgICAgLy8gaHVmZm1hbmlzZWQgbWFnaWMgYnl0ZXMKKyAgICAgICAgYnNQdXRVQnl0ZSgnaCcpOworICAgICAgICBic1B1dFVCeXRlKCcwJyArIHRoaXMuYmxvY2tTaXplMTAwayk7CisKKyAgICAgICAgdGhpcy5jb21iaW5lZENSQyA9IDA7CisgICAgICAgIGluaXRCbG9jaygpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBpbml0QmxvY2soKSB7CisgICAgICAgIC8vIGJsb2NrTm8rKzsKKyAgICAgICAgdGhpcy5jcmMuaW5pdGlhbGlzZUNSQygpOworICAgICAgICB0aGlzLmxhc3QgPSAtMTsKKyAgICAgICAgLy8gY2ggPSAwOworCisgICAgICAgIGZpbmFsIGJvb2xlYW5bXSBpblVzZSA9IHRoaXMuZGF0YS5pblVzZTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDI1NjsgLS1pID49IDA7KSB7CisgICAgICAgICAgICBpblVzZVtpXSA9IGZhbHNlOworICAgICAgICB9CisKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgZW5kQmxvY2soKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzLmJsb2NrQ1JDID0gdGhpcy5jcmMuZ2V0RmluYWxDUkMoKTsKKyAgICAgICAgdGhpcy5jb21iaW5lZENSQyA9ICh0aGlzLmNvbWJpbmVkQ1JDIDw8IDEpIHwgKHRoaXMuY29tYmluZWRDUkMgPj4+IDMxKTsKKyAgICAgICAgdGhpcy5jb21iaW5lZENSQyBePSB0aGlzLmJsb2NrQ1JDOworCisgICAgICAgIC8vIGVtcHR5IGJsb2NrIGF0IGVuZCBvZiBmaWxlCisgICAgICAgIGlmICh0aGlzLmxhc3QgPT0gLTEpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIC8qIHNvcnQgdGhlIGJsb2NrIGFuZCBlc3RhYmxpc2ggcG9zbiBvZiBvcmlnaW5hbCBzdHJpbmcgKi8KKyAgICAgICAgYmxvY2tTb3J0KCk7CisKKyAgICAgICAgLyoKKyAgICAgICAgICogQSA2LWJ5dGUgYmxvY2sgaGVhZGVyLCB0aGUgdmFsdWUgY2hvc2VuIGFyYml0cmFyaWx5IGFzIDB4MzE0MTU5MjY1MzU5CisgICAgICAgICAqIDotKS4gQSAzMiBiaXQgdmFsdWUgZG9lcyBub3QgcmVhbGx5IGdpdmUgYSBzdHJvbmcgZW5vdWdoIGd1YXJhbnRlZQorICAgICAgICAgKiB0aGF0IHRoZSB2YWx1ZSB3aWxsIG5vdCBhcHBlYXIgYnkgY2hhbmNlIGluIHRoZSBjb21wcmVzc2VkCisgICAgICAgICAqIGRhdGFzdHJlYW0uIFdvcnN0LWNhc2UgcHJvYmFiaWxpdHkgb2YgdGhpcyBldmVudCwgZm9yIGEgOTAwayBibG9jaywKKyAgICAgICAgICogaXMgYWJvdXQgMi4wZS0zIGZvciAzMiBiaXRzLCAxLjBlLTUgZm9yIDQwIGJpdHMgYW5kIDQuMGUtOCBmb3IgNDgKKyAgICAgICAgICogYml0cy4gRm9yIGEgY29tcHJlc3NlZCBmaWxlIG9mIHNpemUgMTAwR2IgLS0gYWJvdXQgMTAwMDAwIGJsb2NrcyAtLQorICAgICAgICAgKiBvbmx5IGEgNDgtYml0IG1hcmtlciB3aWxsIGRvLiBOQjogbm9ybWFsIGNvbXByZXNzaW9uLyBkZWNvbXByZXNzaW9uCisgICAgICAgICAqIGRvbm90IHJlbHkgb24gdGhlc2Ugc3RhdGlzdGljYWwgcHJvcGVydGllcy4gVGhleSBhcmUgb25seSBpbXBvcnRhbnQKKyAgICAgICAgICogd2hlbiB0cnlpbmcgdG8gcmVjb3ZlciBibG9ja3MgZnJvbSBkYW1hZ2VkIGZpbGVzLgorICAgICAgICAgKi8KKyAgICAgICAgYnNQdXRVQnl0ZSgweDMxKTsKKyAgICAgICAgYnNQdXRVQnl0ZSgweDQxKTsKKyAgICAgICAgYnNQdXRVQnl0ZSgweDU5KTsKKyAgICAgICAgYnNQdXRVQnl0ZSgweDI2KTsKKyAgICAgICAgYnNQdXRVQnl0ZSgweDUzKTsKKyAgICAgICAgYnNQdXRVQnl0ZSgweDU5KTsKKworICAgICAgICAvKiBOb3cgdGhlIGJsb2NrJ3MgQ1JDLCBzbyBpdCBpcyBpbiBhIGtub3duIHBsYWNlLiAqLworICAgICAgICBic1B1dEludCh0aGlzLmJsb2NrQ1JDKTsKKworICAgICAgICAvKiBOb3cgYSBzaW5nbGUgYml0IGluZGljYXRpbmcgbm8gcmFuZG9taXNhdGlvbi4gKi8KKyAgICAgICAgYnNXKDEsIDApOworCisgICAgICAgIC8qIEZpbmFsbHksIGJsb2NrJ3MgY29udGVudHMgcHJvcGVyLiAqLworICAgICAgICBtb3ZlVG9Gcm9udENvZGVBbmRTZW5kKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGVuZENvbXByZXNzaW9uKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLyoKKyAgICAgICAgICogTm93IGFub3RoZXIgbWFnaWMgNDgtYml0IG51bWJlciwgMHgxNzcyNDUzODUwOTAsIHRvIGluZGljYXRlIHRoZSBlbmQKKyAgICAgICAgICogb2YgdGhlIGxhc3QgYmxvY2suIChzcXJ0KHBpKSwgaWYgeW91IHdhbnQgdG8ga25vdy4gSSBkaWQgd2FudCB0byB1c2UKKyAgICAgICAgICogZSwgYnV0IGl0IGNvbnRhaW5zIHRvbyBtdWNoIHJlcGV0aXRpb24gLS0gMjcgMTggMjggMTggMjggNDYgLS0gZm9yIG1lCisgICAgICAgICAqIHRvIGZlZWwgc3RhdGlzdGljYWxseSBjb21mb3J0YWJsZS4gQ2FsbCBtZSBwYXJhbm9pZC4pCisgICAgICAgICAqLworICAgICAgICBic1B1dFVCeXRlKDB4MTcpOworICAgICAgICBic1B1dFVCeXRlKDB4NzIpOworICAgICAgICBic1B1dFVCeXRlKDB4NDUpOworICAgICAgICBic1B1dFVCeXRlKDB4MzgpOworICAgICAgICBic1B1dFVCeXRlKDB4NTApOworICAgICAgICBic1B1dFVCeXRlKDB4OTApOworCisgICAgICAgIGJzUHV0SW50KHRoaXMuY29tYmluZWRDUkMpOworICAgICAgICBic0ZpbmlzaGVkV2l0aFN0cmVhbSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGJsb2Nrc2l6ZSBwYXJhbWV0ZXIgc3BlY2lmaWVkIGF0IGNvbnN0cnVjdGlvbiB0aW1lLgorICAgICAqIEByZXR1cm4gdGhlIGJsb2Nrc2l6ZSBwYXJhbWV0ZXIgc3BlY2lmaWVkIGF0IGNvbnN0cnVjdGlvbiB0aW1lCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGludCBnZXRCbG9ja1NpemUoKSB7CisgICAgICAgIHJldHVybiB0aGlzLmJsb2NrU2l6ZTEwMGs7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGUoZmluYWwgYnl0ZVtdIGJ1ZiwgaW50IG9mZnMsIGZpbmFsIGludCBsZW4pCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChvZmZzIDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oIm9mZnMoIiArIG9mZnMgKyAiKSA8IDAuIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGxlbiA8IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCJsZW4oIiArIGxlbiArICIpIDwgMC4iKTsKKyAgICAgICAgfQorICAgICAgICBpZiAob2ZmcyArIGxlbiA+IGJ1Zi5sZW5ndGgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCJvZmZzKCIgKyBvZmZzICsgIikgKyBsZW4oIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBsZW4gKyAiKSA+IGJ1Zi5sZW5ndGgoIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBidWYubGVuZ3RoICsgIikuIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGNsb3NlZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJzdHJlYW0gY2xvc2VkIik7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKGZpbmFsIGludCBoaSA9IG9mZnMgKyBsZW47IG9mZnMgPCBoaTspIHsKKyAgICAgICAgICAgIHdyaXRlMChidWZbb2ZmcysrXSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBLZWVwcyB0cmFjayBvZiB0aGUgbGFzdCBieXRlcyB3cml0dGVuIGFuZCBpbXBsaWNpdGx5IHBlcmZvcm1zCisgICAgICogcnVuLWxlbmd0aCBlbmNvZGluZyBhcyB0aGUgZmlyc3Qgc3RlcCBvZiB0aGUgYnppcDIgYWxnb3JpdGhtLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCB3cml0ZTAoaW50IGIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICh0aGlzLmN1cnJlbnRDaGFyICE9IC0xKSB7CisgICAgICAgICAgICBiICY9IDB4ZmY7CisgICAgICAgICAgICBpZiAodGhpcy5jdXJyZW50Q2hhciA9PSBiKSB7CisgICAgICAgICAgICAgICAgaWYgKCsrdGhpcy5ydW5MZW5ndGggPiAyNTQpIHsKKyAgICAgICAgICAgICAgICAgICAgd3JpdGVSdW4oKTsKKyAgICAgICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50Q2hhciA9IC0xOworICAgICAgICAgICAgICAgICAgICB0aGlzLnJ1bkxlbmd0aCA9IDA7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIC8vIGVsc2Ugbm90aGluZyB0byBkbworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB3cml0ZVJ1bigpOworICAgICAgICAgICAgICAgIHRoaXMucnVuTGVuZ3RoID0gMTsKKyAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRDaGFyID0gYjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRoaXMuY3VycmVudENoYXIgPSBiICYgMHhmZjsKKyAgICAgICAgICAgIHRoaXMucnVuTGVuZ3RoKys7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGhiQXNzaWduQ29kZXMoZmluYWwgaW50W10gY29kZSwgZmluYWwgYnl0ZVtdIGxlbmd0aCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IG1pbkxlbiwgZmluYWwgaW50IG1heExlbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGFscGhhU2l6ZSkgeworICAgICAgICBpbnQgdmVjID0gMDsKKyAgICAgICAgZm9yIChpbnQgbiA9IG1pbkxlbjsgbiA8PSBtYXhMZW47IG4rKykgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhbHBoYVNpemU7IGkrKykgeworICAgICAgICAgICAgICAgIGlmICgobGVuZ3RoW2ldICYgMHhmZikgPT0gbikgeworICAgICAgICAgICAgICAgICAgICBjb2RlW2ldID0gdmVjOworICAgICAgICAgICAgICAgICAgICB2ZWMrKzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICB2ZWMgPDw9IDE7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYnNGaW5pc2hlZFdpdGhTdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB3aGlsZSAodGhpcy5ic0xpdmUgPiAwKSB7CisgICAgICAgICAgICBmaW5hbCBpbnQgY2ggPSB0aGlzLmJzQnVmZiA+PiAyNDsKKyAgICAgICAgICAgIHRoaXMub3V0LndyaXRlKGNoKTsgLy8gd3JpdGUgOC1iaXQKKyAgICAgICAgICAgIHRoaXMuYnNCdWZmIDw8PSA4OworICAgICAgICAgICAgdGhpcy5ic0xpdmUgLT0gODsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBic1coZmluYWwgaW50IG4sIGZpbmFsIGludCB2KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBPdXRwdXRTdHJlYW0gb3V0U2hhZG93ID0gdGhpcy5vdXQ7CisgICAgICAgIGludCBic0xpdmVTaGFkb3cgPSB0aGlzLmJzTGl2ZTsKKyAgICAgICAgaW50IGJzQnVmZlNoYWRvdyA9IHRoaXMuYnNCdWZmOworCisgICAgICAgIHdoaWxlIChic0xpdmVTaGFkb3cgPj0gOCkgeworICAgICAgICAgICAgb3V0U2hhZG93LndyaXRlKGJzQnVmZlNoYWRvdyA+PiAyNCk7IC8vIHdyaXRlIDgtYml0CisgICAgICAgICAgICBic0J1ZmZTaGFkb3cgPDw9IDg7CisgICAgICAgICAgICBic0xpdmVTaGFkb3cgLT0gODsKKyAgICAgICAgfQorCisgICAgICAgIHRoaXMuYnNCdWZmID0gYnNCdWZmU2hhZG93IHwgKHYgPDwgKDMyIC0gYnNMaXZlU2hhZG93IC0gbikpOworICAgICAgICB0aGlzLmJzTGl2ZSA9IGJzTGl2ZVNoYWRvdyArIG47CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGJzUHV0VUJ5dGUoZmluYWwgaW50IGMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJzVyg4LCBjKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYnNQdXRJbnQoZmluYWwgaW50IHUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJzVyg4LCAodSA+PiAyNCkgJiAweGZmKTsKKyAgICAgICAgYnNXKDgsICh1ID4+IDE2KSAmIDB4ZmYpOworICAgICAgICBic1coOCwgKHUgPj4gOCkgJiAweGZmKTsKKyAgICAgICAgYnNXKDgsIHUgJiAweGZmKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgc2VuZE1URlZhbHVlcygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIGJ5dGVbXVtdIGxlbiA9IHRoaXMuZGF0YS5zZW5kTVRGVmFsdWVzX2xlbjsKKyAgICAgICAgZmluYWwgaW50IGFscGhhU2l6ZSA9IHRoaXMubkluVXNlICsgMjsKKworICAgICAgICBmb3IgKGludCB0ID0gTl9HUk9VUFM7IC0tdCA+PSAwOykgeworICAgICAgICAgICAgZmluYWwgYnl0ZVtdIGxlbl90ID0gbGVuW3RdOworICAgICAgICAgICAgZm9yIChpbnQgdiA9IGFscGhhU2l6ZTsgLS12ID49IDA7KSB7CisgICAgICAgICAgICAgICAgbGVuX3Rbdl0gPSBHUkVBVEVSX0lDT1NUOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLyogRGVjaWRlIGhvdyBtYW55IGNvZGluZyB0YWJsZXMgdG8gdXNlICovCisgICAgICAgIC8vIGFzc2VydCAodGhpcy5uTVRGID4gMCkgOiB0aGlzLm5NVEY7CisgICAgICAgIGZpbmFsIGludCBuR3JvdXBzID0gKHRoaXMubk1URiA8IDIwMCkgPyAyIDogKHRoaXMubk1URiA8IDYwMCkgPyAzCisgICAgICAgICAgICA6ICh0aGlzLm5NVEYgPCAxMjAwKSA/IDQgOiAodGhpcy5uTVRGIDwgMjQwMCkgPyA1IDogNjsKKworICAgICAgICAvKiBHZW5lcmF0ZSBhbiBpbml0aWFsIHNldCBvZiBjb2RpbmcgdGFibGVzICovCisgICAgICAgIHNlbmRNVEZWYWx1ZXMwKG5Hcm91cHMsIGFscGhhU2l6ZSk7CisKKyAgICAgICAgLyoKKyAgICAgICAgICogSXRlcmF0ZSB1cCB0byBOX0lURVJTIHRpbWVzIHRvIGltcHJvdmUgdGhlIHRhYmxlcy4KKyAgICAgICAgICovCisgICAgICAgIGZpbmFsIGludCBuU2VsZWN0b3JzID0gc2VuZE1URlZhbHVlczEobkdyb3VwcywgYWxwaGFTaXplKTsKKworICAgICAgICAvKiBDb21wdXRlIE1URiB2YWx1ZXMgZm9yIHRoZSBzZWxlY3RvcnMuICovCisgICAgICAgIHNlbmRNVEZWYWx1ZXMyKG5Hcm91cHMsIG5TZWxlY3RvcnMpOworCisgICAgICAgIC8qIEFzc2lnbiBhY3R1YWwgY29kZXMgZm9yIHRoZSB0YWJsZXMuICovCisgICAgICAgIHNlbmRNVEZWYWx1ZXMzKG5Hcm91cHMsIGFscGhhU2l6ZSk7CisKKyAgICAgICAgLyogVHJhbnNtaXQgdGhlIG1hcHBpbmcgdGFibGUuICovCisgICAgICAgIHNlbmRNVEZWYWx1ZXM0KCk7CisKKyAgICAgICAgLyogTm93IHRoZSBzZWxlY3RvcnMuICovCisgICAgICAgIHNlbmRNVEZWYWx1ZXM1KG5Hcm91cHMsIG5TZWxlY3RvcnMpOworCisgICAgICAgIC8qIE5vdyB0aGUgY29kaW5nIHRhYmxlcy4gKi8KKyAgICAgICAgc2VuZE1URlZhbHVlczYobkdyb3VwcywgYWxwaGFTaXplKTsKKworICAgICAgICAvKiBBbmQgZmluYWxseSwgdGhlIGJsb2NrIGRhdGEgcHJvcGVyICovCisgICAgICAgIHNlbmRNVEZWYWx1ZXM3KCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHNlbmRNVEZWYWx1ZXMwKGZpbmFsIGludCBuR3JvdXBzLCBmaW5hbCBpbnQgYWxwaGFTaXplKSB7CisgICAgICAgIGZpbmFsIGJ5dGVbXVtdIGxlbiA9IHRoaXMuZGF0YS5zZW5kTVRGVmFsdWVzX2xlbjsKKyAgICAgICAgZmluYWwgaW50W10gbXRmRnJlcSA9IHRoaXMuZGF0YS5tdGZGcmVxOworCisgICAgICAgIGludCByZW1GID0gdGhpcy5uTVRGOworICAgICAgICBpbnQgZ3MgPSAwOworCisgICAgICAgIGZvciAoaW50IG5QYXJ0ID0gbkdyb3VwczsgblBhcnQgPiAwOyBuUGFydC0tKSB7CisgICAgICAgICAgICBmaW5hbCBpbnQgdEZyZXEgPSByZW1GIC8gblBhcnQ7CisgICAgICAgICAgICBpbnQgZ2UgPSBncyAtIDE7CisgICAgICAgICAgICBpbnQgYUZyZXEgPSAwOworCisgICAgICAgICAgICBmb3IgKGZpbmFsIGludCBhID0gYWxwaGFTaXplIC0gMTsgKGFGcmVxIDwgdEZyZXEpICYmIChnZSA8IGEpOykgeworICAgICAgICAgICAgICAgIGFGcmVxICs9IG10ZkZyZXFbKytnZV07CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmICgoZ2UgPiBncykgJiYgKG5QYXJ0ICE9IG5Hcm91cHMpICYmIChuUGFydCAhPSAxKQorICAgICAgICAgICAgICAgICYmICgoKG5Hcm91cHMgLSBuUGFydCkgJiAxKSAhPSAwKSkgeworICAgICAgICAgICAgICAgIGFGcmVxIC09IG10ZkZyZXFbZ2UtLV07CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBsZW5fbnAgPSBsZW5bblBhcnQgLSAxXTsKKyAgICAgICAgICAgIGZvciAoaW50IHYgPSBhbHBoYVNpemU7IC0tdiA+PSAwOykgeworICAgICAgICAgICAgICAgIGlmICgodiA+PSBncykgJiYgKHYgPD0gZ2UpKSB7CisgICAgICAgICAgICAgICAgICAgIGxlbl9ucFt2XSA9IExFU1NFUl9JQ09TVDsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBsZW5fbnBbdl0gPSBHUkVBVEVSX0lDT1NUOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgZ3MgPSBnZSArIDE7CisgICAgICAgICAgICByZW1GIC09IGFGcmVxOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnQgc2VuZE1URlZhbHVlczEoZmluYWwgaW50IG5Hcm91cHMsIGZpbmFsIGludCBhbHBoYVNpemUpIHsKKyAgICAgICAgZmluYWwgRGF0YSBkYXRhU2hhZG93ID0gdGhpcy5kYXRhOworICAgICAgICBmaW5hbCBpbnRbXVtdIHJmcmVxID0gZGF0YVNoYWRvdy5zZW5kTVRGVmFsdWVzX3JmcmVxOworICAgICAgICBmaW5hbCBpbnRbXSBmYXZlID0gZGF0YVNoYWRvdy5zZW5kTVRGVmFsdWVzX2ZhdmU7CisgICAgICAgIGZpbmFsIHNob3J0W10gY29zdCA9IGRhdGFTaGFkb3cuc2VuZE1URlZhbHVlc19jb3N0OworICAgICAgICBmaW5hbCBjaGFyW10gc2ZtYXAgPSBkYXRhU2hhZG93LnNmbWFwOworICAgICAgICBmaW5hbCBieXRlW10gc2VsZWN0b3IgPSBkYXRhU2hhZG93LnNlbGVjdG9yOworICAgICAgICBmaW5hbCBieXRlW11bXSBsZW4gPSBkYXRhU2hhZG93LnNlbmRNVEZWYWx1ZXNfbGVuOworICAgICAgICBmaW5hbCBieXRlW10gbGVuXzAgPSBsZW5bMF07CisgICAgICAgIGZpbmFsIGJ5dGVbXSBsZW5fMSA9IGxlblsxXTsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGxlbl8yID0gbGVuWzJdOworICAgICAgICBmaW5hbCBieXRlW10gbGVuXzMgPSBsZW5bM107CisgICAgICAgIGZpbmFsIGJ5dGVbXSBsZW5fNCA9IGxlbls0XTsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGxlbl81ID0gbGVuWzVdOworICAgICAgICBmaW5hbCBpbnQgbk1URlNoYWRvdyA9IHRoaXMubk1URjsKKworICAgICAgICBpbnQgblNlbGVjdG9ycyA9IDA7CisKKyAgICAgICAgZm9yIChpbnQgaXRlciA9IDA7IGl0ZXIgPCBOX0lURVJTOyBpdGVyKyspIHsKKyAgICAgICAgICAgIGZvciAoaW50IHQgPSBuR3JvdXBzOyAtLXQgPj0gMDspIHsKKyAgICAgICAgICAgICAgICBmYXZlW3RdID0gMDsKKyAgICAgICAgICAgICAgICBmaW5hbCBpbnRbXSByZnJlcXQgPSByZnJlcVt0XTsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gYWxwaGFTaXplOyAtLWkgPj0gMDspIHsKKyAgICAgICAgICAgICAgICAgICAgcmZyZXF0W2ldID0gMDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIG5TZWxlY3RvcnMgPSAwOworCisgICAgICAgICAgICBmb3IgKGludCBncyA9IDA7IGdzIDwgdGhpcy5uTVRGOykgeworICAgICAgICAgICAgICAgIC8qIFNldCBncm91cCBzdGFydCAmIGVuZCBtYXJrcy4gKi8KKworICAgICAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgICAgICogQ2FsY3VsYXRlIHRoZSBjb3N0IG9mIHRoaXMgZ3JvdXAgYXMgY29kZWQgYnkgZWFjaCBvZiB0aGUKKyAgICAgICAgICAgICAgICAgKiBjb2RpbmcgdGFibGVzLgorICAgICAgICAgICAgICAgICAqLworCisgICAgICAgICAgICAgICAgZmluYWwgaW50IGdlID0gTWF0aC5taW4oZ3MgKyBHX1NJWkUgLSAxLCBuTVRGU2hhZG93IC0gMSk7CisKKyAgICAgICAgICAgICAgICBpZiAobkdyb3VwcyA9PSBOX0dST1VQUykgeworICAgICAgICAgICAgICAgICAgICAvLyB1bnJvbGxlZCB2ZXJzaW9uIG9mIHRoZSBlbHNlLWJsb2NrCisKKyAgICAgICAgICAgICAgICAgICAgc2hvcnQgY29zdDAgPSAwOworICAgICAgICAgICAgICAgICAgICBzaG9ydCBjb3N0MSA9IDA7CisgICAgICAgICAgICAgICAgICAgIHNob3J0IGNvc3QyID0gMDsKKyAgICAgICAgICAgICAgICAgICAgc2hvcnQgY29zdDMgPSAwOworICAgICAgICAgICAgICAgICAgICBzaG9ydCBjb3N0NCA9IDA7CisgICAgICAgICAgICAgICAgICAgIHNob3J0IGNvc3Q1ID0gMDsKKworICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gZ3M7IGkgPD0gZ2U7IGkrKykgeworICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGljdiA9IHNmbWFwW2ldOworICAgICAgICAgICAgICAgICAgICAgICAgY29zdDAgKz0gbGVuXzBbaWN2XSAmIDB4ZmY7CisgICAgICAgICAgICAgICAgICAgICAgICBjb3N0MSArPSBsZW5fMVtpY3ZdICYgMHhmZjsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvc3QyICs9IGxlbl8yW2ljdl0gJiAweGZmOworICAgICAgICAgICAgICAgICAgICAgICAgY29zdDMgKz0gbGVuXzNbaWN2XSAmIDB4ZmY7CisgICAgICAgICAgICAgICAgICAgICAgICBjb3N0NCArPSBsZW5fNFtpY3ZdICYgMHhmZjsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvc3Q1ICs9IGxlbl81W2ljdl0gJiAweGZmOworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgY29zdFswXSA9IGNvc3QwOworICAgICAgICAgICAgICAgICAgICBjb3N0WzFdID0gY29zdDE7CisgICAgICAgICAgICAgICAgICAgIGNvc3RbMl0gPSBjb3N0MjsKKyAgICAgICAgICAgICAgICAgICAgY29zdFszXSA9IGNvc3QzOworICAgICAgICAgICAgICAgICAgICBjb3N0WzRdID0gY29zdDQ7CisgICAgICAgICAgICAgICAgICAgIGNvc3RbNV0gPSBjb3N0NTsKKworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IHQgPSBuR3JvdXBzOyAtLXQgPj0gMDspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvc3RbdF0gPSAwOworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IGdzOyBpIDw9IGdlOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBpY3YgPSBzZm1hcFtpXTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IHQgPSBuR3JvdXBzOyAtLXQgPj0gMDspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3N0W3RdICs9IGxlblt0XVtpY3ZdICYgMHhmZjsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgICAgICogRmluZCB0aGUgY29kaW5nIHRhYmxlIHdoaWNoIGlzIGJlc3QgZm9yIHRoaXMgZ3JvdXAsIGFuZAorICAgICAgICAgICAgICAgICAqIHJlY29yZCBpdHMgaWRlbnRpdHkgaW4gdGhlIHNlbGVjdG9yIHRhYmxlLgorICAgICAgICAgICAgICAgICAqLworICAgICAgICAgICAgICAgIGludCBidCA9IC0xOworICAgICAgICAgICAgICAgIGZvciAoaW50IHQgPSBuR3JvdXBzLCBiYyA9IDk5OTk5OTk5OTsgLS10ID49IDA7KSB7CisgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBjb3N0X3QgPSBjb3N0W3RdOworICAgICAgICAgICAgICAgICAgICBpZiAoY29zdF90IDwgYmMpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJjID0gY29zdF90OworICAgICAgICAgICAgICAgICAgICAgICAgYnQgPSB0OworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgZmF2ZVtidF0rKzsKKyAgICAgICAgICAgICAgICBzZWxlY3RvcltuU2VsZWN0b3JzXSA9IChieXRlKSBidDsKKyAgICAgICAgICAgICAgICBuU2VsZWN0b3JzKys7CisKKyAgICAgICAgICAgICAgICAvKgorICAgICAgICAgICAgICAgICAqIEluY3JlbWVudCB0aGUgc3ltYm9sIGZyZXF1ZW5jaWVzIGZvciB0aGUgc2VsZWN0ZWQgdGFibGUuCisgICAgICAgICAgICAgICAgICovCisgICAgICAgICAgICAgICAgZmluYWwgaW50W10gcmZyZXFfYnQgPSByZnJlcVtidF07CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IGdzOyBpIDw9IGdlOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgcmZyZXFfYnRbc2ZtYXBbaV1dKys7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgZ3MgPSBnZSArIDE7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBSZWNvbXB1dGUgdGhlIHRhYmxlcyBiYXNlZCBvbiB0aGUgYWNjdW11bGF0ZWQgZnJlcXVlbmNpZXMuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIGZvciAoaW50IHQgPSAwOyB0IDwgbkdyb3VwczsgdCsrKSB7CisgICAgICAgICAgICAgICAgaGJNYWtlQ29kZUxlbmd0aHMobGVuW3RdLCByZnJlcVt0XSwgdGhpcy5kYXRhLCBhbHBoYVNpemUsIDIwKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBuU2VsZWN0b3JzOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBzZW5kTVRGVmFsdWVzMihmaW5hbCBpbnQgbkdyb3VwcywgZmluYWwgaW50IG5TZWxlY3RvcnMpIHsKKyAgICAgICAgLy8gYXNzZXJ0IChuR3JvdXBzIDwgOCkgOiBuR3JvdXBzOworCisgICAgICAgIGZpbmFsIERhdGEgZGF0YVNoYWRvdyA9IHRoaXMuZGF0YTsKKyAgICAgICAgZmluYWwgYnl0ZVtdIHBvcyA9IGRhdGFTaGFkb3cuc2VuZE1URlZhbHVlczJfcG9zOworCisgICAgICAgIGZvciAoaW50IGkgPSBuR3JvdXBzOyAtLWkgPj0gMDspIHsKKyAgICAgICAgICAgIHBvc1tpXSA9IChieXRlKSBpOworICAgICAgICB9CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuU2VsZWN0b3JzOyBpKyspIHsKKyAgICAgICAgICAgIGZpbmFsIGJ5dGUgbGxfaSA9IGRhdGFTaGFkb3cuc2VsZWN0b3JbaV07CisgICAgICAgICAgICBieXRlIHRtcCA9IHBvc1swXTsKKyAgICAgICAgICAgIGludCBqID0gMDsKKworICAgICAgICAgICAgd2hpbGUgKGxsX2kgIT0gdG1wKSB7CisgICAgICAgICAgICAgICAgaisrOworICAgICAgICAgICAgICAgIGZpbmFsIGJ5dGUgdG1wMiA9IHRtcDsKKyAgICAgICAgICAgICAgICB0bXAgPSBwb3Nbal07CisgICAgICAgICAgICAgICAgcG9zW2pdID0gdG1wMjsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcG9zWzBdID0gdG1wOworICAgICAgICAgICAgZGF0YVNoYWRvdy5zZWxlY3Rvck10ZltpXSA9IChieXRlKSBqOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHNlbmRNVEZWYWx1ZXMzKGZpbmFsIGludCBuR3JvdXBzLCBmaW5hbCBpbnQgYWxwaGFTaXplKSB7CisgICAgICAgIGZpbmFsIGludFtdW10gY29kZSA9IHRoaXMuZGF0YS5zZW5kTVRGVmFsdWVzX2NvZGU7CisgICAgICAgIGZpbmFsIGJ5dGVbXVtdIGxlbiA9IHRoaXMuZGF0YS5zZW5kTVRGVmFsdWVzX2xlbjsKKworICAgICAgICBmb3IgKGludCB0ID0gMDsgdCA8IG5Hcm91cHM7IHQrKykgeworICAgICAgICAgICAgaW50IG1pbkxlbiA9IDMyOworICAgICAgICAgICAgaW50IG1heExlbiA9IDA7CisgICAgICAgICAgICBmaW5hbCBieXRlW10gbGVuX3QgPSBsZW5bdF07CisgICAgICAgICAgICBmb3IgKGludCBpID0gYWxwaGFTaXplOyAtLWkgPj0gMDspIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBpbnQgbCA9IGxlbl90W2ldICYgMHhmZjsKKyAgICAgICAgICAgICAgICBpZiAobCA+IG1heExlbikgeworICAgICAgICAgICAgICAgICAgICBtYXhMZW4gPSBsOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAobCA8IG1pbkxlbikgeworICAgICAgICAgICAgICAgICAgICBtaW5MZW4gPSBsOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gYXNzZXJ0IChtYXhMZW4gPD0gMjApIDogbWF4TGVuOworICAgICAgICAgICAgLy8gYXNzZXJ0IChtaW5MZW4gPj0gMSkgOiBtaW5MZW47CisKKyAgICAgICAgICAgIGhiQXNzaWduQ29kZXMoY29kZVt0XSwgbGVuW3RdLCBtaW5MZW4sIG1heExlbiwgYWxwaGFTaXplKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBzZW5kTVRGVmFsdWVzNCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIGJvb2xlYW5bXSBpblVzZSA9IHRoaXMuZGF0YS5pblVzZTsKKyAgICAgICAgZmluYWwgYm9vbGVhbltdIGluVXNlMTYgPSB0aGlzLmRhdGEuc2VudE1URlZhbHVlczRfaW5Vc2UxNjsKKworICAgICAgICBmb3IgKGludCBpID0gMTY7IC0taSA+PSAwOykgeworICAgICAgICAgICAgaW5Vc2UxNltpXSA9IGZhbHNlOworICAgICAgICAgICAgZmluYWwgaW50IGkxNiA9IGkgKiAxNjsKKyAgICAgICAgICAgIGZvciAoaW50IGogPSAxNjsgLS1qID49IDA7KSB7CisgICAgICAgICAgICAgICAgaWYgKGluVXNlW2kxNiArIGpdKSB7CisgICAgICAgICAgICAgICAgICAgIGluVXNlMTZbaV0gPSB0cnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTY7IGkrKykgeworICAgICAgICAgICAgYnNXKDEsIGluVXNlMTZbaV0gPyAxIDogMCk7CisgICAgICAgIH0KKworICAgICAgICBmaW5hbCBPdXRwdXRTdHJlYW0gb3V0U2hhZG93ID0gdGhpcy5vdXQ7CisgICAgICAgIGludCBic0xpdmVTaGFkb3cgPSB0aGlzLmJzTGl2ZTsKKyAgICAgICAgaW50IGJzQnVmZlNoYWRvdyA9IHRoaXMuYnNCdWZmOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTY7IGkrKykgeworICAgICAgICAgICAgaWYgKGluVXNlMTZbaV0pIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBpbnQgaTE2ID0gaSAqIDE2OworICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgMTY7IGorKykgeworICAgICAgICAgICAgICAgICAgICAvLyBpbmxpbmVkOiBic1coMSwgaW5Vc2VbaTE2ICsgal0gPyAxIDogMCk7CisgICAgICAgICAgICAgICAgICAgIHdoaWxlIChic0xpdmVTaGFkb3cgPj0gOCkgeworICAgICAgICAgICAgICAgICAgICAgICAgb3V0U2hhZG93LndyaXRlKGJzQnVmZlNoYWRvdyA+PiAyNCk7IC8vIHdyaXRlIDgtYml0CisgICAgICAgICAgICAgICAgICAgICAgICBic0J1ZmZTaGFkb3cgPDw9IDg7CisgICAgICAgICAgICAgICAgICAgICAgICBic0xpdmVTaGFkb3cgLT0gODsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBpZiAoaW5Vc2VbaTE2ICsgal0pIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJzQnVmZlNoYWRvdyB8PSAxIDw8ICgzMiAtIGJzTGl2ZVNoYWRvdyAtIDEpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGJzTGl2ZVNoYWRvdysrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHRoaXMuYnNCdWZmID0gYnNCdWZmU2hhZG93OworICAgICAgICB0aGlzLmJzTGl2ZSA9IGJzTGl2ZVNoYWRvdzsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgc2VuZE1URlZhbHVlczUoZmluYWwgaW50IG5Hcm91cHMsIGZpbmFsIGludCBuU2VsZWN0b3JzKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBic1coMywgbkdyb3Vwcyk7CisgICAgICAgIGJzVygxNSwgblNlbGVjdG9ycyk7CisKKyAgICAgICAgZmluYWwgT3V0cHV0U3RyZWFtIG91dFNoYWRvdyA9IHRoaXMub3V0OworICAgICAgICBmaW5hbCBieXRlW10gc2VsZWN0b3JNdGYgPSB0aGlzLmRhdGEuc2VsZWN0b3JNdGY7CisKKyAgICAgICAgaW50IGJzTGl2ZVNoYWRvdyA9IHRoaXMuYnNMaXZlOworICAgICAgICBpbnQgYnNCdWZmU2hhZG93ID0gdGhpcy5ic0J1ZmY7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuU2VsZWN0b3JzOyBpKyspIHsKKyAgICAgICAgICAgIGZvciAoaW50IGogPSAwLCBoaiA9IHNlbGVjdG9yTXRmW2ldICYgMHhmZjsgaiA8IGhqOyBqKyspIHsKKyAgICAgICAgICAgICAgICAvLyBpbmxpbmVkOiBic1coMSwgMSk7CisgICAgICAgICAgICAgICAgd2hpbGUgKGJzTGl2ZVNoYWRvdyA+PSA4KSB7CisgICAgICAgICAgICAgICAgICAgIG91dFNoYWRvdy53cml0ZShic0J1ZmZTaGFkb3cgPj4gMjQpOworICAgICAgICAgICAgICAgICAgICBic0J1ZmZTaGFkb3cgPDw9IDg7CisgICAgICAgICAgICAgICAgICAgIGJzTGl2ZVNoYWRvdyAtPSA4OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBic0J1ZmZTaGFkb3cgfD0gMSA8PCAoMzIgLSBic0xpdmVTaGFkb3cgLSAxKTsKKyAgICAgICAgICAgICAgICBic0xpdmVTaGFkb3crKzsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gaW5saW5lZDogYnNXKDEsIDApOworICAgICAgICAgICAgd2hpbGUgKGJzTGl2ZVNoYWRvdyA+PSA4KSB7CisgICAgICAgICAgICAgICAgb3V0U2hhZG93LndyaXRlKGJzQnVmZlNoYWRvdyA+PiAyNCk7CisgICAgICAgICAgICAgICAgYnNCdWZmU2hhZG93IDw8PSA4OworICAgICAgICAgICAgICAgIGJzTGl2ZVNoYWRvdyAtPSA4OworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gYnNCdWZmU2hhZG93IHw9IDAgPDwgKDMyIC0gYnNMaXZlU2hhZG93IC0gMSk7CisgICAgICAgICAgICBic0xpdmVTaGFkb3crKzsKKyAgICAgICAgfQorCisgICAgICAgIHRoaXMuYnNCdWZmID0gYnNCdWZmU2hhZG93OworICAgICAgICB0aGlzLmJzTGl2ZSA9IGJzTGl2ZVNoYWRvdzsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgc2VuZE1URlZhbHVlczYoZmluYWwgaW50IG5Hcm91cHMsIGZpbmFsIGludCBhbHBoYVNpemUpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIGJ5dGVbXVtdIGxlbiA9IHRoaXMuZGF0YS5zZW5kTVRGVmFsdWVzX2xlbjsKKyAgICAgICAgZmluYWwgT3V0cHV0U3RyZWFtIG91dFNoYWRvdyA9IHRoaXMub3V0OworCisgICAgICAgIGludCBic0xpdmVTaGFkb3cgPSB0aGlzLmJzTGl2ZTsKKyAgICAgICAgaW50IGJzQnVmZlNoYWRvdyA9IHRoaXMuYnNCdWZmOworCisgICAgICAgIGZvciAoaW50IHQgPSAwOyB0IDwgbkdyb3VwczsgdCsrKSB7CisgICAgICAgICAgICBmaW5hbCBieXRlW10gbGVuX3QgPSBsZW5bdF07CisgICAgICAgICAgICBpbnQgY3VyciA9IGxlbl90WzBdICYgMHhmZjsKKworICAgICAgICAgICAgLy8gaW5saW5lZDogYnNXKDUsIGN1cnIpOworICAgICAgICAgICAgd2hpbGUgKGJzTGl2ZVNoYWRvdyA+PSA4KSB7CisgICAgICAgICAgICAgICAgb3V0U2hhZG93LndyaXRlKGJzQnVmZlNoYWRvdyA+PiAyNCk7IC8vIHdyaXRlIDgtYml0CisgICAgICAgICAgICAgICAgYnNCdWZmU2hhZG93IDw8PSA4OworICAgICAgICAgICAgICAgIGJzTGl2ZVNoYWRvdyAtPSA4OworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnNCdWZmU2hhZG93IHw9IGN1cnIgPDwgKDMyIC0gYnNMaXZlU2hhZG93IC0gNSk7CisgICAgICAgICAgICBic0xpdmVTaGFkb3cgKz0gNTsKKworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhbHBoYVNpemU7IGkrKykgeworICAgICAgICAgICAgICAgIGZpbmFsIGludCBsdGkgPSBsZW5fdFtpXSAmIDB4ZmY7CisgICAgICAgICAgICAgICAgd2hpbGUgKGN1cnIgPCBsdGkpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gaW5saW5lZDogYnNXKDIsIDIpOworICAgICAgICAgICAgICAgICAgICB3aGlsZSAoYnNMaXZlU2hhZG93ID49IDgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIG91dFNoYWRvdy53cml0ZShic0J1ZmZTaGFkb3cgPj4gMjQpOyAvLyB3cml0ZSA4LWJpdAorICAgICAgICAgICAgICAgICAgICAgICAgYnNCdWZmU2hhZG93IDw8PSA4OworICAgICAgICAgICAgICAgICAgICAgICAgYnNMaXZlU2hhZG93IC09IDg7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgYnNCdWZmU2hhZG93IHw9IDIgPDwgKDMyIC0gYnNMaXZlU2hhZG93IC0gMik7CisgICAgICAgICAgICAgICAgICAgIGJzTGl2ZVNoYWRvdyArPSAyOworCisgICAgICAgICAgICAgICAgICAgIGN1cnIrKzsgLyogMTAgKi8KKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICB3aGlsZSAoY3VyciA+IGx0aSkgeworICAgICAgICAgICAgICAgICAgICAvLyBpbmxpbmVkOiBic1coMiwgMyk7CisgICAgICAgICAgICAgICAgICAgIHdoaWxlIChic0xpdmVTaGFkb3cgPj0gOCkgeworICAgICAgICAgICAgICAgICAgICAgICAgb3V0U2hhZG93LndyaXRlKGJzQnVmZlNoYWRvdyA+PiAyNCk7IC8vIHdyaXRlIDgtYml0CisgICAgICAgICAgICAgICAgICAgICAgICBic0J1ZmZTaGFkb3cgPDw9IDg7CisgICAgICAgICAgICAgICAgICAgICAgICBic0xpdmVTaGFkb3cgLT0gODsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBic0J1ZmZTaGFkb3cgfD0gMyA8PCAoMzIgLSBic0xpdmVTaGFkb3cgLSAyKTsKKyAgICAgICAgICAgICAgICAgICAgYnNMaXZlU2hhZG93ICs9IDI7CisKKyAgICAgICAgICAgICAgICAgICAgY3Vyci0tOyAvKiAxMSAqLworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIC8vIGlubGluZWQ6IGJzVygxLCAwKTsKKyAgICAgICAgICAgICAgICB3aGlsZSAoYnNMaXZlU2hhZG93ID49IDgpIHsKKyAgICAgICAgICAgICAgICAgICAgb3V0U2hhZG93LndyaXRlKGJzQnVmZlNoYWRvdyA+PiAyNCk7IC8vIHdyaXRlIDgtYml0CisgICAgICAgICAgICAgICAgICAgIGJzQnVmZlNoYWRvdyA8PD0gODsKKyAgICAgICAgICAgICAgICAgICAgYnNMaXZlU2hhZG93IC09IDg7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIC8vIGJzQnVmZlNoYWRvdyB8PSAwIDw8ICgzMiAtIGJzTGl2ZVNoYWRvdyAtIDEpOworICAgICAgICAgICAgICAgIGJzTGl2ZVNoYWRvdysrOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdGhpcy5ic0J1ZmYgPSBic0J1ZmZTaGFkb3c7CisgICAgICAgIHRoaXMuYnNMaXZlID0gYnNMaXZlU2hhZG93OworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBzZW5kTVRGVmFsdWVzNygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIERhdGEgZGF0YVNoYWRvdyA9IHRoaXMuZGF0YTsKKyAgICAgICAgZmluYWwgYnl0ZVtdW10gbGVuID0gZGF0YVNoYWRvdy5zZW5kTVRGVmFsdWVzX2xlbjsKKyAgICAgICAgZmluYWwgaW50W11bXSBjb2RlID0gZGF0YVNoYWRvdy5zZW5kTVRGVmFsdWVzX2NvZGU7CisgICAgICAgIGZpbmFsIE91dHB1dFN0cmVhbSBvdXRTaGFkb3cgPSB0aGlzLm91dDsKKyAgICAgICAgZmluYWwgYnl0ZVtdIHNlbGVjdG9yID0gZGF0YVNoYWRvdy5zZWxlY3RvcjsKKyAgICAgICAgZmluYWwgY2hhcltdIHNmbWFwID0gZGF0YVNoYWRvdy5zZm1hcDsKKyAgICAgICAgZmluYWwgaW50IG5NVEZTaGFkb3cgPSB0aGlzLm5NVEY7CisKKyAgICAgICAgaW50IHNlbEN0ciA9IDA7CisKKyAgICAgICAgaW50IGJzTGl2ZVNoYWRvdyA9IHRoaXMuYnNMaXZlOworICAgICAgICBpbnQgYnNCdWZmU2hhZG93ID0gdGhpcy5ic0J1ZmY7CisKKyAgICAgICAgZm9yIChpbnQgZ3MgPSAwOyBncyA8IG5NVEZTaGFkb3c7KSB7CisgICAgICAgICAgICBmaW5hbCBpbnQgZ2UgPSBNYXRoLm1pbihncyArIEdfU0laRSAtIDEsIG5NVEZTaGFkb3cgLSAxKTsKKyAgICAgICAgICAgIGZpbmFsIGludCBzZWxlY3Rvcl9zZWxDdHIgPSBzZWxlY3RvcltzZWxDdHJdICYgMHhmZjsKKyAgICAgICAgICAgIGZpbmFsIGludFtdIGNvZGVfc2VsQ3RyID0gY29kZVtzZWxlY3Rvcl9zZWxDdHJdOworICAgICAgICAgICAgZmluYWwgYnl0ZVtdIGxlbl9zZWxDdHIgPSBsZW5bc2VsZWN0b3Jfc2VsQ3RyXTsKKworICAgICAgICAgICAgd2hpbGUgKGdzIDw9IGdlKSB7CisgICAgICAgICAgICAgICAgZmluYWwgaW50IHNmbWFwX2kgPSBzZm1hcFtnc107CisKKyAgICAgICAgICAgICAgICAvLworICAgICAgICAgICAgICAgIC8vIGlubGluZWQ6IGJzVyhsZW5fc2VsQ3RyW3NmbWFwX2ldICYgMHhmZiwKKyAgICAgICAgICAgICAgICAvLyBjb2RlX3NlbEN0cltzZm1hcF9pXSk7CisgICAgICAgICAgICAgICAgLy8KKyAgICAgICAgICAgICAgICB3aGlsZSAoYnNMaXZlU2hhZG93ID49IDgpIHsKKyAgICAgICAgICAgICAgICAgICAgb3V0U2hhZG93LndyaXRlKGJzQnVmZlNoYWRvdyA+PiAyNCk7CisgICAgICAgICAgICAgICAgICAgIGJzQnVmZlNoYWRvdyA8PD0gODsKKyAgICAgICAgICAgICAgICAgICAgYnNMaXZlU2hhZG93IC09IDg7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGZpbmFsIGludCBuID0gbGVuX3NlbEN0cltzZm1hcF9pXSAmIDB4RkY7CisgICAgICAgICAgICAgICAgYnNCdWZmU2hhZG93IHw9IGNvZGVfc2VsQ3RyW3NmbWFwX2ldIDw8ICgzMiAtIGJzTGl2ZVNoYWRvdyAtIG4pOworICAgICAgICAgICAgICAgIGJzTGl2ZVNoYWRvdyArPSBuOworCisgICAgICAgICAgICAgICAgZ3MrKzsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgZ3MgPSBnZSArIDE7CisgICAgICAgICAgICBzZWxDdHIrKzsKKyAgICAgICAgfQorCisgICAgICAgIHRoaXMuYnNCdWZmID0gYnNCdWZmU2hhZG93OworICAgICAgICB0aGlzLmJzTGl2ZSA9IGJzTGl2ZVNoYWRvdzsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgbW92ZVRvRnJvbnRDb2RlQW5kU2VuZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJzVygyNCwgdGhpcy5kYXRhLm9yaWdQdHIpOworICAgICAgICBnZW5lcmF0ZU1URlZhbHVlcygpOworICAgICAgICBzZW5kTVRGVmFsdWVzKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGJsb2NrU29ydCgpIHsKKyAgICAgICAgYmxvY2tTb3J0ZXIuYmxvY2tTb3J0KGRhdGEsIGxhc3QpOworICAgIH0KKworICAgIC8qCisgICAgICogUGVyZm9ybXMgTW92ZS1Uby1Gcm9udCBvbiB0aGUgQnVycm93cy1XaGVlbGVyIHRyYW5zZm9ybWVkCisgICAgICogYnVmZmVyLCBzdG9yaW5nIHRoZSBNVEZlZCBkYXRhIGluIGRhdGEuc2ZtYXAgaW4gUlVOQS9SVU5CCisgICAgICogcnVuLWxlbmd0aC1lbmNvZGVkIGZvcm0uCisgICAgICoKKyAgICAgKiA8cD5LZWVwcyB0cmFjayBvZiBieXRlIGZyZXF1ZW5jaWVzIGluIGRhdGEubXRmRnJlcSBhdCB0aGUgc2FtZSB0aW1lLjwvcD4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgZ2VuZXJhdGVNVEZWYWx1ZXMoKSB7CisgICAgICAgIGZpbmFsIGludCBsYXN0U2hhZG93ID0gdGhpcy5sYXN0OworICAgICAgICBmaW5hbCBEYXRhIGRhdGFTaGFkb3cgPSB0aGlzLmRhdGE7CisgICAgICAgIGZpbmFsIGJvb2xlYW5bXSBpblVzZSA9IGRhdGFTaGFkb3cuaW5Vc2U7CisgICAgICAgIGZpbmFsIGJ5dGVbXSBibG9jayA9IGRhdGFTaGFkb3cuYmxvY2s7CisgICAgICAgIGZpbmFsIGludFtdIGZtYXAgPSBkYXRhU2hhZG93LmZtYXA7CisgICAgICAgIGZpbmFsIGNoYXJbXSBzZm1hcCA9IGRhdGFTaGFkb3cuc2ZtYXA7CisgICAgICAgIGZpbmFsIGludFtdIG10ZkZyZXEgPSBkYXRhU2hhZG93Lm10ZkZyZXE7CisgICAgICAgIGZpbmFsIGJ5dGVbXSB1bnNlcVRvU2VxID0gZGF0YVNoYWRvdy51bnNlcVRvU2VxOworICAgICAgICBmaW5hbCBieXRlW10geXkgPSBkYXRhU2hhZG93LmdlbmVyYXRlTVRGVmFsdWVzX3l5OworCisgICAgICAgIC8vIG1ha2UgbWFwcworICAgICAgICBpbnQgbkluVXNlU2hhZG93ID0gMDsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAyNTY7IGkrKykgeworICAgICAgICAgICAgaWYgKGluVXNlW2ldKSB7CisgICAgICAgICAgICAgICAgdW5zZXFUb1NlcVtpXSA9IChieXRlKSBuSW5Vc2VTaGFkb3c7CisgICAgICAgICAgICAgICAgbkluVXNlU2hhZG93Kys7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5uSW5Vc2UgPSBuSW5Vc2VTaGFkb3c7CisKKyAgICAgICAgZmluYWwgaW50IGVvYiA9IG5JblVzZVNoYWRvdyArIDE7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IGVvYjsgaSA+PSAwOyBpLS0pIHsKKyAgICAgICAgICAgIG10ZkZyZXFbaV0gPSAwOworICAgICAgICB9CisKKyAgICAgICAgZm9yIChpbnQgaSA9IG5JblVzZVNoYWRvdzsgLS1pID49IDA7KSB7CisgICAgICAgICAgICB5eVtpXSA9IChieXRlKSBpOworICAgICAgICB9CisKKyAgICAgICAgaW50IHdyID0gMDsKKyAgICAgICAgaW50IHpQZW5kID0gMDsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8PSBsYXN0U2hhZG93OyBpKyspIHsKKyAgICAgICAgICAgIGZpbmFsIGJ5dGUgbGxfaSA9IHVuc2VxVG9TZXFbYmxvY2tbZm1hcFtpXV0gJiAweGZmXTsKKyAgICAgICAgICAgIGJ5dGUgdG1wID0geXlbMF07CisgICAgICAgICAgICBpbnQgaiA9IDA7CisKKyAgICAgICAgICAgIHdoaWxlIChsbF9pICE9IHRtcCkgeworICAgICAgICAgICAgICAgIGorKzsKKyAgICAgICAgICAgICAgICBmaW5hbCBieXRlIHRtcDIgPSB0bXA7CisgICAgICAgICAgICAgICAgdG1wID0geXlbal07CisgICAgICAgICAgICAgICAgeXlbal0gPSB0bXAyOworICAgICAgICAgICAgfQorICAgICAgICAgICAgeXlbMF0gPSB0bXA7CisKKyAgICAgICAgICAgIGlmIChqID09IDApIHsKKyAgICAgICAgICAgICAgICB6UGVuZCsrOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBpZiAoelBlbmQgPiAwKSB7CisgICAgICAgICAgICAgICAgICAgIHpQZW5kLS07CisgICAgICAgICAgICAgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKHpQZW5kICYgMSkgPT0gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNmbWFwW3dyXSA9IFJVTkE7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgd3IrKzsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdGZGcmVxW1JVTkFdKys7CisgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNmbWFwW3dyXSA9IFJVTkI7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgd3IrKzsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdGZGcmVxW1JVTkJdKys7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmICh6UGVuZCA+PSAyKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgelBlbmQgPSAoelBlbmQgLSAyKSA+PiAxOworICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB6UGVuZCA9IDA7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHNmbWFwW3dyXSA9IChjaGFyKSAoaiArIDEpOworICAgICAgICAgICAgICAgIHdyKys7CisgICAgICAgICAgICAgICAgbXRmRnJlcVtqICsgMV0rKzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmICh6UGVuZCA+IDApIHsKKyAgICAgICAgICAgIHpQZW5kLS07CisgICAgICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgICAgIGlmICgoelBlbmQgJiAxKSA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIHNmbWFwW3dyXSA9IFJVTkE7CisgICAgICAgICAgICAgICAgICAgIHdyKys7CisgICAgICAgICAgICAgICAgICAgIG10ZkZyZXFbUlVOQV0rKzsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBzZm1hcFt3cl0gPSBSVU5COworICAgICAgICAgICAgICAgICAgICB3cisrOworICAgICAgICAgICAgICAgICAgICBtdGZGcmVxW1JVTkJdKys7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgaWYgKHpQZW5kID49IDIpIHsKKyAgICAgICAgICAgICAgICAgICAgelBlbmQgPSAoelBlbmQgLSAyKSA+PiAxOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHNmbWFwW3dyXSA9IChjaGFyKSBlb2I7CisgICAgICAgIG10ZkZyZXFbZW9iXSsrOworICAgICAgICB0aGlzLm5NVEYgPSB3ciArIDE7CisgICAgfQorCisgICAgc3RhdGljIGZpbmFsIGNsYXNzIERhdGEgeworCisgICAgICAgIC8vIHdpdGggYmxvY2tTaXplIDkwMGsKKyAgICAgICAgLyogbWFwcyB1bnNpZ25lZCBieXRlID0+ICJkb2VzIGl0IG9jY3VyIGluIGJsb2NrIiAqLworICAgICAgICBmaW5hbCBib29sZWFuW10gaW5Vc2UgPSBuZXcgYm9vbGVhblsyNTZdOyAvLyAyNTYgYnl0ZQorICAgICAgICBmaW5hbCBieXRlW10gdW5zZXFUb1NlcSA9IG5ldyBieXRlWzI1Nl07IC8vIDI1NiBieXRlCisgICAgICAgIGZpbmFsIGludFtdIG10ZkZyZXEgPSBuZXcgaW50W01BWF9BTFBIQV9TSVpFXTsgLy8gMTAzMiBieXRlCisgICAgICAgIGZpbmFsIGJ5dGVbXSBzZWxlY3RvciA9IG5ldyBieXRlW01BWF9TRUxFQ1RPUlNdOyAvLyAxODAwMiBieXRlCisgICAgICAgIGZpbmFsIGJ5dGVbXSBzZWxlY3Rvck10ZiA9IG5ldyBieXRlW01BWF9TRUxFQ1RPUlNdOyAvLyAxODAwMiBieXRlCisKKyAgICAgICAgZmluYWwgYnl0ZVtdIGdlbmVyYXRlTVRGVmFsdWVzX3l5ID0gbmV3IGJ5dGVbMjU2XTsgLy8gMjU2IGJ5dGUKKyAgICAgICAgZmluYWwgYnl0ZVtdW10gc2VuZE1URlZhbHVlc19sZW4gPSBuZXcgYnl0ZVtOX0dST1VQU11bTUFYX0FMUEhBX1NJWkVdOyAvLyAxNTQ4CisgICAgICAgIC8vIGJ5dGUKKyAgICAgICAgZmluYWwgaW50W11bXSBzZW5kTVRGVmFsdWVzX3JmcmVxID0gbmV3IGludFtOX0dST1VQU11bTUFYX0FMUEhBX1NJWkVdOyAvLyA2MTkyCisgICAgICAgIC8vIGJ5dGUKKyAgICAgICAgZmluYWwgaW50W10gc2VuZE1URlZhbHVlc19mYXZlID0gbmV3IGludFtOX0dST1VQU107IC8vIDI0IGJ5dGUKKyAgICAgICAgZmluYWwgc2hvcnRbXSBzZW5kTVRGVmFsdWVzX2Nvc3QgPSBuZXcgc2hvcnRbTl9HUk9VUFNdOyAvLyAxMiBieXRlCisgICAgICAgIGZpbmFsIGludFtdW10gc2VuZE1URlZhbHVlc19jb2RlID0gbmV3IGludFtOX0dST1VQU11bTUFYX0FMUEhBX1NJWkVdOyAvLyA2MTkyCisgICAgICAgIC8vIGJ5dGUKKyAgICAgICAgZmluYWwgYnl0ZVtdIHNlbmRNVEZWYWx1ZXMyX3BvcyA9IG5ldyBieXRlW05fR1JPVVBTXTsgLy8gNiBieXRlCisgICAgICAgIGZpbmFsIGJvb2xlYW5bXSBzZW50TVRGVmFsdWVzNF9pblVzZTE2ID0gbmV3IGJvb2xlYW5bMTZdOyAvLyAxNiBieXRlCisKKyAgICAgICAgZmluYWwgaW50W10gaGVhcCA9IG5ldyBpbnRbTUFYX0FMUEhBX1NJWkUgKyAyXTsgLy8gMTA0MCBieXRlCisgICAgICAgIGZpbmFsIGludFtdIHdlaWdodCA9IG5ldyBpbnRbTUFYX0FMUEhBX1NJWkUgKiAyXTsgLy8gMjA2NCBieXRlCisgICAgICAgIGZpbmFsIGludFtdIHBhcmVudCA9IG5ldyBpbnRbTUFYX0FMUEhBX1NJWkUgKiAyXTsgLy8gMjA2NCBieXRlCisKKyAgICAgICAgLy8gLS0tLS0tLS0tLS0tCisgICAgICAgIC8vIDMzMzQwOCBieXRlCisKKyAgICAgICAgLyogaG9sZHMgdGhlIFJMRWQgYmxvY2sgb2Ygb3JpZ2luYWwgZGF0YSBzdGFydGluZyBhdCBpbmRleCAxLgorICAgICAgICAgKiBBZnRlciBzb3J0aW5nIHRoZSBsYXN0IGJ5dGUgYWRkZWQgdG8gdGhlIGJ1ZmZlciBpcyBhdCBpbmRleAorICAgICAgICAgKiAwLiAqLworICAgICAgICBmaW5hbCBieXRlW10gYmxvY2s7IC8vIDkwMDAyMSBieXRlCisgICAgICAgIC8qIG1hcHMgaW5kZXggaW4gQnVycm93cy1XaGVlbGVyIHRyYW5zZm9ybWVkIGJsb2NrID0+IGluZGV4IG9mCisgICAgICAgICAqIGJ5dGUgaW4gb3JpZ2luYWwgYmxvY2sgKi8KKyAgICAgICAgZmluYWwgaW50W10gZm1hcDsgLy8gMzYwMDAwMCBieXRlCisgICAgICAgIGZpbmFsIGNoYXJbXSBzZm1hcDsgLy8gMzYwMDAwMCBieXRlCisgICAgICAgIC8vIC0tLS0tLS0tLS0tLQorICAgICAgICAvLyA4NDMzNTI5IGJ5dGUKKyAgICAgICAgLy8gPT09PT09PT09PT09CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEluZGV4IG9mIG9yaWdpbmFsIGxpbmUgaW4gQnVycm93cy1XaGVlbGVyIHRhYmxlLgorICAgICAgICAgKgorICAgICAgICAgKiA8cD5UaGlzIGlzIHRoZSBpbmRleCBpbiBmbWFwIHRoYXQgcG9pbnRzIHRvIHRoZSBsYXN0IGJ5dGUKKyAgICAgICAgICogb2YgdGhlIG9yaWdpbmFsIGRhdGEuPC9wPgorICAgICAgICAgKi8KKyAgICAgICAgaW50IG9yaWdQdHI7CisKKyAgICAgICAgRGF0YShmaW5hbCBpbnQgYmxvY2tTaXplMTAwaykgeworICAgICAgICAgICAgZmluYWwgaW50IG4gPSBibG9ja1NpemUxMDBrICogQlppcDJDb25zdGFudHMuQkFTRUJMT0NLU0laRTsKKyAgICAgICAgICAgIHRoaXMuYmxvY2sgPSBuZXcgYnl0ZVsobiArIDEgKyBOVU1fT1ZFUlNIT09UX0JZVEVTKV07CisgICAgICAgICAgICB0aGlzLmZtYXAgPSBuZXcgaW50W25dOworICAgICAgICAgICAgdGhpcy5zZm1hcCA9IG5ldyBjaGFyWzIgKiBuXTsKKyAgICAgICAgfQorCisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9iemlwMi9CWmlwMkNvbnN0YW50cy5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvYnppcDIvQlppcDJDb25zdGFudHMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45YThiOWM0Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvYnppcDIvQlppcDJDb25zdGFudHMuamF2YQpAQCAtMCwwICsxLDM4IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuYnppcDI7CisKKy8qKgorICogQ29uc3RhbnRzIGZvciBib3RoIHRoZSBjb21wcmVzcyBhbmQgZGVjb21wcmVzcyBCWmlwMiBjbGFzc2VzLgorICovCitpbnRlcmZhY2UgQlppcDJDb25zdGFudHMgeworCisgICAgaW50IEJBU0VCTE9DS1NJWkUgPSAxMDAwMDA7CisgICAgaW50IE1BWF9BTFBIQV9TSVpFID0gMjU4OworICAgIGludCBNQVhfQ09ERV9MRU4gPSAyMzsKKyAgICBpbnQgUlVOQSA9IDA7CisgICAgaW50IFJVTkIgPSAxOworICAgIGludCBOX0dST1VQUyA9IDY7CisgICAgaW50IEdfU0laRSA9IDUwOworICAgIGludCBOX0lURVJTID0gNDsKKyAgICBpbnQgTUFYX1NFTEVDVE9SUyA9ICgyICsgKDkwMDAwMCAvIEdfU0laRSkpOworICAgIGludCBOVU1fT1ZFUlNIT09UX0JZVEVTID0gMjA7CisKK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9iemlwMi9CWmlwMlV0aWxzLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9iemlwMi9CWmlwMlV0aWxzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTU4MmQ5OAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2J6aXAyL0JaaXAyVXRpbHMuamF2YQpAQCAtMCwwICsxLDkzIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLmJ6aXAyOworCitpbXBvcnQgamF2YS51dGlsLkxpbmtlZEhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuRmlsZU5hbWVVdGlsOworCisvKioKKyAqIFV0aWxpdHkgY29kZSBmb3IgdGhlIEJaaXAyIGNvbXByZXNzaW9uIGZvcm1hdC4KKyAqIEBUaHJlYWRTYWZlCisgKiBAc2luY2UgMS4xCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBCWmlwMlV0aWxzIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEZpbGVOYW1lVXRpbCBmaWxlTmFtZVV0aWw7CisKKyAgICBzdGF0aWMgeworICAgICAgICBmaW5hbCBNYXA8U3RyaW5nLCBTdHJpbmc+IHVuY29tcHJlc3NTdWZmaXggPQorICAgICAgICAgICAgbmV3IExpbmtlZEhhc2hNYXA8PigpOworICAgICAgICAvLyBiYWNrd2FyZHMgY29tcGF0aWJpbHR5OiBCWmlwMlV0aWxzIG5ldmVyIGNyZWF0ZWQgdGhlIHNob3J0CisgICAgICAgIC8vIHRieiBmb3JtLCBzbyAudGFyLmJ6MiBoYXMgdG8gYmUgYWRkZWQgZXhwbGljaXRseQorICAgICAgICB1bmNvbXByZXNzU3VmZml4LnB1dCgiLnRhci5iejIiLCAiLnRhciIpOworICAgICAgICB1bmNvbXByZXNzU3VmZml4LnB1dCgiLnRiejIiLCAiLnRhciIpOworICAgICAgICB1bmNvbXByZXNzU3VmZml4LnB1dCgiLnRieiIsICIudGFyIik7CisgICAgICAgIHVuY29tcHJlc3NTdWZmaXgucHV0KCIuYnoyIiwgIiIpOworICAgICAgICB1bmNvbXByZXNzU3VmZml4LnB1dCgiLmJ6IiwgIiIpOworICAgICAgICBmaWxlTmFtZVV0aWwgPSBuZXcgRmlsZU5hbWVVdGlsKHVuY29tcHJlc3NTdWZmaXgsICIuYnoyIik7CisgICAgfQorCisgICAgLyoqIFByaXZhdGUgY29uc3RydWN0b3IgdG8gcHJldmVudCBpbnN0YW50aWF0aW9uIG9mIHRoaXMgdXRpbGl0eSBjbGFzcy4gKi8KKyAgICBwcml2YXRlIEJaaXAyVXRpbHMoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogRGV0ZWN0cyBjb21tb24gYnppcDIgc3VmZml4ZXMgaW4gdGhlIGdpdmVuIGZpbGVuYW1lLgorICAgICAqCisgICAgICogQHBhcmFtIGZpbGVuYW1lIG5hbWUgb2YgYSBmaWxlCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIGZpbGVuYW1lIGhhcyBhIGNvbW1vbiBiemlwMiBzdWZmaXgsCisgICAgICogICAgICAgICB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0NvbXByZXNzZWRGaWxlbmFtZShmaW5hbCBTdHJpbmcgZmlsZW5hbWUpIHsKKyAgICAgICAgcmV0dXJuIGZpbGVOYW1lVXRpbC5pc0NvbXByZXNzZWRGaWxlbmFtZShmaWxlbmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogTWFwcyB0aGUgZ2l2ZW4gbmFtZSBvZiBhIGJ6aXAyLWNvbXByZXNzZWQgZmlsZSB0byB0aGUgbmFtZSB0aGF0IHRoZQorICAgICAqIGZpbGUgc2hvdWxkIGhhdmUgYWZ0ZXIgdW5jb21wcmVzc2lvbi4gQ29tbW9ubHkgdXNlZCBmaWxlIHR5cGUgc3BlY2lmaWMKKyAgICAgKiBzdWZmaXhlcyBsaWtlICIudGJ6IiBvciAiLnRiejIiIGFyZSBhdXRvbWF0aWNhbGx5IGRldGVjdGVkIGFuZAorICAgICAqIGNvcnJlY3RseSBtYXBwZWQuIEZvciBleGFtcGxlIHRoZSBuYW1lICJwYWNrYWdlLnRiejIiIGlzIG1hcHBlZCB0bworICAgICAqICJwYWNrYWdlLnRhciIuIEFuZCBhbnkgZmlsZW5hbWVzIHdpdGggdGhlIGdlbmVyaWMgIi5iejIiIHN1ZmZpeAorICAgICAqIChvciBhbnkgb3RoZXIgZ2VuZXJpYyBiemlwMiBzdWZmaXgpIGlzIG1hcHBlZCB0byBhIG5hbWUgd2l0aG91dCB0aGF0CisgICAgICogc3VmZml4LiBJZiBubyBiemlwMiBzdWZmaXggaXMgZGV0ZWN0ZWQsIHRoZW4gdGhlIGZpbGVuYW1lIGlzIHJldHVybmVkCisgICAgICogdW5tYXBwZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmlsZW5hbWUgbmFtZSBvZiBhIGZpbGUKKyAgICAgKiBAcmV0dXJuIG5hbWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgdW5jb21wcmVzc2VkIGZpbGUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRVbmNvbXByZXNzZWRGaWxlbmFtZShmaW5hbCBTdHJpbmcgZmlsZW5hbWUpIHsKKyAgICAgICAgcmV0dXJuIGZpbGVOYW1lVXRpbC5nZXRVbmNvbXByZXNzZWRGaWxlbmFtZShmaWxlbmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogTWFwcyB0aGUgZ2l2ZW4gZmlsZW5hbWUgdG8gdGhlIG5hbWUgdGhhdCB0aGUgZmlsZSBzaG91bGQgaGF2ZSBhZnRlcgorICAgICAqIGNvbXByZXNzaW9uIHdpdGggYnppcDIuIEN1cnJlbnRseSB0aGlzIG1ldGhvZCBzaW1wbHkgYXBwZW5kcyB0aGUgc3VmZml4CisgICAgICogIi5iejIiIHRvIHRoZSBmaWxlbmFtZSBiYXNlZCBvbiB0aGUgc3RhbmRhcmQgYmVoYXZpb3VyIG9mIHRoZSAiYnppcDIiCisgICAgICogcHJvZ3JhbSwgYnV0IGEgZnV0dXJlIHZlcnNpb24gbWF5IGltcGxlbWVudCBhIG1vcmUgY29tcGxleCBtYXBwaW5nIGlmCisgICAgICogYSBuZXcgd2lkZWx5IHVzZWQgbmFtaW5nIHBhdHRlcm4gZW1lcmdlcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmaWxlbmFtZSBuYW1lIG9mIGEgZmlsZQorICAgICAqIEByZXR1cm4gbmFtZSBvZiB0aGUgY29ycmVzcG9uZGluZyBjb21wcmVzc2VkIGZpbGUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRDb21wcmVzc2VkRmlsZW5hbWUoZmluYWwgU3RyaW5nIGZpbGVuYW1lKSB7CisgICAgICAgIHJldHVybiBmaWxlTmFtZVV0aWwuZ2V0Q29tcHJlc3NlZEZpbGVuYW1lKGZpbGVuYW1lKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2J6aXAyL0Jsb2NrU29ydC5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvYnppcDIvQmxvY2tTb3J0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjk4MTllMwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2J6aXAyL0Jsb2NrU29ydC5qYXZhCkBAIC0wLDAgKzEsMTA4MiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5iemlwMjsKKworaW1wb3J0IGphdmEudXRpbC5CaXRTZXQ7CisKKy8qKgorICogRW5jYXBzdWxhdGVzIHRoZSBCdXJyb3dzLVdoZWVsZXIgc29ydGluZyBhbGdvcml0aG0gbmVlZGVkIGJ5IHtAbGluaworICogQlppcDJDb21wcmVzc29yT3V0cHV0U3RyZWFtfS4KKyAqCisgKiA8cD5UaGlzIGNsYXNzIGlzIGJhc2VkIG9uIGEgSmF2YSBwb3J0IG9mIEp1bGlhbiBTZXdhcmQncworICogYmxvY2tzb3J0LmMgaW4gaGlzIGxpYmJ6aXAyPC9wPgorICoKKyAqIDxwPlRoZSBCdXJyb3dzLVdoZWVsZXIgdHJhbnNmb3JtIGlzIGEgcmV2ZXJzaWJsZSB0cmFuc2Zvcm0gb2YgdGhlCisgKiBvcmlnaW5hbCBkYXRhIHRoYXQgaXMgc3VwcG9zZWQgdG8gZ3JvdXAgc2ltaWxhciBieXRlcyBjbG9zZSB0bworICogZWFjaCBvdGhlci4gIFRoZSBpZGVhIGlzIHRvIHNvcnQgYWxsIHBlcm11dGF0aW9ucyBvZiB0aGUgaW5wdXQgYW5kCisgKiBvbmx5IGtlZXAgdGhlIGxhc3QgYnl0ZSBvZiBlYWNoIHBlcm11dGF0aW9uLiAgRS5nLiBmb3IgIkNvbW1vbnMKKyAqIENvbXByZXNzIiB5b3UnZCBnZXQ6PC9wPgorICoKKyAqIDxwcmU+CisgKiAgQ29tcHJlc3NDb21tb25zCisgKiBDb21tb25zIENvbXByZXNzCisgKiBDb21wcmVzc0NvbW1vbnMKKyAqIGVzc0NvbW1vbnMgQ29tcHIKKyAqIG1tb25zIENvbXByZXNzQ28KKyAqIG1vbnMgQ29tcHJlc3NDb20KKyAqIG1wcmVzc0NvbW1vbnMgQ28KKyAqIG5zIENvbXByZXNzQ29tbW8KKyAqIG9tbW9ucyBDb21wcmVzc0MKKyAqIG9tcHJlc3NDb21tb25zIEMKKyAqIG9ucyBDb21wcmVzc0NvbW0KKyAqIHByZXNzQ29tbW9ucyBDb20KKyAqIHJlc3NDb21tb25zIENvbXAKKyAqIHMgQ29tcHJlc3NDb21tb24KKyAqIHNDb21tb25zIENvbXByZXMKKyAqIHNzQ29tbW9ucyBDb21wcmUKKyAqIDwvcHJlPgorICoKKyAqIDxwPldoaWNoIHJlc3VsdHMgaW4gYSBuZXcgdGV4dCAic3Mgcm9tb29DQ21tcG5zZSIsIGluIGFkaXRpb24gdGhlCisgKiBpbmRleCBvZiB0aGUgZmlyc3QgbGluZSB0aGF0IGNvbnRhaW5lZCB0aGUgb3JpZ2luYWwgdGV4dCBpcyBrZXB0IC0KKyAqIGluIHRoaXMgY2FzZSBpdCBpcyAxLiAgVGhlIGlkZWEgaXMgdGhhdCBpbiBhIGxvbmcgRW5nbGlzaCB0ZXh0IGFsbAorICogcGVybXV0YXRpb25zIHRoYXQgc3RhcnQgd2l0aCAiaGUiIGFyZSBsaWtlbHkgc3VmZml4ZXMgb2YgYSAidGhlIiBhbmQKKyAqIHRodXMgdGhleSBlbmQgaW4gInQiIGxlYWRpbmcgdG8gYSBsYXJnZXIgYmxvY2sgb2YgInQicyB0aGF0IGNhbgorICogYmV0dGVyIGJlIGNvbXByZXNzZWQgYnkgdGhlIHN1YnNlcXVlbnQgTW92ZS10by1Gcm9udCwgcnVuLWxlbmd0aAorICogdW5kIEh1ZmZtYW4gZW5jb2Rpbmcgc3RlcHMuPC9wPgorICoKKyAqIDxwPkZvciBtb3JlIGluZm9ybWF0aW9uIHNlZSBmb3IgZXhhbXBsZTo8L3A+CisgKiA8dWw+CisgKiAgIDxsaT48YQorICogICBocmVmPSJodHRwOi8vd3d3LmhwbC5ocC5jb20vdGVjaHJlcG9ydHMvQ29tcGFxLURFQy9TUkMtUlItMTI0LnBkZiI+QnVycm93cywKKyAqICAgTS4gYW5kIFdoZWVsZXIsIEQuOiBBIEJsb2NrLXNvcnRpbmcgTG9zc2xlc3MgRGF0YSBDb21wcmVzc2lvbgorICogICBBbGdvcml0aG08L2E+PC9saT4KKyAqICAgPGxpPjxhIGhyZWY9Imh0dHA6Ly93ZWJnbGltcHNlLm5ldC9wdWJzL3N1ZmZpeC5wZGYiPk1hbmJlciwgVS4gYW5kCisgKiAgIE15ZXJzLCBHLjogU3VmZml4IGFycmF5czogQSBuZXcgbWV0aG9kIGZvciBvbi1saW5lIHN0cmluZworICogICBzZWFyY2hlczwvYT48L2xpPgorICogICA8bGk+PGEKKyAqICAgaHJlZj0iaHR0cDovL3d3dy5jcy50dWZ0cy5lZHUvfm5yL2NvbXAxNTBmcC9hcmNoaXZlL2JvYi1zZWRnZXdpY2svZmFzdC1zdHJpbmdzLnBkZiI+QmVudGxleSwKKyAqICAgSi5MLiBhbmQgU2VkZ2V3aWNrLCBSLjogRmFzdCBBbGdvcml0aG1zIGZvciBTb3J0aW5nIGFuZCBTZWFyY2hpbmcKKyAqICAgU3RyaW5nczwvYT48L2xpPgorICogPC91bD4KKyAqCisgKiBATm90VGhyZWFkU2FmZQorICovCitjbGFzcyBCbG9ja1NvcnQgeworCisgICAgLyoKKyAgICAgKiBTb21lIG9mIHRoZSBjb25zdHJ1Y3RzIHVzZWQgaW4gdGhlIEMgY29kZSBjYW5ub3QgYmUgcG9ydGVkCisgICAgICogbGl0ZXJhbGx5IHRvIEphdmEgLSBmb3IgZXhhbXBsZSBtYWNyb3MsIHVuc2lnbmVkIHR5cGVzLiAgU29tZQorICAgICAqIGNvZGUgaGFzIGJlZW4gaGFuZC10dW5lZCB0byBpbXByb3ZlIHBlcmZvcm1hbmNlLiAgSW4gb3JkZXIgdG8KKyAgICAgKiBhdm9pZCBtZW1vcnkgcHJlc3N1cmUgc29tZSBzdHJ1Y3R1cmVzIGFyZSByZXVzZWQgZm9yIHNldmVyYWwKKyAgICAgKiBibG9ja3MgYW5kIHNvbWUgbWVtb3J5IGlzIGV2ZW4gc2hhcmVkIGJldHdlZW4gc29ydGluZyBhbmQgdGhlCisgICAgICogTVRGIHN0YWdlIGV2ZW4gdGhvdWdoIGVpdGhlciBhbGdvcml0aG0gdXNlcyBpdCBmb3IgaXRzIG93bgorICAgICAqIHB1cnBvc2UuCisgICAgICoKKyAgICAgKiBDb21tZW50cyBwcmVzZXJ2ZWQgZnJvbSB0aGUgYWN0dWFsIEMgY29kZSBhcmUgcHJlZml4ZWQgd2l0aAorICAgICAqICJMQloyOiIuCisgICAgICovCisKKyAgICAvKgorICAgICAqIDIwMTItMDUtMjAgU3RlZmFuIEJvZGV3aWc6CisgICAgICoKKyAgICAgKiBUaGlzIGNsYXNzIHNlZW1zIHRvIG1peCBzZXZlcmFsIHJldmlzaW9ucyBvZiBsaWJiemlwMidzIGNvZGUuCisgICAgICogVGhlIG1haW5Tb3J0IGZ1bmN0aW9uIGFuZCB0aG9zZSB1c2VkIGJ5IGl0IGxvb2sgY2xvc2VyIHRvIHRoZQorICAgICAqIDAuOS41IHZlcnNpb24gYnV0IHNob3cgc29tZSB2YXJpYXRpb25zIGludHJvZHVjZWQgbGF0ZXIuICBBdAorICAgICAqIHRoZSBzYW1lIHRpbWUgdGhlIGxvZ2ljIG9mIENvbXByZXNzIDEuNCB0byByYW5kb21pemUgdGhlIGJsb2NrCisgICAgICogb24gYmFkIGlucHV0IGhhcyBiZWVuIGRyb3BwZWQgYWZ0ZXIgbGliYnppcDIgMC45LjAgYW5kIHJlcGxhY2VkCisgICAgICogYnkgYSBmYWxsYmFjayBzb3J0aW5nIGFsZ29yaXRobS4KKyAgICAgKgorICAgICAqIEkndmUgYWRkZWQgdGhlIGZhbGxiYWNrU29ydCBmdW5jdGlvbiBvZiAxLjAuNiBhbmQgdHJpZWQgdG8KKyAgICAgKiBpbnRlZ3JhdGUgaXQgd2l0aCB0aGUgZXhpc3RpbmcgY29kZSB3aXRob3V0IHRvdWNoaW5nIHRvbyBtdWNoLgorICAgICAqIEkndmUgYWxzbyByZW1vdmVkIHRoZSBub3cgdW51c2VkIHJhbmRvbWl6YXRpb24gY29kZS4KKyAgICAgKi8KKworICAgIC8qCisgICAgICogTEJaMjogSWYgeW91IGFyZSBldmVyIHVubHVja3kvaW1wcm9iYWJsZSBlbm91Z2ggdG8gZ2V0IGEgc3RhY2sKKyAgICAgKiBvdmVyZmxvdyB3aGlsc3Qgc29ydGluZywgaW5jcmVhc2UgdGhlIGZvbGxvd2luZyBjb25zdGFudCBhbmQKKyAgICAgKiB0cnkgYWdhaW4uIEluIHByYWN0aWNlIEkgaGF2ZSBuZXZlciBzZWVuIHRoZSBzdGFjayBnbyBhYm92ZSAyNworICAgICAqIGVsZW1zLCBzbyB0aGUgZm9sbG93aW5nIGxpbWl0IHNlZW1zIHZlcnkgZ2VuZXJvdXMuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFFTT1JUX1NUQUNLX1NJWkUgPSAxMDAwOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEZBTExCQUNLX1FTT1JUX1NUQUNLX1NJWkUgPSAxMDA7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgU1RBQ0tfU0laRSA9CisgICAgICAgIFFTT1JUX1NUQUNLX1NJWkUgPCBGQUxMQkFDS19RU09SVF9TVEFDS19TSVpFCisgICAgICAgID8gRkFMTEJBQ0tfUVNPUlRfU1RBQ0tfU0laRSA6IFFTT1JUX1NUQUNLX1NJWkU7CisKKyAgICAvKgorICAgICAqIFVzZWQgd2hlbiBzb3J0aW5nLiBJZiB0b28gbWFueSBsb25nIGNvbXBhcmlzb25zIGhhcHBlbiwgd2Ugc3RvcCBzb3J0aW5nLAorICAgICAqIGFuZCB1c2UgZmFsbGJhY2tTb3J0IGluc3RlYWQuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgd29ya0RvbmU7CisgICAgcHJpdmF0ZSBpbnQgd29ya0xpbWl0OworICAgIHByaXZhdGUgYm9vbGVhbiBmaXJzdEF0dGVtcHQ7CisKKyAgICBwcml2YXRlIGZpbmFsIGludFtdIHN0YWNrX2xsID0gbmV3IGludFtTVEFDS19TSVpFXTsgLy8gNDAwMCBieXRlCisgICAgcHJpdmF0ZSBmaW5hbCBpbnRbXSBzdGFja19oaCA9IG5ldyBpbnRbU1RBQ0tfU0laRV07IC8vIDQwMDAgYnl0ZQorICAgIHByaXZhdGUgZmluYWwgaW50W10gc3RhY2tfZGQgPSBuZXcgaW50W1FTT1JUX1NUQUNLX1NJWkVdOyAvLyA0MDAwIGJ5dGUKKworICAgIHByaXZhdGUgZmluYWwgaW50W10gbWFpblNvcnRfcnVubmluZ09yZGVyID0gbmV3IGludFsyNTZdOyAvLyAxMDI0IGJ5dGUKKyAgICBwcml2YXRlIGZpbmFsIGludFtdIG1haW5Tb3J0X2NvcHkgPSBuZXcgaW50WzI1Nl07IC8vIDEwMjQgYnl0ZQorICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbltdIG1haW5Tb3J0X2JpZ0RvbmUgPSBuZXcgYm9vbGVhblsyNTZdOyAvLyAyNTYgYnl0ZQorCisgICAgcHJpdmF0ZSBmaW5hbCBpbnRbXSBmdGFiID0gbmV3IGludFs2NTUzN107IC8vIDI2MjE0OCBieXRlCisKKyAgICAvKioKKyAgICAgKiBBcnJheSBpbnN0YW5jZSBpZGVudGljYWwgdG8gRGF0YSdzIHNmbWFwLCBib3RoIGFyZSB1c2VkIG9ubHkKKyAgICAgKiB0ZW1wb3JhcmlseSBhbmQgaW5kZXBlbnRseSwgc28gd2UgZG8gbm90IG5lZWQgdG8gYWxsb2NhdGUKKyAgICAgKiBhZGRpdGlvbmFsIG1lbW9yeS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIGNoYXJbXSBxdWFkcmFudDsKKworICAgIEJsb2NrU29ydChmaW5hbCBCWmlwMkNvbXByZXNzb3JPdXRwdXRTdHJlYW0uRGF0YSBkYXRhKSB7CisgICAgICAgIHRoaXMucXVhZHJhbnQgPSBkYXRhLnNmbWFwOworICAgIH0KKworICAgIHZvaWQgYmxvY2tTb3J0KGZpbmFsIEJaaXAyQ29tcHJlc3Nvck91dHB1dFN0cmVhbS5EYXRhIGRhdGEsIGZpbmFsIGludCBsYXN0KSB7CisgICAgICAgIHRoaXMud29ya0xpbWl0ID0gV09SS19GQUNUT1IgKiBsYXN0OworICAgICAgICB0aGlzLndvcmtEb25lID0gMDsKKyAgICAgICAgdGhpcy5maXJzdEF0dGVtcHQgPSB0cnVlOworCisgICAgICAgIGlmIChsYXN0ICsgMSA8IDEwMDAwKSB7CisgICAgICAgICAgICBmYWxsYmFja1NvcnQoZGF0YSwgbGFzdCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBtYWluU29ydChkYXRhLCBsYXN0KTsKKworICAgICAgICAgICAgaWYgKHRoaXMuZmlyc3RBdHRlbXB0ICYmICh0aGlzLndvcmtEb25lID4gdGhpcy53b3JrTGltaXQpKSB7CisgICAgICAgICAgICAgICAgZmFsbGJhY2tTb3J0KGRhdGEsIGxhc3QpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgZmluYWwgaW50W10gZm1hcCA9IGRhdGEuZm1hcDsKKyAgICAgICAgZGF0YS5vcmlnUHRyID0gLTE7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDw9IGxhc3Q7IGkrKykgeworICAgICAgICAgICAgaWYgKGZtYXBbaV0gPT0gMCkgeworICAgICAgICAgICAgICAgIGRhdGEub3JpZ1B0ciA9IGk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyBhc3NlcnQgKGRhdGEub3JpZ1B0ciAhPSAtMSkgOiBkYXRhLm9yaWdQdHI7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRhcHQgZmFsbGJhY2tTb3J0IHRvIHRoZSBleHBlY3RlZCBpbnRlcmZhY2Ugb2YgdGhlIHJlc3Qgb2YgdGhlCisgICAgICogY29kZSwgaW4gcGFydGljdWxhciBkZWFsIHdpdGggdGhlIGZhY3QgdGhhdCBibG9jayBzdGFydHMgYXQKKyAgICAgKiBvZmZzZXQgMSAoaW4gbGliYnppcDIgMS4wLjYgaXQgc3RhcnRzIGF0IDApLgorICAgICAqLworICAgIGZpbmFsIHZvaWQgZmFsbGJhY2tTb3J0KGZpbmFsIEJaaXAyQ29tcHJlc3Nvck91dHB1dFN0cmVhbS5EYXRhIGRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGxhc3QpIHsKKyAgICAgICAgZGF0YS5ibG9ja1swXSA9IGRhdGEuYmxvY2tbbGFzdCArIDFdOworICAgICAgICBmYWxsYmFja1NvcnQoZGF0YS5mbWFwLCBkYXRhLmJsb2NrLCBsYXN0ICsgMSk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGFzdCArIDE7IGkrKykgeworICAgICAgICAgICAgLS1kYXRhLmZtYXBbaV07CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsYXN0ICsgMTsgaSsrKSB7CisgICAgICAgICAgICBpZiAoZGF0YS5mbWFwW2ldID09IC0xKSB7CisgICAgICAgICAgICAgICAgZGF0YS5mbWFwW2ldID0gbGFzdDsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisvKi0tLSBMQloyOiBGYWxsYmFjayBPKE4gbG9nKE4pXjIpIHNvcnRpbmcgICAgICAgIC0tLSovCisvKi0tLSBhbGdvcml0aG0sIGZvciByZXBldGl0aXZlIGJsb2NrcyAgICAgIC0tLSovCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisKKyAgICAvKgorICAgICAqIFRoaXMgaXMgdGhlIGZhbGxiYWNrIHNvcnRpbmcgYWxnb3JpdGhtIGxpYmJ6aXAyIDEuMC42IHVzZXMgZm9yCisgICAgICogcmVwZXRpdGl2ZSBvciB2ZXJ5IHNob3J0IGlucHV0cy4KKyAgICAgKgorICAgICAqIFRoZSBpZGVhIGlzIGluc3BpcmVkIGJ5IE1hbmJlci1NeWVycyBzdHJpbmcgc3VmZml4IHNvcnRpbmcKKyAgICAgKiBhbGdvcml0aG0uICBGaXJzdCBhIGJ1Y2tldCBzb3J0IHBsYWNlcyBlYWNoIHBlcm11dGF0aW9uIG9mIHRoZQorICAgICAqIGJsb2NrIGludG8gYSBidWNrZXQgYmFzZWQgb24gaXRzIGZpcnN0IGJ5dGUuICBQZXJtdXRhdGlvbnMgYXJlCisgICAgICogcmVwcmVzZW50ZWQgYnkgcG9pbnRlcnMgdG8gdGhlaXIgZmlyc3QgY2hhcmFjdGVyIGtlcHQgaW4KKyAgICAgKiAocGFydGlhbGx5KSBzb3J0ZWQgb3JkZXIgaW5zaWRlIHRoZSBhcnJheSBmdGFiLgorICAgICAqCisgICAgICogVGhlIG5leHQgc3RlcCB2aXNpdHMgYWxsIGJ1Y2tldHMgaW4gb3JkZXIgYW5kIHBlcmZvcm1zIGEKKyAgICAgKiBxdWlja3NvcnQgb24gYWxsIHBlcm11dGF0aW9ucyBvZiB0aGUgYnVja2V0IGJhc2VkIG9uIHRoZSBpbmRleAorICAgICAqIG9mIHRoZSBidWNrZXQgdGhlIHNlY29uZCBieXRlIG9mIHRoZSBwZXJtdXRhdGlvbiBiZWxvbmdzIHRvLAorICAgICAqIHRoZXJlYnkgZm9ybWluZyBuZXcgYnVja2V0cy4gIFdoZW4gYXJyaXZlZCBoZXJlIHRoZQorICAgICAqIHBlcm11dGF0aW9ucyBhcmUgc29ydGVkIHVwIHRvIHRoZSBzZWNvbmQgY2hhcmFjdGVyIGFuZCB3ZSBoYXZlCisgICAgICogYnVja2V0cyBvZiBwZXJtdXRhdGlvbnMgdGhhdCBhcmUgaWRlbnRpY2FsIHVwIHRvIHR3bworICAgICAqIGNoYXJhY3RlcnMuCisgICAgICoKKyAgICAgKiBSZXBlYXQgdGhlIHN0ZXAgb2YgcXVpY2tzb3J0aW5nIGVhY2ggYnVja2V0LCBub3cgYmFzZWQgb24gdGhlCisgICAgICogYnVja2V0IGhvbGRpbmcgdGhlIHNlcXVlbmNlIG9mIHRoZSB0aGlyZCBhbmQgZm9ydGggY2hhcmFjdGVyCisgICAgICogbGVhZGluZyB0byBmb3VyIGJ5dGUgYnVja2V0cy4gIFJlcGVhdCB0aGlzIGRvdWJsaW5nIG9mIGJ1Y2tldAorICAgICAqIHNpemVzIHVudGlsIGFsbCBidWNrZXRzIG9ubHkgY29udGFpbiBzaW5nbGUgcGVybXV0YXRpb25zIG9yIHRoZQorICAgICAqIGJ1Y2tldCBzaXplIGV4Y2VlZHMgdGhlIGJsb2NrIHNpemUuCisgICAgICoKKyAgICAgKiBJLmUuCisgICAgICoKKyAgICAgKiAiYWJyYWJhIiBmb3JtIHRocmVlIGJ1Y2tldHMgZm9yIHRoZSBjaGFycyAiYSIsICJiIiwgYW5kICJyIiBpbgorICAgICAqIHRoZSBmaXJzdCBzdGVwIHdpdGgKKyAgICAgKgorICAgICAqIGZtYXAgPSB7ICdhOicgNSwgMywgMCwgJ2I6JyA0LCAxLCAncicsIDIgfQorICAgICAqCisgICAgICogd2hlbiBsb29raW5nIGF0IHRoZSBidWNrZXQgb2YgImEicyB0aGUgc2Vjb25kIGNoYXJhY3RlcnMgYXJlIGluCisgICAgICogdGhlIGJ1Y2tldHMgdGhhdCBzdGFydCB3aXRoIGZtYXAtaW5kZXggMCAocm9sbGVkIG92ZXIpLCAzIGFuZCAzCisgICAgICogcmVzcGVjdGl2ZWx5LCBmb3JtaW5nIHR3byBuZXcgYnVja2V0cyAiYWEiIGFuZCAiYWIiLCBzbyB3ZSBnZXQKKyAgICAgKgorICAgICAqIGZtYXAgPSB7ICdhYTonIDUsICdhYjonIDMsIDAsICdiYTonIDQsICdicic6IDEsICdyYTonIDIgfQorICAgICAqCisgICAgICogc2luY2UgdGhlIGxhc3QgYnVja2V0IG9ubHkgY29udGFpbmVkIGEgc2luZ2xlIGl0ZW0gaXQgZGlkbid0CisgICAgICogaGF2ZSB0byBiZSBzb3J0ZWQgYXQgYWxsLgorICAgICAqCisgICAgICogVGhlcmUgbm93IGlzIGp1c3Qgb25lIGJ1Y2tldCB3aXRoIG1vcmUgdGhhbiBvbmUgcGVybXV0YXRpb24KKyAgICAgKiB0aGF0IHJlbWFpbnMgdG8gYmUgc29ydGVkLiAgRm9yIHRoZSBwZXJtdXRhdGlvbiB0aGF0IHN0YXJ0cworICAgICAqIHdpdGggaW5kZXggMyB0aGUgdGhpcmQgYW5kIGZvcnRoIGNoYXIgYXJlIGluIGJ1Y2tldCAnYWEnIGF0CisgICAgICogaW5kZXggMCBhbmQgZm9yIHRoZSBvbmUgc3RhcnRpbmcgYXQgYmxvY2sgaW5kZXggMCB0aGV5IGFyZSBpbgorICAgICAqIGJ1Y2tldCAncmEnIHdpdGggc29ydCBpbmRleCA1LiAgVGhlIGZ1bGx5IHNvcnRlZCBvcmRlciB0aGVuIGJlY29tZXMuCisgICAgICoKKyAgICAgKiBmbWFwID0geyA1LCAzLCAwLCA0LCAxLCAyIH0KKyAgICAgKgorICAgICAqLworCisgICAgLyoqCisgICAgICogQHBhcmFtIGZtYXAgcG9pbnRzIHRvIHRoZSBpbmRleCBvZiB0aGUgc3RhcnRpbmcgcG9pbnQgb2YgYQorICAgICAqICAgICAgICBwZXJtdXRhdGlvbiBpbnNpZGUgdGhlIGJsb2NrIG9mIGRhdGEgaW4gdGhlIGN1cnJlbnQKKyAgICAgKiAgICAgICAgcGFydGlhbGx5IHNvcnRlZCBvcmRlcgorICAgICAqIEBwYXJhbSBlY2xhc3MgcG9pbnRzIGZyb20gdGhlIGluZGV4IG9mIGEgY2hhcmFjdGVyIGluc2lkZSB0aGUKKyAgICAgKiAgICAgICAgYmxvY2sgdG8gdGhlIGZpcnN0IGluZGV4IGluIGZtYXAgdGhhdCBjb250YWlucyB0aGUKKyAgICAgKiAgICAgICAgYnVja2V0IG9mIGl0cyBzdWZmaXggdGhhdCBpcyBzb3J0ZWQgaW4gdGhpcyBzdGVwLgorICAgICAqIEBwYXJhbSBsbyBsb3dlciBib3VuZGFyeSBvZiB0aGUgZm1hcC1pbnRlcnZhbCB0byBiZSBzb3J0ZWQKKyAgICAgKiBAcGFyYW0gaGkgdXBwZXIgYm91bmRhcnkgb2YgdGhlIGZtYXAtaW50ZXJ2YWwgdG8gYmUgc29ydGVkCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGZhbGxiYWNrU2ltcGxlU29ydChmaW5hbCBpbnRbXSBmbWFwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50W10gZWNsYXNzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGxvLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGhpKSB7CisgICAgICAgIGlmIChsbyA9PSBoaSkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgaW50IGo7CisgICAgICAgIGlmIChoaSAtIGxvID4gMykgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IGhpIC0gNDsgaSA+PSBsbzsgaS0tKSB7CisgICAgICAgICAgICAgICAgZmluYWwgaW50IHRtcCA9IGZtYXBbaV07CisgICAgICAgICAgICAgICAgZmluYWwgaW50IGVjX3RtcCA9IGVjbGFzc1t0bXBdOworICAgICAgICAgICAgICAgIGZvciAoaiA9IGkgKyA0OyBqIDw9IGhpICYmIGVjX3RtcCA+IGVjbGFzc1tmbWFwW2pdXTsKKyAgICAgICAgICAgICAgICAgICAgIGogKz0gNCkgeworICAgICAgICAgICAgICAgICAgICBmbWFwW2ogLSA0XSA9IGZtYXBbal07CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGZtYXBbaiAtIDRdID0gdG1wOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgZm9yIChpbnQgaSA9IGhpIC0gMTsgaSA+PSBsbzsgaS0tKSB7CisgICAgICAgICAgICBmaW5hbCBpbnQgdG1wID0gZm1hcFtpXTsKKyAgICAgICAgICAgIGZpbmFsIGludCBlY190bXAgPSBlY2xhc3NbdG1wXTsKKyAgICAgICAgICAgIGZvciAoaiA9IGkgKyAxOyBqIDw9IGhpICYmIGVjX3RtcCA+IGVjbGFzc1tmbWFwW2pdXTsgaisrKSB7CisgICAgICAgICAgICAgICAgZm1hcFtqIC0gMV0gPSBmbWFwW2pdOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZm1hcFtqLTFdID0gdG1wOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEZBTExCQUNLX1FTT1JUX1NNQUxMX1RIUkVTSCA9IDEwOworCisgICAgLyoqCisgICAgICogc3dhcHMgdHdvIHZhbHVlcyBpbiBmbWFwCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGZzd2FwKGZpbmFsIGludFtdIGZtYXAsIGZpbmFsIGludCB6ejEsIGZpbmFsIGludCB6ejIpIHsKKyAgICAgICAgZmluYWwgaW50IHp6dG1wID0gZm1hcFt6ejFdOworICAgICAgICBmbWFwW3p6MV0gPSBmbWFwW3p6Ml07CisgICAgICAgIGZtYXBbenoyXSA9IHp6dG1wOworICAgIH0KKworICAgIC8qKgorICAgICAqIHN3YXBzIHR3byBpbnRlcnZhbHMgc3RhcnRpbmcgYXQgeXlwMSBhbmQgeXlwMiBvZiBsZW5ndGggeXluIGluc2lkZSBmbWFwLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBmdnN3YXAoZmluYWwgaW50W10gZm1hcCwgaW50IHl5cDEsIGludCB5eXAyLCBpbnQgeXluKSB7CisgICAgICAgIHdoaWxlICh5eW4gPiAwKSB7CisgICAgICAgICAgICBmc3dhcChmbWFwLCB5eXAxLCB5eXAyKTsKKyAgICAgICAgICAgIHl5cDErKzsgeXlwMisrOyB5eW4tLTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgaW50IGZtaW4oZmluYWwgaW50IGEsIGZpbmFsIGludCBiKSB7CisgICAgICAgIHJldHVybiBhIDwgYiA/IGEgOiBiOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBmcHVzaChmaW5hbCBpbnQgc3AsIGZpbmFsIGludCBseiwgZmluYWwgaW50IGh6KSB7CisgICAgICAgIHN0YWNrX2xsW3NwXSA9IGx6OworICAgICAgICBzdGFja19oaFtzcF0gPSBoejsKKyAgICB9CisKKyAgICBwcml2YXRlIGludFtdIGZwb3AoZmluYWwgaW50IHNwKSB7CisgICAgICAgIHJldHVybiBuZXcgaW50W10geyBzdGFja19sbFtzcF0sIHN0YWNrX2hoW3NwXSB9OworICAgIH0KKworICAgIC8qKgorICAgICAqIEBwYXJhbSBmbWFwIHBvaW50cyB0byB0aGUgaW5kZXggb2YgdGhlIHN0YXJ0aW5nIHBvaW50IG9mIGEKKyAgICAgKiAgICAgICAgcGVybXV0YXRpb24gaW5zaWRlIHRoZSBibG9jayBvZiBkYXRhIGluIHRoZSBjdXJyZW50CisgICAgICogICAgICAgIHBhcnRpYWxseSBzb3J0ZWQgb3JkZXIKKyAgICAgKiBAcGFyYW0gZWNsYXNzIHBvaW50cyBmcm9tIHRoZSBpbmRleCBvZiBhIGNoYXJhY3RlciBpbnNpZGUgdGhlCisgICAgICogICAgICAgIGJsb2NrIHRvIHRoZSBmaXJzdCBpbmRleCBpbiBmbWFwIHRoYXQgY29udGFpbnMgdGhlCisgICAgICogICAgICAgIGJ1Y2tldCBvZiBpdHMgc3VmZml4IHRoYXQgaXMgc29ydGVkIGluIHRoaXMgc3RlcC4KKyAgICAgKiBAcGFyYW0gbG9TdCBsb3dlciBib3VuZGFyeSBvZiB0aGUgZm1hcC1pbnRlcnZhbCB0byBiZSBzb3J0ZWQKKyAgICAgKiBAcGFyYW0gaGlTdCB1cHBlciBib3VuZGFyeSBvZiB0aGUgZm1hcC1pbnRlcnZhbCB0byBiZSBzb3J0ZWQKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgZmFsbGJhY2tRU29ydDMoZmluYWwgaW50W10gZm1hcCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50W10gZWNsYXNzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgbG9TdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGhpU3QpIHsKKyAgICAgICAgaW50IGxvLCB1bkxvLCBsdExvLCBoaSwgdW5IaSwgZ3RIaSwgbjsKKworICAgICAgICBsb25nIHIgPSAwOworICAgICAgICBpbnQgc3AgPSAwOworICAgICAgICBmcHVzaChzcCsrLCBsb1N0LCBoaVN0KTsKKworICAgICAgICB3aGlsZSAoc3AgPiAwKSB7CisgICAgICAgICAgICBmaW5hbCBpbnRbXSBzID0gZnBvcCgtLXNwKTsKKyAgICAgICAgICAgIGxvID0gc1swXTsgaGkgPSBzWzFdOworCisgICAgICAgICAgICBpZiAoaGkgLSBsbyA8IEZBTExCQUNLX1FTT1JUX1NNQUxMX1RIUkVTSCkgeworICAgICAgICAgICAgICAgIGZhbGxiYWNrU2ltcGxlU29ydChmbWFwLCBlY2xhc3MsIGxvLCBoaSk7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8qIExCWjI6IFJhbmRvbSBwYXJ0aXRpb25pbmcuICBNZWRpYW4gb2YgMyBzb21ldGltZXMgZmFpbHMgdG8KKyAgICAgICAgICAgICAgIGF2b2lkIGJhZCBjYXNlcy4gIE1lZGlhbiBvZiA5IHNlZW1zIHRvIGhlbHAgYnV0CisgICAgICAgICAgICAgICBsb29rcyByYXRoZXIgZXhwZW5zaXZlLiAgVGhpcyB0b28gc2VlbXMgdG8gd29yayBidXQKKyAgICAgICAgICAgICAgIGlzIGNoZWFwZXIuICBHdWlkYW5jZSBmb3IgdGhlIG1hZ2ljIGNvbnN0YW50cworICAgICAgICAgICAgICAgNzYyMSBhbmQgMzI3NjggaXMgdGFrZW4gZnJvbSBTZWRnZXdpY2sncyBhbGdvcml0aG1zCisgICAgICAgICAgICAgICBib29rLCBjaGFwdGVyIDM1LgorICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIHIgPSAoKHIgKiA3NjIxKSArIDEpICUgMzI3Njg7CisgICAgICAgICAgICBmaW5hbCBsb25nIHIzID0gciAlIDM7CisgICAgICAgICAgICBsb25nIG1lZDsKKyAgICAgICAgICAgIGlmIChyMyA9PSAwKSB7CisgICAgICAgICAgICAgICAgbWVkID0gZWNsYXNzW2ZtYXBbbG9dXTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAocjMgPT0gMSkgeworICAgICAgICAgICAgICAgIG1lZCA9IGVjbGFzc1tmbWFwWyhsbyArIGhpKSA+Pj4gMV1dOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBtZWQgPSBlY2xhc3NbZm1hcFtoaV1dOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICB1bkxvID0gbHRMbyA9IGxvOworICAgICAgICAgICAgdW5IaSA9IGd0SGkgPSBoaTsKKworICAgICAgICAgICAgLy8gbG9va3MgbGlrZSB0aGUgdGVybmFyeSBwYXJ0aXRpb24gYXR0cmlidXRlZCB0byBXZWduZXIKKyAgICAgICAgICAgIC8vIGluIHRoZSBjaXRlZCBTZWRnZXdpY2sgcGFwZXIKKyAgICAgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHVuTG8gPiB1bkhpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBuID0gZWNsYXNzW2ZtYXBbdW5Mb11dIC0gKGludCkgbWVkOworICAgICAgICAgICAgICAgICAgICBpZiAobiA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBmc3dhcChmbWFwLCB1bkxvLCBsdExvKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGx0TG8rKzsgdW5MbysrOworICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgaWYgKG4gPiAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB1bkxvKys7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICAgICAgICAgIGlmICh1bkxvID4gdW5IaSkgeworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgbiA9IGVjbGFzc1tmbWFwW3VuSGldXSAtIChpbnQpIG1lZDsKKyAgICAgICAgICAgICAgICAgICAgaWYgKG4gPT0gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgZnN3YXAoZm1hcCwgdW5IaSwgZ3RIaSk7CisgICAgICAgICAgICAgICAgICAgICAgICBndEhpLS07IHVuSGktLTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGlmIChuIDwgMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgdW5IaS0tOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAodW5MbyA+IHVuSGkpIHsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGZzd2FwKGZtYXAsIHVuTG8sIHVuSGkpOyB1bkxvKys7IHVuSGktLTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKGd0SGkgPCBsdExvKSB7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIG4gPSBmbWluKGx0TG8gLSBsbywgdW5MbyAtIGx0TG8pOworICAgICAgICAgICAgZnZzd2FwKGZtYXAsIGxvLCB1bkxvIC0gbiwgbik7CisgICAgICAgICAgICBpbnQgbSA9IGZtaW4oaGkgLSBndEhpLCBndEhpIC0gdW5IaSk7CisgICAgICAgICAgICBmdnN3YXAoZm1hcCwgdW5IaSArIDEsIGhpIC0gbSArIDEsIG0pOworCisgICAgICAgICAgICBuID0gbG8gKyB1bkxvIC0gbHRMbyAtIDE7CisgICAgICAgICAgICBtID0gaGkgLSAoZ3RIaSAtIHVuSGkpICsgMTsKKworICAgICAgICAgICAgaWYgKG4gLSBsbyA+IGhpIC0gbSkgeworICAgICAgICAgICAgICAgIGZwdXNoKHNwKyssIGxvLCBuKTsKKyAgICAgICAgICAgICAgICBmcHVzaChzcCsrLCBtLCBoaSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGZwdXNoKHNwKyssIG0sIGhpKTsKKyAgICAgICAgICAgICAgICBmcHVzaChzcCsrLCBsbywgbik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworCisgICAgcHJpdmF0ZSBpbnRbXSBlY2xhc3M7CisKKyAgICBwcml2YXRlIGludFtdIGdldEVjbGFzcygpIHsKKyAgICAgICAgaWYgKGVjbGFzcyA9PSBudWxsKSB7CisgICAgICAgICAgICBlY2xhc3MgPSBuZXcgaW50W3F1YWRyYW50Lmxlbmd0aCAvIDJdOworICAgICAgICB9CisgICAgICAgIHJldHVybiBlY2xhc3M7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBUaGUgQyBjb2RlIHVzZXMgYW4gYXJyYXkgb2YgaW50cyAoZWFjaCBpbnQgaG9sZGluZyAzMiBmbGFncykgdG8KKyAgICAgKiByZXByZXNlbnRzIHRoZSBidWNrZXQtc3RhcnQgZmxhZ3MgKGJodGFiKS4gIEl0IGFsc28gY29udGFpbnMKKyAgICAgKiBvcHRpbWl6YXRpb25zIHRvIHNraXAgb3ZlciAzMiBjb25zZWN1dGl2ZWx5IHNldCBvcgorICAgICAqIGNvbnNlY3V0aXZlbHkgdW5zZXQgYml0cyBvbiB3b3JkIGJvdW5kYXJpZXMgYXQgb25jZS4gIEZvciBub3cKKyAgICAgKiBJJ3ZlIGNob3NlbiB0byB1c2UgdGhlIHNpbXBsZXIgYnV0IHBvdGVudGlhbGx5IHNsb3dlciBjb2RlCisgICAgICogdXNpbmcgQml0U2V0IC0gYWxzbyBpbiB0aGUgaG9wZSB0aGF0IHVzaW5nIHRoZSBCaXRTZXQjbmV4dFhYWAorICAgICAqIG1ldGhvZHMgbWF5IGJlIGZhc3QgZW5vdWdoLgorICAgICAqLworCisgICAgLyoqCisgICAgICogQHBhcmFtIGZtYXAgcG9pbnRzIHRvIHRoZSBpbmRleCBvZiB0aGUgc3RhcnRpbmcgcG9pbnQgb2YgYQorICAgICAqICAgICAgICBwZXJtdXRhdGlvbiBpbnNpZGUgdGhlIGJsb2NrIG9mIGRhdGEgaW4gdGhlIGN1cnJlbnQKKyAgICAgKiAgICAgICAgcGFydGlhbGx5IHNvcnRlZCBvcmRlcgorICAgICAqIEBwYXJhbSBibG9jayB0aGUgb3JpZ2luYWwgZGF0YQorICAgICAqIEBwYXJhbSBuYmxvY2sgc2l6ZSBvZiB0aGUgYmxvY2sKKyAgICAgKiBAcGFyYW0gb2ZmIG9mZnNldCBvZiBmaXJzdCBieXRlIHRvIHNvcnQgaW4gYmxvY2sKKyAgICAgKi8KKyAgICBmaW5hbCB2b2lkIGZhbGxiYWNrU29ydChmaW5hbCBpbnRbXSBmbWFwLCBmaW5hbCBieXRlW10gYmxvY2ssIGZpbmFsIGludCBuYmxvY2spIHsKKyAgICAgICAgZmluYWwgaW50W10gZnRhYiA9IG5ldyBpbnRbMjU3XTsKKyAgICAgICAgaW50IEgsIGksIGosIGssIGwsIHIsIGNjLCBjYzE7CisgICAgICAgIGludCBuTm90RG9uZTsKKyAgICAgICAgaW50IG5CaHRhYjsKKyAgICAgICAgZmluYWwgaW50W10gZWNsYXNzID0gZ2V0RWNsYXNzKCk7CisKKyAgICAgICAgZm9yIChpID0gMDsgaSA8IG5ibG9jazsgaSsrKSB7CisgICAgICAgICAgICBlY2xhc3NbaV0gPSAwOworICAgICAgICB9CisgICAgICAgIC8qLS0KKyAgICAgICAgICBMQloyOiBJbml0aWFsIDEtY2hhciByYWRpeCBzb3J0IHRvIGdlbmVyYXRlCisgICAgICAgICAgaW5pdGlhbCBmbWFwIGFuZCBpbml0aWFsIEJIIGJpdHMuCisgICAgICAgICAgLS0qLworICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbmJsb2NrOyBpKyspIHsKKyAgICAgICAgICAgIGZ0YWJbYmxvY2tbaV0gJiAweGZmXSsrOworICAgICAgICB9CisgICAgICAgIGZvciAoaSA9IDE7IGkgPCAyNTc7ICAgIGkrKykgeworICAgICAgICAgICAgZnRhYltpXSArPSBmdGFiW2kgLSAxXTsKKyAgICAgICAgfQorCisgICAgICAgIGZvciAoaSA9IDA7IGkgPCBuYmxvY2s7IGkrKykgeworICAgICAgICAgICAgaiA9IGJsb2NrW2ldICYgMHhmZjsKKyAgICAgICAgICAgIGsgPSBmdGFiW2pdIC0gMTsKKyAgICAgICAgICAgIGZ0YWJbal0gPSBrOworICAgICAgICAgICAgZm1hcFtrXSA9IGk7CisgICAgICAgIH0KKworICAgICAgICBuQmh0YWIgPSA2NCArIG5ibG9jazsKKyAgICAgICAgZmluYWwgQml0U2V0IGJodGFiID0gbmV3IEJpdFNldChuQmh0YWIpOworICAgICAgICBmb3IgKGkgPSAwOyBpIDwgMjU2OyBpKyspIHsKKyAgICAgICAgICAgIGJodGFiLnNldChmdGFiW2ldKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qLS0KKyAgICAgICAgICBMQloyOiBJbmR1Y3RpdmVseSByZWZpbmUgdGhlIGJ1Y2tldHMuICBLaW5kLW9mIGFuCisgICAgICAgICAgImV4cG9uZW50aWFsIHJhZGl4IHNvcnQiICghKSwgaW5zcGlyZWQgYnkgdGhlCisgICAgICAgICAgTWFuYmVyLU15ZXJzIHN1ZmZpeCBhcnJheSBjb25zdHJ1Y3Rpb24gYWxnb3JpdGhtLgorICAgICAgICAgIC0tKi8KKworICAgICAgICAvKi0tIExCWjI6IHNldCBzZW50aW5lbCBiaXRzIGZvciBibG9jay1lbmQgZGV0ZWN0aW9uIC0tKi8KKyAgICAgICAgZm9yIChpID0gMDsgaSA8IDMyOyBpKyspIHsKKyAgICAgICAgICAgIGJodGFiLnNldChuYmxvY2sgKyAyICogaSk7CisgICAgICAgICAgICBiaHRhYi5jbGVhcihuYmxvY2sgKyAyICogaSArIDEpOworICAgICAgICB9CisKKyAgICAgICAgLyotLSBMQloyOiB0aGUgbG9nKE4pIGxvb3AgLS0qLworICAgICAgICBIID0gMTsKKyAgICAgICAgd2hpbGUgKHRydWUpIHsKKworICAgICAgICAgICAgaiA9IDA7CisgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbmJsb2NrOyBpKyspIHsKKyAgICAgICAgICAgICAgICBpZiAoYmh0YWIuZ2V0KGkpKSB7CisgICAgICAgICAgICAgICAgICAgIGogPSBpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBrID0gZm1hcFtpXSAtIEg7CisgICAgICAgICAgICAgICAgaWYgKGsgPCAwKSB7CisgICAgICAgICAgICAgICAgICAgIGsgKz0gbmJsb2NrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBlY2xhc3Nba10gPSBqOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBuTm90RG9uZSA9IDA7CisgICAgICAgICAgICByID0gLTE7CisgICAgICAgICAgICB3aGlsZSAodHJ1ZSkgeworCisgICAgICAgICAgICAgICAgLyotLSBMQloyOiBmaW5kIHRoZSBuZXh0IG5vbi1zaW5nbGV0b24gYnVja2V0IC0tKi8KKyAgICAgICAgICAgICAgICBrID0gciArIDE7CisgICAgICAgICAgICAgICAgayA9IGJodGFiLm5leHRDbGVhckJpdChrKTsKKyAgICAgICAgICAgICAgICBsID0gayAtIDE7CisgICAgICAgICAgICAgICAgaWYgKGwgPj0gbmJsb2NrKSB7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBrID0gYmh0YWIubmV4dFNldEJpdChrICsgMSk7CisgICAgICAgICAgICAgICAgciA9IGsgLSAxOworICAgICAgICAgICAgICAgIGlmIChyID49IG5ibG9jaykgeworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAvKi0tIExCWjI6IG5vdyBbbCwgcl0gYnJhY2tldCBjdXJyZW50IGJ1Y2tldCAtLSovCisgICAgICAgICAgICAgICAgaWYgKHIgPiBsKSB7CisgICAgICAgICAgICAgICAgICAgIG5Ob3REb25lICs9IChyIC0gbCArIDEpOworICAgICAgICAgICAgICAgICAgICBmYWxsYmFja1FTb3J0MyhmbWFwLCBlY2xhc3MsIGwsIHIpOworCisgICAgICAgICAgICAgICAgICAgIC8qLS0gTEJaMjogc2NhbiBidWNrZXQgYW5kIGdlbmVyYXRlIGhlYWRlciBiaXRzLS0gKi8KKyAgICAgICAgICAgICAgICAgICAgY2MgPSAtMTsKKyAgICAgICAgICAgICAgICAgICAgZm9yIChpID0gbDsgaSA8PSByOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNjMSA9IGVjbGFzc1tmbWFwW2ldXTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjYyAhPSBjYzEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBiaHRhYi5zZXQoaSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2MgPSBjYzE7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEggKj0gMjsKKyAgICAgICAgICAgIGlmIChIID4gbmJsb2NrIHx8IG5Ob3REb25lID09IDApIHsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworCisgICAgLyoKKyAgICAgKiBMQloyOiBLbnV0aCdzIGluY3JlbWVudHMgc2VlbSB0byB3b3JrIGJldHRlciB0aGFuIEluY2VycGktU2VkZ2V3aWNrIGhlcmUuCisgICAgICogUG9zc2libHkgYmVjYXVzZSB0aGUgbnVtYmVyIG9mIGVsZW1zIHRvIHNvcnQgaXMgdXN1YWxseSBzbWFsbCwgdHlwaWNhbGx5CisgICAgICogJmx0Oz0gMjAuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50W10gSU5DUyA9IHsgMSwgNCwgMTMsIDQwLCAxMjEsIDM2NCwgMTA5MywgMzI4MCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA5ODQxLCAyOTUyNCwgODg1NzMsIDI2NTcyMCwgNzk3MTYxLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDIzOTE0ODQgfTsKKworICAgIC8qKgorICAgICAqIFRoaXMgaXMgdGhlIG1vc3QgaGFtbWVyZWQgbWV0aG9kIG9mIHRoaXMgY2xhc3MuCisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIGlzIHRoZSB2ZXJzaW9uIHVzaW5nIHVucm9sbGVkIGxvb3BzLiBOb3JtYWxseSBJIG5ldmVyIHVzZSBzdWNoIG9uZXMKKyAgICAgKiBpbiBKYXZhIGNvZGUuIFRoZSB1bnJvbGxpbmcgaGFzIHNob3duIGEgbm90aWNhYmxlIHBlcmZvcm1hbmNlIGltcHJvdmVtZW50CisgICAgICogb24gSlJFIDEuNC4yIChMaW51eCBpNTg2IC8gSG90U3BvdCBDbGllbnQpLiBPZiBjb3Vyc2UgaXQgZGVwZW5kcyBvbiB0aGUKKyAgICAgKiBKSVQgY29tcGlsZXIgb2YgdGhlIHZtLgorICAgICAqIDwvcD4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gbWFpblNpbXBsZVNvcnQoZmluYWwgQlppcDJDb21wcmVzc29yT3V0cHV0U3RyZWFtLkRhdGEgZGF0YVNoYWRvdywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGxvLCBmaW5hbCBpbnQgaGksIGZpbmFsIGludCBkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgbGFzdFNoYWRvdykgeworICAgICAgICBmaW5hbCBpbnQgYmlnTiA9IGhpIC0gbG8gKyAxOworICAgICAgICBpZiAoYmlnTiA8IDIpIHsKKyAgICAgICAgICAgIHJldHVybiB0aGlzLmZpcnN0QXR0ZW1wdCAmJiAodGhpcy53b3JrRG9uZSA+IHRoaXMud29ya0xpbWl0KTsKKyAgICAgICAgfQorCisgICAgICAgIGludCBocCA9IDA7CisgICAgICAgIHdoaWxlIChJTkNTW2hwXSA8IGJpZ04pIHsKKyAgICAgICAgICAgIGhwKys7CisgICAgICAgIH0KKworICAgICAgICBmaW5hbCBpbnRbXSBmbWFwID0gZGF0YVNoYWRvdy5mbWFwOworICAgICAgICBmaW5hbCBjaGFyW10gcXVhZHJhbnQgPSB0aGlzLnF1YWRyYW50OworICAgICAgICBmaW5hbCBieXRlW10gYmxvY2sgPSBkYXRhU2hhZG93LmJsb2NrOworICAgICAgICBmaW5hbCBpbnQgbGFzdFBsdXMxID0gbGFzdFNoYWRvdyArIDE7CisgICAgICAgIGZpbmFsIGJvb2xlYW4gZmlyc3RBdHRlbXB0U2hhZG93ID0gdGhpcy5maXJzdEF0dGVtcHQ7CisgICAgICAgIGZpbmFsIGludCB3b3JrTGltaXRTaGFkb3cgPSB0aGlzLndvcmtMaW1pdDsKKyAgICAgICAgaW50IHdvcmtEb25lU2hhZG93ID0gdGhpcy53b3JrRG9uZTsKKworICAgICAgICAvLyBGb2xsb3dpbmcgYmxvY2sgY29udGFpbnMgdW5yb2xsZWQgY29kZSB3aGljaCBjb3VsZCBiZSBzaG9ydGVuZWQgYnkKKyAgICAgICAgLy8gY29kaW5nIGl0IGluIGFkZGl0aW9uYWwgbG9vcHMuCisKKyAgICAgICAgSFA6IHdoaWxlICgtLWhwID49IDApIHsKKyAgICAgICAgICAgIGZpbmFsIGludCBoID0gSU5DU1tocF07CisgICAgICAgICAgICBmaW5hbCBpbnQgbWogPSBsbyArIGggLSAxOworCisgICAgICAgICAgICBmb3IgKGludCBpID0gbG8gKyBoOyBpIDw9IGhpOykgeworICAgICAgICAgICAgICAgIC8vIGNvcHkKKyAgICAgICAgICAgICAgICBmb3IgKGludCBrID0gMzsgKGkgPD0gaGkpICYmICgtLWsgPj0gMCk7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgdiA9IGZtYXBbaV07CisgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCB2ZCA9IHYgKyBkOworICAgICAgICAgICAgICAgICAgICBpbnQgaiA9IGk7CisKKyAgICAgICAgICAgICAgICAgICAgLy8gZm9yIChpbnQgYTsKKyAgICAgICAgICAgICAgICAgICAgLy8gKGogPiBtaikgJiYgbWFpbkd0VSgoYSA9IGZtYXBbaiAtIGhdKSArIGQsIHZkLAorICAgICAgICAgICAgICAgICAgICAvLyBibG9jaywgcXVhZHJhbnQsIGxhc3RTaGFkb3cpOworICAgICAgICAgICAgICAgICAgICAvLyBqIC09IGgpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gZm1hcFtqXSA9IGE7CisgICAgICAgICAgICAgICAgICAgIC8vIH0KKyAgICAgICAgICAgICAgICAgICAgLy8KKyAgICAgICAgICAgICAgICAgICAgLy8gdW5yb2xsZWQgdmVyc2lvbjoKKworICAgICAgICAgICAgICAgICAgICAvLyBzdGFydCBpbmxpbmUgbWFpbkdUVQorICAgICAgICAgICAgICAgICAgICBib29sZWFuIG9uY2VSdW5uZWQgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgaW50IGEgPSAwOworCisgICAgICAgICAgICAgICAgICAgIEhBTU1FUjogd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvbmNlUnVubmVkKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm1hcFtqXSA9IGE7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChqIC09IGgpIDw9IG1qKSB7IC8vTk9TT05BUgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhayBIQU1NRVI7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbmNlUnVubmVkID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICAgICAgYSA9IGZtYXBbaiAtIGhdOworICAgICAgICAgICAgICAgICAgICAgICAgaW50IGkxID0gYSArIGQ7CisgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaTIgPSB2ZDsKKworICAgICAgICAgICAgICAgICAgICAgICAgLy8gZm9sbG93aW5nIGNvdWxkIGJlIGRvbmUgaW4gYSBsb29wLCBidXQKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIHVucm9sbGVkIGl0IGZvciBwZXJmb3JtYW5jZToKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChibG9ja1tpMSArIDFdID09IGJsb2NrW2kyICsgMV0pIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYmxvY2tbaTEgKyAyXSA9PSBibG9ja1tpMiArIDJdKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChibG9ja1tpMSArIDNdID09IGJsb2NrW2kyICsgM10pIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChibG9ja1tpMSArIDRdID09IGJsb2NrW2kyICsgNF0pIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYmxvY2tbaTEgKyA1XSA9PSBibG9ja1tpMiArIDVdKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChibG9ja1soaTEgKz0gNildID09IGJsb2NrWyhpMiArPSA2KV0pIHsgLy9OT1NPTkFSCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgeCA9IGxhc3RTaGFkb3c7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYOiB3aGlsZSAoeCA+IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4IC09IDQ7CisKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYmxvY2tbaTEgKyAxXSA9PSBibG9ja1tpMiArIDFdKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChxdWFkcmFudFtpMV0gPT0gcXVhZHJhbnRbaTJdKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYmxvY2tbaTEgKyAyXSA9PSBibG9ja1tpMiArIDJdKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHF1YWRyYW50W2kxICsgMV0gPT0gcXVhZHJhbnRbaTIgKyAxXSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYmxvY2tbaTEgKyAzXSA9PSBibG9ja1tpMiArIDNdKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocXVhZHJhbnRbaTEgKyAyXSA9PSBxdWFkcmFudFtpMiArIDJdKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJsb2NrW2kxICsgNF0gPT0gYmxvY2tbaTIgKyA0XSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocXVhZHJhbnRbaTEgKyAzXSA9PSBxdWFkcmFudFtpMiArIDNdKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKGkxICs9IDQpID49IGxhc3RQbHVzMSkgeyAvL05PU09OQVIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpMSAtPSBsYXN0UGx1czE7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKGkyICs9IDQpID49IGxhc3RQbHVzMSkgeyAvL05PU09OQVIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpMiAtPSBsYXN0UGx1czE7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3b3JrRG9uZVNoYWRvdysrOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWUgWDsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgocXVhZHJhbnRbaTEgKyAzXSA+IHF1YWRyYW50W2kyICsgM10pKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZSBIQU1NRVI7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhayBIQU1NRVI7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKChibG9ja1tpMSArIDRdICYgMHhmZikgPiAoYmxvY2tbaTIgKyA0XSAmIDB4ZmYpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIEhBTU1FUjsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhayBIQU1NRVI7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgocXVhZHJhbnRbaTEgKyAyXSA+IHF1YWRyYW50W2kyICsgMl0pKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWUgSEFNTUVSOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhayBIQU1NRVI7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoKGJsb2NrW2kxICsgM10gJiAweGZmKSA+IChibG9ja1tpMiArIDNdICYgMHhmZikpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIEhBTU1FUjsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrIEhBTU1FUjsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoKHF1YWRyYW50W2kxICsgMV0gPiBxdWFkcmFudFtpMiArIDFdKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZSBIQU1NRVI7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsgSEFNTUVSOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoKGJsb2NrW2kxICsgMl0gJiAweGZmKSA+IChibG9ja1tpMiArIDJdICYgMHhmZikpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZSBIQU1NRVI7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrIEhBTU1FUjsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgocXVhZHJhbnRbaTFdID4gcXVhZHJhbnRbaTJdKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWUgSEFNTUVSOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsgSEFNTUVSOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgoYmxvY2tbaTEgKyAxXSAmIDB4ZmYpID4gKGJsb2NrW2kyICsgMV0gJiAweGZmKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZSBIQU1NRVI7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsgSEFNTUVSOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsgSEFNTUVSOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IC8vIHdoaWxlIHggPiAwCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoYmxvY2tbaTFdICYgMHhmZikgPiAoYmxvY2tbaTJdICYgMHhmZikpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIEhBTU1FUjsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhayBIQU1NRVI7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgoYmxvY2tbaTEgKyA1XSAmIDB4ZmYpID4gKGJsb2NrW2kyICsgNV0gJiAweGZmKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZSBIQU1NRVI7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsgSEFNTUVSOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoKGJsb2NrW2kxICsgNF0gJiAweGZmKSA+IChibG9ja1tpMiArIDRdICYgMHhmZikpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZSBIQU1NRVI7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrIEhBTU1FUjsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgoYmxvY2tbaTEgKyAzXSAmIDB4ZmYpID4gKGJsb2NrW2kyICsgM10gJiAweGZmKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWUgSEFNTUVSOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsgSEFNTUVSOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgoYmxvY2tbaTEgKyAyXSAmIDB4ZmYpID4gKGJsb2NrW2kyICsgMl0gJiAweGZmKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZSBIQU1NRVI7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsgSEFNTUVSOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoKGJsb2NrW2kxICsgMV0gJiAweGZmKSA+IChibG9ja1tpMiArIDFdICYgMHhmZikpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZSBIQU1NRVI7CisgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrIEhBTU1FUjsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICB9IC8vIEhBTU1FUgorICAgICAgICAgICAgICAgICAgICAvLyBlbmQgaW5saW5lIG1haW5HVFUKKworICAgICAgICAgICAgICAgICAgICBmbWFwW2pdID0gdjsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBpZiAoZmlyc3RBdHRlbXB0U2hhZG93ICYmIChpIDw9IGhpKQorICAgICAgICAgICAgICAgICAgICAmJiAod29ya0RvbmVTaGFkb3cgPiB3b3JrTGltaXRTaGFkb3cpKSB7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrIEhQOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHRoaXMud29ya0RvbmUgPSB3b3JrRG9uZVNoYWRvdzsKKyAgICAgICAgcmV0dXJuIGZpcnN0QXR0ZW1wdFNoYWRvdyAmJiAod29ya0RvbmVTaGFkb3cgPiB3b3JrTGltaXRTaGFkb3cpOworICAgIH0KKworLyotLQorICAgTEJaMjogVGhlIGZvbGxvd2luZyBpcyBhbiBpbXBsZW1lbnRhdGlvbiBvZgorICAgYW4gZWxlZ2FudCAzLXdheSBxdWlja3NvcnQgZm9yIHN0cmluZ3MsCisgICBkZXNjcmliZWQgaW4gYSBwYXBlciAiRmFzdCBBbGdvcml0aG1zIGZvcgorICAgU29ydGluZyBhbmQgU2VhcmNoaW5nIFN0cmluZ3MiLCBieSBSb2JlcnQKKyAgIFNlZGdld2ljayBhbmQgSm9uIEwuIEJlbnRsZXkuCistLSovCisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHZzd2FwKGZpbmFsIGludFtdIGZtYXAsIGludCBwMSwgaW50IHAyLCBpbnQgbikgeworICAgICAgICBuICs9IHAxOworICAgICAgICB3aGlsZSAocDEgPCBuKSB7CisgICAgICAgICAgICBmaW5hbCBpbnQgdCA9IGZtYXBbcDFdOworICAgICAgICAgICAgZm1hcFtwMSsrXSA9IGZtYXBbcDJdOworICAgICAgICAgICAgZm1hcFtwMisrXSA9IHQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBieXRlIG1lZDMoZmluYWwgYnl0ZSBhLCBmaW5hbCBieXRlIGIsIGZpbmFsIGJ5dGUgYykgeworICAgICAgICByZXR1cm4gKGEgPCBiKSA/IChiIDwgYyA/IGIgOiBhIDwgYyA/IGMgOiBhKSA6IChiID4gYyA/IGIgOiBhID4gYyA/IGMKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBhKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgU01BTExfVEhSRVNIID0gMjA7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IERFUFRIX1RIUkVTSCA9IDEwOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBXT1JLX0ZBQ1RPUiA9IDMwOworCisgICAgLyoqCisgICAgICogTWV0aG9kICJtYWluUVNvcnQzIiwgZmlsZSAiYmxvY2tzb3J0LmMiLCBCWmlwMiAxLjAuMgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBtYWluUVNvcnQzKGZpbmFsIEJaaXAyQ29tcHJlc3Nvck91dHB1dFN0cmVhbS5EYXRhIGRhdGFTaGFkb3csCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGxvU3QsIGZpbmFsIGludCBoaVN0LCBmaW5hbCBpbnQgZFN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBsYXN0KSB7CisgICAgICAgIGZpbmFsIGludFtdIHN0YWNrX2xsID0gdGhpcy5zdGFja19sbDsKKyAgICAgICAgZmluYWwgaW50W10gc3RhY2tfaGggPSB0aGlzLnN0YWNrX2hoOworICAgICAgICBmaW5hbCBpbnRbXSBzdGFja19kZCA9IHRoaXMuc3RhY2tfZGQ7CisgICAgICAgIGZpbmFsIGludFtdIGZtYXAgPSBkYXRhU2hhZG93LmZtYXA7CisgICAgICAgIGZpbmFsIGJ5dGVbXSBibG9jayA9IGRhdGFTaGFkb3cuYmxvY2s7CisKKyAgICAgICAgc3RhY2tfbGxbMF0gPSBsb1N0OworICAgICAgICBzdGFja19oaFswXSA9IGhpU3Q7CisgICAgICAgIHN0YWNrX2RkWzBdID0gZFN0OworCisgICAgICAgIGZvciAoaW50IHNwID0gMTsgLS1zcCA+PSAwOykgeworICAgICAgICAgICAgZmluYWwgaW50IGxvID0gc3RhY2tfbGxbc3BdOworICAgICAgICAgICAgZmluYWwgaW50IGhpID0gc3RhY2tfaGhbc3BdOworICAgICAgICAgICAgZmluYWwgaW50IGQgPSBzdGFja19kZFtzcF07CisKKyAgICAgICAgICAgIGlmICgoaGkgLSBsbyA8IFNNQUxMX1RIUkVTSCkgfHwgKGQgPiBERVBUSF9USFJFU0gpKSB7CisgICAgICAgICAgICAgICAgaWYgKG1haW5TaW1wbGVTb3J0KGRhdGFTaGFkb3csIGxvLCBoaSwgZCwgbGFzdCkpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZmluYWwgaW50IGQxID0gZCArIDE7CisgICAgICAgICAgICAgICAgZmluYWwgaW50IG1lZCA9IG1lZDMoYmxvY2tbZm1hcFtsb10gKyBkMV0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmxvY2tbZm1hcFtoaV0gKyBkMV0sIGJsb2NrW2ZtYXBbKGxvICsgaGkpID4+PiAxXSArIGQxXSkgJiAweGZmOworCisgICAgICAgICAgICAgICAgaW50IHVuTG8gPSBsbzsKKyAgICAgICAgICAgICAgICBpbnQgdW5IaSA9IGhpOworICAgICAgICAgICAgICAgIGludCBsdExvID0gbG87CisgICAgICAgICAgICAgICAgaW50IGd0SGkgPSBoaTsKKworICAgICAgICAgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICAgICAgICAgIHdoaWxlICh1bkxvIDw9IHVuSGkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBuID0gKGJsb2NrW2ZtYXBbdW5Mb10gKyBkMV0gJiAweGZmKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0gbWVkOworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG4gPT0gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCB0ZW1wID0gZm1hcFt1bkxvXTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbWFwW3VuTG8rK10gPSBmbWFwW2x0TG9dOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZtYXBbbHRMbysrXSA9IHRlbXA7CisgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG4gPCAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5MbysrOworICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIHdoaWxlICh1bkxvIDw9IHVuSGkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBuID0gKGJsb2NrW2ZtYXBbdW5IaV0gKyBkMV0gJiAweGZmKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0gbWVkOworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG4gPT0gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCB0ZW1wID0gZm1hcFt1bkhpXTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbWFwW3VuSGktLV0gPSBmbWFwW2d0SGldOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZtYXBbZ3RIaS0tXSA9IHRlbXA7CisgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG4gPiAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5IaS0tOworICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIGlmICh1bkxvIDw9IHVuSGkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCB0ZW1wID0gZm1hcFt1bkxvXTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZtYXBbdW5MbysrXSA9IGZtYXBbdW5IaV07CisgICAgICAgICAgICAgICAgICAgICAgICBmbWFwW3VuSGktLV0gPSB0ZW1wOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBpZiAoZ3RIaSA8IGx0TG8pIHsKKyAgICAgICAgICAgICAgICAgICAgc3RhY2tfbGxbc3BdID0gbG87CisgICAgICAgICAgICAgICAgICAgIHN0YWNrX2hoW3NwXSA9IGhpOworICAgICAgICAgICAgICAgICAgICBzdGFja19kZFtzcF0gPSBkMTsKKyAgICAgICAgICAgICAgICAgICAgc3ArKzsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBpbnQgbiA9ICgobHRMbyAtIGxvKSA8ICh1bkxvIC0gbHRMbykpID8gKGx0TG8gLSBsbykKKyAgICAgICAgICAgICAgICAgICAgICAgIDogKHVuTG8gLSBsdExvKTsKKyAgICAgICAgICAgICAgICAgICAgdnN3YXAoZm1hcCwgbG8sIHVuTG8gLSBuLCBuKTsKKyAgICAgICAgICAgICAgICAgICAgaW50IG0gPSAoKGhpIC0gZ3RIaSkgPCAoZ3RIaSAtIHVuSGkpKSA/IChoaSAtIGd0SGkpCisgICAgICAgICAgICAgICAgICAgICAgICA6IChndEhpIC0gdW5IaSk7CisgICAgICAgICAgICAgICAgICAgIHZzd2FwKGZtYXAsIHVuTG8sIGhpIC0gbSArIDEsIG0pOworCisgICAgICAgICAgICAgICAgICAgIG4gPSBsbyArIHVuTG8gLSBsdExvIC0gMTsKKyAgICAgICAgICAgICAgICAgICAgbSA9IGhpIC0gKGd0SGkgLSB1bkhpKSArIDE7CisKKyAgICAgICAgICAgICAgICAgICAgc3RhY2tfbGxbc3BdID0gbG87CisgICAgICAgICAgICAgICAgICAgIHN0YWNrX2hoW3NwXSA9IG47CisgICAgICAgICAgICAgICAgICAgIHN0YWNrX2RkW3NwXSA9IGQ7CisgICAgICAgICAgICAgICAgICAgIHNwKys7CisKKyAgICAgICAgICAgICAgICAgICAgc3RhY2tfbGxbc3BdID0gbiArIDE7CisgICAgICAgICAgICAgICAgICAgIHN0YWNrX2hoW3NwXSA9IG0gLSAxOworICAgICAgICAgICAgICAgICAgICBzdGFja19kZFtzcF0gPSBkMTsKKyAgICAgICAgICAgICAgICAgICAgc3ArKzsKKworICAgICAgICAgICAgICAgICAgICBzdGFja19sbFtzcF0gPSBtOworICAgICAgICAgICAgICAgICAgICBzdGFja19oaFtzcF0gPSBoaTsKKyAgICAgICAgICAgICAgICAgICAgc3RhY2tfZGRbc3BdID0gZDsKKyAgICAgICAgICAgICAgICAgICAgc3ArKzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgU0VUTUFTSyA9ICgxIDw8IDIxKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQ0xFQVJNQVNLID0gKH5TRVRNQVNLKTsKKworICAgIGZpbmFsIHZvaWQgbWFpblNvcnQoZmluYWwgQlppcDJDb21wcmVzc29yT3V0cHV0U3RyZWFtLkRhdGEgZGF0YVNoYWRvdywKKyAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBsYXN0U2hhZG93KSB7CisgICAgICAgIGZpbmFsIGludFtdIHJ1bm5pbmdPcmRlciA9IHRoaXMubWFpblNvcnRfcnVubmluZ09yZGVyOworICAgICAgICBmaW5hbCBpbnRbXSBjb3B5ID0gdGhpcy5tYWluU29ydF9jb3B5OworICAgICAgICBmaW5hbCBib29sZWFuW10gYmlnRG9uZSA9IHRoaXMubWFpblNvcnRfYmlnRG9uZTsKKyAgICAgICAgZmluYWwgaW50W10gZnRhYiA9IHRoaXMuZnRhYjsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGJsb2NrID0gZGF0YVNoYWRvdy5ibG9jazsKKyAgICAgICAgZmluYWwgaW50W10gZm1hcCA9IGRhdGFTaGFkb3cuZm1hcDsKKyAgICAgICAgZmluYWwgY2hhcltdIHF1YWRyYW50ID0gdGhpcy5xdWFkcmFudDsKKyAgICAgICAgZmluYWwgaW50IHdvcmtMaW1pdFNoYWRvdyA9IHRoaXMud29ya0xpbWl0OworICAgICAgICBmaW5hbCBib29sZWFuIGZpcnN0QXR0ZW1wdFNoYWRvdyA9IHRoaXMuZmlyc3RBdHRlbXB0OworCisgICAgICAgIC8vIExCWjI6IFNldCB1cCB0aGUgMi1ieXRlIGZyZXF1ZW5jeSB0YWJsZQorICAgICAgICBmb3IgKGludCBpID0gNjU1Mzc7IC0taSA+PSAwOykgeworICAgICAgICAgICAgZnRhYltpXSA9IDA7CisgICAgICAgIH0KKworICAgICAgICAvKgorICAgICAgICAgKiBJbiB0aGUgdmFyaW91cyBibG9jay1zaXplZCBzdHJ1Y3R1cmVzLCBsaXZlIGRhdGEgcnVucyBmcm9tIDAgdG8KKyAgICAgICAgICogbGFzdCtOVU1fT1ZFUlNIT09UX0JZVEVTIGluY2x1c2l2ZS4gRmlyc3QsIHNldCB1cCB0aGUgb3ZlcnNob290IGFyZWEKKyAgICAgICAgICogZm9yIGJsb2NrLgorICAgICAgICAgKi8KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBCWmlwMkNvbnN0YW50cy5OVU1fT1ZFUlNIT09UX0JZVEVTOyBpKyspIHsKKyAgICAgICAgICAgIGJsb2NrW2xhc3RTaGFkb3cgKyBpICsgMl0gPSBibG9ja1soaSAlIChsYXN0U2hhZG93ICsgMSkpICsgMV07CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IGxhc3RTaGFkb3cgKyBCWmlwMkNvbnN0YW50cy5OVU1fT1ZFUlNIT09UX0JZVEVTICsxOyAtLWkgPj0gMDspIHsKKyAgICAgICAgICAgIHF1YWRyYW50W2ldID0gMDsKKyAgICAgICAgfQorICAgICAgICBibG9ja1swXSA9IGJsb2NrW2xhc3RTaGFkb3cgKyAxXTsKKworICAgICAgICAvLyBMQloyOiBDb21wbGV0ZSB0aGUgaW5pdGlhbCByYWRpeCBzb3J0OgorCisgICAgICAgIGludCBjMSA9IGJsb2NrWzBdICYgMHhmZjsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPD0gbGFzdFNoYWRvdzsgaSsrKSB7CisgICAgICAgICAgICBmaW5hbCBpbnQgYzIgPSBibG9ja1tpICsgMV0gJiAweGZmOworICAgICAgICAgICAgZnRhYlsoYzEgPDwgOCkgKyBjMl0rKzsKKyAgICAgICAgICAgIGMxID0gYzI7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8PSA2NTUzNjsgaSsrKSB7CisgICAgICAgICAgICBmdGFiW2ldICs9IGZ0YWJbaSAtIDFdOworICAgICAgICB9CisKKyAgICAgICAgYzEgPSBibG9ja1sxXSAmIDB4ZmY7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGFzdFNoYWRvdzsgaSsrKSB7CisgICAgICAgICAgICBmaW5hbCBpbnQgYzIgPSBibG9ja1tpICsgMl0gJiAweGZmOworICAgICAgICAgICAgZm1hcFstLWZ0YWJbKGMxIDw8IDgpICsgYzJdXSA9IGk7CisgICAgICAgICAgICBjMSA9IGMyOworICAgICAgICB9CisKKyAgICAgICAgZm1hcFstLWZ0YWJbKChibG9ja1tsYXN0U2hhZG93ICsgMV0gJiAweGZmKSA8PCA4KSArIChibG9ja1sxXSAmIDB4ZmYpXV0gPSBsYXN0U2hhZG93OworCisgICAgICAgIC8qCisgICAgICAgICAqIExCWjI6IE5vdyBmdGFiIGNvbnRhaW5zIHRoZSBmaXJzdCBsb2Mgb2YgZXZlcnkgc21hbGwgYnVja2V0LiBDYWxjdWxhdGUgdGhlCisgICAgICAgICAqIHJ1bm5pbmcgb3JkZXIsIGZyb20gc21hbGxlc3QgdG8gbGFyZ2VzdCBiaWcgYnVja2V0LgorICAgICAgICAgKi8KKyAgICAgICAgZm9yIChpbnQgaSA9IDI1NjsgLS1pID49IDA7KSB7CisgICAgICAgICAgICBiaWdEb25lW2ldID0gZmFsc2U7CisgICAgICAgICAgICBydW5uaW5nT3JkZXJbaV0gPSBpOworICAgICAgICB9CisKKyAgICAgICAgLy8gaCA9IDM2NCwgMTIxLCA0MCwgMTMsIDQsIDEKKyAgICAgICAgZm9yIChpbnQgaCA9IDM2NDsgaCAhPSAxOykgeyAvL05PU09OQVIKKyAgICAgICAgICAgIGggLz0gMzsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSBoOyBpIDw9IDI1NTsgaSsrKSB7CisgICAgICAgICAgICAgICAgZmluYWwgaW50IHZ2ID0gcnVubmluZ09yZGVyW2ldOworICAgICAgICAgICAgICAgIGZpbmFsIGludCBhID0gZnRhYlsodnYgKyAxKSA8PCA4XSAtIGZ0YWJbdnYgPDwgOF07CisgICAgICAgICAgICAgICAgZmluYWwgaW50IGIgPSBoIC0gMTsKKyAgICAgICAgICAgICAgICBpbnQgaiA9IGk7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgcm8gPSBydW5uaW5nT3JkZXJbaiAtIGhdOyAoZnRhYlsocm8gKyAxKSA8PCA4XSAtIGZ0YWJbcm8gPDwgOF0pID4gYTsgcm8gPSBydW5uaW5nT3JkZXJbagorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0gaF0pIHsKKyAgICAgICAgICAgICAgICAgICAgcnVubmluZ09yZGVyW2pdID0gcm87CisgICAgICAgICAgICAgICAgICAgIGogLT0gaDsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGogPD0gYikgeworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcnVubmluZ09yZGVyW2pdID0gdnY7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvKgorICAgICAgICAgKiBMQloyOiBUaGUgbWFpbiBzb3J0aW5nIGxvb3AuCisgICAgICAgICAqLworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8PSAyNTU7IGkrKykgeworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIExCWjI6IFByb2Nlc3MgYmlnIGJ1Y2tldHMsIHN0YXJ0aW5nIHdpdGggdGhlIGxlYXN0IGZ1bGwuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIGZpbmFsIGludCBzcyA9IHJ1bm5pbmdPcmRlcltpXTsKKworICAgICAgICAgICAgLy8gU3RlcCAxOgorICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIExCWjI6IENvbXBsZXRlIHRoZSBiaWcgYnVja2V0IFtzc10gYnkgcXVpY2tzb3J0aW5nIGFueSB1bnNvcnRlZCBzbWFsbAorICAgICAgICAgICAgICogYnVja2V0cyBbc3MsIGpdLiBIb3BlZnVsbHkgcHJldmlvdXMgcG9pbnRlci1zY2FubmluZyBwaGFzZXMgaGF2ZQorICAgICAgICAgICAgICogYWxyZWFkeSBjb21wbGV0ZWQgbWFueSBvZiB0aGUgc21hbGwgYnVja2V0cyBbc3MsIGpdLCBzbyB3ZSBkb24ndAorICAgICAgICAgICAgICogaGF2ZSB0byBzb3J0IHRoZW0gYXQgYWxsLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8PSAyNTU7IGorKykgeworICAgICAgICAgICAgICAgIGZpbmFsIGludCBzYiA9IChzcyA8PCA4KSArIGo7CisgICAgICAgICAgICAgICAgZmluYWwgaW50IGZ0YWJfc2IgPSBmdGFiW3NiXTsKKyAgICAgICAgICAgICAgICBpZiAoKGZ0YWJfc2IgJiBTRVRNQVNLKSAhPSBTRVRNQVNLKSB7CisgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBsbyA9IGZ0YWJfc2IgJiBDTEVBUk1BU0s7CisgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBoaSA9IChmdGFiW3NiICsgMV0gJiBDTEVBUk1BU0spIC0gMTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGhpID4gbG8pIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIG1haW5RU29ydDMoZGF0YVNoYWRvdywgbG8sIGhpLCAyLCBsYXN0U2hhZG93KTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmaXJzdEF0dGVtcHRTaGFkb3cKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiAodGhpcy53b3JrRG9uZSA+IHdvcmtMaW1pdFNoYWRvdykpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgZnRhYltzYl0gPSBmdGFiX3NiIHwgU0VUTUFTSzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIFN0ZXAgMjoKKyAgICAgICAgICAgIC8vIExCWjI6IE5vdyBzY2FuIHRoaXMgYmlnIGJ1Y2tldCBzbyBhcyB0byBzeW50aGVzaXNlIHRoZQorICAgICAgICAgICAgLy8gc29ydGVkIG9yZGVyIGZvciBzbWFsbCBidWNrZXRzIFt0LCBzc10gZm9yIGFsbCB0ICE9IHNzLgorCisgICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8PSAyNTU7IGorKykgeworICAgICAgICAgICAgICAgIGNvcHlbal0gPSBmdGFiWyhqIDw8IDgpICsgc3NdICYgQ0xFQVJNQVNLOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBmb3IgKGludCBqID0gZnRhYltzcyA8PCA4XSAmIENMRUFSTUFTSywgaGogPSAoZnRhYlsoc3MgKyAxKSA8PCA4XSAmIENMRUFSTUFTSyk7IGogPCBoajsgaisrKSB7CisgICAgICAgICAgICAgICAgZmluYWwgaW50IGZtYXBfaiA9IGZtYXBbal07CisgICAgICAgICAgICAgICAgYzEgPSBibG9ja1tmbWFwX2pdICYgMHhmZjsKKyAgICAgICAgICAgICAgICBpZiAoIWJpZ0RvbmVbYzFdKSB7CisgICAgICAgICAgICAgICAgICAgIGZtYXBbY29weVtjMV1dID0gKGZtYXBfaiA9PSAwKSA/IGxhc3RTaGFkb3cgOiAoZm1hcF9qIC0gMSk7CisgICAgICAgICAgICAgICAgICAgIGNvcHlbYzFdKys7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBmb3IgKGludCBqID0gMjU2OyAtLWogPj0gMDspIHsKKyAgICAgICAgICAgICAgICBmdGFiWyhqIDw8IDgpICsgc3NdIHw9IFNFVE1BU0s7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIFN0ZXAgMzoKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBMQloyOiBUaGUgc3MgYmlnIGJ1Y2tldCBpcyBub3cgZG9uZS4gUmVjb3JkIHRoaXMgZmFjdCwgYW5kIHVwZGF0ZSB0aGUKKyAgICAgICAgICAgICAqIHF1YWRyYW50IGRlc2NyaXB0b3JzLiBSZW1lbWJlciB0byB1cGRhdGUgcXVhZHJhbnRzIGluIHRoZQorICAgICAgICAgICAgICogb3ZlcnNob290IGFyZWEgdG9vLCBpZiBuZWNlc3NhcnkuIFRoZSAiaWYgKGkgPCAyNTUpIiB0ZXN0IG1lcmVseQorICAgICAgICAgICAgICogc2tpcHMgdGhpcyB1cGRhdGluZyBmb3IgdGhlIGxhc3QgYnVja2V0IHByb2Nlc3NlZCwgc2luY2UgdXBkYXRpbmcKKyAgICAgICAgICAgICAqIGZvciB0aGUgbGFzdCBidWNrZXQgaXMgcG9pbnRsZXNzLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBiaWdEb25lW3NzXSA9IHRydWU7CisKKyAgICAgICAgICAgIGlmIChpIDwgMjU1KSB7CisgICAgICAgICAgICAgICAgZmluYWwgaW50IGJiU3RhcnQgPSBmdGFiW3NzIDw8IDhdICYgQ0xFQVJNQVNLOworICAgICAgICAgICAgICAgIGZpbmFsIGludCBiYlNpemUgPSAoZnRhYlsoc3MgKyAxKSA8PCA4XSAmIENMRUFSTUFTSykgLSBiYlN0YXJ0OworICAgICAgICAgICAgICAgIGludCBzaGlmdHMgPSAwOworCisgICAgICAgICAgICAgICAgd2hpbGUgKChiYlNpemUgPj4gc2hpZnRzKSA+IDY1NTM0KSB7CisgICAgICAgICAgICAgICAgICAgIHNoaWZ0cysrOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgYmJTaXplOyBqKyspIHsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGEydXBkYXRlID0gZm1hcFtiYlN0YXJ0ICsgal07CisgICAgICAgICAgICAgICAgICAgIGZpbmFsIGNoYXIgcVZhbCA9IChjaGFyKSAoaiA+PiBzaGlmdHMpOworICAgICAgICAgICAgICAgICAgICBxdWFkcmFudFthMnVwZGF0ZV0gPSBxVmFsOworICAgICAgICAgICAgICAgICAgICBpZiAoYTJ1cGRhdGUgPCBCWmlwMkNvbnN0YW50cy5OVU1fT1ZFUlNIT09UX0JZVEVTKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBxdWFkcmFudFthMnVwZGF0ZSArIGxhc3RTaGFkb3cgKyAxXSA9IHFWYWw7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgfQorICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvYnppcDIvQ1JDLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9iemlwMi9DUkMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hMjBlYTcwCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvYnppcDIvQ1JDLmphdmEKQEAgLTAsMCArMSwxMzQgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuYnppcDI7CisKKy8qKgorICogQSBzaW1wbGUgY2xhc3MgdGhlIGhvbGQgYW5kIGNhbGN1bGF0ZSB0aGUgQ1JDIGZvciBzYW5pdHkgY2hlY2tpbmcgb2YgdGhlCisgKiBkYXRhLgorICogQE5vdFRocmVhZFNhZmUKKyAqLworY2xhc3MgQ1JDIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgY3JjMzJUYWJsZVtdID0geworICAgICAgICAgICAgMHgwMDAwMDAwMCwgMHgwNGMxMWRiNywgMHgwOTgyM2I2ZSwgMHgwZDQzMjZkOSwKKyAgICAgICAgICAgIDB4MTMwNDc2ZGMsIDB4MTdjNTZiNmIsIDB4MWE4NjRkYjIsIDB4MWU0NzUwMDUsCisgICAgICAgICAgICAweDI2MDhlZGI4LCAweDIyYzlmMDBmLCAweDJmOGFkNmQ2LCAweDJiNGJjYjYxLAorICAgICAgICAgICAgMHgzNTBjOWI2NCwgMHgzMWNkODZkMywgMHgzYzhlYTAwYSwgMHgzODRmYmRiZCwKKyAgICAgICAgICAgIDB4NGMxMWRiNzAsIDB4NDhkMGM2YzcsIDB4NDU5M2UwMWUsIDB4NDE1MmZkYTksCisgICAgICAgICAgICAweDVmMTVhZGFjLCAweDViZDRiMDFiLCAweDU2OTc5NmMyLCAweDUyNTY4Yjc1LAorICAgICAgICAgICAgMHg2YTE5MzZjOCwgMHg2ZWQ4MmI3ZiwgMHg2MzliMGRhNiwgMHg2NzVhMTAxMSwKKyAgICAgICAgICAgIDB4NzkxZDQwMTQsIDB4N2RkYzVkYTMsIDB4NzA5ZjdiN2EsIDB4NzQ1ZTY2Y2QsCisgICAgICAgICAgICAweDk4MjNiNmUwLCAweDljZTJhYjU3LCAweDkxYTE4ZDhlLCAweDk1NjA5MDM5LAorICAgICAgICAgICAgMHg4YjI3YzAzYywgMHg4ZmU2ZGQ4YiwgMHg4MmE1ZmI1MiwgMHg4NjY0ZTZlNSwKKyAgICAgICAgICAgIDB4YmUyYjViNTgsIDB4YmFlYTQ2ZWYsIDB4YjdhOTYwMzYsIDB4YjM2ODdkODEsCisgICAgICAgICAgICAweGFkMmYyZDg0LCAweGE5ZWUzMDMzLCAweGE0YWQxNmVhLCAweGEwNmMwYjVkLAorICAgICAgICAgICAgMHhkNDMyNmQ5MCwgMHhkMGYzNzAyNywgMHhkZGIwNTZmZSwgMHhkOTcxNGI0OSwKKyAgICAgICAgICAgIDB4YzczNjFiNGMsIDB4YzNmNzA2ZmIsIDB4Y2ViNDIwMjIsIDB4Y2E3NTNkOTUsCisgICAgICAgICAgICAweGYyM2E4MDI4LCAweGY2ZmI5ZDlmLCAweGZiYjhiYjQ2LCAweGZmNzlhNmYxLAorICAgICAgICAgICAgMHhlMTNlZjZmNCwgMHhlNWZmZWI0MywgMHhlOGJjY2Q5YSwgMHhlYzdkZDAyZCwKKyAgICAgICAgICAgIDB4MzQ4NjcwNzcsIDB4MzA0NzZkYzAsIDB4M2QwNDRiMTksIDB4MzljNTU2YWUsCisgICAgICAgICAgICAweDI3ODIwNmFiLCAweDIzNDMxYjFjLCAweDJlMDAzZGM1LCAweDJhYzEyMDcyLAorICAgICAgICAgICAgMHgxMjhlOWRjZiwgMHgxNjRmODA3OCwgMHgxYjBjYTZhMSwgMHgxZmNkYmIxNiwKKyAgICAgICAgICAgIDB4MDE4YWViMTMsIDB4MDU0YmY2YTQsIDB4MDgwOGQwN2QsIDB4MGNjOWNkY2EsCisgICAgICAgICAgICAweDc4OTdhYjA3LCAweDdjNTZiNmIwLCAweDcxMTU5MDY5LCAweDc1ZDQ4ZGRlLAorICAgICAgICAgICAgMHg2YjkzZGRkYiwgMHg2ZjUyYzA2YywgMHg2MjExZTZiNSwgMHg2NmQwZmIwMiwKKyAgICAgICAgICAgIDB4NWU5ZjQ2YmYsIDB4NWE1ZTViMDgsIDB4NTcxZDdkZDEsIDB4NTNkYzYwNjYsCisgICAgICAgICAgICAweDRkOWIzMDYzLCAweDQ5NWEyZGQ0LCAweDQ0MTkwYjBkLCAweDQwZDgxNmJhLAorICAgICAgICAgICAgMHhhY2E1YzY5NywgMHhhODY0ZGIyMCwgMHhhNTI3ZmRmOSwgMHhhMWU2ZTA0ZSwKKyAgICAgICAgICAgIDB4YmZhMWIwNGIsIDB4YmI2MGFkZmMsIDB4YjYyMzhiMjUsIDB4YjJlMjk2OTIsCisgICAgICAgICAgICAweDhhYWQyYjJmLCAweDhlNmMzNjk4LCAweDgzMmYxMDQxLCAweDg3ZWUwZGY2LAorICAgICAgICAgICAgMHg5OWE5NWRmMywgMHg5ZDY4NDA0NCwgMHg5MDJiNjY5ZCwgMHg5NGVhN2IyYSwKKyAgICAgICAgICAgIDB4ZTBiNDFkZTcsIDB4ZTQ3NTAwNTAsIDB4ZTkzNjI2ODksIDB4ZWRmNzNiM2UsCisgICAgICAgICAgICAweGYzYjA2YjNiLCAweGY3NzE3NjhjLCAweGZhMzI1MDU1LCAweGZlZjM0ZGUyLAorICAgICAgICAgICAgMHhjNmJjZjA1ZiwgMHhjMjdkZWRlOCwgMHhjZjNlY2IzMSwgMHhjYmZmZDY4NiwKKyAgICAgICAgICAgIDB4ZDViODg2ODMsIDB4ZDE3OTliMzQsIDB4ZGMzYWJkZWQsIDB4ZDhmYmEwNWEsCisgICAgICAgICAgICAweDY5MGNlMGVlLCAweDZkY2RmZDU5LCAweDYwOGVkYjgwLCAweDY0NGZjNjM3LAorICAgICAgICAgICAgMHg3YTA4OTYzMiwgMHg3ZWM5OGI4NSwgMHg3MzhhYWQ1YywgMHg3NzRiYjBlYiwKKyAgICAgICAgICAgIDB4NGYwNDBkNTYsIDB4NGJjNTEwZTEsIDB4NDY4NjM2MzgsIDB4NDI0NzJiOGYsCisgICAgICAgICAgICAweDVjMDA3YjhhLCAweDU4YzE2NjNkLCAweDU1ODI0MGU0LCAweDUxNDM1ZDUzLAorICAgICAgICAgICAgMHgyNTFkM2I5ZSwgMHgyMWRjMjYyOSwgMHgyYzlmMDBmMCwgMHgyODVlMWQ0NywKKyAgICAgICAgICAgIDB4MzYxOTRkNDIsIDB4MzJkODUwZjUsIDB4M2Y5Yjc2MmMsIDB4M2I1YTZiOWIsCisgICAgICAgICAgICAweDAzMTVkNjI2LCAweDA3ZDRjYjkxLCAweDBhOTdlZDQ4LCAweDBlNTZmMGZmLAorICAgICAgICAgICAgMHgxMDExYTBmYSwgMHgxNGQwYmQ0ZCwgMHgxOTkzOWI5NCwgMHgxZDUyODYyMywKKyAgICAgICAgICAgIDB4ZjEyZjU2MGUsIDB4ZjVlZTRiYjksIDB4ZjhhZDZkNjAsIDB4ZmM2YzcwZDcsCisgICAgICAgICAgICAweGUyMmIyMGQyLCAweGU2ZWEzZDY1LCAweGViYTkxYmJjLCAweGVmNjgwNjBiLAorICAgICAgICAgICAgMHhkNzI3YmJiNiwgMHhkM2U2YTYwMSwgMHhkZWE1ODBkOCwgMHhkYTY0OWQ2ZiwKKyAgICAgICAgICAgIDB4YzQyM2NkNmEsIDB4YzBlMmQwZGQsIDB4Y2RhMWY2MDQsIDB4Yzk2MGViYjMsCisgICAgICAgICAgICAweGJkM2U4ZDdlLCAweGI5ZmY5MGM5LCAweGI0YmNiNjEwLCAweGIwN2RhYmE3LAorICAgICAgICAgICAgMHhhZTNhZmJhMiwgMHhhYWZiZTYxNSwgMHhhN2I4YzBjYywgMHhhMzc5ZGQ3YiwKKyAgICAgICAgICAgIDB4OWIzNjYwYzYsIDB4OWZmNzdkNzEsIDB4OTJiNDViYTgsIDB4OTY3NTQ2MWYsCisgICAgICAgICAgICAweDg4MzIxNjFhLCAweDhjZjMwYmFkLCAweDgxYjAyZDc0LCAweDg1NzEzMGMzLAorICAgICAgICAgICAgMHg1ZDhhOTA5OSwgMHg1OTRiOGQyZSwgMHg1NDA4YWJmNywgMHg1MGM5YjY0MCwKKyAgICAgICAgICAgIDB4NGU4ZWU2NDUsIDB4NGE0ZmZiZjIsIDB4NDcwY2RkMmIsIDB4NDNjZGMwOWMsCisgICAgICAgICAgICAweDdiODI3ZDIxLCAweDdmNDM2MDk2LCAweDcyMDA0NjRmLCAweDc2YzE1YmY4LAorICAgICAgICAgICAgMHg2ODg2MGJmZCwgMHg2YzQ3MTY0YSwgMHg2MTA0MzA5MywgMHg2NWM1MmQyNCwKKyAgICAgICAgICAgIDB4MTE5YjRiZTksIDB4MTU1YTU2NWUsIDB4MTgxOTcwODcsIDB4MWNkODZkMzAsCisgICAgICAgICAgICAweDAyOWYzZDM1LCAweDA2NWUyMDgyLCAweDBiMWQwNjViLCAweDBmZGMxYmVjLAorICAgICAgICAgICAgMHgzNzkzYTY1MSwgMHgzMzUyYmJlNiwgMHgzZTExOWQzZiwgMHgzYWQwODA4OCwKKyAgICAgICAgICAgIDB4MjQ5N2QwOGQsIDB4MjA1NmNkM2EsIDB4MmQxNWViZTMsIDB4MjlkNGY2NTQsCisgICAgICAgICAgICAweGM1YTkyNjc5LCAweGMxNjgzYmNlLCAweGNjMmIxZDE3LCAweGM4ZWEwMGEwLAorICAgICAgICAgICAgMHhkNmFkNTBhNSwgMHhkMjZjNGQxMiwgMHhkZjJmNmJjYiwgMHhkYmVlNzY3YywKKyAgICAgICAgICAgIDB4ZTNhMWNiYzEsIDB4ZTc2MGQ2NzYsIDB4ZWEyM2YwYWYsIDB4ZWVlMmVkMTgsCisgICAgICAgICAgICAweGYwYTViZDFkLCAweGY0NjRhMGFhLCAweGY5Mjc4NjczLCAweGZkZTY5YmM0LAorICAgICAgICAgICAgMHg4OWI4ZmQwOSwgMHg4ZDc5ZTBiZSwgMHg4MDNhYzY2NywgMHg4NGZiZGJkMCwKKyAgICAgICAgICAgIDB4OWFiYzhiZDUsIDB4OWU3ZDk2NjIsIDB4OTMzZWIwYmIsIDB4OTdmZmFkMGMsCisgICAgICAgICAgICAweGFmYjAxMGIxLCAweGFiNzEwZDA2LCAweGE2MzIyYmRmLCAweGEyZjMzNjY4LAorICAgICAgICAgICAgMHhiY2I0NjY2ZCwgMHhiODc1N2JkYSwgMHhiNTM2NWQwMywgMHhiMWY3NDBiNAorICAgICAgICB9OworCisgICAgICAgIENSQygpIHsKKyAgICAgICAgICAgIGluaXRpYWxpc2VDUkMoKTsKKyAgICAgICAgfQorCisgICAgICAgIHZvaWQgaW5pdGlhbGlzZUNSQygpIHsKKyAgICAgICAgICAgIGdsb2JhbENyYyA9IDB4ZmZmZmZmZmY7CisgICAgICAgIH0KKworICAgICAgICBpbnQgZ2V0RmluYWxDUkMoKSB7CisgICAgICAgICAgICByZXR1cm4gfmdsb2JhbENyYzsKKyAgICAgICAgfQorCisgICAgICAgIGludCBnZXRHbG9iYWxDUkMoKSB7CisgICAgICAgICAgICByZXR1cm4gZ2xvYmFsQ3JjOworICAgICAgICB9CisKKyAgICAgICAgdm9pZCBzZXRHbG9iYWxDUkMoZmluYWwgaW50IG5ld0NyYykgeworICAgICAgICAgICAgZ2xvYmFsQ3JjID0gbmV3Q3JjOworICAgICAgICB9CisKKyAgICAgICAgdm9pZCB1cGRhdGVDUkMoZmluYWwgaW50IGluQ2gpIHsKKyAgICAgICAgICAgIGludCB0ZW1wID0gKGdsb2JhbENyYyA+PiAyNCkgXiBpbkNoOworICAgICAgICAgICAgaWYgKHRlbXAgPCAwKSB7CisgICAgICAgICAgICAgICAgdGVtcCA9IDI1NiArIHRlbXA7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBnbG9iYWxDcmMgPSAoZ2xvYmFsQ3JjIDw8IDgpIF4gQ1JDLmNyYzMyVGFibGVbdGVtcF07CisgICAgICAgIH0KKworICAgICAgICB2b2lkIHVwZGF0ZUNSQyhmaW5hbCBpbnQgaW5DaCwgaW50IHJlcGVhdCkgeworICAgICAgICAgICAgaW50IGdsb2JhbENyY1NoYWRvdyA9IHRoaXMuZ2xvYmFsQ3JjOworICAgICAgICAgICAgd2hpbGUgKHJlcGVhdC0tID4gMCkgeworICAgICAgICAgICAgICAgIGZpbmFsIGludCB0ZW1wID0gKGdsb2JhbENyY1NoYWRvdyA+PiAyNCkgXiBpbkNoOworICAgICAgICAgICAgICAgIGdsb2JhbENyY1NoYWRvdyA9IChnbG9iYWxDcmNTaGFkb3cgPDwgOCkgXiBjcmMzMlRhYmxlWyh0ZW1wID49IDApCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyB0ZW1wCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAodGVtcCArIDI1NildOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhpcy5nbG9iYWxDcmMgPSBnbG9iYWxDcmNTaGFkb3c7CisgICAgICAgIH0KKworICAgICAgICBwcml2YXRlIGludCBnbG9iYWxDcmM7Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvYnppcDIvUmFuZC5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvYnppcDIvUmFuZC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJiNmVmODAKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9iemlwMi9SYW5kLmphdmEKQEAgLTAsMCArMSw5MSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLmJ6aXAyOworCisvKioKKyAqIFJhbmRvbSBudW1iZXJzIGZvciBib3RoIHRoZSBjb21wcmVzcyBhbmQgZGVjb21wcmVzcyBCWmlwMiBjbGFzc2VzLgorICovCitmaW5hbCBjbGFzcyBSYW5kIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludFtdIFJOVU1TID0geworICAgICAgICA2MTksIDcyMCwgMTI3LCA0ODEsIDkzMSwgODE2LCA4MTMsIDIzMywgNTY2LCAyNDcsCisgICAgICAgIDk4NSwgNzI0LCAyMDUsIDQ1NCwgODYzLCA0OTEsIDc0MSwgMjQyLCA5NDksIDIxNCwKKyAgICAgICAgNzMzLCA4NTksIDMzNSwgNzA4LCA2MjEsIDU3NCwgIDczLCA2NTQsIDczMCwgNDcyLAorICAgICAgICA0MTksIDQzNiwgMjc4LCA0OTYsIDg2NywgMjEwLCAzOTksIDY4MCwgNDgwLCAgNTEsCisgICAgICAgIDg3OCwgNDY1LCA4MTEsIDE2OSwgODY5LCA2NzUsIDYxMSwgNjk3LCA4NjcsIDU2MSwKKyAgICAgICAgODYyLCA2ODcsIDUwNywgMjgzLCA0ODIsIDEyOSwgODA3LCA1OTEsIDczMywgNjIzLAorICAgICAgICAxNTAsIDIzOCwgIDU5LCAzNzksIDY4NCwgODc3LCA2MjUsIDE2OSwgNjQzLCAxMDUsCisgICAgICAgIDE3MCwgNjA3LCA1MjAsIDkzMiwgNzI3LCA0NzYsIDY5MywgNDI1LCAxNzQsIDY0NywKKyAgICAgICAgIDczLCAxMjIsIDMzNSwgNTMwLCA0NDIsIDg1MywgNjk1LCAyNDksIDQ0NSwgNTE1LAorICAgICAgICA5MDksIDU0NSwgNzAzLCA5MTksIDg3NCwgNDc0LCA4ODIsIDUwMCwgNTk0LCA2MTIsCisgICAgICAgIDY0MSwgODAxLCAyMjAsIDE2MiwgODE5LCA5ODQsIDU4OSwgNTEzLCA0OTUsIDc5OSwKKyAgICAgICAgMTYxLCA2MDQsIDk1OCwgNTMzLCAyMjEsIDQwMCwgMzg2LCA4NjcsIDYwMCwgNzgyLAorICAgICAgICAzODIsIDU5NiwgNDE0LCAxNzEsIDUxNiwgMzc1LCA2ODIsIDQ4NSwgOTExLCAyNzYsCisgICAgICAgICA5OCwgNTUzLCAxNjMsIDM1NCwgNjY2LCA5MzMsIDQyNCwgMzQxLCA1MzMsIDg3MCwKKyAgICAgICAgMjI3LCA3MzAsIDQ3NSwgMTg2LCAyNjMsIDY0NywgNTM3LCA2ODYsIDYwMCwgMjI0LAorICAgICAgICA0NjksICA2OCwgNzcwLCA5MTksIDE5MCwgMzczLCAyOTQsIDgyMiwgODA4LCAyMDYsCisgICAgICAgIDE4NCwgOTQzLCA3OTUsIDM4NCwgMzgzLCA0NjEsIDQwNCwgNzU4LCA4MzksIDg4NywKKyAgICAgICAgNzE1LCAgNjcsIDYxOCwgMjc2LCAyMDQsIDkxOCwgODczLCA3NzcsIDYwNCwgNTYwLAorICAgICAgICA5NTEsIDE2MCwgNTc4LCA3MjIsICA3OSwgODA0LCAgOTYsIDQwOSwgNzEzLCA5NDAsCisgICAgICAgIDY1MiwgOTM0LCA5NzAsIDQ0NywgMzE4LCAzNTMsIDg1OSwgNjcyLCAxMTIsIDc4NSwKKyAgICAgICAgNjQ1LCA4NjMsIDgwMywgMzUwLCAxMzksICA5MywgMzU0LCAgOTksIDgyMCwgOTA4LAorICAgICAgICA2MDksIDc3MiwgMTU0LCAyNzQsIDU4MCwgMTg0LCAgNzksIDYyNiwgNjMwLCA3NDIsCisgICAgICAgIDY1MywgMjgyLCA3NjIsIDYyMywgNjgwLCAgODEsIDkyNywgNjI2LCA3ODksIDEyNSwKKyAgICAgICAgNDExLCA1MjEsIDkzOCwgMzAwLCA4MjEsICA3OCwgMzQzLCAxNzUsIDEyOCwgMjUwLAorICAgICAgICAxNzAsIDc3NCwgOTcyLCAyNzUsIDk5OSwgNjM5LCA0OTUsICA3OCwgMzUyLCAxMjYsCisgICAgICAgIDg1NywgOTU2LCAzNTgsIDYxOSwgNTgwLCAxMjQsIDczNywgNTk0LCA3MDEsIDYxMiwKKyAgICAgICAgNjY5LCAxMTIsIDEzNCwgNjk0LCAzNjMsIDk5MiwgODA5LCA3NDMsIDE2OCwgOTc0LAorICAgICAgICA5NDQsIDM3NSwgNzQ4LCAgNTIsIDYwMCwgNzQ3LCA2NDIsIDE4MiwgODYyLCAgODEsCisgICAgICAgIDM0NCwgODA1LCA5ODgsIDczOSwgNTExLCA2NTUsIDgxNCwgMzM0LCAyNDksIDUxNSwKKyAgICAgICAgODk3LCA5NTUsIDY2NCwgOTgxLCA2NDksIDExMywgOTc0LCA0NTksIDg5MywgMjI4LAorICAgICAgICA0MzMsIDgzNywgNTUzLCAyNjgsIDkyNiwgMjQwLCAxMDIsIDY1NCwgNDU5LCA1MSwKKyAgICAgICAgNjg2LCA3NTQsIDgwNiwgNzYwLCA0OTMsIDQwMywgNDE1LCAzOTQsIDY4NywgNzAwLAorICAgICAgICA5NDYsIDY3MCwgNjU2LCA2MTAsIDczOCwgMzkyLCA3NjAsIDc5OSwgODg3LCA2NTMsCisgICAgICAgIDk3OCwgMzIxLCA1NzYsIDYxNywgNjI2LCA1MDIsIDg5NCwgNjc5LCAyNDMsIDQ0MCwKKyAgICAgICAgNjgwLCA4NzksIDE5NCwgNTcyLCA2NDAsIDcyNCwgOTI2LCAgNTYsIDIwNCwgNzAwLAorICAgICAgICA3MDcsIDE1MSwgNDU3LCA0NDksIDc5NywgMTk1LCA3OTEsIDU1OCwgOTQ1LCA2NzksCisgICAgICAgIDI5NywgIDU5LCAgODcsIDgyNCwgNzEzLCA2NjMsIDQxMiwgNjkzLCAzNDIsIDYwNiwKKyAgICAgICAgMTM0LCAxMDgsIDU3MSwgMzY0LCA2MzEsIDIxMiwgMTc0LCA2NDMsIDMwNCwgMzI5LAorICAgICAgICAzNDMsICA5NywgNDMwLCA3NTEsIDQ5NywgMzE0LCA5ODMsIDM3NCwgODIyLCA5MjgsCisgICAgICAgIDE0MCwgMjA2LCAgNzMsIDI2MywgOTgwLCA3MzYsIDg3NiwgNDc4LCA0MzAsIDMwNSwKKyAgICAgICAgMTcwLCA1MTQsIDM2NCwgNjkyLCA4MjksICA4MiwgODU1LCA5NTMsIDY3NiwgMjQ2LAorICAgICAgICAzNjksIDk3MCwgMjk0LCA3NTAsIDgwNywgODI3LCAxNTAsIDc5MCwgMjg4LCA5MjMsCisgICAgICAgIDgwNCwgMzc4LCAyMTUsIDgyOCwgNTkyLCAyODEsIDU2NSwgNTU1LCA3MTAsICA4MiwKKyAgICAgICAgODk2LCA4MzEsIDU0NywgMjYxLCA1MjQsIDQ2MiwgMjkzLCA0NjUsIDUwMiwgIDU2LAorICAgICAgICA2NjEsIDgyMSwgOTc2LCA5OTEsIDY1OCwgODY5LCA5MDUsIDc1OCwgNzQ1LCAxOTMsCisgICAgICAgIDc2OCwgNTUwLCA2MDgsIDkzMywgMzc4LCAyODYsIDIxNSwgOTc5LCA3OTIsIDk2MSwKKyAgICAgICAgIDYxLCA2ODgsIDc5MywgNjQ0LCA5ODYsIDQwMywgMTA2LCAzNjYsIDkwNSwgNjQ0LAorICAgICAgICAzNzIsIDU2NywgNDY2LCA0MzQsIDY0NSwgMjEwLCAzODksIDU1MCwgOTE5LCAxMzUsCisgICAgICAgIDc4MCwgNzczLCA2MzUsIDM4OSwgNzA3LCAxMDAsIDYyNiwgOTU4LCAxNjUsIDUwNCwKKyAgICAgICAgOTIwLCAxNzYsIDE5MywgNzEzLCA4NTcsIDI2NSwgMjAzLCAgNTAsIDY2OCwgMTA4LAorICAgICAgICA2NDUsIDk5MCwgNjI2LCAxOTcsIDUxMCwgMzU3LCAzNTgsIDg1MCwgODU4LCAzNjQsCisgICAgICAgIDkzNiwgNjM4CisgICAgfTsKKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgcmFuZG9tIG51bWJlciBhdCBhIHNwZWNpZmljIGluZGV4LgorICAgICAqCisgICAgICogQHBhcmFtIGkgdGhlIGluZGV4CisgICAgICogQHJldHVybiB0aGUgcmFuZG9tIG51bWJlcgorICAgICAqLworICAgIHN0YXRpYyBpbnQgck51bXMoZmluYWwgaW50IGkpeworICAgICAgICByZXR1cm4gUk5VTVNbaV07CisgICAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2J6aXAyL3BhY2thZ2UuaHRtbCBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2J6aXAyL3BhY2thZ2UuaHRtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mZTI3ZTZlCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvYnppcDIvcGFja2FnZS5odG1sCkBAIC0wLDAgKzEsMjQgQEAKKzxodG1sPgorPCEtLQorCisgICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAgIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAgICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorCisgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisKKyAgIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAgIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAgIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAgIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorCistLT4KKyAgPGJvZHk+CisgICAgPHA+UHJvdmlkZXMgc3RyZWFtIGNsYXNzZXMgZm9yIGNvbXByZXNzaW5nIGFuZCBkZWNvbXByZXNzaW5nCisgICAgICBzdHJlYW1zIHVzaW5nIHRoZSBCWmlwMiBhbGdvcml0aG0uPC9wPgorICA8L2JvZHk+Cis8L2h0bWw+CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9kZWZsYXRlL0RlZmxhdGVDb21wcmVzc29ySW5wdXRTdHJlYW0uamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2RlZmxhdGUvRGVmbGF0ZUNvbXByZXNzb3JJbnB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBlMDcyODQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9kZWZsYXRlL0RlZmxhdGVDb21wcmVzc29ySW5wdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDEzOCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5kZWZsYXRlOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC56aXAuSW5mbGF0ZXI7CitpbXBvcnQgamF2YS51dGlsLnppcC5JbmZsYXRlcklucHV0U3RyZWFtOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLkNvbXByZXNzb3JJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuQ291bnRpbmdJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuSU9VdGlsczsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuSW5wdXRTdHJlYW1TdGF0aXN0aWNzOworCisvKioKKyAqIERlZmxhdGUgZGVjb21wcmVzc29yLgorICogQHNpbmNlIDEuOQorICovCitwdWJsaWMgY2xhc3MgRGVmbGF0ZUNvbXByZXNzb3JJbnB1dFN0cmVhbSBleHRlbmRzIENvbXByZXNzb3JJbnB1dFN0cmVhbQorICAgIGltcGxlbWVudHMgSW5wdXRTdHJlYW1TdGF0aXN0aWNzIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNQUdJQ18xID0gMHg3ODsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTUFHSUNfMmEgPSAweDAxOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNQUdJQ18yYiA9IDB4NWU7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE1BR0lDXzJjID0gMHg5YzsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTUFHSUNfMmQgPSAweGRhOworCisgICAgcHJpdmF0ZSBmaW5hbCBDb3VudGluZ0lucHV0U3RyZWFtIGNvdW50aW5nU3RyZWFtOworICAgIHByaXZhdGUgZmluYWwgSW5wdXRTdHJlYW0gaW47CisgICAgcHJpdmF0ZSBmaW5hbCBJbmZsYXRlciBpbmZsYXRlcjsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgaW5wdXQgc3RyZWFtIHRoYXQgZGVjb21wcmVzc2VzIERlZmxhdGUtY29tcHJlc3NlZCBkYXRhCisgICAgICogZnJvbSB0aGUgc3BlY2lmaWVkIGlucHV0IHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSAgICAgICBpbnB1dFN0cmVhbSB3aGVyZSB0byByZWFkIHRoZSBjb21wcmVzc2VkIGRhdGEKKyAgICAgKgorICAgICAqLworICAgIHB1YmxpYyBEZWZsYXRlQ29tcHJlc3NvcklucHV0U3RyZWFtKGZpbmFsIElucHV0U3RyZWFtIGlucHV0U3RyZWFtKSB7CisgICAgICAgIHRoaXMoaW5wdXRTdHJlYW0sIG5ldyBEZWZsYXRlUGFyYW1ldGVycygpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IGlucHV0IHN0cmVhbSB0aGF0IGRlY29tcHJlc3NlcyBEZWZsYXRlLWNvbXByZXNzZWQgZGF0YQorICAgICAqIGZyb20gdGhlIHNwZWNpZmllZCBpbnB1dCBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gICAgICAgaW5wdXRTdHJlYW0gd2hlcmUgdG8gcmVhZCB0aGUgY29tcHJlc3NlZCBkYXRhCisgICAgICogQHBhcmFtICAgICAgIHBhcmFtZXRlcnMgcGFyYW1ldGVycworICAgICAqLworICAgIHB1YmxpYyBEZWZsYXRlQ29tcHJlc3NvcklucHV0U3RyZWFtKGZpbmFsIElucHV0U3RyZWFtIGlucHV0U3RyZWFtLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIERlZmxhdGVQYXJhbWV0ZXJzIHBhcmFtZXRlcnMpIHsKKyAgICAgICAgaW5mbGF0ZXIgPSBuZXcgSW5mbGF0ZXIoIXBhcmFtZXRlcnMud2l0aFpsaWJIZWFkZXIoKSk7CisgICAgICAgIGluID0gbmV3IEluZmxhdGVySW5wdXRTdHJlYW0oY291bnRpbmdTdHJlYW0gPSBuZXcgQ291bnRpbmdJbnB1dFN0cmVhbShpbnB1dFN0cmVhbSksIGluZmxhdGVyKTsKKyAgICB9CisKKyAgICAvKioge0Bpbmhlcml0RG9jfSAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIGludCByZXQgPSBpbi5yZWFkKCk7CisgICAgICAgIGNvdW50KHJldCA9PSAtMSA/IDAgOiAxKTsKKyAgICAgICAgcmV0dXJuIHJldDsKKyAgICB9CisKKyAgICAvKioge0Bpbmhlcml0RG9jfSAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZChmaW5hbCBieXRlW10gYnVmLCBmaW5hbCBpbnQgb2ZmLCBmaW5hbCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBpbnQgcmV0ID0gaW4ucmVhZChidWYsIG9mZiwgbGVuKTsKKyAgICAgICAgY291bnQocmV0KTsKKyAgICAgICAgcmV0dXJuIHJldDsKKyAgICB9CisKKyAgICAvKioge0Bpbmhlcml0RG9jfSAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBsb25nIHNraXAoZmluYWwgbG9uZyBuKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gSU9VdGlscy5za2lwKGluLCBuKTsKKyAgICB9CisKKyAgICAvKioge0Bpbmhlcml0RG9jfSAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgYXZhaWxhYmxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGluLmF2YWlsYWJsZSgpOworICAgIH0KKworICAgIC8qKiB7QGluaGVyaXREb2N9ICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGluZmxhdGVyLmVuZCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNpbmNlIDEuMTcKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgbG9uZyBnZXRDb21wcmVzc2VkQ291bnQoKSB7CisgICAgICAgIHJldHVybiBjb3VudGluZ1N0cmVhbS5nZXRCeXRlc1JlYWQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgaWYgdGhlIHNpZ25hdHVyZSBtYXRjaGVzIHdoYXQgaXMgZXhwZWN0ZWQgZm9yIGEgemxpYiAvIGRlZmxhdGVkIGZpbGUKKyAgICAgKiAgd2l0aCB0aGUgemxpYiBoZWFkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc2lnbmF0dXJlCisgICAgICogICAgICAgICAgICB0aGUgYnl0ZXMgdG8gY2hlY2sKKyAgICAgKiBAcGFyYW0gbGVuZ3RoCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRvIGNoZWNrCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGlzIHN0cmVhbSBpcyB6bGliIC8gZGVmbGF0ZSBjb21wcmVzc2VkIHdpdGggYSBoZWFkZXIKKyAgICAgKiBzdHJlYW0sIGZhbHNlIG90aGVyd2lzZQorICAgICAqCisgICAgICogQHNpbmNlIDEuMTAKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gbWF0Y2hlcyhmaW5hbCBieXRlW10gc2lnbmF0dXJlLCBmaW5hbCBpbnQgbGVuZ3RoKSB7CisgICAgICAgIHJldHVybiBsZW5ndGggPiAzICYmIHNpZ25hdHVyZVswXSA9PSBNQUdJQ18xICYmICgKKyAgICAgICAgICAgICAgICBzaWduYXR1cmVbMV0gPT0gKGJ5dGUpIE1BR0lDXzJhIHx8CisgICAgICAgICAgICAgICAgc2lnbmF0dXJlWzFdID09IChieXRlKSBNQUdJQ18yYiB8fAorICAgICAgICAgICAgICAgIHNpZ25hdHVyZVsxXSA9PSAoYnl0ZSkgTUFHSUNfMmMgfHwKKyAgICAgICAgICAgICAgICBzaWduYXR1cmVbMV0gPT0gKGJ5dGUpIE1BR0lDXzJkKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9kZWZsYXRlL0RlZmxhdGVDb21wcmVzc29yT3V0cHV0U3RyZWFtLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9kZWZsYXRlL0RlZmxhdGVDb21wcmVzc29yT3V0cHV0U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTMxNTYwNQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2RlZmxhdGUvRGVmbGF0ZUNvbXByZXNzb3JPdXRwdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDk1IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLmRlZmxhdGU7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC56aXAuRGVmbGF0ZXI7CitpbXBvcnQgamF2YS51dGlsLnppcC5EZWZsYXRlck91dHB1dFN0cmVhbTsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5Db21wcmVzc29yT3V0cHV0U3RyZWFtOworCisvKioKKyAqIERlZmxhdGUgY29tcHJlc3Nvci4KKyAqIEBzaW5jZSAxLjkKKyAqLworcHVibGljIGNsYXNzIERlZmxhdGVDb21wcmVzc29yT3V0cHV0U3RyZWFtIGV4dGVuZHMgQ29tcHJlc3Nvck91dHB1dFN0cmVhbSB7CisgICAgcHJpdmF0ZSBmaW5hbCBEZWZsYXRlck91dHB1dFN0cmVhbSBvdXQ7CisgICAgcHJpdmF0ZSBmaW5hbCBEZWZsYXRlciBkZWZsYXRlcjsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBEZWZsYXRlIGNvbXByZXNzZWQgb3V0cHV0IHN0cmVhbSB3aXRoIHRoZSBkZWZhdWx0IHBhcmFtZXRlcnMuCisgICAgICogQHBhcmFtIG91dHB1dFN0cmVhbSB0aGUgc3RyZWFtIHRvIHdyYXAKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIG9uIGVycm9yCisgICAgICovCisgICAgcHVibGljIERlZmxhdGVDb21wcmVzc29yT3V0cHV0U3RyZWFtKGZpbmFsIE91dHB1dFN0cmVhbSBvdXRwdXRTdHJlYW0pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMob3V0cHV0U3RyZWFtLCBuZXcgRGVmbGF0ZVBhcmFtZXRlcnMoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIERlZmxhdGUgY29tcHJlc3NlZCBvdXRwdXQgc3RyZWFtIHdpdGggdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXJzLgorICAgICAqIEBwYXJhbSBvdXRwdXRTdHJlYW0gdGhlIHN0cmVhbSB0byB3cmFwCisgICAgICogQHBhcmFtIHBhcmFtZXRlcnMgdGhlIGRlZmxhdGUgcGFyYW1ldGVycyB0byBhcHBseQorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gb24gZXJyb3IKKyAgICAgKi8KKyAgICBwdWJsaWMgRGVmbGF0ZUNvbXByZXNzb3JPdXRwdXRTdHJlYW0oZmluYWwgT3V0cHV0U3RyZWFtIG91dHB1dFN0cmVhbSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgRGVmbGF0ZVBhcmFtZXRlcnMgcGFyYW1ldGVycykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcy5kZWZsYXRlciA9IG5ldyBEZWZsYXRlcihwYXJhbWV0ZXJzLmdldENvbXByZXNzaW9uTGV2ZWwoKSwgIXBhcmFtZXRlcnMud2l0aFpsaWJIZWFkZXIoKSk7CisgICAgICAgIHRoaXMub3V0ID0gbmV3IERlZmxhdGVyT3V0cHV0U3RyZWFtKG91dHB1dFN0cmVhbSwgZGVmbGF0ZXIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGZpbmFsIGludCBiKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvdXQud3JpdGUoYik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGUoZmluYWwgYnl0ZVtdIGJ1ZiwgZmluYWwgaW50IG9mZiwgZmluYWwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgb3V0LndyaXRlKGJ1Ziwgb2ZmLCBsZW4pOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZsdXNoZXMgdGhlIGVuY29kZXIgYW5kIGNhbGxzIDxjb2RlPm91dHB1dFN0cmVhbS5mbHVzaCgpPC9jb2RlPi4KKyAgICAgKiBBbGwgYnVmZmVyZWQgcGVuZGluZyBkYXRhIHdpbGwgdGhlbiBiZSBkZWNvbXByZXNzaWJsZSBmcm9tCisgICAgICogdGhlIG91dHB1dCBzdHJlYW0uIENhbGxpbmcgdGhpcyBmdW5jdGlvbiB2ZXJ5IG9mdGVuIG1heSBpbmNyZWFzZQorICAgICAqIHRoZSBjb21wcmVzc2VkIGZpbGUgc2l6ZSBhIGxvdC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBmbHVzaCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG91dC5mbHVzaCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbmlzaGVzIGNvbXByZXNzaW9uIHdpdGhvdXQgY2xvc2luZyB0aGUgdW5kZXJseWluZyBzdHJlYW0uCisgICAgICogPHA+Tm8gbW9yZSBkYXRhIGNhbiBiZSB3cml0dGVuIHRvIHRoaXMgc3RyZWFtIGFmdGVyIGZpbmlzaGluZy48L3A+CisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBvbiBlcnJvcgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGZpbmlzaCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG91dC5maW5pc2goKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGRlZmxhdGVyLmVuZCgpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvZGVmbGF0ZS9EZWZsYXRlUGFyYW1ldGVycy5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvZGVmbGF0ZS9EZWZsYXRlUGFyYW1ldGVycy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc2Nzk5NDIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9kZWZsYXRlL0RlZmxhdGVQYXJhbWV0ZXJzLmphdmEKQEAgLTAsMCArMSw3OSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLmRlZmxhdGU7CisKK2ltcG9ydCBqYXZhLnV0aWwuemlwLkRlZmxhdGVyOworCisvKioKKyAqIFBhcmFtZXRlcnMgZm9yIHRoZSBEZWZsYXRlIGNvbXByZXNzb3IuCisgKiBAc2luY2UgMS45CisgKi8KK3B1YmxpYyBjbGFzcyBEZWZsYXRlUGFyYW1ldGVycyB7CisKKyAgICBwcml2YXRlIGJvb2xlYW4gemxpYkhlYWRlciA9IHRydWU7CisgICAgcHJpdmF0ZSBpbnQgY29tcHJlc3Npb25MZXZlbCA9IERlZmxhdGVyLkRFRkFVTFRfQ09NUFJFU1NJT047CisKKyAgICAvKioKKyAgICAgKiBXaGV0aGVyIG9yIG5vdCB0aGUgemxpYiBoZWFkZXIgc2hhbGwgYmUgd3JpdHRlbiAod2hlbgorICAgICAqIGNvbXByZXNzaW5nKSBvciBleHBlY3RlZCAod2hlbiBkZWNvbXByZXNzaW5nKS4KKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgemxpYiBoZWFkZXIgc2hhbGwgYmUgd3JpdHRlbgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHdpdGhabGliSGVhZGVyKCkgeworICAgICAgICByZXR1cm4gemxpYkhlYWRlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB6bGliIGhlYWRlciBwcmVzZW5jZSBwYXJhbWV0ZXIuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIGFmZmVjdHMgd2hldGhlciBvciBub3QgdGhlIHpsaWIgaGVhZGVyIHdpbGwgYmUgd3JpdHRlbgorICAgICAqICh3aGVuIGNvbXByZXNzaW5nKSBvciBleHBlY3RlZCAod2hlbiBkZWNvbXByZXNzaW5nKS48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gemxpYkhlYWRlciB0cnVlIGlmIHpsaWIgaGVhZGVyIHNoYWxsIGJlIHdyaXR0ZW4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRXaXRoWmxpYkhlYWRlcihmaW5hbCBib29sZWFuIHpsaWJIZWFkZXIpIHsKKyAgICAgICAgdGhpcy56bGliSGVhZGVyID0gemxpYkhlYWRlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgY29tcHJlc3Npb24gbGV2ZWwuCisgICAgICogQHNlZSAjc2V0Q29tcHJlc3Npb25MZXZlbAorICAgICAqIEByZXR1cm4gdGhlIGNvbXByZXNzaW9uIGxldmVsCisgICAgICovCisgICAgcHVibGljIGludCBnZXRDb21wcmVzc2lvbkxldmVsKCkgeworICAgICAgICByZXR1cm4gY29tcHJlc3Npb25MZXZlbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBjb21wcmVzc2lvbiBsZXZlbC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb21wcmVzc2lvbkxldmVsIHRoZSBjb21wcmVzc2lvbiBsZXZlbCAoYmV0d2VlbiAwIGFuZCA5KQorICAgICAqIEBzZWUgRGVmbGF0ZXIjTk9fQ09NUFJFU1NJT04KKyAgICAgKiBAc2VlIERlZmxhdGVyI0JFU1RfU1BFRUQKKyAgICAgKiBAc2VlIERlZmxhdGVyI0RFRkFVTFRfQ09NUFJFU1NJT04KKyAgICAgKiBAc2VlIERlZmxhdGVyI0JFU1RfQ09NUFJFU1NJT04KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRDb21wcmVzc2lvbkxldmVsKGZpbmFsIGludCBjb21wcmVzc2lvbkxldmVsKSB7CisgICAgICAgIGlmIChjb21wcmVzc2lvbkxldmVsIDwgLTEgfHwgY29tcHJlc3Npb25MZXZlbCA+IDkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkludmFsaWQgRGVmbGF0ZSBjb21wcmVzc2lvbiBsZXZlbDogIiArIGNvbXByZXNzaW9uTGV2ZWwpOworICAgICAgICB9CisgICAgICAgIHRoaXMuY29tcHJlc3Npb25MZXZlbCA9IGNvbXByZXNzaW9uTGV2ZWw7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9kZWZsYXRlL3BhY2thZ2UuaHRtbCBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2RlZmxhdGUvcGFja2FnZS5odG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRkZGViNzQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9kZWZsYXRlL3BhY2thZ2UuaHRtbApAQCAtMCwwICsxLDI0IEBACis8aHRtbD4KKzwhLS0KKworICAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAgIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAgIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKworICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorCisgICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKworLS0+CisgIDxib2R5PgorICAgIDxwPlByb3ZpZGVzIGEgc3RyZWFtIGNsYXNzZXMgdGhhdCBhbGxvdyAoZGUpY29tcHJlc3Npbmcgc3RyZWFtcworICAgICAgdXNpbmcgdGhlIERFRkxBVEUgYWxnb3JpdGhtLjwvcD4KKyAgPC9ib2R5PgorPC9odG1sPgpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvZGVmbGF0ZTY0L0RlZmxhdGU2NENvbXByZXNzb3JJbnB1dFN0cmVhbS5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvZGVmbGF0ZTY0L0RlZmxhdGU2NENvbXByZXNzb3JJbnB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhjYmU0NGQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9kZWZsYXRlNjQvRGVmbGF0ZTY0Q29tcHJlc3NvcklucHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwxMjAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLmRlZmxhdGU2NDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5Db21wcmVzc29ySW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLklucHV0U3RyZWFtU3RhdGlzdGljczsKKworaW1wb3J0IHN0YXRpYyBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuSU9VdGlscy5jbG9zZVF1aWV0bHk7CisKKy8qKgorICogRGVmbGF0ZTY0IGRlY29tcHJlc3Nvci4KKyAqCisgKiBAc2luY2UgMS4xNgorICogQE5vdFRocmVhZFNhZmUKKyAqLworcHVibGljIGNsYXNzIERlZmxhdGU2NENvbXByZXNzb3JJbnB1dFN0cmVhbSBleHRlbmRzIENvbXByZXNzb3JJbnB1dFN0cmVhbSBpbXBsZW1lbnRzIElucHV0U3RyZWFtU3RhdGlzdGljcyB7CisgICAgcHJpdmF0ZSBJbnB1dFN0cmVhbSBvcmlnaW5hbFN0cmVhbTsKKyAgICBwcml2YXRlIEh1ZmZtYW5EZWNvZGVyIGRlY29kZXI7CisgICAgcHJpdmF0ZSBsb25nIGNvbXByZXNzZWRCeXRlc1JlYWQ7CisgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10gb25lQnl0ZSA9IG5ldyBieXRlWzFdOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIERlZmxhdGU2NENvbXByZXNzb3JJbnB1dFN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbiB0aGUgc3RyZWFtIHRvIHJlYWQgZnJvbQorICAgICAqLworICAgIHB1YmxpYyBEZWZsYXRlNjRDb21wcmVzc29ySW5wdXRTdHJlYW0oSW5wdXRTdHJlYW0gaW4pIHsKKyAgICAgICAgdGhpcyhuZXcgSHVmZm1hbkRlY29kZXIoaW4pKTsKKyAgICAgICAgb3JpZ2luYWxTdHJlYW0gPSBpbjsKKyAgICB9CisKKyAgICBEZWZsYXRlNjRDb21wcmVzc29ySW5wdXRTdHJlYW0oSHVmZm1hbkRlY29kZXIgZGVjb2RlcikgeworICAgICAgICB0aGlzLmRlY29kZXIgPSBkZWNvZGVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgamF2YS5pby5FT0ZFeGNlcHRpb24gaWYgdGhlIHVuZGVybHlpbmcgc3RyZWFtIGlzIGV4aGF1c3RlZCBiZWZvcmUgdGhlIGVuZCBvZiBkZWZhbHRlZCBkYXRhIHdhcyByZWFjaGVkLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICBpbnQgciA9IHJlYWQob25lQnl0ZSk7CisgICAgICAgICAgICBzd2l0Y2ggKHIpIHsKKyAgICAgICAgICAgICAgICBjYXNlIDE6CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBvbmVCeXRlWzBdICYgMHhGRjsKKyAgICAgICAgICAgICAgICBjYXNlIC0xOgorICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICAgICAgY2FzZSAwOgorICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJJbnZhbGlkIHJldHVybiB2YWx1ZSBmcm9tIHJlYWQ6ICIgKyByKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgamF2YS5pby5FT0ZFeGNlcHRpb24gaWYgdGhlIHVuZGVybHlpbmcgc3RyZWFtIGlzIGV4aGF1c3RlZCBiZWZvcmUgdGhlIGVuZCBvZiBkZWZhbHRlZCBkYXRhIHdhcyByZWFjaGVkLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZChieXRlW10gYiwgaW50IG9mZiwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IHJlYWQgPSAtMTsKKyAgICAgICAgaWYgKGRlY29kZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgcmVhZCA9IGRlY29kZXIuZGVjb2RlKGIsIG9mZiwgbGVuKTsKKyAgICAgICAgICAgIGNvbXByZXNzZWRCeXRlc1JlYWQgPSBkZWNvZGVyLmdldEJ5dGVzUmVhZCgpOworICAgICAgICAgICAgY291bnQocmVhZCk7CisgICAgICAgICAgICBpZiAocmVhZCA9PSAtMSkgeworICAgICAgICAgICAgICAgIGNsb3NlRGVjb2RlcigpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiByZWFkOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgYXZhaWxhYmxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGRlY29kZXIgIT0gbnVsbCA/IGRlY29kZXIuYXZhaWxhYmxlKCkgOiAwOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNsb3NlRGVjb2RlcigpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKG9yaWdpbmFsU3RyZWFtICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBvcmlnaW5hbFN0cmVhbS5jbG9zZSgpOworICAgICAgICAgICAgICAgIG9yaWdpbmFsU3RyZWFtID0gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEBzaW5jZSAxLjE3CisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGxvbmcgZ2V0Q29tcHJlc3NlZENvdW50KCkgeworICAgICAgICByZXR1cm4gY29tcHJlc3NlZEJ5dGVzUmVhZDsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY2xvc2VEZWNvZGVyKCkgeworICAgICAgICBjbG9zZVF1aWV0bHkoZGVjb2Rlcik7CisgICAgICAgIGRlY29kZXIgPSBudWxsOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2RlZmxhdGU2NC9IdWZmbWFuRGVjb2Rlci5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvZGVmbGF0ZTY0L0h1ZmZtYW5EZWNvZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTZhZmEyYwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2RlZmxhdGU2NC9IdWZmbWFuRGVjb2Rlci5qYXZhCkBAIC0wLDAgKzEsNTQxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5kZWZsYXRlNjQ7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuQml0SW5wdXRTdHJlYW07CisKK2ltcG9ydCBqYXZhLmlvLkNsb3NlYWJsZTsKK2ltcG9ydCBqYXZhLmlvLkVPRkV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5uaW8uQnl0ZU9yZGVyOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CisKK2ltcG9ydCBzdGF0aWMgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLmRlZmxhdGU2NC5IdWZmbWFuU3RhdGUuKjsKKworY2xhc3MgSHVmZm1hbkRlY29kZXIgaW1wbGVtZW50cyBDbG9zZWFibGUgeworICAgIAorICAgIC8qKgorICAgICAqIDxwcmU+CisgICAgICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgICAgKiBpZHggIHh0cmEgIGJhc2UgICAgIGlkeCAgeHRyYSAgYmFzZSAgICAgaWR4ICB4dHJhICBiYXNlCisgICAgICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgICAgKiAyNTcgICAwICAgICAzICAgICAgIDI2NyAgIDEgICAxNSwxNiAgICAgMjc3ICAgNCAgIDY3LTgyCisgICAgICogMjU4ICAgMCAgICAgNCAgICAgICAyNjggICAxICAgMTcsMTggICAgIDI3OCAgIDQgICA4My05OAorICAgICAqIDI1OSAgIDAgICAgIDUgICAgICAgMjY5ICAgMiAgIDE5LTIyICAgICAyNzkgICA0ICAgOTktMTE0CisgICAgICogMjYwICAgMCAgICAgNiAgICAgICAyNzAgICAyICAgMjMtMjYgICAgIDI4MCAgIDQgICAxMTUtMTMwCisgICAgICogMjYxICAgMCAgICAgNyAgICAgICAyNzEgICAyICAgMjctMzAgICAgIDI4MSAgIDUgICAxMzEtMTYyCisgICAgICogMjYyICAgMCAgICAgOCAgICAgICAyNzIgICAyICAgMzEtMzQgICAgIDI4MiAgIDUgICAxNjMtMTk0CisgICAgICogMjYzICAgMCAgICAgOSAgICAgICAyNzMgICAzICAgMzUtNDIgICAgIDI4MyAgIDUgICAxOTUtMjI2CisgICAgICogMjY0ICAgMCAgICAgMTAgICAgICAyNzQgICAzICAgNDMtNTAgICAgIDI4NCAgIDUgICAyMjctMjU3CisgICAgICogMjY1ICAgMSAgICAgMTEsMTIgICAyNzUgICAzICAgNTEtNTggICAgIDI4NSAgIDE2ICAzCisgICAgICogMjY2ICAgMSAgICAgMTMsMTQgICAyNzYgICAzICAgNTktNjYKKyAgICAgKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAgICAqIDwvcHJlPgorICAgICAqIHZhbHVlID0gKGJhc2Ugb2YgcnVuIGxlbmd0aCkgPDwgNSB8IChudW1iZXIgb2YgZXh0cmEgYml0cyB0byByZWFkKQorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHNob3J0W10gUlVOX0xFTkdUSF9UQUJMRSA9IHsKKyAgICAgICAgICAgIDk2LCAxMjgsIDE2MCwgMTkyLCAyMjQsIDI1NiwgMjg4LCAzMjAsIDM1MywgNDE3LCA0ODEsIDU0NSwgNjEwLCA3MzgsIDg2NiwKKyAgICAgICAgICAgIDk5NCwgMTEyMywgMTM3OSwgMTYzNSwgMTg5MSwgMjE0OCwgMjY2MCwgMzE3MiwgMzY4NCwgNDE5NywgNTIyMSwgNjI0NSwgNzI2OSwgMTEyCisgICAgfTsKKworICAgIC8qKgorICAgICAqIDxwcmU+CisgICAgICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgICAgKiBpZHggIHh0cmEgIGRpc3QgICAgIGlkeCAgeHRyYSAgZGlzdCAgICAgICBpZHggIHh0cmEgIGRpc3QKKyAgICAgKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAgICAqIDAgICAgMCAgICAgMSAgICAgICAgMTAgICA0ICAgICAzMy00OCAgICAgIDIwICAgIDkgICAxMDI1LTE1MzYKKyAgICAgKiAxICAgIDAgICAgIDIgICAgICAgIDExICAgNCAgICAgNDktNjQgICAgICAyMSAgICA5ICAgMTUzNy0yMDQ4CisgICAgICogMiAgICAwICAgICAzICAgICAgICAxMiAgIDUgICAgIDY1LTk2ICAgICAgMjIgICAxMCAgIDIwNDktMzA3MgorICAgICAqIDMgICAgMCAgICAgNCAgICAgICAgMTMgICA1ICAgICA5Ny0xMjggICAgIDIzICAgMTAgICAzMDczLTQwOTYKKyAgICAgKiA0ICAgIDEgICAgIDUsNiAgICAgIDE0ICAgNiAgICAgMTI5LTE5MiAgICAyNCAgIDExICAgNDA5Ny02MTQ0CisgICAgICogNSAgICAxICAgICA3LDggICAgICAxNSAgIDYgICAgIDE5My0yNTYgICAgMjUgICAxMSAgIDYxNDUtODE5MgorICAgICAqIDYgICAgMiAgICAgOS0xMiAgICAgMTYgICA3ICAgICAyNTctMzg0ICAgIDI2ICAgMTIgICA4MTkzLTEyMjg4CisgICAgICogNyAgICAyICAgICAxMy0xNiAgICAxNyAgIDcgICAgIDM4NS01MTIgICAgMjcgICAxMiAgIDEyMjg5LTE2Mzg0CisgICAgICogOCAgICAzICAgICAxNy0yNCAgICAxOCAgIDggICAgIDUxMy03NjggICAgMjggICAxMyAgIDE2Mzg1LTI0NTc2CisgICAgICogOSAgICAzICAgICAyNS0zMiAgICAxOSAgIDggICAgIDc2OS0xMDI0ICAgMjkgICAxMyAgIDI0NTc3LTMyNzY4CisgICAgICogMzAgICAxNCAgIDMyNzY5LTQ5MTUyCisgICAgICogMzEgICAxNCAgIDQ5MTUzLTY1NTM2CisgICAgICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgICAgKiA8L3ByZT4KKyAgICAgKiB2YWx1ZSA9IChiYXNlIG9mIGRpc3RhbmNlKSA8PCA0IHwgKG51bWJlciBvZiBleHRyYSBiaXRzIHRvIHJlYWQpCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50W10gRElTVEFOQ0VfVEFCTEUgPSB7CisgICAgICAgICAgICAxNiwgMzIsIDQ4LCA2NCwgODEsIDExMywgMTQ2LCAyMTAsIDI3NSwgNDAzLCAgLy8gMC05CisgICAgICAgICAgICA1MzIsIDc4OCwgMTA0NSwgMTU1NywgMjA3MCwgMzA5NCwgNDExOSwgNjE2NywgODIxNiwgMTIzMTIsIC8vIDEwLTE5CisgICAgICAgICAgICAxNjQwOSwgMjQ2MDEsIDMyNzk0LCA0OTE3OCwgNjU1NjMsIDk4MzMxLCAxMzExMDAsIDE5NjYzNiwgMjYyMTczLCAzOTMyNDUsIC8vIDIwLTI5CisgICAgICAgICAgICA1MjQzMTgsIDc4NjQ2MiAvLyAzMC0zMQorICAgIH07CisKKyAgICAvKioKKyAgICAgKiBXaGVuIHVzaW5nIGR5bmFtaWMgaHVmZm1hbiBjb2RlcyB0aGUgb3JkZXIgaW4gd2hpY2ggdGhlIHZhbHVlcyBhcmUgc3RvcmVkCisgICAgICogZm9sbG93cyB0aGUgcG9zaXRpb25pbmcgYmVsb3cKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnRbXSBDT0RFX0xFTkdUSFNfT1JERVIgPQorICAgICAgICAgICAgezE2LCAxNywgMTgsIDAsIDgsIDcsIDksIDYsIDEwLCA1LCAxMSwgNCwgMTIsIDMsIDEzLCAyLCAxNCwgMSwgMTV9OworCisgICAgLyoqCisgICAgICogSHVmZm1hbiBGaXhlZCBMaXRlcmFsIC8gRGlzdGFuY2UgdGFibGVzIGZvciBtb2RlIDEKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnRbXSBGSVhFRF9MSVRFUkFMUzsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnRbXSBGSVhFRF9ESVNUQU5DRTsKKworICAgIHN0YXRpYyB7CisgICAgICAgIEZJWEVEX0xJVEVSQUxTID0gbmV3IGludFsyODhdOworICAgICAgICBBcnJheXMuZmlsbChGSVhFRF9MSVRFUkFMUywgMCwgMTQ0LCA4KTsKKyAgICAgICAgQXJyYXlzLmZpbGwoRklYRURfTElURVJBTFMsIDE0NCwgMjU2LCA5KTsKKyAgICAgICAgQXJyYXlzLmZpbGwoRklYRURfTElURVJBTFMsIDI1NiwgMjgwLCA3KTsKKyAgICAgICAgQXJyYXlzLmZpbGwoRklYRURfTElURVJBTFMsIDI4MCwgMjg4LCA4KTsKKworICAgICAgICBGSVhFRF9ESVNUQU5DRSA9IG5ldyBpbnRbMzJdOworICAgICAgICBBcnJheXMuZmlsbChGSVhFRF9ESVNUQU5DRSwgNSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBib29sZWFuIGZpbmFsQmxvY2sgPSBmYWxzZTsKKyAgICBwcml2YXRlIERlY29kZXJTdGF0ZSBzdGF0ZTsKKyAgICBwcml2YXRlIEJpdElucHV0U3RyZWFtIHJlYWRlcjsKKyAgICBwcml2YXRlIGZpbmFsIElucHV0U3RyZWFtIGluOworCisgICAgcHJpdmF0ZSBmaW5hbCBEZWNvZGluZ01lbW9yeSBtZW1vcnkgPSBuZXcgRGVjb2RpbmdNZW1vcnkoKTsKKworICAgIEh1ZmZtYW5EZWNvZGVyKElucHV0U3RyZWFtIGluKSB7CisgICAgICAgIHRoaXMucmVhZGVyID0gbmV3IEJpdElucHV0U3RyZWFtKGluLCBCeXRlT3JkZXIuTElUVExFX0VORElBTik7CisgICAgICAgIHRoaXMuaW4gPSBpbjsKKyAgICAgICAgc3RhdGUgPSBuZXcgSW5pdGlhbFN0YXRlKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB7CisgICAgICAgIHN0YXRlID0gbmV3IEluaXRpYWxTdGF0ZSgpOworICAgICAgICByZWFkZXIgPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZGVjb2RlKGJ5dGVbXSBiKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gZGVjb2RlKGIsIDAsIGIubGVuZ3RoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGRlY29kZShieXRlW10gYiwgaW50IG9mZiwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgd2hpbGUgKCFmaW5hbEJsb2NrIHx8IHN0YXRlLmhhc0RhdGEoKSkgeworICAgICAgICAgICAgaWYgKHN0YXRlLnN0YXRlKCkgPT0gSU5JVElBTCkgeworICAgICAgICAgICAgICAgIGZpbmFsQmxvY2sgPSByZWFkQml0cygxKSA9PSAxOworICAgICAgICAgICAgICAgIGludCBtb2RlID0gKGludCkgcmVhZEJpdHMoMik7CisgICAgICAgICAgICAgICAgc3dpdGNoIChtb2RlKSB7CisgICAgICAgICAgICAgICAgY2FzZSAwOgorICAgICAgICAgICAgICAgICAgICBzd2l0Y2hUb1VuY29tcHJlc3NlZFN0YXRlKCk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgMToKKyAgICAgICAgICAgICAgICAgICAgc3RhdGUgPSBuZXcgSHVmZm1hbkNvZGVzKEZJWEVEX0NPREVTLCBGSVhFRF9MSVRFUkFMUywgRklYRURfRElTVEFOQ0UpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlIDI6CisgICAgICAgICAgICAgICAgICAgIGludFtdW10gdGFibGVzID0gcmVhZER5bmFtaWNUYWJsZXMoKTsKKyAgICAgICAgICAgICAgICAgICAgc3RhdGUgPSBuZXcgSHVmZm1hbkNvZGVzKERZTkFNSUNfQ09ERVMsIHRhYmxlc1swXSwgdGFibGVzWzFdKTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiVW5zdXBwb3J0ZWQgY29tcHJlc3Npb246ICIgKyBtb2RlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHJldHVybiBzdGF0ZS5yZWFkKGIsIG9mZiwgbGVuKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNpbmNlIDEuMTcKKyAgICAgKi8KKyAgICBsb25nIGdldEJ5dGVzUmVhZCgpIHsKKyAgICAgICAgcmV0dXJuIHJlYWRlci5nZXRCeXRlc1JlYWQoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgc3dpdGNoVG9VbmNvbXByZXNzZWRTdGF0ZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJlYWRlci5hbGlnbldpdGhCeXRlQm91bmRhcnkoKTsKKyAgICAgICAgbG9uZyBiTGVuID0gcmVhZEJpdHMoMTYpOworICAgICAgICBsb25nIGJOTGVuID0gcmVhZEJpdHMoMTYpOworICAgICAgICBpZiAoKChiTGVuIF4gMHhGRkZGKSAmIDB4RkZGRikgIT0gYk5MZW4pIHsKKyAgICAgICAgICAgIC8vbm9pbnNwZWN0aW9uIER1cGxpY2F0ZVN0cmluZ0xpdGVyYWxJbnNwZWN0aW9uCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJJbGxlZ2FsIExFTiAvIE5MRU4gdmFsdWVzIik7CisgICAgICAgIH0KKyAgICAgICAgc3RhdGUgPSBuZXcgVW5jb21wcmVzc2VkU3RhdGUoYkxlbik7CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnRbXVtdIHJlYWREeW5hbWljVGFibGVzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50W11bXSByZXN1bHQgPSBuZXcgaW50WzJdW107CisgICAgICAgIGludCBsaXRlcmFscyA9IChpbnQpIChyZWFkQml0cyg1KSArIDI1Nyk7CisgICAgICAgIHJlc3VsdFswXSA9IG5ldyBpbnRbbGl0ZXJhbHNdOworCisgICAgICAgIGludCBkaXN0YW5jZXMgPSAoaW50KSAocmVhZEJpdHMoNSkgKyAxKTsKKyAgICAgICAgcmVzdWx0WzFdID0gbmV3IGludFtkaXN0YW5jZXNdOworCisgICAgICAgIHBvcHVsYXRlRHluYW1pY1RhYmxlcyhyZWFkZXIsIHJlc3VsdFswXSwgcmVzdWx0WzFdKTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBpbnQgYXZhaWxhYmxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHN0YXRlLmF2YWlsYWJsZSgpOworICAgIH0KKworICAgIHByaXZhdGUgYWJzdHJhY3Qgc3RhdGljIGNsYXNzIERlY29kZXJTdGF0ZSB7CisgICAgICAgIGFic3RyYWN0IEh1ZmZtYW5TdGF0ZSBzdGF0ZSgpOworCisgICAgICAgIGFic3RyYWN0IGludCByZWFkKGJ5dGVbXSBiLCBpbnQgb2ZmLCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAgICAgYWJzdHJhY3QgYm9vbGVhbiBoYXNEYXRhKCk7CisKKyAgICAgICAgYWJzdHJhY3QgaW50IGF2YWlsYWJsZSgpIHRocm93cyBJT0V4Y2VwdGlvbiA7CisgICAgfQorCisgICAgcHJpdmF0ZSBjbGFzcyBVbmNvbXByZXNzZWRTdGF0ZSBleHRlbmRzIERlY29kZXJTdGF0ZSB7CisgICAgICAgIHByaXZhdGUgZmluYWwgbG9uZyBibG9ja0xlbmd0aDsKKyAgICAgICAgcHJpdmF0ZSBsb25nIHJlYWQ7CisKKyAgICAgICAgcHJpdmF0ZSBVbmNvbXByZXNzZWRTdGF0ZShsb25nIGJsb2NrTGVuZ3RoKSB7CisgICAgICAgICAgICB0aGlzLmJsb2NrTGVuZ3RoID0gYmxvY2tMZW5ndGg7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgSHVmZm1hblN0YXRlIHN0YXRlKCkgeworICAgICAgICAgICAgcmV0dXJuIHJlYWQgPCBibG9ja0xlbmd0aCA/IFNUT1JFRCA6IElOSVRJQUw7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgaW50IHJlYWQoYnl0ZVtdIGIsIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAvLyBhcyBsZW4gaXMgYW4gaW50IGFuZCAoYmxvY2tMZW5ndGggLSByZWFkKSBpcyA+PSAwIHRoZSBtaW4gbXVzdCBmaXQgaW50byBhbiBpbnQgYXMgd2VsbAorICAgICAgICAgICAgaW50IG1heCA9IChpbnQpIE1hdGgubWluKGJsb2NrTGVuZ3RoIC0gcmVhZCwgbGVuKTsKKyAgICAgICAgICAgIGludCByZWFkU29GYXIgPSAwOworICAgICAgICAgICAgd2hpbGUgKHJlYWRTb0ZhciA8IG1heCkgeworICAgICAgICAgICAgICAgIGludCByZWFkTm93OworICAgICAgICAgICAgICAgIGlmIChyZWFkZXIuYml0c0NhY2hlZCgpID4gMCkgeworICAgICAgICAgICAgICAgICAgICBieXRlIG5leHQgPSAoYnl0ZSkgcmVhZEJpdHMoQnl0ZS5TSVpFKTsKKyAgICAgICAgICAgICAgICAgICAgYltvZmYgKyByZWFkU29GYXJdID0gbWVtb3J5LmFkZChuZXh0KTsKKyAgICAgICAgICAgICAgICAgICAgcmVhZE5vdyA9IDE7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgcmVhZE5vdyA9IGluLnJlYWQoYiwgb2ZmICsgcmVhZFNvRmFyLCBtYXggLSByZWFkU29GYXIpOworICAgICAgICAgICAgICAgICAgICBpZiAocmVhZE5vdyA9PSAtMSkgeworICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVPRkV4Y2VwdGlvbigiVHJ1bmNhdGVkIERlZmxhdGU2NCBTdHJlYW0iKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBtZW1vcnkuYWRkKGIsIG9mZiArIHJlYWRTb0ZhciwgcmVhZE5vdyk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJlYWQgKz0gcmVhZE5vdzsKKyAgICAgICAgICAgICAgICByZWFkU29GYXIgKz0gcmVhZE5vdzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBtYXg7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgYm9vbGVhbiBoYXNEYXRhKCkgeworICAgICAgICAgICAgcmV0dXJuIHJlYWQgPCBibG9ja0xlbmd0aDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBpbnQgYXZhaWxhYmxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiAoaW50KSBNYXRoLm1pbihibG9ja0xlbmd0aCAtIHJlYWQsIHJlYWRlci5iaXRzQXZhaWxhYmxlKCkgLyBCeXRlLlNJWkUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBjbGFzcyBJbml0aWFsU3RhdGUgZXh0ZW5kcyBEZWNvZGVyU3RhdGUgeworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgSHVmZm1hblN0YXRlIHN0YXRlKCkgeworICAgICAgICAgICAgcmV0dXJuIElOSVRJQUw7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgaW50IHJlYWQoYnl0ZVtdIGIsIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJDYW5ub3QgcmVhZCBpbiB0aGlzIHN0YXRlIik7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgYm9vbGVhbiBoYXNEYXRhKCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIGludCBhdmFpbGFibGUoKSB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgY2xhc3MgSHVmZm1hbkNvZGVzIGV4dGVuZHMgRGVjb2RlclN0YXRlIHsKKyAgICAgICAgcHJpdmF0ZSBib29sZWFuIGVuZE9mQmxvY2sgPSBmYWxzZTsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBIdWZmbWFuU3RhdGUgc3RhdGU7CisgICAgICAgIHByaXZhdGUgZmluYWwgQmluYXJ5VHJlZU5vZGUgbGVuZ3RoVHJlZTsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBCaW5hcnlUcmVlTm9kZSBkaXN0YW5jZVRyZWU7CisKKyAgICAgICAgcHJpdmF0ZSBpbnQgcnVuQnVmZmVyUG9zID0gMDsKKyAgICAgICAgcHJpdmF0ZSBieXRlW10gcnVuQnVmZmVyID0gbmV3IGJ5dGVbMF07CisgICAgICAgIHByaXZhdGUgaW50IHJ1bkJ1ZmZlckxlbmd0aCA9IDA7CisKKyAgICAgICAgSHVmZm1hbkNvZGVzKEh1ZmZtYW5TdGF0ZSBzdGF0ZSwgaW50W10gbGVuZ3RocywgaW50W10gZGlzdGFuY2UpIHsKKyAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBzdGF0ZTsKKyAgICAgICAgICAgIGxlbmd0aFRyZWUgPSBidWlsZFRyZWUobGVuZ3Rocyk7CisgICAgICAgICAgICBkaXN0YW5jZVRyZWUgPSBidWlsZFRyZWUoZGlzdGFuY2UpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIEh1ZmZtYW5TdGF0ZSBzdGF0ZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBlbmRPZkJsb2NrID8gSU5JVElBTCA6IHN0YXRlOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIGludCByZWFkKGJ5dGVbXSBiLCBpbnQgb2ZmLCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIGRlY29kZU5leHQoYiwgb2ZmLCBsZW4pOworICAgICAgICB9CisKKyAgICAgICAgcHJpdmF0ZSBpbnQgZGVjb2RlTmV4dChieXRlW10gYiwgaW50IG9mZiwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGlmIChlbmRPZkJsb2NrKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaW50IHJlc3VsdCA9IGNvcHlGcm9tUnVuQnVmZmVyKGIsIG9mZiwgbGVuKTsKKworICAgICAgICAgICAgd2hpbGUgKHJlc3VsdCA8IGxlbikgeworICAgICAgICAgICAgICAgIGludCBzeW1ib2wgPSBuZXh0U3ltYm9sKHJlYWRlciwgbGVuZ3RoVHJlZSk7CisgICAgICAgICAgICAgICAgaWYgKHN5bWJvbCA8IDI1NikgeworICAgICAgICAgICAgICAgICAgICBiW29mZiArIHJlc3VsdCsrXSA9IG1lbW9yeS5hZGQoKGJ5dGUpIHN5bWJvbCk7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzeW1ib2wgPiAyNTYpIHsKKyAgICAgICAgICAgICAgICAgICAgaW50IHJ1bk1hc2sgPSBSVU5fTEVOR1RIX1RBQkxFW3N5bWJvbCAtIDI1N107CisgICAgICAgICAgICAgICAgICAgIGludCBydW4gPSBydW5NYXNrID4+PiA1OworICAgICAgICAgICAgICAgICAgICBpbnQgcnVuWHRyYSA9IHJ1bk1hc2sgJiAweDFGOworICAgICAgICAgICAgICAgICAgICBydW4gKz0gcmVhZEJpdHMocnVuWHRyYSk7CisKKyAgICAgICAgICAgICAgICAgICAgaW50IGRpc3RTeW0gPSBuZXh0U3ltYm9sKHJlYWRlciwgZGlzdGFuY2VUcmVlKTsKKworICAgICAgICAgICAgICAgICAgICBpbnQgZGlzdE1hc2sgPSBESVNUQU5DRV9UQUJMRVtkaXN0U3ltXTsKKyAgICAgICAgICAgICAgICAgICAgaW50IGRpc3QgPSBkaXN0TWFzayA+Pj4gNDsKKyAgICAgICAgICAgICAgICAgICAgaW50IGRpc3RYdHJhID0gZGlzdE1hc2sgJiAweEY7CisgICAgICAgICAgICAgICAgICAgIGRpc3QgKz0gcmVhZEJpdHMoZGlzdFh0cmEpOworCisgICAgICAgICAgICAgICAgICAgIGlmIChydW5CdWZmZXIubGVuZ3RoIDwgcnVuKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBydW5CdWZmZXIgPSBuZXcgYnl0ZVtydW5dOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHJ1bkJ1ZmZlckxlbmd0aCA9IHJ1bjsKKyAgICAgICAgICAgICAgICAgICAgcnVuQnVmZmVyUG9zID0gMDsKKyAgICAgICAgICAgICAgICAgICAgbWVtb3J5LnJlY29yZFRvQnVmZmVyKGRpc3QsIHJ1biwgcnVuQnVmZmVyKTsKKworICAgICAgICAgICAgICAgICAgICByZXN1bHQgKz0gY29weUZyb21SdW5CdWZmZXIoYiwgb2ZmICsgcmVzdWx0LCBsZW4gLSByZXN1bHQpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGVuZE9mQmxvY2sgPSB0cnVlOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgaW50IGNvcHlGcm9tUnVuQnVmZmVyKGJ5dGVbXSBiLCBpbnQgb2ZmLCBpbnQgbGVuKSB7CisgICAgICAgICAgICBpbnQgYnl0ZXNJbkJ1ZmZlciA9IHJ1bkJ1ZmZlckxlbmd0aCAtIHJ1bkJ1ZmZlclBvczsKKyAgICAgICAgICAgIGludCBjb3BpZWRCeXRlcyA9IDA7CisgICAgICAgICAgICBpZiAoYnl0ZXNJbkJ1ZmZlciA+IDApIHsKKyAgICAgICAgICAgICAgICBjb3BpZWRCeXRlcyA9IE1hdGgubWluKGxlbiwgYnl0ZXNJbkJ1ZmZlcik7CisgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShydW5CdWZmZXIsIHJ1bkJ1ZmZlclBvcywgYiwgb2ZmLCBjb3BpZWRCeXRlcyk7CisgICAgICAgICAgICAgICAgcnVuQnVmZmVyUG9zICs9IGNvcGllZEJ5dGVzOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGNvcGllZEJ5dGVzOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIGJvb2xlYW4gaGFzRGF0YSgpIHsKKyAgICAgICAgICAgIHJldHVybiAhZW5kT2ZCbG9jazsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBpbnQgYXZhaWxhYmxlKCkgeworICAgICAgICAgICAgcmV0dXJuIHJ1bkJ1ZmZlckxlbmd0aCAtIHJ1bkJ1ZmZlclBvczsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGludCBuZXh0U3ltYm9sKEJpdElucHV0U3RyZWFtIHJlYWRlciwgQmluYXJ5VHJlZU5vZGUgdHJlZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgQmluYXJ5VHJlZU5vZGUgbm9kZSA9IHRyZWU7CisgICAgICAgIHdoaWxlIChub2RlICE9IG51bGwgJiYgbm9kZS5saXRlcmFsID09IC0xKSB7CisgICAgICAgICAgICBsb25nIGJpdCA9IHJlYWRCaXRzKHJlYWRlciwgMSk7CisgICAgICAgICAgICBub2RlID0gYml0ID09IDAgPyBub2RlLmxlZnROb2RlIDogbm9kZS5yaWdodE5vZGU7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5vZGUgIT0gbnVsbCA/IG5vZGUubGl0ZXJhbCA6IC0xOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgcG9wdWxhdGVEeW5hbWljVGFibGVzKEJpdElucHV0U3RyZWFtIHJlYWRlciwgaW50W10gbGl0ZXJhbHMsIGludFtdIGRpc3RhbmNlcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IGNvZGVMZW5ndGhzID0gKGludCkgKHJlYWRCaXRzKHJlYWRlciwgNCkgKyA0KTsKKworICAgICAgICBpbnRbXSBjb2RlTGVuZ3RoVmFsdWVzID0gbmV3IGludFsxOV07CisgICAgICAgIGZvciAoaW50IGNMZW4gPSAwOyBjTGVuIDwgY29kZUxlbmd0aHM7IGNMZW4rKykgeworICAgICAgICAgICAgY29kZUxlbmd0aFZhbHVlc1tDT0RFX0xFTkdUSFNfT1JERVJbY0xlbl1dID0gKGludCkgcmVhZEJpdHMocmVhZGVyLCAzKTsKKyAgICAgICAgfQorCisgICAgICAgIEJpbmFyeVRyZWVOb2RlIGNvZGVMZW5ndGhUcmVlID0gYnVpbGRUcmVlKGNvZGVMZW5ndGhWYWx1ZXMpOworCisgICAgICAgIGZpbmFsIGludFtdIGF1eEJ1ZmZlciA9IG5ldyBpbnRbbGl0ZXJhbHMubGVuZ3RoICsgZGlzdGFuY2VzLmxlbmd0aF07CisKKyAgICAgICAgaW50IHZhbHVlID0gLTE7CisgICAgICAgIGludCBsZW5ndGggPSAwOworICAgICAgICBpbnQgb2ZmID0gMDsKKyAgICAgICAgd2hpbGUgKG9mZiA8IGF1eEJ1ZmZlci5sZW5ndGgpIHsKKyAgICAgICAgICAgIGlmIChsZW5ndGggPiAwKSB7CisgICAgICAgICAgICAgICAgYXV4QnVmZmVyW29mZisrXSA9IHZhbHVlOworICAgICAgICAgICAgICAgIGxlbmd0aC0tOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBpbnQgc3ltYm9sID0gbmV4dFN5bWJvbChyZWFkZXIsIGNvZGVMZW5ndGhUcmVlKTsKKyAgICAgICAgICAgICAgICBpZiAoc3ltYm9sIDwgMTYpIHsKKyAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBzeW1ib2w7CisgICAgICAgICAgICAgICAgICAgIGF1eEJ1ZmZlcltvZmYrK10gPSB2YWx1ZTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHN5bWJvbCA9PSAxNikgeworICAgICAgICAgICAgICAgICAgICBsZW5ndGggPSAoaW50KSAocmVhZEJpdHMocmVhZGVyLCAyKSArIDMpOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc3ltYm9sID09IDE3KSB7CisgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gMDsKKyAgICAgICAgICAgICAgICAgICAgbGVuZ3RoID0gKGludCkgKHJlYWRCaXRzKHJlYWRlciwgMykgKyAzKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHN5bWJvbCA9PSAxOCkgeworICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IDA7CisgICAgICAgICAgICAgICAgICAgIGxlbmd0aCA9IChpbnQpIChyZWFkQml0cyhyZWFkZXIsIDcpICsgMTEpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYXV4QnVmZmVyLCAwLCBsaXRlcmFscywgMCwgbGl0ZXJhbHMubGVuZ3RoKTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShhdXhCdWZmZXIsIGxpdGVyYWxzLmxlbmd0aCwgZGlzdGFuY2VzLCAwLCBkaXN0YW5jZXMubGVuZ3RoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBCaW5hcnlUcmVlTm9kZSB7CisgICAgICAgIHByaXZhdGUgZmluYWwgaW50IGJpdHM7CisgICAgICAgIGludCBsaXRlcmFsID0gLTE7CisgICAgICAgIEJpbmFyeVRyZWVOb2RlIGxlZnROb2RlOworICAgICAgICBCaW5hcnlUcmVlTm9kZSByaWdodE5vZGU7CisKKyAgICAgICAgcHJpdmF0ZSBCaW5hcnlUcmVlTm9kZShpbnQgYml0cykgeworICAgICAgICAgICAgdGhpcy5iaXRzID0gYml0czsKKyAgICAgICAgfQorCisgICAgICAgIHZvaWQgbGVhZihpbnQgc3ltYm9sKSB7CisgICAgICAgICAgICBsaXRlcmFsID0gc3ltYm9sOworICAgICAgICAgICAgbGVmdE5vZGUgPSBudWxsOworICAgICAgICAgICAgcmlnaHROb2RlID0gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIEJpbmFyeVRyZWVOb2RlIGxlZnQoKSB7CisgICAgICAgICAgICBpZiAobGVmdE5vZGUgPT0gbnVsbCAmJiBsaXRlcmFsID09IC0xKSB7CisgICAgICAgICAgICAgICAgbGVmdE5vZGUgPSBuZXcgQmluYXJ5VHJlZU5vZGUoYml0cyArIDEpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGxlZnROb2RlOworICAgICAgICB9CisKKyAgICAgICAgQmluYXJ5VHJlZU5vZGUgcmlnaHQoKSB7CisgICAgICAgICAgICBpZiAocmlnaHROb2RlID09IG51bGwgJiYgbGl0ZXJhbCA9PSAtMSkgeworICAgICAgICAgICAgICAgIHJpZ2h0Tm9kZSA9IG5ldyBCaW5hcnlUcmVlTm9kZShiaXRzICsgMSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gcmlnaHROb2RlOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgQmluYXJ5VHJlZU5vZGUgYnVpbGRUcmVlKGludFtdIGxpdFRhYmxlKSB7CisgICAgICAgIGludFtdIGxpdGVyYWxDb2RlcyA9IGdldENvZGVzKGxpdFRhYmxlKTsKKworICAgICAgICBCaW5hcnlUcmVlTm9kZSByb290ID0gbmV3IEJpbmFyeVRyZWVOb2RlKDApOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGl0VGFibGUubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGludCBsZW4gPSBsaXRUYWJsZVtpXTsKKyAgICAgICAgICAgIGlmIChsZW4gIT0gMCkgeworICAgICAgICAgICAgICAgIEJpbmFyeVRyZWVOb2RlIG5vZGUgPSByb290OworICAgICAgICAgICAgICAgIGludCBsaXQgPSBsaXRlcmFsQ29kZXNbbGVuIC0gMV07CisgICAgICAgICAgICAgICAgZm9yIChpbnQgcCA9IGxlbiAtIDE7IHAgPj0gMDsgcC0tKSB7CisgICAgICAgICAgICAgICAgICAgIGludCBiaXQgPSBsaXQgJiAoMSA8PCBwKTsKKyAgICAgICAgICAgICAgICAgICAgbm9kZSA9IGJpdCA9PSAwID8gbm9kZS5sZWZ0KCkgOiBub2RlLnJpZ2h0KCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIG5vZGUubGVhZihpKTsKKyAgICAgICAgICAgICAgICBsaXRlcmFsQ29kZXNbbGVuIC0gMV0rKzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcm9vdDsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBpbnRbXSBnZXRDb2RlcyhpbnRbXSBsaXRUYWJsZSkgeworICAgICAgICBpbnQgbWF4ID0gMDsKKyAgICAgICAgaW50W10gYmxDb3VudCA9IG5ldyBpbnRbNjVdOworCisgICAgICAgIGZvciAoaW50IGFMaXRUYWJsZSA6IGxpdFRhYmxlKSB7CisgICAgICAgICAgICBtYXggPSBNYXRoLm1heChtYXgsIGFMaXRUYWJsZSk7CisgICAgICAgICAgICBibENvdW50W2FMaXRUYWJsZV0rKzsKKyAgICAgICAgfQorICAgICAgICBibENvdW50ID0gQXJyYXlzLmNvcHlPZihibENvdW50LCBtYXggKyAxKTsKKworICAgICAgICBpbnQgY29kZSA9IDA7CisgICAgICAgIGludFtdIG5leHRDb2RlID0gbmV3IGludFttYXggKyAxXTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPD0gbWF4OyBpKyspIHsKKyAgICAgICAgICAgIGNvZGUgPSAoY29kZSArIGJsQ291bnRbaV0pIDw8IDE7CisgICAgICAgICAgICBuZXh0Q29kZVtpXSA9IGNvZGU7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gbmV4dENvZGU7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgRGVjb2RpbmdNZW1vcnkgeworICAgICAgICBwcml2YXRlIGZpbmFsIGJ5dGVbXSBtZW1vcnk7CisgICAgICAgIHByaXZhdGUgZmluYWwgaW50IG1hc2s7CisgICAgICAgIHByaXZhdGUgaW50IHdIZWFkOworICAgICAgICBwcml2YXRlIGJvb2xlYW4gd3JhcHBlZEFyb3VuZDsKKworICAgICAgICBwcml2YXRlIERlY29kaW5nTWVtb3J5KCkgeworICAgICAgICAgICAgdGhpcygxNik7CisgICAgICAgIH0KKworICAgICAgICBwcml2YXRlIERlY29kaW5nTWVtb3J5KGludCBiaXRzKSB7CisgICAgICAgICAgICBtZW1vcnkgPSBuZXcgYnl0ZVsxIDw8IGJpdHNdOworICAgICAgICAgICAgbWFzayA9IG1lbW9yeS5sZW5ndGggLSAxOworICAgICAgICB9CisKKyAgICAgICAgYnl0ZSBhZGQoYnl0ZSBiKSB7CisgICAgICAgICAgICBtZW1vcnlbd0hlYWRdID0gYjsKKyAgICAgICAgICAgIHdIZWFkID0gaW5jQ291bnRlcih3SGVhZCk7CisgICAgICAgICAgICByZXR1cm4gYjsKKyAgICAgICAgfQorCisgICAgICAgIHZvaWQgYWRkKGJ5dGVbXSBiLCBpbnQgb2ZmLCBpbnQgbGVuKSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gb2ZmOyBpIDwgb2ZmICsgbGVuOyBpKyspIHsKKyAgICAgICAgICAgICAgICBhZGQoYltpXSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB2b2lkIHJlY29yZFRvQnVmZmVyKGludCBkaXN0YW5jZSwgaW50IGxlbmd0aCwgYnl0ZVtdIGJ1ZmYpIHsKKyAgICAgICAgICAgIGlmIChkaXN0YW5jZSA+IG1lbW9yeS5sZW5ndGgpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJJbGxlZ2FsIGRpc3RhbmNlIHBhcmFtZXRlcjogIiArIGRpc3RhbmNlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGludCBzdGFydCA9ICh3SGVhZCAtIGRpc3RhbmNlKSAmIG1hc2s7CisgICAgICAgICAgICBpZiAoIXdyYXBwZWRBcm91bmQgJiYgc3RhcnQgPj0gd0hlYWQpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJBdHRlbXB0IHRvIHJlYWQgYmV5b25kIG1lbW9yeTogZGlzdD0iICsgZGlzdGFuY2UpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZm9yIChpbnQgaSA9IDAsIHBvcyA9IHN0YXJ0OyBpIDwgbGVuZ3RoOyBpKyssIHBvcyA9IGluY0NvdW50ZXIocG9zKSkgeworICAgICAgICAgICAgICAgIGJ1ZmZbaV0gPSBhZGQobWVtb3J5W3Bvc10pOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHJpdmF0ZSBpbnQgaW5jQ291bnRlcihpbnQgY291bnRlcikgeworICAgICAgICAgICAgZmluYWwgaW50IG5ld0NvdW50ZXIgPSAoY291bnRlciArIDEpICYgbWFzazsKKyAgICAgICAgICAgIGlmICghd3JhcHBlZEFyb3VuZCAmJiBuZXdDb3VudGVyIDwgY291bnRlcikgeworICAgICAgICAgICAgICAgIHdyYXBwZWRBcm91bmQgPSB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIG5ld0NvdW50ZXI7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIGxvbmcgcmVhZEJpdHMoaW50IG51bUJpdHMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiByZWFkQml0cyhyZWFkZXIsIG51bUJpdHMpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGxvbmcgcmVhZEJpdHMoQml0SW5wdXRTdHJlYW0gcmVhZGVyLCBpbnQgbnVtQml0cykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgbG9uZyByID0gcmVhZGVyLnJlYWRCaXRzKG51bUJpdHMpOworICAgICAgICBpZiAociA9PSAtMSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEVPRkV4Y2VwdGlvbigiVHJ1bmNhdGVkIERlZmxhdGU2NCBTdHJlYW0iKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcjsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9kZWZsYXRlNjQvSHVmZm1hblN0YXRlLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9kZWZsYXRlNjQvSHVmZm1hblN0YXRlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjM0YmI3ZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2RlZmxhdGU2NC9IdWZmbWFuU3RhdGUuamF2YQpAQCAtMCwwICsxLDI1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5kZWZsYXRlNjQ7CisKK2VudW0gSHVmZm1hblN0YXRlIHsKKyAgICBJTklUSUFMLAorICAgIFNUT1JFRCwKKyAgICBEWU5BTUlDX0NPREVTLAorICAgIEZJWEVEX0NPREVTCit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9kZWZsYXRlNjQvcGFja2FnZS5odG1sIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvZGVmbGF0ZTY0L3BhY2thZ2UuaHRtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40YTBjZGQwCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvZGVmbGF0ZTY0L3BhY2thZ2UuaHRtbApAQCAtMCwwICsxLDI1IEBACis8aHRtbD4KKzwhLS0KKworICAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAgIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAgIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKworICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorCisgICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKworLS0+CisgIDxib2R5PgorICAgIDxwPlByb3ZpZGVzIGEgc3RyZWFtIHRoYXQgYWxsb3dzIGRlY29tcHJlc3Npbmcgc3RyZWFtcyB1c2luZyB0aGUKKyAgICAgIERFRkxBVEU2NCh0bSkgYWxnb3JpdGhtLiBERUZMQVRFNjQgaXMgYSB0cmFkZW1hcmsgb2YgUEtXQVJFLAorICAgICAgSW5jLjwvcD4KKyAgPC9ib2R5PgorPC9odG1sPgpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvZ3ppcC9HemlwQ29tcHJlc3NvcklucHV0U3RyZWFtLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9nemlwL0d6aXBDb21wcmVzc29ySW5wdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45ZTA1ZjhiCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvZ3ppcC9HemlwQ29tcHJlc3NvcklucHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSw0MDUgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuZ3ppcDsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5FT0ZFeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkRhdGFJbnB1dDsKK2ltcG9ydCBqYXZhLmlvLkRhdGFJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLnppcC5EYXRhRm9ybWF0RXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC56aXAuRGVmbGF0ZXI7CitpbXBvcnQgamF2YS51dGlsLnppcC5JbmZsYXRlcjsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLkNSQzMyOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLkNvbXByZXNzb3JJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuQnl0ZVV0aWxzOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5DaGFyc2V0TmFtZXM7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLkNvdW50aW5nSW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLklPVXRpbHM7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLklucHV0U3RyZWFtU3RhdGlzdGljczsKKworLyoqCisgKiBJbnB1dCBzdHJlYW0gdGhhdCBkZWNvbXByZXNzZXMgLmd6IGZpbGVzLgorICoKKyAqIDxwPlRoaXMgc3VwcG9ydHMgZGVjb21wcmVzc2luZyBjb25jYXRlbmF0ZWQgLmd6IGZpbGVzIHdoaWNoIGlzIGltcG9ydGFudAorICogd2hlbiBkZWNvbXByZXNzaW5nIHN0YW5kYWxvbmUgLmd6IGZpbGVzLjwvcD4KKyAqCisgKiA8cD4KKyAqIHtAbGluayBqYXZhLnV0aWwuemlwLkdaSVBJbnB1dFN0cmVhbX0gZG9lc24ndCBkZWNvbXByZXNzIGNvbmNhdGVuYXRlZCAuZ3oKKyAqIGZpbGVzOiBpdCBzdG9wcyBhZnRlciB0aGUgZmlyc3QgbWVtYmVyIGFuZCBzaWxlbnRseSBpZ25vcmVzIHRoZSByZXN0LgorICogSXQgZG9lc24ndCBsZWF2ZSB0aGUgcmVhZCBwb3NpdGlvbiB0byBwb2ludCB0byB0aGUgYmVnaW5uaW5nIG9mIHRoZSBuZXh0CisgKiBtZW1iZXIsIHdoaWNoIG1ha2VzIGl0IGRpZmZpY3VsdCB3b3JrYXJvdW5kIHRoZSBsYWNrIG9mIGNvbmNhdGVuYXRpb24KKyAqIHN1cHBvcnQuCisgKiA8L3A+CisgKgorICogPHA+CisgKiBJbnN0ZWFkIG9mIHVzaW5nIDxjb2RlPkdaSVBJbnB1dFN0cmVhbTwvY29kZT4sIHRoaXMgY2xhc3MgaGFzIGl0cyBvd24gLmd6CisgKiBjb250YWluZXIgZm9ybWF0IGRlY29kZXIuIFRoZSBhY3R1YWwgZGVjb21wcmVzc2lvbiBpcyBkb25lIHdpdGgKKyAqIHtAbGluayBqYXZhLnV0aWwuemlwLkluZmxhdGVyfS4KKyAqIDwvcD4KKyAqCisgKiA8cD5JZiB5b3UgdXNlIHRoZSBjb25zdHJ1Y3RvciB7QGNvZGUgR3ppcENvbXByZXNzb3JJbnB1dFN0cmVhbShpbil9CisgKiBvciB7QGNvZGUgR3ppcENvbXByZXNzb3JJbnB1dFN0cmVhbShpbiwgZmFsc2UpfSB3aXRoIHNvbWUge0Bjb2RlCisgKiBJbnB1dFN0cmVhbX0ge0Bjb2RlIGlufSB0aGVuIHtAbGluayAjcmVhZH0gd2lsbCByZXR1cm4gLTEgYXMgc29vbgorICogYXMgdGhlIGZpcnN0IGludGVybmFsIG1lbWJlciBoYXMgYmVlbiByZWFkIGNvbXBsZXRlbHkuIFRoZSBzdHJlYW0KKyAqIHtAY29kZSBpbn0gd2lsbCBiZSBwb3NpdGlvbmVkIGF0IHRoZSBzdGFydCBvZiB0aGUgc2Vjb25kIGd6aXAKKyAqIG1lbWJlciBpZiB0aGVyZSBpcyBvbmUuPC9wPgorICoKKyAqIDxwPklmIHlvdSB1c2UgdGhlIGNvbnN0cnVjdG9yIHtAY29kZSBHemlwQ29tcHJlc3NvcklucHV0U3RyZWFtKGluLAorICogdHJ1ZSl9IHdpdGggc29tZSB7QGNvZGUgSW5wdXRTdHJlYW19IHtAY29kZSBpbn0gdGhlbiB7QGxpbmsgI3JlYWR9CisgKiB3aWxsIHJldHVybiAtMSBvbmNlIHRoZSBzdHJlYW0ge0Bjb2RlIGlufSBoYXMgYmVlbiBleGhhdXN0ZWQuIFRoZQorICogZGF0YSByZWFkIGZyb20gYSBzdHJlYW0gY29uc3RydWN0ZWQgdGhpcyB3YXkgd2lsbCBjb25zaXN0IG9mIHRoZQorICogY29uY2F0ZW5hdGVkIGRhdGEgb2YgYWxsIGd6aXAgbWVtYmVycyBjb250YWluZWQgaW5zaWRlIHtAY29kZQorICogaW59LjwvcD4KKyAqCisgKiBAc2VlICJodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjMTk1MiIKKyAqLworcHVibGljIGNsYXNzIEd6aXBDb21wcmVzc29ySW5wdXRTdHJlYW0gZXh0ZW5kcyBDb21wcmVzc29ySW5wdXRTdHJlYW0KKyAgICBpbXBsZW1lbnRzIElucHV0U3RyZWFtU3RhdGlzdGljcyB7CisKKyAgICAvLyBIZWFkZXIgZmxhZ3MKKyAgICAvLyBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgRlRFWFQgPSAweDAxOyAvLyBVbmludGVyZXN0aW5nIGZvciB1cworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBGSENSQyA9IDB4MDI7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEZFWFRSQSA9IDB4MDQ7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEZOQU1FID0gMHgwODsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgRkNPTU1FTlQgPSAweDEwOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBGUkVTRVJWRUQgPSAweEUwOworCisgICAgcHJpdmF0ZSBmaW5hbCBDb3VudGluZ0lucHV0U3RyZWFtIGNvdW50aW5nU3RyZWFtOworCisgICAgLy8gQ29tcHJlc3NlZCBpbnB1dCBzdHJlYW0sIHBvc3NpYmx5IHdyYXBwZWQgaW4gYQorICAgIC8vIEJ1ZmZlcmVkSW5wdXRTdHJlYW0sIGFsd2F5cyB3cmFwcGVkIGluIGNvdW50aW5nU3RyZWFtIGFib3ZlCisgICAgcHJpdmF0ZSBmaW5hbCBJbnB1dFN0cmVhbSBpbjsKKworICAgIC8vIFRydWUgaWYgZGVjb21wcmVzc2luZyBtdWx0aSBtZW1iZXIgc3RyZWFtcy4KKyAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gZGVjb21wcmVzc0NvbmNhdGVuYXRlZDsKKworICAgIC8vIEJ1ZmZlciB0byBob2xkIHRoZSBpbnB1dCBkYXRhCisgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10gYnVmID0gbmV3IGJ5dGVbODE5Ml07CisKKyAgICAvLyBBbW91bnQgb2YgZGF0YSBpbiBidWYuCisgICAgcHJpdmF0ZSBpbnQgYnVmVXNlZDsKKworICAgIC8vIERlY29tcHJlc3NvcgorICAgIHByaXZhdGUgSW5mbGF0ZXIgaW5mID0gbmV3IEluZmxhdGVyKHRydWUpOworCisgICAgLy8gQ1JDMzIgZnJvbSB1bmNvbXByZXNzZWQgZGF0YQorICAgIHByaXZhdGUgZmluYWwgQ1JDMzIgY3JjID0gbmV3IENSQzMyKCk7CisKKyAgICAvLyBUcnVlIG9uY2UgZXZlcnl0aGluZyBoYXMgYmVlbiBkZWNvbXByZXNzZWQKKyAgICBwcml2YXRlIGJvb2xlYW4gZW5kUmVhY2hlZCA9IGZhbHNlOworCisgICAgLy8gdXNlZCBpbiBuby1hcmcgcmVhZCBtZXRob2QKKyAgICBwcml2YXRlIGZpbmFsIGJ5dGVbXSBvbmVCeXRlID0gbmV3IGJ5dGVbMV07CisKKyAgICBwcml2YXRlIGZpbmFsIEd6aXBQYXJhbWV0ZXJzIHBhcmFtZXRlcnMgPSBuZXcgR3ppcFBhcmFtZXRlcnMoKTsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5wdXQgc3RyZWFtIHRoYXQgZGVjb21wcmVzc2VzIGd6aXAtY29tcHJlc3NlZCBkYXRhCisgICAgICogZnJvbSB0aGUgc3BlY2lmaWVkIGlucHV0IHN0cmVhbS4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIGlzIGVxdWl2YWxlbnQgdG8KKyAgICAgKiA8Y29kZT5HemlwQ29tcHJlc3NvcklucHV0U3RyZWFtKGlucHV0U3RyZWFtLCBmYWxzZSk8L2NvZGU+IGFuZCB0aHVzCisgICAgICogd2lsbCBub3QgZGVjb21wcmVzcyBjb25jYXRlbmF0ZWQgLmd6IGZpbGVzLgorICAgICAqCisgICAgICogQHBhcmFtIGlucHV0U3RyZWFtICB0aGUgSW5wdXRTdHJlYW0gZnJvbSB3aGljaCB0aGlzIG9iamVjdCBzaG91bGQKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgIGJlIGNyZWF0ZWQgb2YKKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgdGhlIHN0cmVhbSBjb3VsZCBub3QgYmUgY3JlYXRlZAorICAgICAqLworICAgIHB1YmxpYyBHemlwQ29tcHJlc3NvcklucHV0U3RyZWFtKGZpbmFsIElucHV0U3RyZWFtIGlucHV0U3RyZWFtKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcyhpbnB1dFN0cmVhbSwgZmFsc2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5wdXQgc3RyZWFtIHRoYXQgZGVjb21wcmVzc2VzIGd6aXAtY29tcHJlc3NlZCBkYXRhCisgICAgICogZnJvbSB0aGUgc3BlY2lmaWVkIGlucHV0IHN0cmVhbS4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiA8Y29kZT5kZWNvbXByZXNzQ29uY2F0ZW5hdGVkPC9jb2RlPiBpcyB7QGNvZGUgZmFsc2V9OgorICAgICAqIFRoaXMgZGVjb21wcmVzc29yIG1pZ2h0IHJlYWQgbW9yZSBpbnB1dCB0aGFuIGl0IHdpbGwgYWN0dWFsbHkgdXNlLgorICAgICAqIElmIDxjb2RlPmlucHV0U3RyZWFtPC9jb2RlPiBzdXBwb3J0cyA8Y29kZT5tYXJrPC9jb2RlPiBhbmQKKyAgICAgKiA8Y29kZT5yZXNldDwvY29kZT4sIHRoZW4gdGhlIGlucHV0IHBvc2l0aW9uIHdpbGwgYmUgYWRqdXN0ZWQKKyAgICAgKiBzbyB0aGF0IGl0IGlzIHJpZ2h0IGFmdGVyIHRoZSBsYXN0IGJ5dGUgb2YgdGhlIGNvbXByZXNzZWQgc3RyZWFtLgorICAgICAqIElmIDxjb2RlPm1hcms8L2NvZGU+IGlzbid0IHN1cHBvcnRlZCwgdGhlIGlucHV0IHBvc2l0aW9uIHdpbGwgYmUKKyAgICAgKiB1bmRlZmluZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5wdXRTdHJlYW0gIHRoZSBJbnB1dFN0cmVhbSBmcm9tIHdoaWNoIHRoaXMgb2JqZWN0IHNob3VsZAorICAgICAqICAgICAgICAgICAgICAgICAgICAgYmUgY3JlYXRlZCBvZgorICAgICAqIEBwYXJhbSBkZWNvbXByZXNzQ29uY2F0ZW5hdGVkCisgICAgICogICAgICAgICAgICAgICAgICAgICBpZiB0cnVlLCBkZWNvbXByZXNzIHVudGlsIHRoZSBlbmQgb2YgdGhlIGlucHV0OworICAgICAqICAgICAgICAgICAgICAgICAgICAgaWYgZmFsc2UsIHN0b3AgYWZ0ZXIgdGhlIGZpcnN0IC5neiBtZW1iZXIKKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgdGhlIHN0cmVhbSBjb3VsZCBub3QgYmUgY3JlYXRlZAorICAgICAqLworICAgIHB1YmxpYyBHemlwQ29tcHJlc3NvcklucHV0U3RyZWFtKGZpbmFsIElucHV0U3RyZWFtIGlucHV0U3RyZWFtLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGJvb2xlYW4gZGVjb21wcmVzc0NvbmNhdGVuYXRlZCkKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNvdW50aW5nU3RyZWFtID0gbmV3IENvdW50aW5nSW5wdXRTdHJlYW0oaW5wdXRTdHJlYW0pOworICAgICAgICAvLyBNYXJrIHN1cHBvcnQgaXMgc3RyaWN0bHkgbmVlZGVkIGZvciBjb25jYXRlbmF0ZWQgZmlsZXMgb25seSwKKyAgICAgICAgLy8gYnV0IGl0J3Mgc2ltcGxlciBpZiBpdCBpcyBhbHdheXMgYXZhaWxhYmxlLgorICAgICAgICBpZiAoY291bnRpbmdTdHJlYW0ubWFya1N1cHBvcnRlZCgpKSB7CisgICAgICAgICAgICBpbiA9IGNvdW50aW5nU3RyZWFtOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaW4gPSBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShjb3VudGluZ1N0cmVhbSk7CisgICAgICAgIH0KKworICAgICAgICB0aGlzLmRlY29tcHJlc3NDb25jYXRlbmF0ZWQgPSBkZWNvbXByZXNzQ29uY2F0ZW5hdGVkOworICAgICAgICBpbml0KHRydWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByb3ZpZGVzIHRoZSBzdHJlYW0ncyBtZXRhIGRhdGEgLSBtYXkgY2hhbmdlIHdpdGggZWFjaCBzdHJlYW0KKyAgICAgKiB3aGVuIGRlY29tcHJlc3NpbmcgY29uY2F0ZW5hdGVkIHN0cmVhbXMuCisgICAgICogQHJldHVybiB0aGUgc3RyZWFtJ3MgbWV0YSBkYXRhCisgICAgICogQHNpbmNlIDEuOAorICAgICAqLworICAgIHB1YmxpYyBHemlwUGFyYW1ldGVycyBnZXRNZXRhRGF0YSgpIHsKKyAgICAgICAgcmV0dXJuIHBhcmFtZXRlcnM7CisgICAgfQorCisgICAgcHJpdmF0ZSBib29sZWFuIGluaXQoZmluYWwgYm9vbGVhbiBpc0ZpcnN0TWVtYmVyKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBhc3NlcnQgaXNGaXJzdE1lbWJlciB8fCBkZWNvbXByZXNzQ29uY2F0ZW5hdGVkOworCisgICAgICAgIC8vIENoZWNrIHRoZSBtYWdpYyBieXRlcyB3aXRob3V0IGEgcG9zc2liaWxpdHkgb2YgRU9GRXhjZXB0aW9uLgorICAgICAgICBmaW5hbCBpbnQgbWFnaWMwID0gaW4ucmVhZCgpOworICAgICAgICBmaW5hbCBpbnQgbWFnaWMxID0gaW4ucmVhZCgpOworCisgICAgICAgIC8vIElmIGVuZCBvZiBpbnB1dCB3YXMgcmVhY2hlZCBhZnRlciBkZWNvbXByZXNzaW5nIGF0IGxlYXN0CisgICAgICAgIC8vIG9uZSAuZ3ogbWVtYmVyLCB3ZSBoYXZlIHJlYWNoZWQgdGhlIGVuZCBvZiB0aGUgZmlsZSBzdWNjZXNzZnVsbHkuCisgICAgICAgIGlmIChtYWdpYzAgPT0gLTEgJiYgIWlzRmlyc3RNZW1iZXIpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChtYWdpYzAgIT0gMzEgfHwgbWFnaWMxICE9IDEzOSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKGlzRmlyc3RNZW1iZXIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/ICJJbnB1dCBpcyBub3QgaW4gdGhlIC5neiBmb3JtYXQiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAiR2FyYmFnZSBhZnRlciBhIHZhbGlkIC5neiBzdHJlYW0iKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFBhcnNpbmcgdGhlIHJlc3Qgb2YgdGhlIGhlYWRlciBtYXkgdGhyb3cgRU9GRXhjZXB0aW9uLgorICAgICAgICBmaW5hbCBEYXRhSW5wdXQgaW5EYXRhID0gbmV3IERhdGFJbnB1dFN0cmVhbShpbik7CisgICAgICAgIGZpbmFsIGludCBtZXRob2QgPSBpbkRhdGEucmVhZFVuc2lnbmVkQnl0ZSgpOworICAgICAgICBpZiAobWV0aG9kICE9IERlZmxhdGVyLkRFRkxBVEVEKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlVuc3VwcG9ydGVkIGNvbXByZXNzaW9uIG1ldGhvZCAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBtZXRob2QgKyAiIGluIHRoZSAuZ3ogaGVhZGVyIik7CisgICAgICAgIH0KKworICAgICAgICBmaW5hbCBpbnQgZmxnID0gaW5EYXRhLnJlYWRVbnNpZ25lZEJ5dGUoKTsKKyAgICAgICAgaWYgKChmbGcgJiBGUkVTRVJWRUQpICE9IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgIlJlc2VydmVkIGZsYWdzIGFyZSBzZXQgaW4gdGhlIC5neiBoZWFkZXIiKTsKKyAgICAgICAgfQorCisgICAgICAgIHBhcmFtZXRlcnMuc2V0TW9kaWZpY2F0aW9uVGltZShCeXRlVXRpbHMuZnJvbUxpdHRsZUVuZGlhbihpbkRhdGEsIDQpICogMTAwMCk7CisgICAgICAgIHN3aXRjaCAoaW5EYXRhLnJlYWRVbnNpZ25lZEJ5dGUoKSkgeyAvLyBleHRyYSBmbGFncworICAgICAgICBjYXNlIDI6CisgICAgICAgICAgICBwYXJhbWV0ZXJzLnNldENvbXByZXNzaW9uTGV2ZWwoRGVmbGF0ZXIuQkVTVF9DT01QUkVTU0lPTik7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSA0OgorICAgICAgICAgICAgcGFyYW1ldGVycy5zZXRDb21wcmVzc2lvbkxldmVsKERlZmxhdGVyLkJFU1RfU1BFRUQpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAvLyBpZ25vcmVkIGZvciBub3cKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIHBhcmFtZXRlcnMuc2V0T3BlcmF0aW5nU3lzdGVtKGluRGF0YS5yZWFkVW5zaWduZWRCeXRlKCkpOworCisgICAgICAgIC8vIEV4dHJhIGZpZWxkLCBpZ25vcmVkCisgICAgICAgIGlmICgoZmxnICYgRkVYVFJBKSAhPSAwKSB7CisgICAgICAgICAgICBpbnQgeGxlbiA9IGluRGF0YS5yZWFkVW5zaWduZWRCeXRlKCk7CisgICAgICAgICAgICB4bGVuIHw9IGluRGF0YS5yZWFkVW5zaWduZWRCeXRlKCkgPDwgODsKKworICAgICAgICAgICAgLy8gVGhpcyBpc24ndCBhcyBlZmZpY2llbnQgYXMgY2FsbGluZyBpbi5za2lwIHdvdWxkIGJlLAorICAgICAgICAgICAgLy8gYnV0IGl0J3MgbGF6aWVyIHRvIGhhbmRsZSB1bmV4cGVjdGVkIGVuZCBvZiBpbnB1dCB0aGlzIHdheS4KKyAgICAgICAgICAgIC8vIE1vc3QgZmlsZXMgZG9uJ3QgaGF2ZSBhbiBleHRyYSBmaWVsZCBhbnl3YXkuCisgICAgICAgICAgICB3aGlsZSAoeGxlbi0tID4gMCkgeworICAgICAgICAgICAgICAgIGluRGF0YS5yZWFkVW5zaWduZWRCeXRlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyBPcmlnaW5hbCBmaWxlIG5hbWUKKyAgICAgICAgaWYgKChmbGcgJiBGTkFNRSkgIT0gMCkgeworICAgICAgICAgICAgcGFyYW1ldGVycy5zZXRGaWxlbmFtZShuZXcgU3RyaW5nKHJlYWRUb051bGwoaW5EYXRhKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDaGFyc2V0TmFtZXMuSVNPXzg4NTlfMSkpOworICAgICAgICB9CisKKyAgICAgICAgLy8gQ29tbWVudAorICAgICAgICBpZiAoKGZsZyAmIEZDT01NRU5UKSAhPSAwKSB7CisgICAgICAgICAgICBwYXJhbWV0ZXJzLnNldENvbW1lbnQobmV3IFN0cmluZyhyZWFkVG9OdWxsKGluRGF0YSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDaGFyc2V0TmFtZXMuSVNPXzg4NTlfMSkpOworICAgICAgICB9CisKKyAgICAgICAgLy8gSGVhZGVyICJDUkMxNiIgd2hpY2ggaXMgYWN0dWFsbHkgYSB0cnVuY2F0ZWQgQ1JDMzIgKHdoaWNoIGlzbid0CisgICAgICAgIC8vIGFzIGdvb2QgYXMgcmVhbCBDUkMxNikuIEkgZG9uJ3Qga25vdyBpZiBhbnkgZW5jb2RlciBpbXBsZW1lbnRhdGlvbgorICAgICAgICAvLyBzZXRzIHRoaXMsIHNvIGl0J3Mgbm90IHdvcnRoIHRyeWluZyB0byB2ZXJpZnkgaXQuIEdOVSBnemlwIDEuNAorICAgICAgICAvLyBkb2Vzbid0IHN1cHBvcnQgdGhpcyBmaWVsZCwgYnV0IHpsaWIgc2VlbXMgdG8gYmUgYWJsZSB0byBhdCBsZWFzdAorICAgICAgICAvLyBza2lwIG92ZXIgaXQuCisgICAgICAgIGlmICgoZmxnICYgRkhDUkMpICE9IDApIHsKKyAgICAgICAgICAgIGluRGF0YS5yZWFkU2hvcnQoKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFJlc2V0CisgICAgICAgIGluZi5yZXNldCgpOworICAgICAgICBjcmMucmVzZXQoKTsKKworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBieXRlW10gcmVhZFRvTnVsbChmaW5hbCBEYXRhSW5wdXQgaW5EYXRhKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICBpbnQgYiA9IDA7CisgICAgICAgIHdoaWxlICgoYiA9IGluRGF0YS5yZWFkVW5zaWduZWRCeXRlKCkpICE9IDB4MDApIHsgLy8gTk9QTUQKKyAgICAgICAgICAgIGJvcy53cml0ZShiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYm9zLnRvQnl0ZUFycmF5KCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCByZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHJlYWQob25lQnl0ZSwgMCwgMSkgPT0gLTEgPyAtMSA6IG9uZUJ5dGVbMF0gJiAweEZGOworICAgIH0KKworICAgIC8qKgorICAgICAqIHtAaW5oZXJpdERvY30KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjEKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHJlYWQoZmluYWwgYnl0ZVtdIGIsIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChlbmRSZWFjaGVkKSB7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKworICAgICAgICBpbnQgc2l6ZSA9IDA7CisKKyAgICAgICAgd2hpbGUgKGxlbiA+IDApIHsKKyAgICAgICAgICAgIGlmIChpbmYubmVlZHNJbnB1dCgpKSB7CisgICAgICAgICAgICAgICAgLy8gUmVtZW1iZXIgdGhlIGN1cnJlbnQgcG9zaXRpb24gYmVjYXVzZSB3ZSBtYXkgbmVlZCB0bworICAgICAgICAgICAgICAgIC8vIHJld2luZCBhZnRlciByZWFkaW5nIHRvbyBtdWNoIGlucHV0LgorICAgICAgICAgICAgICAgIGluLm1hcmsoYnVmLmxlbmd0aCk7CisKKyAgICAgICAgICAgICAgICBidWZVc2VkID0gaW4ucmVhZChidWYpOworICAgICAgICAgICAgICAgIGlmIChidWZVc2VkID09IC0xKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFT0ZFeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBpbmYuc2V0SW5wdXQoYnVmLCAwLCBidWZVc2VkKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaW50IHJldDsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcmV0ID0gaW5mLmluZmxhdGUoYiwgb2ZmLCBsZW4pOworICAgICAgICAgICAgfSBjYXRjaCAoZmluYWwgRGF0YUZvcm1hdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJHemlwLWNvbXByZXNzZWQgZGF0YSBpcyBjb3JydXB0Iik7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGNyYy51cGRhdGUoYiwgb2ZmLCByZXQpOworICAgICAgICAgICAgb2ZmICs9IHJldDsKKyAgICAgICAgICAgIGxlbiAtPSByZXQ7CisgICAgICAgICAgICBzaXplICs9IHJldDsKKyAgICAgICAgICAgIGNvdW50KHJldCk7CisKKyAgICAgICAgICAgIGlmIChpbmYuZmluaXNoZWQoKSkgeworICAgICAgICAgICAgICAgIC8vIFdlIG1heSBoYXZlIHJlYWQgdG9vIG1hbnkgYnl0ZXMuIFJld2luZCB0aGUgcmVhZAorICAgICAgICAgICAgICAgIC8vIHBvc2l0aW9uIHRvIG1hdGNoIHRoZSBhY3R1YWwgYW1vdW50IHVzZWQuCisgICAgICAgICAgICAgICAgLy8KKyAgICAgICAgICAgICAgICAvLyBOT1RFOiBUaGUgImlmIiBpcyB0aGVyZSBqdXN0IGluIGNhc2UuIFNpbmNlIHdlIHVzZWQKKyAgICAgICAgICAgICAgICAvLyBpbi5tYXJrIGVhcmxpZXIsIGl0IHNob3VsZCBhbHdheXMgc2tpcCBlbm91Z2guCisgICAgICAgICAgICAgICAgaW4ucmVzZXQoKTsKKworICAgICAgICAgICAgICAgIGZpbmFsIGludCBza2lwQW1vdW50ID0gYnVmVXNlZCAtIGluZi5nZXRSZW1haW5pbmcoKTsKKyAgICAgICAgICAgICAgICBpZiAoSU9VdGlscy5za2lwKGluLCBza2lwQW1vdW50KSAhPSBza2lwQW1vdW50KSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGJ1ZlVzZWQgPSAwOworCisgICAgICAgICAgICAgICAgZmluYWwgRGF0YUlucHV0IGluRGF0YSA9IG5ldyBEYXRhSW5wdXRTdHJlYW0oaW4pOworCisgICAgICAgICAgICAgICAgLy8gQ1JDMzIKKyAgICAgICAgICAgICAgICBmaW5hbCBsb25nIGNyY1N0b3JlZCA9IEJ5dGVVdGlscy5mcm9tTGl0dGxlRW5kaWFuKGluRGF0YSwgNCk7CisKKyAgICAgICAgICAgICAgICBpZiAoY3JjU3RvcmVkICE9IGNyYy5nZXRWYWx1ZSgpKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiR3ppcC1jb21wcmVzc2VkIGRhdGEgaXMgY29ycnVwdCAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIoQ1JDMzIgZXJyb3IpIik7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgLy8gVW5jb21wcmVzc2VkIHNpemUgbW9kdWxvIDJeMzIgKElTSVpFIGluIHRoZSBzcGVjKQorICAgICAgICAgICAgICAgIGZpbmFsIGxvbmcgaXNpemUgPSBCeXRlVXRpbHMuZnJvbUxpdHRsZUVuZGlhbihpbkRhdGEsIDQpOworCisgICAgICAgICAgICAgICAgaWYgKGlzaXplICE9IChpbmYuZ2V0Qnl0ZXNXcml0dGVuKCkgJiAweGZmZmZmZmZmTCkpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJHemlwLWNvbXByZXNzZWQgZGF0YSBpcyBjb3JydXB0IgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiKHVuY29tcHJlc3NlZCBzaXplIG1pc21hdGNoKSIpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIC8vIFNlZSBpZiB0aGlzIGlzIHRoZSBlbmQgb2YgdGhlIGZpbGUuCisgICAgICAgICAgICAgICAgaWYgKCFkZWNvbXByZXNzQ29uY2F0ZW5hdGVkIHx8ICFpbml0KGZhbHNlKSkgeworICAgICAgICAgICAgICAgICAgICBpbmYuZW5kKCk7CisgICAgICAgICAgICAgICAgICAgIGluZiA9IG51bGw7CisgICAgICAgICAgICAgICAgICAgIGVuZFJlYWNoZWQgPSB0cnVlOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2l6ZSA9PSAwID8gLTEgOiBzaXplOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBzaXplOworICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrcyBpZiB0aGUgc2lnbmF0dXJlIG1hdGNoZXMgd2hhdCBpcyBleHBlY3RlZCBmb3IgYSAuZ3ogZmlsZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzaWduYXR1cmUgdGhlIGJ5dGVzIHRvIGNoZWNrCisgICAgICogQHBhcmFtIGxlbmd0aCAgICB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRvIGNoZWNrCisgICAgICogQHJldHVybiAgICAgICAgICB0cnVlIGlmIHRoaXMgaXMgYSAuZ3ogc3RyZWFtLCBmYWxzZSBvdGhlcndpc2UKKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjEKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gbWF0Y2hlcyhmaW5hbCBieXRlW10gc2lnbmF0dXJlLCBmaW5hbCBpbnQgbGVuZ3RoKSB7CisgICAgICAgIHJldHVybiBsZW5ndGggPj0gMiAmJiBzaWduYXR1cmVbMF0gPT0gMzEgJiYgc2lnbmF0dXJlWzFdID09IC0xMTc7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvc2VzIHRoZSBpbnB1dCBzdHJlYW0gKHVubGVzcyBpdCBpcyBTeXN0ZW0uaW4pLgorICAgICAqCisgICAgICogQHNpbmNlIDEuMgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGluZiAhPSBudWxsKSB7CisgICAgICAgICAgICBpbmYuZW5kKCk7CisgICAgICAgICAgICBpbmYgPSBudWxsOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHRoaXMuaW4gIT0gU3lzdGVtLmluKSB7CisgICAgICAgICAgICB0aGlzLmluLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2luY2UgMS4xNworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBsb25nIGdldENvbXByZXNzZWRDb3VudCgpIHsKKyAgICAgICAgcmV0dXJuIGNvdW50aW5nU3RyZWFtLmdldEJ5dGVzUmVhZCgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2d6aXAvR3ppcENvbXByZXNzb3JPdXRwdXRTdHJlYW0uamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2d6aXAvR3ppcENvbXByZXNzb3JPdXRwdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iYjVlMTc3Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvZ3ppcC9HemlwQ29tcHJlc3Nvck91dHB1dFN0cmVhbS5qYXZhCkBAIC0wLDAgKzEsMjE3IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLmd6aXA7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEubmlvLkJ5dGVCdWZmZXI7CitpbXBvcnQgamF2YS5uaW8uQnl0ZU9yZGVyOworaW1wb3J0IGphdmEudXRpbC56aXAuQ1JDMzI7CitpbXBvcnQgamF2YS51dGlsLnppcC5EZWZsYXRlcjsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLkdaSVBJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLkdaSVBPdXRwdXRTdHJlYW07CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuQ29tcHJlc3Nvck91dHB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuQ2hhcnNldE5hbWVzOworCisvKioKKyAqIENvbXByZXNzZWQgb3V0cHV0IHN0cmVhbSB1c2luZyB0aGUgZ3ppcCBmb3JtYXQuIFRoaXMgaW1wbGVtZW50YXRpb24gaW1wcm92ZXMKKyAqIG92ZXIgdGhlIHN0YW5kYXJkIHtAbGluayBHWklQT3V0cHV0U3RyZWFtfSBjbGFzcyBieSBhbGxvd2luZworICogdGhlIGNvbmZpZ3VyYXRpb24gb2YgdGhlIGNvbXByZXNzaW9uIGxldmVsIGFuZCB0aGUgaGVhZGVyIG1ldGFkYXRhIChmaWxlbmFtZSwKKyAqIGNvbW1lbnQsIG1vZGlmaWNhdGlvbiB0aW1lLCBvcGVyYXRpbmcgc3lzdGVtIGFuZCBleHRyYSBmbGFncykuCisgKgorICogQHNlZSA8YSBocmVmPSJodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjMTk1MiI+R1pJUCBGaWxlIEZvcm1hdCBTcGVjaWZpY2F0aW9uPC9hPgorICovCitwdWJsaWMgY2xhc3MgR3ppcENvbXByZXNzb3JPdXRwdXRTdHJlYW0gZXh0ZW5kcyBDb21wcmVzc29yT3V0cHV0U3RyZWFtIHsKKworICAgIC8qKiBIZWFkZXIgZmxhZyBpbmRpY2F0aW5nIGEgZmlsZSBuYW1lIGZvbGxvd3MgdGhlIGhlYWRlciAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBGTkFNRSA9IDEgPDwgMzsKKworICAgIC8qKiBIZWFkZXIgZmxhZyBpbmRpY2F0aW5nIGEgY29tbWVudCBmb2xsb3dzIHRoZSBoZWFkZXIgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgRkNPTU1FTlQgPSAxIDw8IDQ7CisKKyAgICAvKiogVGhlIHVuZGVybHlpbmcgc3RyZWFtICovCisgICAgcHJpdmF0ZSBmaW5hbCBPdXRwdXRTdHJlYW0gb3V0OworCisgICAgLyoqIERlZmxhdGVyIHVzZWQgdG8gY29tcHJlc3MgdGhlIGRhdGEgKi8KKyAgICBwcml2YXRlIGZpbmFsIERlZmxhdGVyIGRlZmxhdGVyOworCisgICAgLyoqIFRoZSBidWZmZXIgcmVjZWl2aW5nIHRoZSBjb21wcmVzc2VkIGRhdGEgZnJvbSB0aGUgZGVmbGF0ZXIgKi8KKyAgICBwcml2YXRlIGZpbmFsIGJ5dGVbXSBkZWZsYXRlQnVmZmVyID0gbmV3IGJ5dGVbNTEyXTsKKworICAgIC8qKiBJbmRpY2F0ZXMgaWYgdGhlIHN0cmVhbSBoYXMgYmVlbiBjbG9zZWQgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gY2xvc2VkOworCisgICAgLyoqIFRoZSBjaGVja3N1bSBvZiB0aGUgdW5jb21wcmVzc2VkIGRhdGEgKi8KKyAgICBwcml2YXRlIGZpbmFsIENSQzMyIGNyYyA9IG5ldyBDUkMzMigpOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIGd6aXAgY29tcHJlc3NlZCBvdXRwdXQgc3RyZWFtIHdpdGggdGhlIGRlZmF1bHQgcGFyYW1ldGVycy4KKyAgICAgKiBAcGFyYW0gb3V0IHRoZSBzdHJlYW0gdG8gY29tcHJlc3MgdG8KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHdyaXRpbmcgZmFpbHMKKyAgICAgKi8KKyAgICBwdWJsaWMgR3ppcENvbXByZXNzb3JPdXRwdXRTdHJlYW0oZmluYWwgT3V0cHV0U3RyZWFtIG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcyhvdXQsIG5ldyBHemlwUGFyYW1ldGVycygpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgZ3ppcCBjb21wcmVzc2VkIG91dHB1dCBzdHJlYW0gd2l0aCB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlcnMuCisgICAgICogQHBhcmFtIG91dCB0aGUgc3RyZWFtIHRvIGNvbXByZXNzIHRvCisgICAgICogQHBhcmFtIHBhcmFtZXRlcnMgdGhlIHBhcmFtZXRlcnMgdG8gdXNlCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiB3cml0aW5nIGZhaWxzCisgICAgICoKKyAgICAgKiBAc2luY2UgMS43CisgICAgICovCisgICAgcHVibGljIEd6aXBDb21wcmVzc29yT3V0cHV0U3RyZWFtKGZpbmFsIE91dHB1dFN0cmVhbSBvdXQsIGZpbmFsIEd6aXBQYXJhbWV0ZXJzIHBhcmFtZXRlcnMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMub3V0ID0gb3V0OworICAgICAgICB0aGlzLmRlZmxhdGVyID0gbmV3IERlZmxhdGVyKHBhcmFtZXRlcnMuZ2V0Q29tcHJlc3Npb25MZXZlbCgpLCB0cnVlKTsKKworICAgICAgICB3cml0ZUhlYWRlcihwYXJhbWV0ZXJzKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgd3JpdGVIZWFkZXIoZmluYWwgR3ppcFBhcmFtZXRlcnMgcGFyYW1ldGVycykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgU3RyaW5nIGZpbGVuYW1lID0gcGFyYW1ldGVycy5nZXRGaWxlbmFtZSgpOworICAgICAgICBmaW5hbCBTdHJpbmcgY29tbWVudCA9IHBhcmFtZXRlcnMuZ2V0Q29tbWVudCgpOworCisgICAgICAgIGZpbmFsIEJ5dGVCdWZmZXIgYnVmZmVyID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxMCk7CisgICAgICAgIGJ1ZmZlci5vcmRlcihCeXRlT3JkZXIuTElUVExFX0VORElBTik7CisgICAgICAgIGJ1ZmZlci5wdXRTaG9ydCgoc2hvcnQpIEdaSVBJbnB1dFN0cmVhbS5HWklQX01BR0lDKTsKKyAgICAgICAgYnVmZmVyLnB1dCgoYnl0ZSkgRGVmbGF0ZXIuREVGTEFURUQpOyAvLyBjb21wcmVzc2lvbiBtZXRob2QgKDg6IGRlZmxhdGUpCisgICAgICAgIGJ1ZmZlci5wdXQoKGJ5dGUpICgoZmlsZW5hbWUgIT0gbnVsbCA/IEZOQU1FIDogMCkgfCAoY29tbWVudCAhPSBudWxsID8gRkNPTU1FTlQgOiAwKSkpOyAvLyBmbGFncworICAgICAgICBidWZmZXIucHV0SW50KChpbnQpIChwYXJhbWV0ZXJzLmdldE1vZGlmaWNhdGlvblRpbWUoKSAvIDEwMDApKTsKKworICAgICAgICAvLyBleHRyYSBmbGFncworICAgICAgICBmaW5hbCBpbnQgY29tcHJlc3Npb25MZXZlbCA9IHBhcmFtZXRlcnMuZ2V0Q29tcHJlc3Npb25MZXZlbCgpOworICAgICAgICBpZiAoY29tcHJlc3Npb25MZXZlbCA9PSBEZWZsYXRlci5CRVNUX0NPTVBSRVNTSU9OKSB7CisgICAgICAgICAgICBidWZmZXIucHV0KChieXRlKSAyKTsKKyAgICAgICAgfSBlbHNlIGlmIChjb21wcmVzc2lvbkxldmVsID09IERlZmxhdGVyLkJFU1RfU1BFRUQpIHsKKyAgICAgICAgICAgIGJ1ZmZlci5wdXQoKGJ5dGUpIDQpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgYnVmZmVyLnB1dCgoYnl0ZSkgMCk7CisgICAgICAgIH0KKworICAgICAgICBidWZmZXIucHV0KChieXRlKSBwYXJhbWV0ZXJzLmdldE9wZXJhdGluZ1N5c3RlbSgpKTsKKworICAgICAgICBvdXQud3JpdGUoYnVmZmVyLmFycmF5KCkpOworCisgICAgICAgIGlmIChmaWxlbmFtZSAhPSBudWxsKSB7CisgICAgICAgICAgICBvdXQud3JpdGUoZmlsZW5hbWUuZ2V0Qnl0ZXMoQ2hhcnNldE5hbWVzLklTT184ODU5XzEpKTsKKyAgICAgICAgICAgIG91dC53cml0ZSgwKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChjb21tZW50ICE9IG51bGwpIHsKKyAgICAgICAgICAgIG91dC53cml0ZShjb21tZW50LmdldEJ5dGVzKENoYXJzZXROYW1lcy5JU09fODg1OV8xKSk7CisgICAgICAgICAgICBvdXQud3JpdGUoMCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgd3JpdGVUcmFpbGVyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgQnl0ZUJ1ZmZlciBidWZmZXIgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKDgpOworICAgICAgICBidWZmZXIub3JkZXIoQnl0ZU9yZGVyLkxJVFRMRV9FTkRJQU4pOworICAgICAgICBidWZmZXIucHV0SW50KChpbnQpIGNyYy5nZXRWYWx1ZSgpKTsKKyAgICAgICAgYnVmZmVyLnB1dEludChkZWZsYXRlci5nZXRUb3RhbEluKCkpOworCisgICAgICAgIG91dC53cml0ZShidWZmZXIuYXJyYXkoKSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGUoZmluYWwgaW50IGIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHdyaXRlKG5ldyBieXRlW117KGJ5dGUpIChiICYgMHhmZil9LCAwLCAxKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB7QGluaGVyaXREb2N9CisgICAgICoKKyAgICAgKiBAc2luY2UgMS4xCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGUoZmluYWwgYnl0ZVtdIGJ1ZmZlcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgd3JpdGUoYnVmZmVyLCAwLCBidWZmZXIubGVuZ3RoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB7QGluaGVyaXREb2N9CisgICAgICoKKyAgICAgKiBAc2luY2UgMS4xCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGUoZmluYWwgYnl0ZVtdIGJ1ZmZlciwgZmluYWwgaW50IG9mZnNldCwgZmluYWwgaW50IGxlbmd0aCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGRlZmxhdGVyLmZpbmlzaGVkKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiQ2Fubm90IHdyaXRlIG1vcmUgZGF0YSwgdGhlIGVuZCBvZiB0aGUgY29tcHJlc3NlZCBkYXRhIHN0cmVhbSBoYXMgYmVlbiByZWFjaGVkIik7CisKKyAgICAgICAgfSBlbHNlIGlmIChsZW5ndGggPiAwKSB7CisgICAgICAgICAgICBkZWZsYXRlci5zZXRJbnB1dChidWZmZXIsIG9mZnNldCwgbGVuZ3RoKTsKKworICAgICAgICAgICAgd2hpbGUgKCFkZWZsYXRlci5uZWVkc0lucHV0KCkpIHsKKyAgICAgICAgICAgICAgICBkZWZsYXRlKCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGNyYy51cGRhdGUoYnVmZmVyLCBvZmZzZXQsIGxlbmd0aCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgZGVmbGF0ZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIGludCBsZW5ndGggPSBkZWZsYXRlci5kZWZsYXRlKGRlZmxhdGVCdWZmZXIsIDAsIGRlZmxhdGVCdWZmZXIubGVuZ3RoKTsKKyAgICAgICAgaWYgKGxlbmd0aCA+IDApIHsKKyAgICAgICAgICAgIG91dC53cml0ZShkZWZsYXRlQnVmZmVyLCAwLCBsZW5ndGgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRmluaXNoZXMgd3JpdGluZyBjb21wcmVzc2VkIGRhdGEgdG8gdGhlIHVuZGVybHlpbmcgc3RyZWFtIHdpdGhvdXQgY2xvc2luZyBpdC4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjcKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIG9uIGVycm9yCisgICAgICovCisgICAgcHVibGljIHZvaWQgZmluaXNoKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFkZWZsYXRlci5maW5pc2hlZCgpKSB7CisgICAgICAgICAgICBkZWZsYXRlci5maW5pc2goKTsKKworICAgICAgICAgICAgd2hpbGUgKCFkZWZsYXRlci5maW5pc2hlZCgpKSB7CisgICAgICAgICAgICAgICAgZGVmbGF0ZSgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICB3cml0ZVRyYWlsZXIoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIHtAaW5oZXJpdERvY30KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjcKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBmbHVzaCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG91dC5mbHVzaCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFjbG9zZWQpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZmluaXNoKCk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIGRlZmxhdGVyLmVuZCgpOworICAgICAgICAgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICAgICAgICAgIGNsb3NlZCA9IHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2d6aXAvR3ppcFBhcmFtZXRlcnMuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2d6aXAvR3ppcFBhcmFtZXRlcnMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zODg3YTY4Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvZ3ppcC9HemlwUGFyYW1ldGVycy5qYXZhCkBAIC0wLDAgKzEsMTIxIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuZ3ppcDsKKworaW1wb3J0IGphdmEudXRpbC56aXAuRGVmbGF0ZXI7CisKKy8qKgorICogUGFyYW1ldGVycyBmb3IgdGhlIEdaSVAgY29tcHJlc3Nvci4KKyAqCisgKiBAc2luY2UgMS43CisgKi8KK3B1YmxpYyBjbGFzcyBHemlwUGFyYW1ldGVycyB7CisKKyAgICBwcml2YXRlIGludCBjb21wcmVzc2lvbkxldmVsID0gRGVmbGF0ZXIuREVGQVVMVF9DT01QUkVTU0lPTjsKKyAgICBwcml2YXRlIGxvbmcgbW9kaWZpY2F0aW9uVGltZTsKKyAgICBwcml2YXRlIFN0cmluZyBmaWxlbmFtZTsKKyAgICBwcml2YXRlIFN0cmluZyBjb21tZW50OworICAgIHByaXZhdGUgaW50IG9wZXJhdGluZ1N5c3RlbSA9IDI1NTsgLy8gVW5rbm93biBPUyBieSBkZWZhdWx0CisKKyAgICBwdWJsaWMgaW50IGdldENvbXByZXNzaW9uTGV2ZWwoKSB7CisgICAgICAgIHJldHVybiBjb21wcmVzc2lvbkxldmVsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGNvbXByZXNzaW9uIGxldmVsLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbXByZXNzaW9uTGV2ZWwgdGhlIGNvbXByZXNzaW9uIGxldmVsIChiZXR3ZWVuIDAgYW5kIDkpCisgICAgICogQHNlZSBEZWZsYXRlciNOT19DT01QUkVTU0lPTgorICAgICAqIEBzZWUgRGVmbGF0ZXIjQkVTVF9TUEVFRAorICAgICAqIEBzZWUgRGVmbGF0ZXIjREVGQVVMVF9DT01QUkVTU0lPTgorICAgICAqIEBzZWUgRGVmbGF0ZXIjQkVTVF9DT01QUkVTU0lPTgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldENvbXByZXNzaW9uTGV2ZWwoZmluYWwgaW50IGNvbXByZXNzaW9uTGV2ZWwpIHsKKyAgICAgICAgaWYgKGNvbXByZXNzaW9uTGV2ZWwgPCAtMSB8fCBjb21wcmVzc2lvbkxldmVsID4gOSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSW52YWxpZCBnemlwIGNvbXByZXNzaW9uIGxldmVsOiAiICsgY29tcHJlc3Npb25MZXZlbCk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5jb21wcmVzc2lvbkxldmVsID0gY29tcHJlc3Npb25MZXZlbDsKKyAgICB9CisKKyAgICBwdWJsaWMgbG9uZyBnZXRNb2RpZmljYXRpb25UaW1lKCkgeworICAgICAgICByZXR1cm4gbW9kaWZpY2F0aW9uVGltZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBtb2RpZmljYXRpb24gdGltZSBvZiB0aGUgY29tcHJlc3NlZCBmaWxlLgorICAgICAqCisgICAgICogQHBhcmFtIG1vZGlmaWNhdGlvblRpbWUgdGhlIG1vZGlmaWNhdGlvbiB0aW1lLCBpbiBtaWxsaXNlY29uZHMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRNb2RpZmljYXRpb25UaW1lKGZpbmFsIGxvbmcgbW9kaWZpY2F0aW9uVGltZSkgeworICAgICAgICB0aGlzLm1vZGlmaWNhdGlvblRpbWUgPSBtb2RpZmljYXRpb25UaW1lOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0RmlsZW5hbWUoKSB7CisgICAgICAgIHJldHVybiBmaWxlbmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBuYW1lIG9mIHRoZSBjb21wcmVzc2VkIGZpbGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmlsZW5hbWUgdGhlIG5hbWUgb2YgdGhlIGZpbGUgd2l0aG91dCB0aGUgZGlyZWN0b3J5IHBhdGgKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRGaWxlbmFtZShmaW5hbCBTdHJpbmcgZmlsZW5hbWUpIHsKKyAgICAgICAgdGhpcy5maWxlbmFtZSA9IGZpbGVuYW1lOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q29tbWVudCgpIHsKKyAgICAgICAgcmV0dXJuIGNvbW1lbnQ7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0Q29tbWVudChmaW5hbCBTdHJpbmcgY29tbWVudCkgeworICAgICAgICB0aGlzLmNvbW1lbnQgPSBjb21tZW50OworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0T3BlcmF0aW5nU3lzdGVtKCkgeworICAgICAgICByZXR1cm4gb3BlcmF0aW5nU3lzdGVtOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIG9wZXJhdGluZyBzeXN0ZW0gb24gd2hpY2ggdGhlIGNvbXByZXNzaW9uIHRvb2sgcGxhY2UuCisgICAgICogVGhlIGRlZmluZWQgdmFsdWVzIGFyZToKKyAgICAgKiA8dWw+CisgICAgICogICA8bGk+MDogRkFUIGZpbGVzeXN0ZW0gKE1TLURPUywgT1MvMiwgTlQvV2luMzIpPC9saT4KKyAgICAgKiAgIDxsaT4xOiBBbWlnYTwvbGk+CisgICAgICogICA8bGk+MjogVk1TIChvciBPcGVuVk1TKTwvbGk+CisgICAgICogICA8bGk+MzogVW5peDwvbGk+CisgICAgICogICA8bGk+NDogVk0vQ01TPC9saT4KKyAgICAgKiAgIDxsaT41OiBBdGFyaSBUT1M8L2xpPgorICAgICAqICAgPGxpPjY6IEhQRlMgZmlsZXN5c3RlbSAoT1MvMiwgTlQpPC9saT4KKyAgICAgKiAgIDxsaT43OiBNYWNpbnRvc2g8L2xpPgorICAgICAqICAgPGxpPjg6IFotU3lzdGVtPC9saT4KKyAgICAgKiAgIDxsaT45OiBDUC9NPC9saT4KKyAgICAgKiAgIDxsaT4xMDogVE9QUy0yMDwvbGk+CisgICAgICogICA8bGk+MTE6IE5URlMgZmlsZXN5c3RlbSAoTlQpPC9saT4KKyAgICAgKiAgIDxsaT4xMjogUURPUzwvbGk+CisgICAgICogICA8bGk+MTM6IEFjb3JuIFJJU0NPUzwvbGk+CisgICAgICogICA8bGk+MjU1OiBVbmtub3duPC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqCisgICAgICogQHBhcmFtIG9wZXJhdGluZ1N5c3RlbSB0aGUgY29kZSBvZiB0aGUgb3BlcmF0aW5nIHN5c3RlbQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE9wZXJhdGluZ1N5c3RlbShmaW5hbCBpbnQgb3BlcmF0aW5nU3lzdGVtKSB7CisgICAgICAgIHRoaXMub3BlcmF0aW5nU3lzdGVtID0gb3BlcmF0aW5nU3lzdGVtOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2d6aXAvR3ppcFV0aWxzLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9nemlwL0d6aXBVdGlscy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBlZGY2NTUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9nemlwL0d6aXBVdGlscy5qYXZhCkBAIC0wLDAgKzEsMTAwIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLmd6aXA7CisKK2ltcG9ydCBqYXZhLnV0aWwuTGlua2VkSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5GaWxlTmFtZVV0aWw7CisKKy8qKgorICogVXRpbGl0eSBjb2RlIGZvciB0aGUgZ3ppcCBjb21wcmVzc2lvbiBmb3JtYXQuCisgKiBAVGhyZWFkU2FmZQorICovCitwdWJsaWMgY2xhc3MgR3ppcFV0aWxzIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEZpbGVOYW1lVXRpbCBmaWxlTmFtZVV0aWw7CisKKyAgICBzdGF0aWMgeworICAgICAgICAvLyB1c2luZyBMaW5rZWRIYXNoTWFwIHNvIC50Z3ogaXMgcHJlZmVycmVkIG92ZXIgLnRheiBhcworICAgICAgICAvLyBjb21wcmVzc2VkIGV4dGVuc2lvbiBvZiAudGFyIGFzIEZpbGVOYW1lVXRpbCB3aWxsIHVzZSB0aGUKKyAgICAgICAgLy8gZmlyc3Qgb25lIGZvdW5kCisgICAgICAgIGZpbmFsIE1hcDxTdHJpbmcsIFN0cmluZz4gdW5jb21wcmVzc1N1ZmZpeCA9CisgICAgICAgICAgICBuZXcgTGlua2VkSGFzaE1hcDw+KCk7CisgICAgICAgIHVuY29tcHJlc3NTdWZmaXgucHV0KCIudGd6IiwgIi50YXIiKTsKKyAgICAgICAgdW5jb21wcmVzc1N1ZmZpeC5wdXQoIi50YXoiLCAiLnRhciIpOworICAgICAgICB1bmNvbXByZXNzU3VmZml4LnB1dCgiLnN2Z3oiLCAiLnN2ZyIpOworICAgICAgICB1bmNvbXByZXNzU3VmZml4LnB1dCgiLmNwZ3oiLCAiLmNwaW8iKTsKKyAgICAgICAgdW5jb21wcmVzc1N1ZmZpeC5wdXQoIi53bXoiLCAiLndtZiIpOworICAgICAgICB1bmNvbXByZXNzU3VmZml4LnB1dCgiLmVteiIsICIuZW1mIik7CisgICAgICAgIHVuY29tcHJlc3NTdWZmaXgucHV0KCIuZ3oiLCAiIik7CisgICAgICAgIHVuY29tcHJlc3NTdWZmaXgucHV0KCIueiIsICIiKTsKKyAgICAgICAgdW5jb21wcmVzc1N1ZmZpeC5wdXQoIi1neiIsICIiKTsKKyAgICAgICAgdW5jb21wcmVzc1N1ZmZpeC5wdXQoIi16IiwgIiIpOworICAgICAgICB1bmNvbXByZXNzU3VmZml4LnB1dCgiX3oiLCAiIik7CisgICAgICAgIGZpbGVOYW1lVXRpbCA9IG5ldyBGaWxlTmFtZVV0aWwodW5jb21wcmVzc1N1ZmZpeCwgIi5neiIpOworICAgIH0KKworICAgIC8qKiBQcml2YXRlIGNvbnN0cnVjdG9yIHRvIHByZXZlbnQgaW5zdGFudGlhdGlvbiBvZiB0aGlzIHV0aWxpdHkgY2xhc3MuICovCisgICAgcHJpdmF0ZSBHemlwVXRpbHMoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogRGV0ZWN0cyBjb21tb24gZ3ppcCBzdWZmaXhlcyBpbiB0aGUgZ2l2ZW4gZmlsZW5hbWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmlsZW5hbWUgbmFtZSBvZiBhIGZpbGUKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgZmlsZW5hbWUgaGFzIGEgY29tbW9uIGd6aXAgc3VmZml4LAorICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNDb21wcmVzc2VkRmlsZW5hbWUoZmluYWwgU3RyaW5nIGZpbGVuYW1lKSB7CisgICAgICAgIHJldHVybiBmaWxlTmFtZVV0aWwuaXNDb21wcmVzc2VkRmlsZW5hbWUoZmlsZW5hbWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIE1hcHMgdGhlIGdpdmVuIG5hbWUgb2YgYSBnemlwLWNvbXByZXNzZWQgZmlsZSB0byB0aGUgbmFtZSB0aGF0IHRoZQorICAgICAqIGZpbGUgc2hvdWxkIGhhdmUgYWZ0ZXIgdW5jb21wcmVzc2lvbi4gQ29tbW9ubHkgdXNlZCBmaWxlIHR5cGUgc3BlY2lmaWMKKyAgICAgKiBzdWZmaXhlcyBsaWtlICIudGd6IiBvciAiLnN2Z3oiIGFyZSBhdXRvbWF0aWNhbGx5IGRldGVjdGVkIGFuZAorICAgICAqIGNvcnJlY3RseSBtYXBwZWQuIEZvciBleGFtcGxlIHRoZSBuYW1lICJwYWNrYWdlLnRneiIgaXMgbWFwcGVkIHRvCisgICAgICogInBhY2thZ2UudGFyIi4gQW5kIGFueSBmaWxlbmFtZXMgd2l0aCB0aGUgZ2VuZXJpYyAiLmd6IiBzdWZmaXgKKyAgICAgKiAob3IgYW55IG90aGVyIGdlbmVyaWMgZ3ppcCBzdWZmaXgpIGlzIG1hcHBlZCB0byBhIG5hbWUgd2l0aG91dCB0aGF0CisgICAgICogc3VmZml4LiBJZiBubyBnemlwIHN1ZmZpeCBpcyBkZXRlY3RlZCwgdGhlbiB0aGUgZmlsZW5hbWUgaXMgcmV0dXJuZWQKKyAgICAgKiB1bm1hcHBlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmaWxlbmFtZSBuYW1lIG9mIGEgZmlsZQorICAgICAqIEByZXR1cm4gbmFtZSBvZiB0aGUgY29ycmVzcG9uZGluZyB1bmNvbXByZXNzZWQgZmlsZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldFVuY29tcHJlc3NlZEZpbGVuYW1lKGZpbmFsIFN0cmluZyBmaWxlbmFtZSkgeworICAgICAgICByZXR1cm4gZmlsZU5hbWVVdGlsLmdldFVuY29tcHJlc3NlZEZpbGVuYW1lKGZpbGVuYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBNYXBzIHRoZSBnaXZlbiBmaWxlbmFtZSB0byB0aGUgbmFtZSB0aGF0IHRoZSBmaWxlIHNob3VsZCBoYXZlIGFmdGVyCisgICAgICogY29tcHJlc3Npb24gd2l0aCBnemlwLiBDb21tb24gZmlsZSB0eXBlcyB3aXRoIGN1c3RvbSBzdWZmaXhlcyBmb3IKKyAgICAgKiBjb21wcmVzc2VkIHZlcnNpb25zIGFyZSBhdXRvbWF0aWNhbGx5IGRldGVjdGVkIGFuZCBjb3JyZWN0bHkgbWFwcGVkLgorICAgICAqIEZvciBleGFtcGxlIHRoZSBuYW1lICJwYWNrYWdlLnRhciIgaXMgbWFwcGVkIHRvICJwYWNrYWdlLnRneiIuIElmIG5vCisgICAgICogY3VzdG9tIG1hcHBpbmcgaXMgYXBwbGljYWJsZSwgdGhlbiB0aGUgZGVmYXVsdCAiLmd6IiBzdWZmaXggaXMgYXBwZW5kZWQKKyAgICAgKiB0byB0aGUgZmlsZW5hbWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmlsZW5hbWUgbmFtZSBvZiBhIGZpbGUKKyAgICAgKiBAcmV0dXJuIG5hbWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgY29tcHJlc3NlZCBmaWxlCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0Q29tcHJlc3NlZEZpbGVuYW1lKGZpbmFsIFN0cmluZyBmaWxlbmFtZSkgeworICAgICAgICByZXR1cm4gZmlsZU5hbWVVdGlsLmdldENvbXByZXNzZWRGaWxlbmFtZShmaWxlbmFtZSk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9nemlwL3BhY2thZ2UuaHRtbCBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2d6aXAvcGFja2FnZS5odG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUxOGI1MGYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9nemlwL3BhY2thZ2UuaHRtbApAQCAtMCwwICsxLDI5IEBACis8aHRtbD4KKzwhLS0KKworICAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAgIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAgIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKworICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorCisgICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKworLS0+CisgIDxib2R5PgorICAgIDxwPlByb3ZpZGVzIHN0cmVhbSBjbGFzc2VzIGZvciBjb21wcmVzc2luZyBhbmQgZGVjb21wcmVzc2luZworICAgICAgc3RyZWFtcyB1c2luZyB0aGUgR1ppcCBhbGdvcml0aG0uPC9wPgorCisgICAgPHA+VGhlIGNsYXNzZXMgaW4gdGhpcyBwYWNrYWdlIGFyZSB3cmFwcGVycyBhcm91bmQge0BsaW5rCisgICAgICBqYXZhLnV0aWwuemlwLkdaSVBJbnB1dFN0cmVhbSBqYXZhLnV0aWwuemlwLkdaSVBJbnB1dFN0cmVhbX0gYW5kCisgICAgICB7QGxpbmsgamF2YS51dGlsLnppcC5HWklQT3V0cHV0U3RyZWFtCisgICAgICBqYXZhLnV0aWwuemlwLkdaSVBPdXRwdXRTdHJlYW19LjwvcD4KKyAgPC9ib2R5PgorPC9odG1sPgpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvbHo0L0Jsb2NrTFo0Q29tcHJlc3NvcklucHV0U3RyZWFtLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9sejQvQmxvY2tMWjRDb21wcmVzc29ySW5wdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hNTJkYzYwCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvbHo0L0Jsb2NrTFo0Q29tcHJlc3NvcklucHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwxNDcgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMubHo0OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLmx6NzdzdXBwb3J0LkFic3RyYWN0TFo3N0NvbXByZXNzb3JJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuQnl0ZVV0aWxzOworCisvKioKKyAqIENvbXByZXNzb3JJbnB1dFN0cmVhbSBmb3IgdGhlIExaNCBibG9jayBmb3JtYXQuCisgKgorICogQHNlZSA8YSBocmVmPSJodHRwOi8vbHo0LmdpdGh1Yi5pby9sejQvbHo0X0Jsb2NrX2Zvcm1hdC5odG1sIj5MWjQgQmxvY2sgRm9ybWF0IERlc2NyaXB0aW9uPC9hPgorICogQHNpbmNlIDEuMTQKKyAqIEBOb3RUaHJlYWRTYWZlCisgKi8KK3B1YmxpYyBjbGFzcyBCbG9ja0xaNENvbXByZXNzb3JJbnB1dFN0cmVhbSBleHRlbmRzIEFic3RyYWN0TFo3N0NvbXByZXNzb3JJbnB1dFN0cmVhbSB7CisKKyAgICBzdGF0aWMgZmluYWwgaW50IFdJTkRPV19TSVpFID0gMSA8PCAxNjsKKyAgICBzdGF0aWMgZmluYWwgaW50IFNJWkVfQklUUyA9IDQ7CisgICAgc3RhdGljIGZpbmFsIGludCBCQUNLX1JFRkVSRU5DRV9TSVpFX01BU0sgPSAoMSA8PCBTSVpFX0JJVFMpIC0gMTsKKyAgICBzdGF0aWMgZmluYWwgaW50IExJVEVSQUxfU0laRV9NQVNLID0gQkFDS19SRUZFUkVOQ0VfU0laRV9NQVNLIDw8IFNJWkVfQklUUzsKKworICAgIC8qKiBCYWNrLVJlZmVyZW5jZS1zaXplIHBhcnQgb2YgdGhlIGJsb2NrIHN0YXJ0aW5nIGJ5dGUuICovCisgICAgcHJpdmF0ZSBpbnQgbmV4dEJhY2tSZWZlcmVuY2VTaXplOworCisgICAgLyoqIEN1cnJlbnQgc3RhdGUgb2YgdGhlIHN0cmVhbSAqLworICAgIHByaXZhdGUgU3RhdGUgc3RhdGUgPSBTdGF0ZS5OT19CTE9DSzsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgTFo0IGlucHV0IHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpcworICAgICAqICAgICAgICAgICAgQW4gSW5wdXRTdHJlYW0gdG8gcmVhZCBjb21wcmVzc2VkIGRhdGEgZnJvbQorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiByZWFkaW5nIGZhaWxzCisgICAgICovCisgICAgcHVibGljIEJsb2NrTFo0Q29tcHJlc3NvcklucHV0U3RyZWFtKGZpbmFsIElucHV0U3RyZWFtIGlzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzdXBlcihpcywgV0lORE9XX1NJWkUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIHtAaW5oZXJpdERvY30KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHJlYWQoZmluYWwgYnl0ZVtdIGIsIGZpbmFsIGludCBvZmYsIGZpbmFsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN3aXRjaCAoc3RhdGUpIHsKKyAgICAgICAgY2FzZSBFT0Y6CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIGNhc2UgTk9fQkxPQ0s6IC8vIE5PU09OQVIgLSBmYWxsdGhyb3VnaCBpbnRlbmRlZAorICAgICAgICAgICAgcmVhZFNpemVzKCk7CisgICAgICAgICAgICAvKkZBTExUSFJPVUdIKi8KKyAgICAgICAgY2FzZSBJTl9MSVRFUkFMOgorICAgICAgICAgICAgaW50IGxpdExlbiA9IHJlYWRMaXRlcmFsKGIsIG9mZiwgbGVuKTsKKyAgICAgICAgICAgIGlmICghaGFzTW9yZURhdGFJbkJsb2NrKCkpIHsKKyAgICAgICAgICAgICAgICBzdGF0ZSA9IFN0YXRlLkxPT0tJTkdfRk9SX0JBQ0tfUkVGRVJFTkNFOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGxpdExlbiA+IDAgPyBsaXRMZW4gOiByZWFkKGIsIG9mZiwgbGVuKTsKKyAgICAgICAgY2FzZSBMT09LSU5HX0ZPUl9CQUNLX1JFRkVSRU5DRTogLy8gTk9TT05BUiAtIGZhbGx0aHJvdWdoIGludGVuZGVkCisgICAgICAgICAgICBpZiAoIWluaXRpYWxpemVCYWNrUmVmZXJlbmNlKCkpIHsKKyAgICAgICAgICAgICAgICBzdGF0ZSA9IFN0YXRlLkVPRjsKKyAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICB9CisgICAgICAgICAgICAvKkZBTExUSFJPVUdIKi8KKyAgICAgICAgY2FzZSBJTl9CQUNLX1JFRkVSRU5DRToKKyAgICAgICAgICAgIGludCBiYWNrUmVmZXJlbmNlTGVuID0gcmVhZEJhY2tSZWZlcmVuY2UoYiwgb2ZmLCBsZW4pOworICAgICAgICAgICAgaWYgKCFoYXNNb3JlRGF0YUluQmxvY2soKSkgeworICAgICAgICAgICAgICAgIHN0YXRlID0gU3RhdGUuTk9fQkxPQ0s7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gYmFja1JlZmVyZW5jZUxlbiA+IDAgPyBiYWNrUmVmZXJlbmNlTGVuIDogcmVhZChiLCBvZmYsIGxlbik7CisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlVua25vd24gc3RyZWFtIHN0YXRlICIgKyBzdGF0ZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcmVhZFNpemVzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IG5leHRCbG9jayA9IHJlYWRPbmVCeXRlKCk7CisgICAgICAgIGlmIChuZXh0QmxvY2sgPT0gLTEpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiUHJlbWF0dXJlIGVuZCBvZiBzdHJlYW0gd2hpbGUgbG9va2luZyBmb3IgbmV4dCBibG9jayIpOworICAgICAgICB9CisgICAgICAgIG5leHRCYWNrUmVmZXJlbmNlU2l6ZSA9IG5leHRCbG9jayAmIEJBQ0tfUkVGRVJFTkNFX1NJWkVfTUFTSzsKKyAgICAgICAgbG9uZyBsaXRlcmFsU2l6ZVBhcnQgPSAobmV4dEJsb2NrICYgTElURVJBTF9TSVpFX01BU0spID4+IFNJWkVfQklUUzsKKyAgICAgICAgaWYgKGxpdGVyYWxTaXplUGFydCA9PSBCQUNLX1JFRkVSRU5DRV9TSVpFX01BU0spIHsKKyAgICAgICAgICAgIGxpdGVyYWxTaXplUGFydCArPSByZWFkU2l6ZUJ5dGVzKCk7CisgICAgICAgIH0KKyAgICAgICAgc3RhcnRMaXRlcmFsKGxpdGVyYWxTaXplUGFydCk7CisgICAgICAgIHN0YXRlID0gU3RhdGUuSU5fTElURVJBTDsKKyAgICB9CisKKyAgICBwcml2YXRlIGxvbmcgcmVhZFNpemVCeXRlcygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGxvbmcgYWNjdW0gPSAwOworICAgICAgICBpbnQgbmV4dEJ5dGU7CisgICAgICAgIGRvIHsKKyAgICAgICAgICAgIG5leHRCeXRlID0gcmVhZE9uZUJ5dGUoKTsKKyAgICAgICAgICAgIGlmIChuZXh0Qnl0ZSA9PSAtMSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiUHJlbWF0dXJlIGVuZCBvZiBzdHJlYW0gd2hpbGUgcGFyc2luZyBsZW5ndGgiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFjY3VtICs9IG5leHRCeXRlOworICAgICAgICB9IHdoaWxlIChuZXh0Qnl0ZSA9PSAyNTUpOworICAgICAgICByZXR1cm4gYWNjdW07CisgICAgfQorCisgICAgLyoqCisgICAgICogQHJldHVybiBmYWxzZSBpZiB0aGVyZSBpcyBubyBtb3JlIGJhY2stcmVmZXJlbmNlIC0gdGhpcyBtZWFucyB0aGlzIGlzIHRoZQorICAgICAqIGxhc3QgYmxvY2sgb2YgdGhlIHN0cmVhbS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gaW5pdGlhbGl6ZUJhY2tSZWZlcmVuY2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgYmFja1JlZmVyZW5jZU9mZnNldCA9IDA7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBiYWNrUmVmZXJlbmNlT2Zmc2V0ID0gKGludCkgQnl0ZVV0aWxzLmZyb21MaXR0bGVFbmRpYW4oc3VwcGxpZXIsIDIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgaWYgKG5leHRCYWNrUmVmZXJlbmNlU2l6ZSA9PSAwKSB7IC8vIHRoZSBsYXN0IGJsb2NrIGhhcyBubyBiYWNrLXJlZmVyZW5jZQorICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRocm93IGV4OworICAgICAgICB9CisgICAgICAgIGxvbmcgYmFja1JlZmVyZW5jZVNpemUgPSBuZXh0QmFja1JlZmVyZW5jZVNpemU7CisgICAgICAgIGlmIChuZXh0QmFja1JlZmVyZW5jZVNpemUgPT0gQkFDS19SRUZFUkVOQ0VfU0laRV9NQVNLKSB7CisgICAgICAgICAgICBiYWNrUmVmZXJlbmNlU2l6ZSArPSByZWFkU2l6ZUJ5dGVzKCk7CisgICAgICAgIH0KKyAgICAgICAgLy8gbWluaW1hbCBtYXRjaCBsZW5ndGggNCBpcyBlbmNvZGVkIGFzIDAKKyAgICAgICAgc3RhcnRCYWNrUmVmZXJlbmNlKGJhY2tSZWZlcmVuY2VPZmZzZXQsIGJhY2tSZWZlcmVuY2VTaXplICsgNCk7CisgICAgICAgIHN0YXRlID0gU3RhdGUuSU5fQkFDS19SRUZFUkVOQ0U7CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIHByaXZhdGUgZW51bSBTdGF0ZSB7CisgICAgICAgIE5PX0JMT0NLLCBJTl9MSVRFUkFMLCBMT09LSU5HX0ZPUl9CQUNLX1JFRkVSRU5DRSwgSU5fQkFDS19SRUZFUkVOQ0UsIEVPRgorICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2x6NC9CbG9ja0xaNENvbXByZXNzb3JPdXRwdXRTdHJlYW0uamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2x6NC9CbG9ja0xaNENvbXByZXNzb3JPdXRwdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ZjI0MzAwCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvbHo0L0Jsb2NrTFo0Q29tcHJlc3Nvck91dHB1dFN0cmVhbS5qYXZhCkBAIC0wLDAgKzEsNTA4IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLmx6NDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuRGVxdWU7CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5MaW5rZWRMaXN0OworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLkNvbXByZXNzb3JPdXRwdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLmx6NzdzdXBwb3J0LkxaNzdDb21wcmVzc29yOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5sejc3c3VwcG9ydC5QYXJhbWV0ZXJzOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5CeXRlVXRpbHM7CisKKy8qKgorICogQ29tcHJlc3Nvck91dHB1dFN0cmVhbSBmb3IgdGhlIExaNCBibG9jayBmb3JtYXQuCisgKgorICogQHNlZSA8YSBocmVmPSJodHRwOi8vbHo0LmdpdGh1Yi5pby9sejQvbHo0X0Jsb2NrX2Zvcm1hdC5odG1sIj5MWjQgQmxvY2sgRm9ybWF0IERlc2NyaXB0aW9uPC9hPgorICogQHNpbmNlIDEuMTQKKyAqIEBOb3RUaHJlYWRTYWZlCisgKi8KK3B1YmxpYyBjbGFzcyBCbG9ja0xaNENvbXByZXNzb3JPdXRwdXRTdHJlYW0gZXh0ZW5kcyBDb21wcmVzc29yT3V0cHV0U3RyZWFtIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNSU5fQkFDS19SRUZFUkVOQ0VfTEVOR1RIID0gNDsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTUlOX09GRlNFVF9PRl9MQVNUX0JBQ0tfUkVGRVJFTkNFID0gMTI7CisKKyAgICAvKgorCisgICAgICBUaGUgTFo0IGJsb2NrIGZvcm1hdCBoYXMgYSBmZXcgcHJvcGVydGllcyB0aGF0IG1ha2UgaXQgbGVzcworICAgICAgc3RyYWlnaHQtZm9yd2FyZCB0aGFuIG9uZSB3b3VsZCBob3BlOgorCisgICAgICAqIGxpdGVyYWwgYmxvY2tzIGFuZCBiYWNrLXJlZmVyZW5jZXMgbXVzdCBjb21lIGluIHBhaXJzIChleGNlcHQKKyAgICAgICAgZm9yIHRoZSB2ZXJ5IGxhc3QgbGl0ZXJhbCBibG9jayksIHNvIGNvbnNlY3V0aXZlIGxpdGVyYWwKKyAgICAgICAgYmxvY2tzIGNyZWF0ZWQgYnkgdGhlIGNvbXByZXNzb3IgbXVzdCBiZSBtZXJnZWQgaW50byBhIHNpbmdsZQorICAgICAgICBibG9jay4KKworICAgICAgKiB0aGUgc3RhcnQgb2YgYSBsaXRlcmFsL2JhY2stcmVmZXJlbmNlIHBhaXIgY29udGFpbnMgdGhlIGxlbmd0aAorICAgICAgICBvZiB0aGUgYmFjay1yZWZlcmVuY2UgKGF0IGxlYXN0IHNvbWUgcGFydCBvZiBpdCkgc28gd2UgY2FuJ3QKKyAgICAgICAgc3RhcnQgd3JpdGluZyB0aGUgbGl0ZXJhbCBiZWZvcmUgd2Uga25vdyBob3cgbG9uZyB0aGUgbmV4dAorICAgICAgICBiYWNrLXJlZmVyZW5jZSBpcyBnb2luZyB0byBiZS4KKworICAgICAgKiB0aGVyZSBhcmUgc3BlY2lhbCBydWxlcyBmb3IgdGhlIGZpbmFsIGJsb2NrcworCisgICAgICAgID4gVGhlcmUgYXJlIHNwZWNpZmljIHBhcnNpbmcgcnVsZXMgdG8gcmVzcGVjdCBpbiBvcmRlciB0byByZW1haW4KKyAgICAgICAgPiBjb21wYXRpYmxlIHdpdGggYXNzdW1wdGlvbnMgbWFkZSBieSB0aGUgZGVjb2RlciA6CisgICAgICAgID4KKyAgICAgICAgPiAgICAgMS4gVGhlIGxhc3QgNSBieXRlcyBhcmUgYWx3YXlzIGxpdGVyYWxzCisgICAgICAgID4KKyAgICAgICAgPiAgICAgMi4gVGhlIGxhc3QgbWF0Y2ggbXVzdCBzdGFydCBhdCBsZWFzdCAxMiBieXRlcyBiZWZvcmUgZW5kIG9mCisgICAgICAgID4gICAgICAgIGJsb2NrLiBDb25zZXF1ZW50bHksIGEgYmxvY2sgd2l0aCBsZXNzIHRoYW4gMTMgYnl0ZXMgY2Fubm90IGJlCisgICAgICAgID4gICAgICAgIGNvbXByZXNzZWQuCisKKyAgICAgICAgd2hpY2ggbWVhbnMgYW55IGJhY2stcmVmZXJlbmNlIG1heSBuZWVkIHRvIGdldCByZXdyaXR0ZW4gYXMgYQorICAgICAgICBsaXRlcmFsIGJsb2NrIHVubGVzcyB3ZSBrbm93IHRoZSBuZXh0IGJsb2NrIGlzIGF0IGxlYXN0IG9mCisgICAgICAgIGxlbmd0aCA1IGFuZCB0aGUgc3VtIG9mIHRoaXMgYmxvY2sncyBsZW5ndGggYW5kIG9mZnNldCBhbmQgdGhlCisgICAgICAgIG5leHQgYmxvY2sncyBsZW5ndGggaXMgYXQgbGVhc3QgdHdlbHZlLgorCisgICAgKi8KKworICAgIHByaXZhdGUgZmluYWwgTFo3N0NvbXByZXNzb3IgY29tcHJlc3NvcjsKKyAgICBwcml2YXRlIGZpbmFsIE91dHB1dFN0cmVhbSBvczsKKworICAgIC8vIHVzZWQgaW4gb25lLWFyZyB3cml0ZSBtZXRob2QKKyAgICBwcml2YXRlIGZpbmFsIGJ5dGVbXSBvbmVCeXRlID0gbmV3IGJ5dGVbMV07CisKKyAgICBwcml2YXRlIGJvb2xlYW4gZmluaXNoZWQgPSBmYWxzZTsKKworICAgIHByaXZhdGUgRGVxdWU8UGFpcj4gcGFpcnMgPSBuZXcgTGlua2VkTGlzdDw+KCk7CisgICAgLy8ga2VlcHMgdHJhY2sgb2YgdGhlIGxhc3Qgd2luZG93LXNpemUgYnl0ZXMgKDY0aykgaW4gb3JkZXIgdG8gYmUKKyAgICAvLyBhYmxlIHRvIGV4cGFuZCBiYWNrLXJlZmVyZW5jZXMgd2hlbiBuZWVkZWQKKyAgICBwcml2YXRlIERlcXVlPGJ5dGVbXT4gZXhwYW5kZWRCbG9ja3MgPSBuZXcgTGlua2VkTGlzdDw+KCk7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IExaNCBvdXRwdXQgc3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtIG9zCisgICAgICogICAgICAgICAgICBBbiBPdXRwdXRTdHJlYW0gdG8gcmVhZCBjb21wcmVzc2VkIGRhdGEgZnJvbQorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiByZWFkaW5nIGZhaWxzCisgICAgICovCisgICAgcHVibGljIEJsb2NrTFo0Q29tcHJlc3Nvck91dHB1dFN0cmVhbShmaW5hbCBPdXRwdXRTdHJlYW0gb3MpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMob3MsIGNyZWF0ZVBhcmFtZXRlckJ1aWxkZXIoKS5idWlsZCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IExaNCBvdXRwdXQgc3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtIG9zCisgICAgICogICAgICAgICAgICBBbiBPdXRwdXRTdHJlYW0gdG8gcmVhZCBjb21wcmVzc2VkIGRhdGEgZnJvbQorICAgICAqIEBwYXJhbSBwYXJhbXMKKyAgICAgKiAgICAgICAgICAgIFRoZSBwYXJhbWV0ZXJzIHRvIHVzZSBmb3IgTFo3NyBjb21wcmVzc2lvbi4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgcmVhZGluZyBmYWlscworICAgICAqLworICAgIHB1YmxpYyBCbG9ja0xaNENvbXByZXNzb3JPdXRwdXRTdHJlYW0oZmluYWwgT3V0cHV0U3RyZWFtIG9zLCBQYXJhbWV0ZXJzIHBhcmFtcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcy5vcyA9IG9zOworICAgICAgICBjb21wcmVzc29yID0gbmV3IExaNzdDb21wcmVzc29yKHBhcmFtcywKKyAgICAgICAgICAgIG5ldyBMWjc3Q29tcHJlc3Nvci5DYWxsYmFjaygpIHsKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBhY2NlcHQoTFo3N0NvbXByZXNzb3IuQmxvY2sgYmxvY2spIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoYmxvY2suZ2V0VHlwZSgpKSB7CisgICAgICAgICAgICAgICAgICAgIGNhc2UgTElURVJBTDoKKyAgICAgICAgICAgICAgICAgICAgICAgIGFkZExpdGVyYWxCbG9jaygoTFo3N0NvbXByZXNzb3IuTGl0ZXJhbEJsb2NrKSBibG9jayk7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSBCQUNLX1JFRkVSRU5DRToKKyAgICAgICAgICAgICAgICAgICAgICAgIGFkZEJhY2tSZWZlcmVuY2UoKExaNzdDb21wcmVzc29yLkJhY2tSZWZlcmVuY2UpIGJsb2NrKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICBjYXNlIEVPRDoKKyAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlRmluYWxMaXRlcmFsQmxvY2soKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGUoaW50IGIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG9uZUJ5dGVbMF0gPSAoYnl0ZSkgKGIgJiAweGZmKTsKKyAgICAgICAgd3JpdGUob25lQnl0ZSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGUoYnl0ZVtdIGRhdGEsIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNvbXByZXNzb3IuY29tcHJlc3MoZGF0YSwgb2ZmLCBsZW4pOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZpbmlzaCgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgb3MuY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXByZXNzZXMgYWxsIHJlbWFpbmluZyBkYXRhIGFuZCB3cml0ZXMgaXQgdG8gdGhlIHN0cmVhbSwKKyAgICAgKiBkb2Vzbid0IGNsb3NlIHRoZSB1bmRlcmx5aW5nIHN0cmVhbS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIGFuIGVycm9yIG9jY3VycworICAgICAqLworICAgIHB1YmxpYyB2b2lkIGZpbmlzaCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICghZmluaXNoZWQpIHsKKyAgICAgICAgICAgIGNvbXByZXNzb3IuZmluaXNoKCk7CisgICAgICAgICAgICBmaW5pc2hlZCA9IHRydWU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHNvbWUgaW5pdGlhbCBkYXRhIHRvIGZpbGwgdGhlIHdpbmRvdyB3aXRoLgorICAgICAqCisgICAgICogQHBhcmFtIGRhdGEgdGhlIGRhdGEgdG8gZmlsbCB0aGUgd2luZG93IHdpdGguCisgICAgICogQHBhcmFtIG9mZiBvZmZzZXQgb2YgcmVhbCBkYXRhIGludG8gdGhlIGFycmF5CisgICAgICogQHBhcmFtIGxlbiBhbW91bnQgb2YgZGF0YQorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoZSBzdHJlYW0gaGFzIGFscmVhZHkgc3RhcnRlZCB0byB3cml0ZSBkYXRhCisgICAgICogQHNlZSBMWjc3Q29tcHJlc3NvciNwcmVmaWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgcHJlZmlsbChieXRlW10gZGF0YSwgaW50IG9mZiwgaW50IGxlbikgeworICAgICAgICBpZiAobGVuID4gMCkgeworICAgICAgICAgICAgYnl0ZVtdIGIgPSBBcnJheXMuY29weU9mUmFuZ2UoZGF0YSwgb2ZmLCBvZmYgKyBsZW4pOworICAgICAgICAgICAgY29tcHJlc3Nvci5wcmVmaWxsKGIpOworICAgICAgICAgICAgcmVjb3JkTGl0ZXJhbChiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhZGRMaXRlcmFsQmxvY2soTFo3N0NvbXByZXNzb3IuTGl0ZXJhbEJsb2NrIGJsb2NrKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBQYWlyIGxhc3QgPSB3cml0ZUJsb2Nrc0FuZFJldHVyblVuZmluaXNoZWRQYWlyKGJsb2NrLmdldExlbmd0aCgpKTsKKyAgICAgICAgcmVjb3JkTGl0ZXJhbChsYXN0LmFkZExpdGVyYWwoYmxvY2spKTsKKyAgICAgICAgY2xlYXJVbnVzZWRCbG9ja3NBbmRQYWlycygpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhZGRCYWNrUmVmZXJlbmNlKExaNzdDb21wcmVzc29yLkJhY2tSZWZlcmVuY2UgYmxvY2spIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFBhaXIgbGFzdCA9IHdyaXRlQmxvY2tzQW5kUmV0dXJuVW5maW5pc2hlZFBhaXIoYmxvY2suZ2V0TGVuZ3RoKCkpOworICAgICAgICBsYXN0LnNldEJhY2tSZWZlcmVuY2UoYmxvY2spOworICAgICAgICByZWNvcmRCYWNrUmVmZXJlbmNlKGJsb2NrKTsKKyAgICAgICAgY2xlYXJVbnVzZWRCbG9ja3NBbmRQYWlycygpOworICAgIH0KKworICAgIHByaXZhdGUgUGFpciB3cml0ZUJsb2Nrc0FuZFJldHVyblVuZmluaXNoZWRQYWlyKGludCBsZW5ndGgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHdyaXRlV3JpdGFibGVQYWlycyhsZW5ndGgpOworICAgICAgICBQYWlyIGxhc3QgPSBwYWlycy5wZWVrTGFzdCgpOworICAgICAgICBpZiAobGFzdCA9PSBudWxsIHx8IGxhc3QuaGFzQmFja1JlZmVyZW5jZSgpKSB7CisgICAgICAgICAgICBsYXN0ID0gbmV3IFBhaXIoKTsKKyAgICAgICAgICAgIHBhaXJzLmFkZExhc3QobGFzdCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGxhc3Q7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHJlY29yZExpdGVyYWwoYnl0ZVtdIGIpIHsKKyAgICAgICAgZXhwYW5kZWRCbG9ja3MuYWRkRmlyc3QoYik7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNsZWFyVW51c2VkQmxvY2tzQW5kUGFpcnMoKSB7CisgICAgICAgIGNsZWFyVW51c2VkQmxvY2tzKCk7CisgICAgICAgIGNsZWFyVW51c2VkUGFpcnMoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY2xlYXJVbnVzZWRCbG9ja3MoKSB7CisgICAgICAgIGludCBibG9ja0xlbmd0aHMgPSAwOworICAgICAgICBpbnQgYmxvY2tzVG9LZWVwID0gMDsKKyAgICAgICAgZm9yIChieXRlW10gYiA6IGV4cGFuZGVkQmxvY2tzKSB7CisgICAgICAgICAgICBibG9ja3NUb0tlZXArKzsKKyAgICAgICAgICAgIGJsb2NrTGVuZ3RocyArPSBiLmxlbmd0aDsKKyAgICAgICAgICAgIGlmIChibG9ja0xlbmd0aHMgPj0gQmxvY2tMWjRDb21wcmVzc29ySW5wdXRTdHJlYW0uV0lORE9XX1NJWkUpIHsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBmaW5hbCBpbnQgc2l6ZSA9IGV4cGFuZGVkQmxvY2tzLnNpemUoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IGJsb2Nrc1RvS2VlcDsgaSA8IHNpemU7IGkrKykgeworICAgICAgICAgICAgZXhwYW5kZWRCbG9ja3MucmVtb3ZlTGFzdCgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHJlY29yZEJhY2tSZWZlcmVuY2UoTFo3N0NvbXByZXNzb3IuQmFja1JlZmVyZW5jZSBibG9jaykgeworICAgICAgICBleHBhbmRlZEJsb2Nrcy5hZGRGaXJzdChleHBhbmQoYmxvY2suZ2V0T2Zmc2V0KCksIGJsb2NrLmdldExlbmd0aCgpKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBieXRlW10gZXhwYW5kKGZpbmFsIGludCBvZmZzZXQsIGZpbmFsIGludCBsZW5ndGgpIHsKKyAgICAgICAgYnl0ZVtdIGV4cGFuZGVkID0gbmV3IGJ5dGVbbGVuZ3RoXTsKKyAgICAgICAgaWYgKG9mZnNldCA9PSAxKSB7IC8vIHN1cnByaXNpbmdseSBjb21tb24gc3BlY2lhbCBjYXNlCisgICAgICAgICAgICBieXRlW10gYmxvY2sgPSBleHBhbmRlZEJsb2Nrcy5wZWVrRmlyc3QoKTsKKyAgICAgICAgICAgIGJ5dGUgYiA9IGJsb2NrW2Jsb2NrLmxlbmd0aCAtIDFdOworICAgICAgICAgICAgaWYgKGIgIT0gMCkgeyAvLyB0aGUgZnJlc2ggYXJyYXkgY29udGFpbnMgMHMgYW55d2F5CisgICAgICAgICAgICAgICAgQXJyYXlzLmZpbGwoZXhwYW5kZWQsIGIpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZXhwYW5kRnJvbUxpc3QoZXhwYW5kZWQsIG9mZnNldCwgbGVuZ3RoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZXhwYW5kZWQ7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGV4cGFuZEZyb21MaXN0KGZpbmFsIGJ5dGVbXSBleHBhbmRlZCwgaW50IG9mZnNldCwgaW50IGxlbmd0aCkgeworICAgICAgICBpbnQgb2Zmc2V0UmVtYWluaW5nID0gb2Zmc2V0OworICAgICAgICBpbnQgbGVuZ3RoUmVtYWluaW5nID0gbGVuZ3RoOworICAgICAgICBpbnQgd3JpdGVPZmZzZXQgPSAwOworICAgICAgICB3aGlsZSAobGVuZ3RoUmVtYWluaW5nID4gMCkgeworICAgICAgICAgICAgLy8gZmluZCBibG9jayB0aGF0IGNvbnRhaW5zIG9mZnNldFJlbWFpbmluZworICAgICAgICAgICAgYnl0ZVtdIGJsb2NrID0gbnVsbDsKKyAgICAgICAgICAgIGludCBjb3B5TGVuLCBjb3B5T2Zmc2V0OworICAgICAgICAgICAgaWYgKG9mZnNldFJlbWFpbmluZyA+IDApIHsKKyAgICAgICAgICAgICAgICBpbnQgYmxvY2tPZmZzZXQgPSAwOworICAgICAgICAgICAgICAgIGZvciAoYnl0ZVtdIGIgOiBleHBhbmRlZEJsb2NrcykgeworICAgICAgICAgICAgICAgICAgICBpZiAoYi5sZW5ndGggKyBibG9ja09mZnNldCA+PSBvZmZzZXRSZW1haW5pbmcpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJsb2NrID0gYjsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGJsb2NrT2Zmc2V0ICs9IGIubGVuZ3RoOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoYmxvY2sgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAvLyBzaG91bGQgbm90IGJlIHBvc3NpYmxlCisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oImZhaWxlZCB0byBmaW5kIGEgYmxvY2sgY29udGFpbmluZyBvZmZzZXQgIiArIG9mZnNldCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGNvcHlPZmZzZXQgPSBibG9ja09mZnNldCArIGJsb2NrLmxlbmd0aCAtIG9mZnNldFJlbWFpbmluZzsKKyAgICAgICAgICAgICAgICBjb3B5TGVuID0gTWF0aC5taW4obGVuZ3RoUmVtYWluaW5nLCBibG9jay5sZW5ndGggLSBjb3B5T2Zmc2V0KTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgLy8gb2Zmc2V0UmVtYWluaW5nIGlzIG5lZ2F0aXZlIG9yIDAgYW5kIHBvaW50cyBpbnRvIHRoZSBleHBhbmRlZCBieXRlcworICAgICAgICAgICAgICAgIGJsb2NrID0gZXhwYW5kZWQ7CisgICAgICAgICAgICAgICAgY29weU9mZnNldCA9IC1vZmZzZXRSZW1haW5pbmc7CisgICAgICAgICAgICAgICAgY29weUxlbiA9IE1hdGgubWluKGxlbmd0aFJlbWFpbmluZywgd3JpdGVPZmZzZXQgKyBvZmZzZXRSZW1haW5pbmcpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShibG9jaywgY29weU9mZnNldCwgZXhwYW5kZWQsIHdyaXRlT2Zmc2V0LCBjb3B5TGVuKTsKKyAgICAgICAgICAgIG9mZnNldFJlbWFpbmluZyAtPSBjb3B5TGVuOworICAgICAgICAgICAgbGVuZ3RoUmVtYWluaW5nIC09IGNvcHlMZW47CisgICAgICAgICAgICB3cml0ZU9mZnNldCArPSBjb3B5TGVuOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNsZWFyVW51c2VkUGFpcnMoKSB7CisgICAgICAgIGludCBwYWlyTGVuZ3RocyA9IDA7CisgICAgICAgIGludCBwYWlyc1RvS2VlcCA9IDA7CisgICAgICAgIGZvciAoSXRlcmF0b3I8UGFpcj4gaXQgPSBwYWlycy5kZXNjZW5kaW5nSXRlcmF0b3IoKTsgaXQuaGFzTmV4dCgpOyApIHsKKyAgICAgICAgICAgIFBhaXIgcCA9IGl0Lm5leHQoKTsKKyAgICAgICAgICAgIHBhaXJzVG9LZWVwKys7CisgICAgICAgICAgICBwYWlyTGVuZ3RocyArPSBwLmxlbmd0aCgpOworICAgICAgICAgICAgaWYgKHBhaXJMZW5ndGhzID49IEJsb2NrTFo0Q29tcHJlc3NvcklucHV0U3RyZWFtLldJTkRPV19TSVpFKSB7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgZmluYWwgaW50IHNpemUgPSBwYWlycy5zaXplKCk7CisgICAgICAgIGZvciAoaW50IGkgPSBwYWlyc1RvS2VlcDsgaSA8IHNpemU7IGkrKykgeworICAgICAgICAgICAgUGFpciBwID0gcGFpcnMucGVla0ZpcnN0KCk7CisgICAgICAgICAgICBpZiAocC5oYXNCZWVuV3JpdHRlbigpKSB7CisgICAgICAgICAgICAgICAgcGFpcnMucmVtb3ZlRmlyc3QoKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgd3JpdGVGaW5hbExpdGVyYWxCbG9jaygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJld3JpdGVMYXN0UGFpcnMoKTsKKyAgICAgICAgZm9yIChQYWlyIHAgOiBwYWlycykgeworICAgICAgICAgICAgaWYgKCFwLmhhc0JlZW5Xcml0dGVuKCkpIHsKKyAgICAgICAgICAgICAgICBwLndyaXRlVG8ob3MpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHBhaXJzLmNsZWFyKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlV3JpdGFibGVQYWlycyhpbnQgbGVuZ3RoT2ZCbG9ja3NBZnRlckxhc3RQYWlyKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgdW53cml0dGVuTGVuZ3RoID0gbGVuZ3RoT2ZCbG9ja3NBZnRlckxhc3RQYWlyOworICAgICAgICBmb3IgKEl0ZXJhdG9yPFBhaXI+IGl0ID0gcGFpcnMuZGVzY2VuZGluZ0l0ZXJhdG9yKCk7IGl0Lmhhc05leHQoKTsgKSB7CisgICAgICAgICAgICBQYWlyIHAgPSBpdC5uZXh0KCk7CisgICAgICAgICAgICBpZiAocC5oYXNCZWVuV3JpdHRlbigpKSB7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB1bndyaXR0ZW5MZW5ndGggKz0gcC5sZW5ndGgoKTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKFBhaXIgcCA6IHBhaXJzKSB7CisgICAgICAgICAgICBpZiAocC5oYXNCZWVuV3JpdHRlbigpKSB7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB1bndyaXR0ZW5MZW5ndGggLT0gcC5sZW5ndGgoKTsKKyAgICAgICAgICAgIGlmIChwLmNhbkJlV3JpdHRlbih1bndyaXR0ZW5MZW5ndGgpKSB7CisgICAgICAgICAgICAgICAgcC53cml0ZVRvKG9zKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcmV3cml0ZUxhc3RQYWlycygpIHsKKyAgICAgICAgTGlua2VkTGlzdDxQYWlyPiBsYXN0UGFpcnMgPSBuZXcgTGlua2VkTGlzdDw+KCk7CisgICAgICAgIExpbmtlZExpc3Q8SW50ZWdlcj4gcGFpckxlbmd0aCA9IG5ldyBMaW5rZWRMaXN0PD4oKTsKKyAgICAgICAgaW50IG9mZnNldCA9IDA7CisgICAgICAgIGZvciAoSXRlcmF0b3I8UGFpcj4gaXQgPSBwYWlycy5kZXNjZW5kaW5nSXRlcmF0b3IoKTsgaXQuaGFzTmV4dCgpOyApIHsKKyAgICAgICAgICAgIFBhaXIgcCA9IGl0Lm5leHQoKTsKKyAgICAgICAgICAgIGlmIChwLmhhc0JlZW5Xcml0dGVuKCkpIHsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGludCBsZW4gPSBwLmxlbmd0aCgpOworICAgICAgICAgICAgcGFpckxlbmd0aC5hZGRGaXJzdChsZW4pOworICAgICAgICAgICAgbGFzdFBhaXJzLmFkZEZpcnN0KHApOworICAgICAgICAgICAgb2Zmc2V0ICs9IGxlbjsKKyAgICAgICAgICAgIGlmIChvZmZzZXQgPj0gTUlOX09GRlNFVF9PRl9MQVNUX0JBQ0tfUkVGRVJFTkNFKSB7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgZm9yIChQYWlyIHAgOiBsYXN0UGFpcnMpIHsKKyAgICAgICAgICAgIHBhaXJzLnJlbW92ZShwKTsKKyAgICAgICAgfQorICAgICAgICAvLyBsYXN0UGFpcnMgbWF5IGNvbnRhaW4gYmV0d2VlbiBvbmUgYW5kIGZvdXIgUGFpcnM6CisgICAgICAgIC8vICogdGhlIGxhc3QgcGFpciBtYXkgYmUgYSBvbmUgYnl0ZSBsaXRlcmFsCisgICAgICAgIC8vICogYWxsIG90aGVyIFBhaXJzIGNvbnRhaW4gYSBiYWNrLXJlZmVyZW5jZSB3aGljaCBtdXN0IGJlIGZvdXIgYnl0ZXMgbG9uZyBhdCBtaW5pbXVtCisgICAgICAgIC8vIHdlIGNvdWxkIG1lcmdlIHRoZW0gYWxsIGludG8gYSBzaW5nbGUgbGl0ZXJhbCBibG9jayBidXQKKyAgICAgICAgLy8gdGhpcyBtYXkgaGFybSBjb21wcmVzc2lvbi4gRm9yIGV4YW1wbGUgY29tcHJlc3NpbmcKKyAgICAgICAgLy8gImJsYS50YXIiIGZyb20gb3VyIHRlc3RzIHlpZWxkcyBhIGxhc3QgYmxvY2sgY29udGFpbmluZyBhCisgICAgICAgIC8vIGJhY2stcmVmZXJlbmNlIG9mIGxlbmd0aCA+IDJrIGFuZCB3ZSdkIGVuZCB1cCB3aXRoIGEgbGFzdAorICAgICAgICAvLyBsaXRlcmFsIG9mIHRoYXQgc2l6ZSByYXRoZXIgdGhhbiBhIDJrIGJhY2stcmVmZXJlbmNlIGFuZCBhCisgICAgICAgIC8vIDEyIGJ5dGUgbGl0ZXJhbCBhdCB0aGUgZW5kLgorCisgICAgICAgIC8vIEluc3RlYWQgd2UgbWVyZ2UgYWxsIGJ1dCB0aGUgZmlyc3Qgb2YgbGFzdFBhaXJzIGludG8gYSBuZXcKKyAgICAgICAgLy8gbGl0ZXJhbC1vbmx5IFBhaXIgInJlcGxhY2VtZW50IiBhbmQgbG9vayBhdCB0aGUKKyAgICAgICAgLy8gYmFjay1yZWZlcmVuY2UgaW4gdGhlIGZpcnN0IG9mIGxhc3RQYWlycyBhbmQgc2VlIGlmIHdlIGNhbgorICAgICAgICAvLyBzcGxpdCBpdC4gV2UgY2FuIHNwbGl0IGl0IGlmIGl0IGlzIGxvbmdlciB0aGFuIDE2IC0KKyAgICAgICAgLy8gcmVwbGFjZW1lbnQubGVuZ3RoIChpLmUuIHRoZSBtaW5pbWFsIGxlbmd0aCBvZiBmb3VyIGlzIGtlcHQKKyAgICAgICAgLy8gd2hpbGUgbWFraW5nIHN1cmUgdGhlIGxhc3QgbGl0ZXJhbCBpcyBhdCBsZWFzdCB0d2VsdmUgYnl0ZXMKKyAgICAgICAgLy8gbG9uZykuIElmIHdlIGNhbid0IHNwbGl0IGl0LCB3ZSBleHBhbmQgdGhlIGZpcnN0IG9mIHRoZSBwYWlycworICAgICAgICAvLyBhcyB3ZWxsLgorCisgICAgICAgIC8vIHRoaXMgaXMgbm90IG9wdGltYWwsIHdlIGNvdWxkIGdldCBiZXR0ZXIgY29tcHJlc3Npb24KKyAgICAgICAgLy8gcmVzdWx0cyB3aXRoIG1vcmUgY29tcGxleCBhcHByb2FjaGVzIGFzIHRoZSBsYXN0IGxpdGVyYWwKKyAgICAgICAgLy8gb25seSBuZWVkcyB0byBiZSBmaXZlIGJ5dGVzIGxvbmcgaWYgdGhlIHByZXZpb3VzCisgICAgICAgIC8vIGJhY2stcmVmZXJlbmNlIGhhcyBhbiBvZmZzZXQgYmlnIGVub3VnaAorCisgICAgICAgIGZpbmFsIGludCBsYXN0UGFpcnNTaXplID0gbGFzdFBhaXJzLnNpemUoKTsKKyAgICAgICAgaW50IHRvRXhwYW5kID0gMDsKKyAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPCBsYXN0UGFpcnNTaXplOyBpKyspIHsKKyAgICAgICAgICAgIHRvRXhwYW5kICs9IHBhaXJMZW5ndGguZ2V0KGkpOworICAgICAgICB9CisgICAgICAgIFBhaXIgcmVwbGFjZW1lbnQgPSBuZXcgUGFpcigpOworICAgICAgICBpZiAodG9FeHBhbmQgPiAwKSB7CisgICAgICAgICAgICByZXBsYWNlbWVudC5wcmVwZW5kTGl0ZXJhbChleHBhbmQodG9FeHBhbmQsIHRvRXhwYW5kKSk7CisgICAgICAgIH0KKyAgICAgICAgUGFpciBzcGxpdENhbmRpZGF0ZSA9IGxhc3RQYWlycy5nZXQoMCk7CisgICAgICAgIGludCBzdGlsbE5lZWRlZCA9IE1JTl9PRkZTRVRfT0ZfTEFTVF9CQUNLX1JFRkVSRU5DRSAtIHRvRXhwYW5kOworICAgICAgICBpbnQgYnJMZW4gPSBzcGxpdENhbmRpZGF0ZS5oYXNCYWNrUmVmZXJlbmNlKCkgPyBzcGxpdENhbmRpZGF0ZS5iYWNrUmVmZXJlbmNlTGVuZ3RoKCkgOiAwOworICAgICAgICBpZiAoc3BsaXRDYW5kaWRhdGUuaGFzQmFja1JlZmVyZW5jZSgpICYmIGJyTGVuID49IE1JTl9CQUNLX1JFRkVSRU5DRV9MRU5HVEggKyBzdGlsbE5lZWRlZCkgeworICAgICAgICAgICAgcmVwbGFjZW1lbnQucHJlcGVuZExpdGVyYWwoZXhwYW5kKHRvRXhwYW5kICsgc3RpbGxOZWVkZWQsIHN0aWxsTmVlZGVkKSk7CisgICAgICAgICAgICBwYWlycy5hZGQoc3BsaXRDYW5kaWRhdGUuc3BsaXRXaXRoTmV3QmFja1JlZmVyZW5jZUxlbmd0aE9mKGJyTGVuIC0gc3RpbGxOZWVkZWQpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGlmIChzcGxpdENhbmRpZGF0ZS5oYXNCYWNrUmVmZXJlbmNlKCkpIHsKKyAgICAgICAgICAgICAgICByZXBsYWNlbWVudC5wcmVwZW5kTGl0ZXJhbChleHBhbmQodG9FeHBhbmQgKyBickxlbiwgYnJMZW4pKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHNwbGl0Q2FuZGlkYXRlLnByZXBlbmRUbyhyZXBsYWNlbWVudCk7CisgICAgICAgIH0KKyAgICAgICAgcGFpcnMuYWRkKHJlcGxhY2VtZW50KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgYnVpbGRlciBjb3JyZWN0bHkgY29uZmlndXJlZCBmb3IgdGhlIExaNCBhbGdvcml0aG0uCisgICAgICogQHJldHVybiBhIGJ1aWxkZXIgY29ycmVjdGx5IGNvbmZpZ3VyZWQgZm9yIHRoZSBMWjQgYWxnb3JpdGhtCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBQYXJhbWV0ZXJzLkJ1aWxkZXIgY3JlYXRlUGFyYW1ldGVyQnVpbGRlcigpIHsKKyAgICAgICAgaW50IG1heExlbiA9IEJsb2NrTFo0Q29tcHJlc3NvcklucHV0U3RyZWFtLldJTkRPV19TSVpFIC0gMTsKKyAgICAgICAgcmV0dXJuIFBhcmFtZXRlcnMuYnVpbGRlcihCbG9ja0xaNENvbXByZXNzb3JJbnB1dFN0cmVhbS5XSU5ET1dfU0laRSkKKyAgICAgICAgICAgIC53aXRoTWluQmFja1JlZmVyZW5jZUxlbmd0aChNSU5fQkFDS19SRUZFUkVOQ0VfTEVOR1RIKQorICAgICAgICAgICAgLndpdGhNYXhCYWNrUmVmZXJlbmNlTGVuZ3RoKG1heExlbikKKyAgICAgICAgICAgIC53aXRoTWF4T2Zmc2V0KG1heExlbikKKyAgICAgICAgICAgIC53aXRoTWF4TGl0ZXJhbExlbmd0aChtYXhMZW4pOworICAgIH0KKworICAgIGZpbmFsIHN0YXRpYyBjbGFzcyBQYWlyIHsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBEZXF1ZTxieXRlW10+IGxpdGVyYWxzID0gbmV3IExpbmtlZExpc3Q8PigpOworICAgICAgICBwcml2YXRlIGludCBick9mZnNldCwgYnJMZW5ndGg7CisgICAgICAgIHByaXZhdGUgYm9vbGVhbiB3cml0dGVuOworCisgICAgICAgIHByaXZhdGUgdm9pZCBwcmVwZW5kTGl0ZXJhbChieXRlW10gZGF0YSkgeworICAgICAgICAgICAgbGl0ZXJhbHMuYWRkRmlyc3QoZGF0YSk7CisgICAgICAgIH0KKyAgICAgICAgYnl0ZVtdIGFkZExpdGVyYWwoTFo3N0NvbXByZXNzb3IuTGl0ZXJhbEJsb2NrIGJsb2NrKSB7CisgICAgICAgICAgICBieXRlW10gY29weSA9IEFycmF5cy5jb3B5T2ZSYW5nZShibG9jay5nZXREYXRhKCksIGJsb2NrLmdldE9mZnNldCgpLAorICAgICAgICAgICAgICAgIGJsb2NrLmdldE9mZnNldCgpICsgYmxvY2suZ2V0TGVuZ3RoKCkpOworICAgICAgICAgICAgbGl0ZXJhbHMuYWRkKGNvcHkpOworICAgICAgICAgICAgcmV0dXJuIGNvcHk7CisgICAgICAgIH0KKyAgICAgICAgdm9pZCBzZXRCYWNrUmVmZXJlbmNlKExaNzdDb21wcmVzc29yLkJhY2tSZWZlcmVuY2UgYmxvY2spIHsKKyAgICAgICAgICAgIGlmIChoYXNCYWNrUmVmZXJlbmNlKCkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBick9mZnNldCA9IGJsb2NrLmdldE9mZnNldCgpOworICAgICAgICAgICAgYnJMZW5ndGggPSBibG9jay5nZXRMZW5ndGgoKTsKKyAgICAgICAgfQorICAgICAgICBib29sZWFuIGhhc0JhY2tSZWZlcmVuY2UoKSB7CisgICAgICAgICAgICByZXR1cm4gYnJPZmZzZXQgPiAwOworICAgICAgICB9CisgICAgICAgIGJvb2xlYW4gY2FuQmVXcml0dGVuKGludCBsZW5ndGhPZkJsb2Nrc0FmdGVyVGhpc1BhaXIpIHsKKyAgICAgICAgICAgIHJldHVybiBoYXNCYWNrUmVmZXJlbmNlKCkKKyAgICAgICAgICAgICAgICAmJiBsZW5ndGhPZkJsb2Nrc0FmdGVyVGhpc1BhaXIgPj0gTUlOX09GRlNFVF9PRl9MQVNUX0JBQ0tfUkVGRVJFTkNFICsgTUlOX0JBQ0tfUkVGRVJFTkNFX0xFTkdUSDsKKyAgICAgICAgfQorICAgICAgICBpbnQgbGVuZ3RoKCkgeworICAgICAgICAgICAgcmV0dXJuIGxpdGVyYWxMZW5ndGgoKSArIGJyTGVuZ3RoOworICAgICAgICB9CisgICAgICAgIHByaXZhdGUgYm9vbGVhbiBoYXNCZWVuV3JpdHRlbigpIHsKKyAgICAgICAgICAgIHJldHVybiB3cml0dGVuOworICAgICAgICB9CisgICAgICAgIHZvaWQgd3JpdGVUbyhPdXRwdXRTdHJlYW0gb3V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgaW50IGxpdExlbmd0aCA9IGxpdGVyYWxMZW5ndGgoKTsKKyAgICAgICAgICAgIG91dC53cml0ZShsZW5ndGhzKGxpdExlbmd0aCwgYnJMZW5ndGgpKTsKKyAgICAgICAgICAgIGlmIChsaXRMZW5ndGggPj0gQmxvY2tMWjRDb21wcmVzc29ySW5wdXRTdHJlYW0uQkFDS19SRUZFUkVOQ0VfU0laRV9NQVNLKSB7CisgICAgICAgICAgICAgICAgd3JpdGVMZW5ndGgobGl0TGVuZ3RoIC0gQmxvY2tMWjRDb21wcmVzc29ySW5wdXRTdHJlYW0uQkFDS19SRUZFUkVOQ0VfU0laRV9NQVNLLCBvdXQpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZm9yIChieXRlW10gYiA6IGxpdGVyYWxzKSB7CisgICAgICAgICAgICAgICAgb3V0LndyaXRlKGIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGhhc0JhY2tSZWZlcmVuY2UoKSkgeworICAgICAgICAgICAgICAgIEJ5dGVVdGlscy50b0xpdHRsZUVuZGlhbihvdXQsIGJyT2Zmc2V0LCAyKTsKKyAgICAgICAgICAgICAgICBpZiAoYnJMZW5ndGggLSBNSU5fQkFDS19SRUZFUkVOQ0VfTEVOR1RIID49IEJsb2NrTFo0Q29tcHJlc3NvcklucHV0U3RyZWFtLkJBQ0tfUkVGRVJFTkNFX1NJWkVfTUFTSykgeworICAgICAgICAgICAgICAgICAgICB3cml0ZUxlbmd0aChickxlbmd0aCAtIE1JTl9CQUNLX1JFRkVSRU5DRV9MRU5HVEgKKyAgICAgICAgICAgICAgICAgICAgICAgIC0gQmxvY2tMWjRDb21wcmVzc29ySW5wdXRTdHJlYW0uQkFDS19SRUZFUkVOQ0VfU0laRV9NQVNLLCBvdXQpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHdyaXR0ZW4gPSB0cnVlOworICAgICAgICB9CisgICAgICAgIHByaXZhdGUgaW50IGxpdGVyYWxMZW5ndGgoKSB7CisgICAgICAgICAgICBpbnQgbGVuZ3RoID0gMDsKKyAgICAgICAgICAgIGZvciAoYnl0ZVtdIGIgOiBsaXRlcmFscykgeworICAgICAgICAgICAgICAgIGxlbmd0aCArPSBiLmxlbmd0aDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBsZW5ndGg7CisgICAgICAgIH0KKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgaW50IGxlbmd0aHMoaW50IGxpdExlbmd0aCwgaW50IGJyTGVuZ3RoKSB7CisgICAgICAgICAgICBpbnQgbCA9IGxpdExlbmd0aCA8IDE1ID8gbGl0TGVuZ3RoIDogMTU7CisgICAgICAgICAgICBpbnQgYnIgPSBickxlbmd0aCA8IDQgPyAwIDogKGJyTGVuZ3RoIDwgMTkgPyBickxlbmd0aCAtIDQgOiAxNSk7CisgICAgICAgICAgICByZXR1cm4gKGwgPDwgQmxvY2tMWjRDb21wcmVzc29ySW5wdXRTdHJlYW0uU0laRV9CSVRTKSB8IGJyOworICAgICAgICB9CisgICAgICAgIHByaXZhdGUgc3RhdGljIHZvaWQgd3JpdGVMZW5ndGgoaW50IGxlbmd0aCwgT3V0cHV0U3RyZWFtIG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHdoaWxlIChsZW5ndGggPj0gMjU1KSB7CisgICAgICAgICAgICAgICAgb3V0LndyaXRlKDI1NSk7CisgICAgICAgICAgICAgICAgbGVuZ3RoIC09IDI1NTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIG91dC53cml0ZShsZW5ndGgpOworICAgICAgICB9CisgICAgICAgIHByaXZhdGUgaW50IGJhY2tSZWZlcmVuY2VMZW5ndGgoKSB7CisgICAgICAgICAgICByZXR1cm4gYnJMZW5ndGg7CisgICAgICAgIH0KKyAgICAgICAgcHJpdmF0ZSB2b2lkIHByZXBlbmRUbyhQYWlyIG90aGVyKSB7CisgICAgICAgICAgICBJdGVyYXRvcjxieXRlW10+IGxpc3RCYWNrd2FyZHMgPSBsaXRlcmFscy5kZXNjZW5kaW5nSXRlcmF0b3IoKTsKKyAgICAgICAgICAgIHdoaWxlIChsaXN0QmFja3dhcmRzLmhhc05leHQoKSkgeworICAgICAgICAgICAgICAgIG90aGVyLnByZXBlbmRMaXRlcmFsKGxpc3RCYWNrd2FyZHMubmV4dCgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBwcml2YXRlIFBhaXIgc3BsaXRXaXRoTmV3QmFja1JlZmVyZW5jZUxlbmd0aE9mKGludCBuZXdCYWNrUmVmZXJlbmNlTGVuZ3RoKSB7CisgICAgICAgICAgICBQYWlyIHAgPSBuZXcgUGFpcigpOworICAgICAgICAgICAgcC5saXRlcmFscy5hZGRBbGwobGl0ZXJhbHMpOworICAgICAgICAgICAgcC5ick9mZnNldCA9IGJyT2Zmc2V0OworICAgICAgICAgICAgcC5ickxlbmd0aCA9IG5ld0JhY2tSZWZlcmVuY2VMZW5ndGg7CisgICAgICAgICAgICByZXR1cm4gcDsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2x6NC9GcmFtZWRMWjRDb21wcmVzc29ySW5wdXRTdHJlYW0uamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2x6NC9GcmFtZWRMWjRDb21wcmVzc29ySW5wdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42Y2I2NmVjCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvbHo0L0ZyYW1lZExaNENvbXByZXNzb3JJbnB1dFN0cmVhbS5qYXZhCkBAIC0wLDAgKzEsNDA0IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLmx6NDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLkNvbXByZXNzb3JJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuQm91bmRlZElucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5CeXRlVXRpbHM7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLkNoZWNrc3VtQ2FsY3VsYXRpbmdJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuQ291bnRpbmdJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuSU9VdGlsczsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuSW5wdXRTdHJlYW1TdGF0aXN0aWNzOworCisvKioKKyAqIENvbXByZXNzb3JJbnB1dFN0cmVhbSBmb3IgdGhlIExaNCBmcmFtZSBmb3JtYXQuCisgKgorICogPHA+QmFzZWQgb24gdGhlICJzcGVjIiBpbiB0aGUgdmVyc2lvbiAiMS41LjEgKDMxLzAzLzIwMTUpIjwvcD4KKyAqCisgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly9sejQuZ2l0aHViLmlvL2x6NC9sejRfRnJhbWVfZm9ybWF0Lmh0bWwiPkxaNCBGcmFtZSBGb3JtYXQgRGVzY3JpcHRpb248L2E+CisgKiBAc2luY2UgMS4xNAorICogQE5vdFRocmVhZFNhZmUKKyAqLworcHVibGljIGNsYXNzIEZyYW1lZExaNENvbXByZXNzb3JJbnB1dFN0cmVhbSBleHRlbmRzIENvbXByZXNzb3JJbnB1dFN0cmVhbQorICAgIGltcGxlbWVudHMgSW5wdXRTdHJlYW1TdGF0aXN0aWNzIHsKKworICAgIC8vIHVzZWQgYnkgRnJhbWVkTFo0Q29tcHJlc3Nvck91dHB1dFN0cmVhbSBhcyB3ZWxsCisgICAgc3RhdGljIGZpbmFsIGJ5dGVbXSBMWjRfU0lHTkFUVVJFID0gbmV3IGJ5dGVbXSB7IC8vTk9TT05BUgorICAgICAgICA0LCAweDIyLCAweDRkLCAweDE4CisgICAgfTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gU0tJUFBBQkxFX0ZSQU1FX1RSQUlMRVIgPSBuZXcgYnl0ZVtdIHsKKyAgICAgICAgMHgyYSwgMHg0ZCwgMHgxOAorICAgIH07CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZSBTS0lQUEFCTEVfRlJBTUVfUFJFRklYX0JZVEVfTUFTSyA9IDB4NTA7CisKKyAgICBzdGF0aWMgZmluYWwgaW50IFZFUlNJT05fTUFTSyA9IDB4QzA7CisgICAgc3RhdGljIGZpbmFsIGludCBTVVBQT1JURURfVkVSU0lPTiA9IDB4NDA7CisgICAgc3RhdGljIGZpbmFsIGludCBCTE9DS19JTkRFUEVOREVOQ0VfTUFTSyA9IDB4MjA7CisgICAgc3RhdGljIGZpbmFsIGludCBCTE9DS19DSEVDS1NVTV9NQVNLID0gMHgxMDsKKyAgICBzdGF0aWMgZmluYWwgaW50IENPTlRFTlRfU0laRV9NQVNLID0gMHgwODsKKyAgICBzdGF0aWMgZmluYWwgaW50IENPTlRFTlRfQ0hFQ0tTVU1fTUFTSyA9IDB4MDQ7CisgICAgc3RhdGljIGZpbmFsIGludCBCTE9DS19NQVhfU0laRV9NQVNLID0gMHg3MDsKKyAgICBzdGF0aWMgZmluYWwgaW50IFVOQ09NUFJFU1NFRF9GTEFHX01BU0sgPSAweDgwMDAwMDAwOworCisgICAgLy8gdXNlZCBpbiBuby1hcmcgcmVhZCBtZXRob2QKKyAgICBwcml2YXRlIGZpbmFsIGJ5dGVbXSBvbmVCeXRlID0gbmV3IGJ5dGVbMV07CisKKyAgICBwcml2YXRlIGZpbmFsIEJ5dGVVdGlscy5CeXRlU3VwcGxpZXIgc3VwcGxpZXIgPSBuZXcgQnl0ZVV0aWxzLkJ5dGVTdXBwbGllcigpIHsKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBpbnQgZ2V0QXNCeXRlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiByZWFkT25lQnl0ZSgpOworICAgICAgICB9CisgICAgfTsKKworICAgIHByaXZhdGUgZmluYWwgQ291bnRpbmdJbnB1dFN0cmVhbSBpbjsKKyAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gZGVjb21wcmVzc0NvbmNhdGVuYXRlZDsKKworICAgIHByaXZhdGUgYm9vbGVhbiBleHBlY3RCbG9ja0NoZWNrc3VtOworICAgIHByaXZhdGUgYm9vbGVhbiBleHBlY3RCbG9ja0RlcGVuZGVuY3k7CisgICAgcHJpdmF0ZSBib29sZWFuIGV4cGVjdENvbnRlbnRTaXplOworICAgIHByaXZhdGUgYm9vbGVhbiBleHBlY3RDb250ZW50Q2hlY2tzdW07CisKKyAgICBwcml2YXRlIElucHV0U3RyZWFtIGN1cnJlbnRCbG9jazsKKyAgICBwcml2YXRlIGJvb2xlYW4gZW5kUmVhY2hlZCwgaW5VbmNvbXByZXNzZWQ7CisKKyAgICAvLyB1c2VkIGZvciBmcmFtZSBoZWFkZXIgY2hlY2tzdW0gYW5kIGNvbnRlbnQgY2hlY2tzdW0sIGlmIHByZXNlbnQKKyAgICBwcml2YXRlIGZpbmFsIFhYSGFzaDMyIGNvbnRlbnRIYXNoID0gbmV3IFhYSGFzaDMyKCk7CisKKyAgICAvLyB1c2VkIGZvciBibG9jayBjaGVja3N1bSwgaWYgcHJlc2VudAorICAgIHByaXZhdGUgZmluYWwgWFhIYXNoMzIgYmxvY2tIYXNoID0gbmV3IFhYSGFzaDMyKCk7CisKKyAgICAvLyBvbmx5IGNyZWF0ZWQgaWYgdGhlIGZyYW1lIGRvZXNuJ3Qgc2V0IHRoZSBibG9jayBpbmRlcGVuZGVuY2UgZmxhZworICAgIHByaXZhdGUgYnl0ZVtdIGJsb2NrRGVwZW5kZW5jeUJ1ZmZlcjsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgaW5wdXQgc3RyZWFtIHRoYXQgZGVjb21wcmVzc2VzIHN0cmVhbXMgY29tcHJlc3NlZAorICAgICAqIHVzaW5nIHRoZSBMWjQgZnJhbWUgZm9ybWF0IGFuZCBzdG9wcyBhZnRlciBkZWNvbXByZXNzaW5nIHRoZQorICAgICAqIGZpcnN0IGZyYW1lLgorICAgICAqIEBwYXJhbSBpbiAgdGhlIElucHV0U3RyZWFtIGZyb20gd2hpY2ggdG8gcmVhZCB0aGUgY29tcHJlc3NlZCBkYXRhCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiByZWFkaW5nIGZhaWxzCisgICAgICovCisgICAgcHVibGljIEZyYW1lZExaNENvbXByZXNzb3JJbnB1dFN0cmVhbShJbnB1dFN0cmVhbSBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcyhpbiwgZmFsc2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgaW5wdXQgc3RyZWFtIHRoYXQgZGVjb21wcmVzc2VzIHN0cmVhbXMgY29tcHJlc3NlZAorICAgICAqIHVzaW5nIHRoZSBMWjQgZnJhbWUgZm9ybWF0LgorICAgICAqIEBwYXJhbSBpbiAgdGhlIElucHV0U3RyZWFtIGZyb20gd2hpY2ggdG8gcmVhZCB0aGUgY29tcHJlc3NlZCBkYXRhCisgICAgICogQHBhcmFtIGRlY29tcHJlc3NDb25jYXRlbmF0ZWQgaWYgdHJ1ZSwgZGVjb21wcmVzcyB1bnRpbCB0aGUgZW5kCisgICAgICogICAgICAgICAgb2YgdGhlIGlucHV0OyBpZiBmYWxzZSwgc3RvcCBhZnRlciB0aGUgZmlyc3QgTFo0IGZyYW1lCisgICAgICogICAgICAgICAgYW5kIGxlYXZlIHRoZSBpbnB1dCBwb3NpdGlvbiB0byBwb2ludCB0byB0aGUgbmV4dCBieXRlCisgICAgICogICAgICAgICAgYWZ0ZXIgdGhlIGZyYW1lIHN0cmVhbQorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgcmVhZGluZyBmYWlscworICAgICAqLworICAgIHB1YmxpYyBGcmFtZWRMWjRDb21wcmVzc29ySW5wdXRTdHJlYW0oSW5wdXRTdHJlYW0gaW4sIGJvb2xlYW4gZGVjb21wcmVzc0NvbmNhdGVuYXRlZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcy5pbiA9IG5ldyBDb3VudGluZ0lucHV0U3RyZWFtKGluKTsKKyAgICAgICAgdGhpcy5kZWNvbXByZXNzQ29uY2F0ZW5hdGVkID0gZGVjb21wcmVzc0NvbmNhdGVuYXRlZDsKKyAgICAgICAgaW5pdCh0cnVlKTsKKyAgICB9CisKKyAgICAvKioge0Bpbmhlcml0RG9jfSAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiByZWFkKG9uZUJ5dGUsIDAsIDEpID09IC0xID8gLTEgOiBvbmVCeXRlWzBdICYgMHhGRjsKKyAgICB9CisKKyAgICAvKioge0Bpbmhlcml0RG9jfSAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlmIChjdXJyZW50QmxvY2sgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGN1cnJlbnRCbG9jay5jbG9zZSgpOworICAgICAgICAgICAgICAgIGN1cnJlbnRCbG9jayA9IG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqIHtAaW5oZXJpdERvY30gKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHJlYWQoZmluYWwgYnl0ZVtdIGIsIGZpbmFsIGludCBvZmYsIGZpbmFsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChlbmRSZWFjaGVkKSB7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICAgICAgaW50IHIgPSByZWFkT25jZShiLCBvZmYsIGxlbik7CisgICAgICAgIGlmIChyID09IC0xKSB7CisgICAgICAgICAgICBuZXh0QmxvY2soKTsKKyAgICAgICAgICAgIGlmICghZW5kUmVhY2hlZCkgeworICAgICAgICAgICAgICAgIHIgPSByZWFkT25jZShiLCBvZmYsIGxlbik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKHIgIT0gLTEpIHsKKyAgICAgICAgICAgIGlmIChleHBlY3RCbG9ja0RlcGVuZGVuY3kpIHsKKyAgICAgICAgICAgICAgICBhcHBlbmRUb0Jsb2NrRGVwZW5kZW5jeUJ1ZmZlcihiLCBvZmYsIHIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGV4cGVjdENvbnRlbnRDaGVja3N1bSkgeworICAgICAgICAgICAgICAgIGNvbnRlbnRIYXNoLnVwZGF0ZShiLCBvZmYsIHIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiByOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzaW5jZSAxLjE3CisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGxvbmcgZ2V0Q29tcHJlc3NlZENvdW50KCkgeworICAgICAgICByZXR1cm4gaW4uZ2V0Qnl0ZXNSZWFkKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGluaXQoYm9vbGVhbiBmaXJzdEZyYW1lKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAocmVhZFNpZ25hdHVyZShmaXJzdEZyYW1lKSkgeworICAgICAgICAgICAgcmVhZEZyYW1lRGVzY3JpcHRvcigpOworICAgICAgICAgICAgbmV4dEJsb2NrKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIGJvb2xlYW4gcmVhZFNpZ25hdHVyZShib29sZWFuIGZpcnN0RnJhbWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBnYXJiYWdlTWVzc2FnZSA9IGZpcnN0RnJhbWUgPyAiTm90IGEgTFo0IGZyYW1lIHN0cmVhbSIgOiAiTFo0IGZyYW1lIHN0cmVhbSBmb2xsb3dlZCBieSBnYXJiYWdlIjsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGIgPSBuZXcgYnl0ZVs0XTsKKyAgICAgICAgaW50IHJlYWQgPSBJT1V0aWxzLnJlYWRGdWxseShpbiwgYik7CisgICAgICAgIGNvdW50KHJlYWQpOworICAgICAgICBpZiAoMCA9PSByZWFkICYmICFmaXJzdEZyYW1lKSB7CisgICAgICAgICAgICAvLyBnb29kIExaNCBmcmFtZSBhbmQgbm90aGluZyBhZnRlciBpdAorICAgICAgICAgICAgZW5kUmVhY2hlZCA9IHRydWU7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgaWYgKDQgIT0gcmVhZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKGdhcmJhZ2VNZXNzYWdlKTsKKyAgICAgICAgfQorCisgICAgICAgIHJlYWQgPSBza2lwU2tpcHBhYmxlRnJhbWUoYik7CisgICAgICAgIGlmICgwID09IHJlYWQgJiYgIWZpcnN0RnJhbWUpIHsKKyAgICAgICAgICAgIC8vIGdvb2QgTFo0IGZyYW1lIHdpdGggb25seSBzb21lIHNraXBwYWJsZSBmcmFtZXMgYWZ0ZXIgaXQKKyAgICAgICAgICAgIGVuZFJlYWNoZWQgPSB0cnVlOworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIGlmICg0ICE9IHJlYWQgfHwgIW1hdGNoZXMoYiwgNCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihnYXJiYWdlTWVzc2FnZSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHJlYWRGcmFtZURlc2NyaXB0b3IoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgZmxhZ3MgPSByZWFkT25lQnl0ZSgpOworICAgICAgICBpZiAoZmxhZ3MgPT0gLTEpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiUHJlbWF0dXJlIGVuZCBvZiBzdHJlYW0gd2hpbGUgcmVhZGluZyBmcmFtZSBmbGFncyIpOworICAgICAgICB9CisgICAgICAgIGNvbnRlbnRIYXNoLnVwZGF0ZShmbGFncyk7CisgICAgICAgIGlmICgoZmxhZ3MgJiBWRVJTSU9OX01BU0spICE9IFNVUFBPUlRFRF9WRVJTSU9OKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlVuc3VwcG9ydGVkIHZlcnNpb24gIiArIChmbGFncyA+PiA2KSk7CisgICAgICAgIH0KKyAgICAgICAgZXhwZWN0QmxvY2tEZXBlbmRlbmN5ID0gKGZsYWdzICYgQkxPQ0tfSU5ERVBFTkRFTkNFX01BU0spID09IDA7CisgICAgICAgIGlmIChleHBlY3RCbG9ja0RlcGVuZGVuY3kpIHsKKyAgICAgICAgICAgIGlmIChibG9ja0RlcGVuZGVuY3lCdWZmZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGJsb2NrRGVwZW5kZW5jeUJ1ZmZlciA9IG5ldyBieXRlW0Jsb2NrTFo0Q29tcHJlc3NvcklucHV0U3RyZWFtLldJTkRPV19TSVpFXTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGJsb2NrRGVwZW5kZW5jeUJ1ZmZlciA9IG51bGw7CisgICAgICAgIH0KKyAgICAgICAgZXhwZWN0QmxvY2tDaGVja3N1bSA9IChmbGFncyAmIEJMT0NLX0NIRUNLU1VNX01BU0spICE9IDA7CisgICAgICAgIGV4cGVjdENvbnRlbnRTaXplID0gKGZsYWdzICYgQ09OVEVOVF9TSVpFX01BU0spICE9IDA7CisgICAgICAgIGV4cGVjdENvbnRlbnRDaGVja3N1bSA9IChmbGFncyAmIENPTlRFTlRfQ0hFQ0tTVU1fTUFTSykgIT0gMDsKKyAgICAgICAgaW50IGJkQnl0ZSA9IHJlYWRPbmVCeXRlKCk7CisgICAgICAgIGlmIChiZEJ5dGUgPT0gLTEpIHsgLy8gbWF4IHNpemUgaXMgaXJyZWxldmFudCBmb3IgdGhpcyBpbXBsZW1lbnRhdGlvbgorICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJQcmVtYXR1cmUgZW5kIG9mIHN0cmVhbSB3aGlsZSByZWFkaW5nIGZyYW1lIEJEIGJ5dGUiKTsKKyAgICAgICAgfQorICAgICAgICBjb250ZW50SGFzaC51cGRhdGUoYmRCeXRlKTsKKyAgICAgICAgaWYgKGV4cGVjdENvbnRlbnRTaXplKSB7IC8vIGZvciBub3cgd2UgZG9uJ3QgY2FyZSwgY29udGFpbnMgdGhlIHVuY29tcHJlc3NlZCBzaXplCisgICAgICAgICAgICBieXRlW10gY29udGVudFNpemUgPSBuZXcgYnl0ZVs4XTsKKyAgICAgICAgICAgIGludCBza2lwcGVkID0gSU9VdGlscy5yZWFkRnVsbHkoaW4sIGNvbnRlbnRTaXplKTsKKyAgICAgICAgICAgIGNvdW50KHNraXBwZWQpOworICAgICAgICAgICAgaWYgKDggIT0gc2tpcHBlZCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiUHJlbWF0dXJlIGVuZCBvZiBzdHJlYW0gd2hpbGUgcmVhZGluZyBjb250ZW50IHNpemUiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNvbnRlbnRIYXNoLnVwZGF0ZShjb250ZW50U2l6ZSwgMCwgY29udGVudFNpemUubGVuZ3RoKTsKKyAgICAgICAgfQorICAgICAgICBpbnQgaGVhZGVySGFzaCA9IHJlYWRPbmVCeXRlKCk7CisgICAgICAgIGlmIChoZWFkZXJIYXNoID09IC0xKSB7IC8vIHBhcnRpYWwgaGFzaCBvZiBoZWFkZXIuCisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlByZW1hdHVyZSBlbmQgb2Ygc3RyZWFtIHdoaWxlIHJlYWRpbmcgZnJhbWUgaGVhZGVyIGNoZWNrc3VtIik7CisgICAgICAgIH0KKyAgICAgICAgaW50IGV4cGVjdGVkSGFzaCA9IChpbnQpICgoY29udGVudEhhc2guZ2V0VmFsdWUoKSA+PiA4KSAmIDB4ZmYpOworICAgICAgICBjb250ZW50SGFzaC5yZXNldCgpOworICAgICAgICBpZiAoaGVhZGVySGFzaCAhPSBleHBlY3RlZEhhc2gpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiZnJhbWUgaGVhZGVyIGNoZWNrc3VtIG1pc21hdGNoLiIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIG5leHRCbG9jaygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG1heWJlRmluaXNoQ3VycmVudEJsb2NrKCk7CisgICAgICAgIGxvbmcgbGVuID0gQnl0ZVV0aWxzLmZyb21MaXR0bGVFbmRpYW4oc3VwcGxpZXIsIDQpOworICAgICAgICBib29sZWFuIHVuY29tcHJlc3NlZCA9IChsZW4gJiBVTkNPTVBSRVNTRURfRkxBR19NQVNLKSAhPSAwOworICAgICAgICBpbnQgcmVhbExlbiA9IChpbnQpIChsZW4gJiAoflVOQ09NUFJFU1NFRF9GTEFHX01BU0spKTsKKyAgICAgICAgaWYgKHJlYWxMZW4gPT0gMCkgeworICAgICAgICAgICAgdmVyaWZ5Q29udGVudENoZWNrc3VtKCk7CisgICAgICAgICAgICBpZiAoIWRlY29tcHJlc3NDb25jYXRlbmF0ZWQpIHsKKyAgICAgICAgICAgICAgICBlbmRSZWFjaGVkID0gdHJ1ZTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgaW5pdChmYWxzZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgSW5wdXRTdHJlYW0gY2FwcGVkID0gbmV3IEJvdW5kZWRJbnB1dFN0cmVhbShpbiwgcmVhbExlbik7CisgICAgICAgIGlmIChleHBlY3RCbG9ja0NoZWNrc3VtKSB7CisgICAgICAgICAgICBjYXBwZWQgPSBuZXcgQ2hlY2tzdW1DYWxjdWxhdGluZ0lucHV0U3RyZWFtKGJsb2NrSGFzaCwgY2FwcGVkKTsKKyAgICAgICAgfQorICAgICAgICBpZiAodW5jb21wcmVzc2VkKSB7CisgICAgICAgICAgICBpblVuY29tcHJlc3NlZCA9IHRydWU7CisgICAgICAgICAgICBjdXJyZW50QmxvY2sgPSBjYXBwZWQ7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpblVuY29tcHJlc3NlZCA9IGZhbHNlOworICAgICAgICAgICAgQmxvY2tMWjRDb21wcmVzc29ySW5wdXRTdHJlYW0gcyA9IG5ldyBCbG9ja0xaNENvbXByZXNzb3JJbnB1dFN0cmVhbShjYXBwZWQpOworICAgICAgICAgICAgaWYgKGV4cGVjdEJsb2NrRGVwZW5kZW5jeSkgeworICAgICAgICAgICAgICAgIHMucHJlZmlsbChibG9ja0RlcGVuZGVuY3lCdWZmZXIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgY3VycmVudEJsb2NrID0gczsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBtYXliZUZpbmlzaEN1cnJlbnRCbG9jaygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChjdXJyZW50QmxvY2sgIT0gbnVsbCkgeworICAgICAgICAgICAgY3VycmVudEJsb2NrLmNsb3NlKCk7CisgICAgICAgICAgICBjdXJyZW50QmxvY2sgPSBudWxsOworICAgICAgICAgICAgaWYgKGV4cGVjdEJsb2NrQ2hlY2tzdW0pIHsKKyAgICAgICAgICAgICAgICB2ZXJpZnlDaGVja3N1bShibG9ja0hhc2gsICJibG9jayIpOworICAgICAgICAgICAgICAgIGJsb2NrSGFzaC5yZXNldCgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHZlcmlmeUNvbnRlbnRDaGVja3N1bSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChleHBlY3RDb250ZW50Q2hlY2tzdW0pIHsKKyAgICAgICAgICAgIHZlcmlmeUNoZWNrc3VtKGNvbnRlbnRIYXNoLCAiY29udGVudCIpOworICAgICAgICB9CisgICAgICAgIGNvbnRlbnRIYXNoLnJlc2V0KCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHZlcmlmeUNoZWNrc3VtKFhYSGFzaDMyIGhhc2gsIFN0cmluZyBraW5kKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBieXRlW10gY2hlY2tzdW0gPSBuZXcgYnl0ZVs0XTsKKyAgICAgICAgaW50IHJlYWQgPSBJT1V0aWxzLnJlYWRGdWxseShpbiwgY2hlY2tzdW0pOworICAgICAgICBjb3VudChyZWFkKTsKKyAgICAgICAgaWYgKDQgIT0gcmVhZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJQcmVtYXR1cmUgZW5kIG9mIHN0cmVhbSB3aGlsZSByZWFkaW5nICIgKyBraW5kICsgIiBjaGVja3N1bSIpOworICAgICAgICB9CisgICAgICAgIGxvbmcgZXhwZWN0ZWRIYXNoID0gaGFzaC5nZXRWYWx1ZSgpOworICAgICAgICBpZiAoZXhwZWN0ZWRIYXNoICE9IEJ5dGVVdGlscy5mcm9tTGl0dGxlRW5kaWFuKGNoZWNrc3VtKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKGtpbmQgKyAiIGNoZWNrc3VtIG1pc21hdGNoLiIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnQgcmVhZE9uZUJ5dGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBpbnQgYiA9IGluLnJlYWQoKTsKKyAgICAgICAgaWYgKGIgIT0gLTEpIHsKKyAgICAgICAgICAgIGNvdW50KDEpOworICAgICAgICAgICAgcmV0dXJuIGIgJiAweEZGOworICAgICAgICB9CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICBwcml2YXRlIGludCByZWFkT25jZShieXRlW10gYiwgaW50IG9mZiwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGluVW5jb21wcmVzc2VkKSB7CisgICAgICAgICAgICBpbnQgY250ID0gY3VycmVudEJsb2NrLnJlYWQoYiwgb2ZmLCBsZW4pOworICAgICAgICAgICAgY291bnQoY250KTsKKyAgICAgICAgICAgIHJldHVybiBjbnQ7CisgICAgICAgIH0KKyAgICAgICAgQmxvY2tMWjRDb21wcmVzc29ySW5wdXRTdHJlYW0gbCA9IChCbG9ja0xaNENvbXByZXNzb3JJbnB1dFN0cmVhbSkgY3VycmVudEJsb2NrOworICAgICAgICBsb25nIGJlZm9yZSA9IGwuZ2V0Qnl0ZXNSZWFkKCk7CisgICAgICAgIGludCBjbnQgPSBjdXJyZW50QmxvY2sucmVhZChiLCBvZmYsIGxlbik7CisgICAgICAgIGNvdW50KGwuZ2V0Qnl0ZXNSZWFkKCkgLSBiZWZvcmUpOworICAgICAgICByZXR1cm4gY250OworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNTa2lwcGFibGVGcmFtZVNpZ25hdHVyZShieXRlW10gYikgeworICAgICAgICBpZiAoKGJbMF0gJiBTS0lQUEFCTEVfRlJBTUVfUFJFRklYX0JZVEVfTUFTSykgIT0gU0tJUFBBQkxFX0ZSQU1FX1BSRUZJWF9CWVRFX01BU0spIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8IDQ7IGkrKykgeworICAgICAgICAgICAgaWYgKGJbaV0gIT0gU0tJUFBBQkxFX0ZSQU1FX1RSQUlMRVJbaSAtIDFdKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNraXBzIG92ZXIgdGhlIGNvbnRlbnRzIG9mIGEgc2tpcHBhYmxlIGZyYW1lIGFzIHdlbGwgYXMKKyAgICAgKiBza2lwcGFibGUgZnJhbWVzIGZvbGxvd2luZyBpdC4KKyAgICAgKgorICAgICAqIDxwPkl0IHRoZW4gdHJpZXMgdG8gcmVhZCBmb3VyIG1vcmUgYnl0ZXMgd2hpY2ggYXJlIHN1cHBvc2VkIHRvCisgICAgICogaG9sZCBhbiBMWjQgc2lnbmF0dXJlIGFuZCByZXR1cm5zIHRoZSBudW1iZXIgb2YgYnl0ZXMgcmVhZAorICAgICAqIHdoaWxlIHN0b3JpbmcgdGhlIGJ5dGVzIGluIHRoZSBnaXZlbiBhcnJheS48L3A+CisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgc2tpcFNraXBwYWJsZUZyYW1lKGJ5dGVbXSBiKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgcmVhZCA9IDQ7CisgICAgICAgIHdoaWxlIChyZWFkID09IDQgJiYgaXNTa2lwcGFibGVGcmFtZVNpZ25hdHVyZShiKSkgeworICAgICAgICAgICAgbG9uZyBsZW4gPSBCeXRlVXRpbHMuZnJvbUxpdHRsZUVuZGlhbihzdXBwbGllciwgNCk7CisgICAgICAgICAgICBsb25nIHNraXBwZWQgPSBJT1V0aWxzLnNraXAoaW4sIGxlbik7CisgICAgICAgICAgICBjb3VudChza2lwcGVkKTsKKyAgICAgICAgICAgIGlmIChsZW4gIT0gc2tpcHBlZCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiUHJlbWF0dXJlIGVuZCBvZiBzdHJlYW0gd2hpbGUgc2tpcHBpbmcgZnJhbWUiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJlYWQgPSBJT1V0aWxzLnJlYWRGdWxseShpbiwgYik7CisgICAgICAgICAgICBjb3VudChyZWFkKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVhZDsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYXBwZW5kVG9CbG9ja0RlcGVuZGVuY3lCdWZmZXIoZmluYWwgYnl0ZVtdIGIsIGZpbmFsIGludCBvZmYsIGludCBsZW4pIHsKKyAgICAgICAgbGVuID0gTWF0aC5taW4obGVuLCBibG9ja0RlcGVuZGVuY3lCdWZmZXIubGVuZ3RoKTsKKyAgICAgICAgaWYgKGxlbiA+IDApIHsKKyAgICAgICAgICAgIGludCBrZWVwID0gYmxvY2tEZXBlbmRlbmN5QnVmZmVyLmxlbmd0aCAtIGxlbjsKKyAgICAgICAgICAgIGlmIChrZWVwID4gMCkgeworICAgICAgICAgICAgICAgIC8vIG1vdmUgbGFzdCBrZWVwIGJ5dGVzIHRvd2FyZHMgdGhlIHN0YXJ0IG9mIHRoZSBidWZmZXIKKyAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGJsb2NrRGVwZW5kZW5jeUJ1ZmZlciwgbGVuLCBibG9ja0RlcGVuZGVuY3lCdWZmZXIsIDAsIGtlZXApOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gYXBwZW5kIG5ldyBkYXRhCisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGIsIG9mZiwgYmxvY2tEZXBlbmRlbmN5QnVmZmVyLCBrZWVwLCBsZW4pOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIHRoZSBzaWduYXR1cmUgbWF0Y2hlcyB3aGF0IGlzIGV4cGVjdGVkIGZvciBhIC5sejQgZmlsZS4KKyAgICAgKgorICAgICAqIDxwPi5sejQgZmlsZXMgc3RhcnQgd2l0aCBhIGZvdXIgYnl0ZSBzaWduYXR1cmUuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIHNpZ25hdHVyZSB0aGUgYnl0ZXMgdG8gY2hlY2sKKyAgICAgKiBAcGFyYW0gbGVuZ3RoICAgIHRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gY2hlY2sKKyAgICAgKiBAcmV0dXJuICAgICAgICAgIHRydWUgaWYgdGhpcyBpcyBhIC5zeiBzdHJlYW0sIGZhbHNlIG90aGVyd2lzZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBtYXRjaGVzKGZpbmFsIGJ5dGVbXSBzaWduYXR1cmUsIGZpbmFsIGludCBsZW5ndGgpIHsKKworICAgICAgICBpZiAobGVuZ3RoIDwgTFo0X1NJR05BVFVSRS5sZW5ndGgpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIGJ5dGVbXSBzaG9ydGVuZWRTaWcgPSBzaWduYXR1cmU7CisgICAgICAgIGlmIChzaWduYXR1cmUubGVuZ3RoID4gTFo0X1NJR05BVFVSRS5sZW5ndGgpIHsKKyAgICAgICAgICAgIHNob3J0ZW5lZFNpZyA9IG5ldyBieXRlW0xaNF9TSUdOQVRVUkUubGVuZ3RoXTsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoc2lnbmF0dXJlLCAwLCBzaG9ydGVuZWRTaWcsIDAsIExaNF9TSUdOQVRVUkUubGVuZ3RoKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBBcnJheXMuZXF1YWxzKHNob3J0ZW5lZFNpZywgTFo0X1NJR05BVFVSRSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvbHo0L0ZyYW1lZExaNENvbXByZXNzb3JPdXRwdXRTdHJlYW0uamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2x6NC9GcmFtZWRMWjRDb21wcmVzc29yT3V0cHV0U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGJkMDAyMwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2x6NC9GcmFtZWRMWjRDb21wcmVzc29yT3V0cHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwzMjkgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMubHo0OworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5Db21wcmVzc29yT3V0cHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5CeXRlVXRpbHM7CisKKy8qKgorICogQ29tcHJlc3Nvck91dHB1dFN0cmVhbSBmb3IgdGhlIExaNCBmcmFtZSBmb3JtYXQuCisgKgorICogPHA+QmFzZWQgb24gdGhlICJzcGVjIiBpbiB0aGUgdmVyc2lvbiAiMS41LjEgKDMxLzAzLzIwMTUpIjwvcD4KKyAqCisgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly9sejQuZ2l0aHViLmlvL2x6NC9sejRfRnJhbWVfZm9ybWF0Lmh0bWwiPkxaNCBGcmFtZSBGb3JtYXQgRGVzY3JpcHRpb248L2E+CisgKiBAc2luY2UgMS4xNAorICogQE5vdFRocmVhZFNhZmUKKyAqLworcHVibGljIGNsYXNzIEZyYW1lZExaNENvbXByZXNzb3JPdXRwdXRTdHJlYW0gZXh0ZW5kcyBDb21wcmVzc29yT3V0cHV0U3RyZWFtIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBFTkRfTUFSSyA9IG5ldyBieXRlWzRdOworCisgICAgLy8gdXNlZCBpbiBvbmUtYXJnIHdyaXRlIG1ldGhvZAorICAgIHByaXZhdGUgZmluYWwgYnl0ZVtdIG9uZUJ5dGUgPSBuZXcgYnl0ZVsxXTsKKworICAgIHByaXZhdGUgZmluYWwgYnl0ZVtdIGJsb2NrRGF0YTsKKyAgICBwcml2YXRlIGZpbmFsIE91dHB1dFN0cmVhbSBvdXQ7CisgICAgcHJpdmF0ZSBmaW5hbCBQYXJhbWV0ZXJzIHBhcmFtczsKKyAgICBwcml2YXRlIGJvb2xlYW4gZmluaXNoZWQgPSBmYWxzZTsKKyAgICBwcml2YXRlIGludCBjdXJyZW50SW5kZXggPSAwOworCisgICAgLy8gdXNlZCBmb3IgZnJhbWUgaGVhZGVyIGNoZWNrc3VtIGFuZCBjb250ZW50IGNoZWNrc3VtLCBpZiByZXF1ZXN0ZWQKKyAgICBwcml2YXRlIGZpbmFsIFhYSGFzaDMyIGNvbnRlbnRIYXNoID0gbmV3IFhYSGFzaDMyKCk7CisgICAgLy8gdXNlZCBmb3IgYmxvY2sgY2hlY2tzdW0sIGlmIHJlcXVlc3RlZAorICAgIHByaXZhdGUgZmluYWwgWFhIYXNoMzIgYmxvY2tIYXNoOworCisgICAgLy8gb25seSBjcmVhdGVkIGlmIHRoZSBjb25maWcgcmVxdWlyZXMgYmxvY2sgZGVwZW5kZW5jeQorICAgIHByaXZhdGUgYnl0ZVtdIGJsb2NrRGVwZW5kZW5jeUJ1ZmZlcjsKKyAgICBwcml2YXRlIGludCBjb2xsZWN0ZWRCbG9ja0RlcGVuZGVuY3lCeXRlczsKKworICAgIC8qKgorICAgICAqIFRoZSBibG9jayBzaXplcyBzdXBwb3J0ZWQgYnkgdGhlIGZvcm1hdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgZW51bSBCbG9ja1NpemUgeworICAgICAgICAvKiogQmxvY2sgc2l6ZSBvZiA2NEsgKi8KKyAgICAgICAgSzY0KDY0ICogMTAyNCwgNCksCisgICAgICAgIC8qKiBCbG9jayBzaXplIG9mIDI1NksgKi8KKyAgICAgICAgSzI1NigyNTYgKiAxMDI0LCA1KSwKKyAgICAgICAgLyoqIEJsb2NrIHNpemUgb2YgMU0gKi8KKyAgICAgICAgTTEoMTAyNCAqIDEwMjQsIDYpLAorICAgICAgICAvKiogQmxvY2sgc2l6ZSBvZiA0TSAqLworICAgICAgICBNNCg0MDk2ICogMTAyNCwgNyk7CisKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBpbnQgc2l6ZSwgaW5kZXg7CisgICAgICAgIEJsb2NrU2l6ZShpbnQgc2l6ZSwgaW50IGluZGV4KSB7CisgICAgICAgICAgICB0aGlzLnNpemUgPSBzaXplOworICAgICAgICAgICAgdGhpcy5pbmRleCA9IGluZGV4OworICAgICAgICB9CisgICAgICAgIGludCBnZXRTaXplKCkgeworICAgICAgICAgICAgcmV0dXJuIHNpemU7CisgICAgICAgIH0KKyAgICAgICAgaW50IGdldEluZGV4KCkgeworICAgICAgICAgICAgcmV0dXJuIGluZGV4OworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyYW1ldGVycyBvZiB0aGUgTFo0IGZyYW1lIGZvcm1hdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFBhcmFtZXRlcnMgeworICAgICAgICBwcml2YXRlIGZpbmFsIEJsb2NrU2l6ZSBibG9ja1NpemU7CisgICAgICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiB3aXRoQ29udGVudENoZWNrc3VtLCB3aXRoQmxvY2tDaGVja3N1bSwgd2l0aEJsb2NrRGVwZW5kZW5jeTsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMubHo3N3N1cHBvcnQuUGFyYW1ldGVycyBsejc3cGFyYW1zOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgZGVmYXVsdCBwYXJhbWV0ZXJzIG9mIDRNIGJsb2NrIHNpemUsIGVuYWJsZWQgY29udGVudAorICAgICAgICAgKiBjaGVja3N1bSwgZGlzYWJsZWQgYmxvY2sgY2hlY2tzdW1zIGFuZCBpbmRlcGVuZGVudCBibG9ja3MuCisgICAgICAgICAqCisgICAgICAgICAqIDxwPlRoaXMgbWF0Y2hlcyB0aGUgZGVmYXVsdHMgb2YgdGhlIGx6NCBjb21tYW5kIGxpbmUgdXRpbGl0eS48L3A+CisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFBhcmFtZXRlcnMgREVGQVVMVCA9IG5ldyBQYXJhbWV0ZXJzKEJsb2NrU2l6ZS5NNCwgdHJ1ZSwgZmFsc2UsIGZhbHNlKTsKKworICAgICAgICAvKioKKyAgICAgICAgICogU2V0cyB1cCBjdXN0b20gYSBjdXN0b20gYmxvY2sgc2l6ZSBmb3IgdGhlIExaNCBzdHJlYW0gYnV0CisgICAgICAgICAqIG90aGVyd2lzZSB1c2VzIHRoZSBkZWZhdWx0cyBvZiBlbmFibGVkIGNvbnRlbnQgY2hlY2tzdW0sCisgICAgICAgICAqIGRpc2FibGVkIGJsb2NrIGNoZWNrc3VtcyBhbmQgaW5kZXBlbmRlbnQgYmxvY2tzLgorICAgICAgICAgKiBAcGFyYW0gYmxvY2tTaXplIHRoZSBzaXplIG9mIGEgc2luZ2xlIGJsb2NrLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIFBhcmFtZXRlcnMoQmxvY2tTaXplIGJsb2NrU2l6ZSkgeworICAgICAgICAgICAgdGhpcyhibG9ja1NpemUsIHRydWUsIGZhbHNlLCBmYWxzZSk7CisgICAgICAgIH0KKyAgICAgICAgLyoqCisgICAgICAgICAqIFNldHMgdXAgY3VzdG9tIGEgY3VzdG9tIGJsb2NrIHNpemUgZm9yIHRoZSBMWjQgc3RyZWFtIGJ1dAorICAgICAgICAgKiBvdGhlcndpc2UgdXNlcyB0aGUgZGVmYXVsdHMgb2YgZW5hYmxlZCBjb250ZW50IGNoZWNrc3VtLAorICAgICAgICAgKiBkaXNhYmxlZCBibG9jayBjaGVja3N1bXMgYW5kIGluZGVwZW5kZW50IGJsb2Nrcy4KKyAgICAgICAgICogQHBhcmFtIGJsb2NrU2l6ZSB0aGUgc2l6ZSBvZiBhIHNpbmdsZSBibG9jay4KKyAgICAgICAgICogQHBhcmFtIGx6NzdwYXJhbXMgcGFyYW1ldGVycyB1c2VkIHRvIGZpbmUtdHVuZSBjb21wcmVzc2lvbiwKKyAgICAgICAgICogaW4gcGFydGljdWxhciB0byBiYWxhbmNlIGNvbXByZXNzaW9uIHJhdGlvIHZzIGNvbXByZXNzaW9uCisgICAgICAgICAqIHNwZWVkLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIFBhcmFtZXRlcnMoQmxvY2tTaXplIGJsb2NrU2l6ZSwKKyAgICAgICAgICAgIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5sejc3c3VwcG9ydC5QYXJhbWV0ZXJzIGx6NzdwYXJhbXMpIHsKKyAgICAgICAgICAgIHRoaXMoYmxvY2tTaXplLCB0cnVlLCBmYWxzZSwgZmFsc2UsIGx6NzdwYXJhbXMpOworICAgICAgICB9CisgICAgICAgIC8qKgorICAgICAgICAgKiBTZXRzIHVwIGN1c3RvbSBwYXJhbWV0ZXJzIGZvciB0aGUgTFo0IHN0cmVhbS4KKyAgICAgICAgICogQHBhcmFtIGJsb2NrU2l6ZSB0aGUgc2l6ZSBvZiBhIHNpbmdsZSBibG9jay4KKyAgICAgICAgICogQHBhcmFtIHdpdGhDb250ZW50Q2hlY2tzdW0gd2hldGhlciB0byB3cml0ZSBhIGNvbnRlbnQgY2hlY2tzdW0KKyAgICAgICAgICogQHBhcmFtIHdpdGhCbG9ja0NoZWNrc3VtIHdoZXRoZXIgdG8gd3JpdGUgYSBibG9jayBjaGVja3N1bS4KKyAgICAgICAgICogTm90ZSB0aGF0IGJsb2NrIGNoZWNrc3VtcyBhcmUgbm90IHN1cHBvcnRlZCBieSB0aGUgbHo0CisgICAgICAgICAqIGNvbW1hbmQgbGluZSB1dGlsaXR5CisgICAgICAgICAqIEBwYXJhbSB3aXRoQmxvY2tEZXBlbmRlbmN5IHdoZXRoZXIgYSBibG9jayBtYXkgZGVwZW5kIG9uCisgICAgICAgICAqIHRoZSBjb250ZW50IG9mIGEgcHJldmlvdXMgYmxvY2suIEVuYWJsaW5nIHRoaXMgbWF5IGltcHJvdmUKKyAgICAgICAgICogY29tcHJlc3Npb24gcmF0aW8gYnV0IG1ha2VzIGl0IGltcG9zc2libGUgdG8gZGVjb21wcmVzcyB0aGUKKyAgICAgICAgICogb3V0cHV0IGluIHBhcmFsbGVsLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIFBhcmFtZXRlcnMoQmxvY2tTaXplIGJsb2NrU2l6ZSwgYm9vbGVhbiB3aXRoQ29udGVudENoZWNrc3VtLCBib29sZWFuIHdpdGhCbG9ja0NoZWNrc3VtLAorICAgICAgICAgICAgYm9vbGVhbiB3aXRoQmxvY2tEZXBlbmRlbmN5KSB7CisgICAgICAgICAgICB0aGlzKGJsb2NrU2l6ZSwgd2l0aENvbnRlbnRDaGVja3N1bSwgd2l0aEJsb2NrQ2hlY2tzdW0sIHdpdGhCbG9ja0RlcGVuZGVuY3ksCisgICAgICAgICAgICAgICAgIEJsb2NrTFo0Q29tcHJlc3Nvck91dHB1dFN0cmVhbS5jcmVhdGVQYXJhbWV0ZXJCdWlsZGVyKCkuYnVpbGQoKSk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogU2V0cyB1cCBjdXN0b20gcGFyYW1ldGVycyBmb3IgdGhlIExaNCBzdHJlYW0uCisgICAgICAgICAqIEBwYXJhbSBibG9ja1NpemUgdGhlIHNpemUgb2YgYSBzaW5nbGUgYmxvY2suCisgICAgICAgICAqIEBwYXJhbSB3aXRoQ29udGVudENoZWNrc3VtIHdoZXRoZXIgdG8gd3JpdGUgYSBjb250ZW50IGNoZWNrc3VtCisgICAgICAgICAqIEBwYXJhbSB3aXRoQmxvY2tDaGVja3N1bSB3aGV0aGVyIHRvIHdyaXRlIGEgYmxvY2sgY2hlY2tzdW0uCisgICAgICAgICAqIE5vdGUgdGhhdCBibG9jayBjaGVja3N1bXMgYXJlIG5vdCBzdXBwb3J0ZWQgYnkgdGhlIGx6NAorICAgICAgICAgKiBjb21tYW5kIGxpbmUgdXRpbGl0eQorICAgICAgICAgKiBAcGFyYW0gd2l0aEJsb2NrRGVwZW5kZW5jeSB3aGV0aGVyIGEgYmxvY2sgbWF5IGRlcGVuZCBvbgorICAgICAgICAgKiB0aGUgY29udGVudCBvZiBhIHByZXZpb3VzIGJsb2NrLiBFbmFibGluZyB0aGlzIG1heSBpbXByb3ZlCisgICAgICAgICAqIGNvbXByZXNzaW9uIHJhdGlvIGJ1dCBtYWtlcyBpdCBpbXBvc3NpYmxlIHRvIGRlY29tcHJlc3MgdGhlCisgICAgICAgICAqIG91dHB1dCBpbiBwYXJhbGxlbC4KKyAgICAgICAgICogQHBhcmFtIGx6NzdwYXJhbXMgcGFyYW1ldGVycyB1c2VkIHRvIGZpbmUtdHVuZSBjb21wcmVzc2lvbiwKKyAgICAgICAgICogaW4gcGFydGljdWxhciB0byBiYWxhbmNlIGNvbXByZXNzaW9uIHJhdGlvIHZzIGNvbXByZXNzaW9uCisgICAgICAgICAqIHNwZWVkLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIFBhcmFtZXRlcnMoQmxvY2tTaXplIGJsb2NrU2l6ZSwgYm9vbGVhbiB3aXRoQ29udGVudENoZWNrc3VtLCBib29sZWFuIHdpdGhCbG9ja0NoZWNrc3VtLAorICAgICAgICAgICAgICAgIGJvb2xlYW4gd2l0aEJsb2NrRGVwZW5kZW5jeSwKKyAgICAgICAgICAgICAgICBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMubHo3N3N1cHBvcnQuUGFyYW1ldGVycyBsejc3cGFyYW1zKSB7CisgICAgICAgICAgICB0aGlzLmJsb2NrU2l6ZSA9IGJsb2NrU2l6ZTsKKyAgICAgICAgICAgIHRoaXMud2l0aENvbnRlbnRDaGVja3N1bSA9IHdpdGhDb250ZW50Q2hlY2tzdW07CisgICAgICAgICAgICB0aGlzLndpdGhCbG9ja0NoZWNrc3VtID0gd2l0aEJsb2NrQ2hlY2tzdW07CisgICAgICAgICAgICB0aGlzLndpdGhCbG9ja0RlcGVuZGVuY3kgPSB3aXRoQmxvY2tEZXBlbmRlbmN5OworICAgICAgICAgICAgdGhpcy5sejc3cGFyYW1zID0gbHo3N3BhcmFtczsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICAgICAgcmV0dXJuICJMWjQgUGFyYW1ldGVycyB3aXRoIEJsb2NrU2l6ZSAiICsgYmxvY2tTaXplICsgIiwgd2l0aENvbnRlbnRDaGVja3N1bSAiICsgd2l0aENvbnRlbnRDaGVja3N1bQorICAgICAgICAgICAgICAgICsgIiwgd2l0aEJsb2NrQ2hlY2tzdW0gIiArIHdpdGhCbG9ja0NoZWNrc3VtICsgIiwgd2l0aEJsb2NrRGVwZW5kZW5jeSAiICsgd2l0aEJsb2NrRGVwZW5kZW5jeTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgb3V0cHV0IHN0cmVhbSB0aGF0IGNvbXByZXNzZXMgZGF0YSB1c2luZyB0aGUKKyAgICAgKiBMWjQgZnJhbWUgZm9ybWF0IHVzaW5nIHRoZSBkZWZhdWx0IGJsb2NrIHNpemUgb2YgNE1CLgorICAgICAqIEBwYXJhbSBvdXQgdGhlIE91dHB1dFN0cmVhbSB0byB3aGljaCB0byB3cml0ZSB0aGUgY29tcHJlc3NlZCBkYXRhCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiB3cml0aW5nIHRoZSBzaWduYXR1cmUgZmFpbHMKKyAgICAgKi8KKyAgICBwdWJsaWMgRnJhbWVkTFo0Q29tcHJlc3Nvck91dHB1dFN0cmVhbShPdXRwdXRTdHJlYW0gb3V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzKG91dCwgUGFyYW1ldGVycy5ERUZBVUxUKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IG91dHB1dCBzdHJlYW0gdGhhdCBjb21wcmVzc2VzIGRhdGEgdXNpbmcgdGhlCisgICAgICogTFo0IGZyYW1lIGZvcm1hdCB1c2luZyB0aGUgZ2l2ZW4gYmxvY2sgc2l6ZS4KKyAgICAgKiBAcGFyYW0gb3V0IHRoZSBPdXRwdXRTdHJlYW0gdG8gd2hpY2ggdG8gd3JpdGUgdGhlIGNvbXByZXNzZWQgZGF0YQorICAgICAqIEBwYXJhbSBwYXJhbXMgdGhlIHBhcmFtZXRlcnMgdG8gdXNlCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiB3cml0aW5nIHRoZSBzaWduYXR1cmUgZmFpbHMKKyAgICAgKi8KKyAgICBwdWJsaWMgRnJhbWVkTFo0Q29tcHJlc3Nvck91dHB1dFN0cmVhbShPdXRwdXRTdHJlYW0gb3V0LCBQYXJhbWV0ZXJzIHBhcmFtcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcy5wYXJhbXMgPSBwYXJhbXM7CisgICAgICAgIGJsb2NrRGF0YSA9IG5ldyBieXRlW3BhcmFtcy5ibG9ja1NpemUuZ2V0U2l6ZSgpXTsKKyAgICAgICAgdGhpcy5vdXQgPSBvdXQ7CisgICAgICAgIGJsb2NrSGFzaCA9IHBhcmFtcy53aXRoQmxvY2tDaGVja3N1bSA/IG5ldyBYWEhhc2gzMigpIDogbnVsbDsKKyAgICAgICAgb3V0LndyaXRlKEZyYW1lZExaNENvbXByZXNzb3JJbnB1dFN0cmVhbS5MWjRfU0lHTkFUVVJFKTsKKyAgICAgICAgd3JpdGVGcmFtZURlc2NyaXB0b3IoKTsKKyAgICAgICAgYmxvY2tEZXBlbmRlbmN5QnVmZmVyID0gcGFyYW1zLndpdGhCbG9ja0RlcGVuZGVuY3kKKyAgICAgICAgICAgID8gbmV3IGJ5dGVbQmxvY2tMWjRDb21wcmVzc29ySW5wdXRTdHJlYW0uV0lORE9XX1NJWkVdCisgICAgICAgICAgICA6IG51bGw7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGUoaW50IGIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG9uZUJ5dGVbMF0gPSAoYnl0ZSkgKGIgJiAweGZmKTsKKyAgICAgICAgd3JpdGUob25lQnl0ZSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGUoYnl0ZVtdIGRhdGEsIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChwYXJhbXMud2l0aENvbnRlbnRDaGVja3N1bSkgeworICAgICAgICAgICAgY29udGVudEhhc2gudXBkYXRlKGRhdGEsIG9mZiwgbGVuKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoY3VycmVudEluZGV4ICsgbGVuID4gYmxvY2tEYXRhLmxlbmd0aCkgeworICAgICAgICAgICAgZmx1c2hCbG9jaygpOworICAgICAgICAgICAgd2hpbGUgKGxlbiA+IGJsb2NrRGF0YS5sZW5ndGgpIHsKKyAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGRhdGEsIG9mZiwgYmxvY2tEYXRhLCAwLCBibG9ja0RhdGEubGVuZ3RoKTsKKyAgICAgICAgICAgICAgICBvZmYgKz0gYmxvY2tEYXRhLmxlbmd0aDsKKyAgICAgICAgICAgICAgICBsZW4gLT0gYmxvY2tEYXRhLmxlbmd0aDsKKyAgICAgICAgICAgICAgICBjdXJyZW50SW5kZXggPSBibG9ja0RhdGEubGVuZ3RoOworICAgICAgICAgICAgICAgIGZsdXNoQmxvY2soKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGRhdGEsIG9mZiwgYmxvY2tEYXRhLCBjdXJyZW50SW5kZXgsIGxlbik7CisgICAgICAgIGN1cnJlbnRJbmRleCArPSBsZW47CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmluaXNoKCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXByZXNzZXMgYWxsIHJlbWFpbmluZyBkYXRhIGFuZCB3cml0ZXMgaXQgdG8gdGhlIHN0cmVhbSwKKyAgICAgKiBkb2Vzbid0IGNsb3NlIHRoZSB1bmRlcmx5aW5nIHN0cmVhbS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIGFuIGVycm9yIG9jY3VycworICAgICAqLworICAgIHB1YmxpYyB2b2lkIGZpbmlzaCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICghZmluaXNoZWQpIHsKKyAgICAgICAgICAgIGlmIChjdXJyZW50SW5kZXggPiAwKSB7CisgICAgICAgICAgICAgICAgZmx1c2hCbG9jaygpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgd3JpdGVUcmFpbGVyKCk7CisgICAgICAgICAgICBmaW5pc2hlZCA9IHRydWU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgd3JpdGVGcmFtZURlc2NyaXB0b3IoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgZmxhZ3MgPSBGcmFtZWRMWjRDb21wcmVzc29ySW5wdXRTdHJlYW0uU1VQUE9SVEVEX1ZFUlNJT047CisgICAgICAgIGlmICghcGFyYW1zLndpdGhCbG9ja0RlcGVuZGVuY3kpIHsKKyAgICAgICAgICAgIGZsYWdzIHw9IEZyYW1lZExaNENvbXByZXNzb3JJbnB1dFN0cmVhbS5CTE9DS19JTkRFUEVOREVOQ0VfTUFTSzsKKyAgICAgICAgfQorICAgICAgICBpZiAocGFyYW1zLndpdGhDb250ZW50Q2hlY2tzdW0pIHsKKyAgICAgICAgICAgIGZsYWdzIHw9IEZyYW1lZExaNENvbXByZXNzb3JJbnB1dFN0cmVhbS5DT05URU5UX0NIRUNLU1VNX01BU0s7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHBhcmFtcy53aXRoQmxvY2tDaGVja3N1bSkgeworICAgICAgICAgICAgZmxhZ3MgfD0gRnJhbWVkTFo0Q29tcHJlc3NvcklucHV0U3RyZWFtLkJMT0NLX0NIRUNLU1VNX01BU0s7CisgICAgICAgIH0KKyAgICAgICAgb3V0LndyaXRlKGZsYWdzKTsKKyAgICAgICAgY29udGVudEhhc2gudXBkYXRlKGZsYWdzKTsKKyAgICAgICAgaW50IGJkID0gKHBhcmFtcy5ibG9ja1NpemUuZ2V0SW5kZXgoKSA8PCA0KSAmIEZyYW1lZExaNENvbXByZXNzb3JJbnB1dFN0cmVhbS5CTE9DS19NQVhfU0laRV9NQVNLOworICAgICAgICBvdXQud3JpdGUoYmQpOworICAgICAgICBjb250ZW50SGFzaC51cGRhdGUoYmQpOworICAgICAgICBvdXQud3JpdGUoKGludCkgKChjb250ZW50SGFzaC5nZXRWYWx1ZSgpID4+IDgpICYgMHhmZikpOworICAgICAgICBjb250ZW50SGFzaC5yZXNldCgpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBmbHVzaEJsb2NrKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgYm9vbGVhbiB3aXRoQmxvY2tEZXBlbmRlbmN5ID0gcGFyYW1zLndpdGhCbG9ja0RlcGVuZGVuY3k7CisgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBiYW9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICB0cnkgKEJsb2NrTFo0Q29tcHJlc3Nvck91dHB1dFN0cmVhbSBvID0gbmV3IEJsb2NrTFo0Q29tcHJlc3Nvck91dHB1dFN0cmVhbShiYW9zLCBwYXJhbXMubHo3N3BhcmFtcykpIHsKKyAgICAgICAgICAgIGlmICh3aXRoQmxvY2tEZXBlbmRlbmN5KSB7CisgICAgICAgICAgICAgICAgby5wcmVmaWxsKGJsb2NrRGVwZW5kZW5jeUJ1ZmZlciwgYmxvY2tEZXBlbmRlbmN5QnVmZmVyLmxlbmd0aCAtIGNvbGxlY3RlZEJsb2NrRGVwZW5kZW5jeUJ5dGVzLAorICAgICAgICAgICAgICAgICAgICBjb2xsZWN0ZWRCbG9ja0RlcGVuZGVuY3lCeXRlcyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBvLndyaXRlKGJsb2NrRGF0YSwgMCwgY3VycmVudEluZGV4KTsKKyAgICAgICAgfQorICAgICAgICBpZiAod2l0aEJsb2NrRGVwZW5kZW5jeSkgeworICAgICAgICAgICAgYXBwZW5kVG9CbG9ja0RlcGVuZGVuY3lCdWZmZXIoYmxvY2tEYXRhLCAwLCBjdXJyZW50SW5kZXgpOworICAgICAgICB9CisgICAgICAgIGJ5dGVbXSBiID0gYmFvcy50b0J5dGVBcnJheSgpOworICAgICAgICBpZiAoYi5sZW5ndGggPiBjdXJyZW50SW5kZXgpIHsgLy8gY29tcHJlc3Npb24gaW5jcmVhc2VkIHNpemUsIG1heWJlIGJleW9uZCBibG9ja3NpemUKKyAgICAgICAgICAgIEJ5dGVVdGlscy50b0xpdHRsZUVuZGlhbihvdXQsIGN1cnJlbnRJbmRleCB8IEZyYW1lZExaNENvbXByZXNzb3JJbnB1dFN0cmVhbS5VTkNPTVBSRVNTRURfRkxBR19NQVNLLAorICAgICAgICAgICAgICAgIDQpOworICAgICAgICAgICAgb3V0LndyaXRlKGJsb2NrRGF0YSwgMCwgY3VycmVudEluZGV4KTsKKyAgICAgICAgICAgIGlmIChwYXJhbXMud2l0aEJsb2NrQ2hlY2tzdW0pIHsKKyAgICAgICAgICAgICAgICBibG9ja0hhc2gudXBkYXRlKGJsb2NrRGF0YSwgMCwgY3VycmVudEluZGV4KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIEJ5dGVVdGlscy50b0xpdHRsZUVuZGlhbihvdXQsIGIubGVuZ3RoLCA0KTsKKyAgICAgICAgICAgIG91dC53cml0ZShiKTsKKyAgICAgICAgICAgIGlmIChwYXJhbXMud2l0aEJsb2NrQ2hlY2tzdW0pIHsKKyAgICAgICAgICAgICAgICBibG9ja0hhc2gudXBkYXRlKGIsIDAsIGIubGVuZ3RoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAocGFyYW1zLndpdGhCbG9ja0NoZWNrc3VtKSB7CisgICAgICAgICAgICBCeXRlVXRpbHMudG9MaXR0bGVFbmRpYW4ob3V0LCBibG9ja0hhc2guZ2V0VmFsdWUoKSwgNCk7CisgICAgICAgICAgICBibG9ja0hhc2gucmVzZXQoKTsKKyAgICAgICAgfQorICAgICAgICBjdXJyZW50SW5kZXggPSAwOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB3cml0ZVRyYWlsZXIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvdXQud3JpdGUoRU5EX01BUkspOworICAgICAgICBpZiAocGFyYW1zLndpdGhDb250ZW50Q2hlY2tzdW0pIHsKKyAgICAgICAgICAgIEJ5dGVVdGlscy50b0xpdHRsZUVuZGlhbihvdXQsIGNvbnRlbnRIYXNoLmdldFZhbHVlKCksIDQpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGFwcGVuZFRvQmxvY2tEZXBlbmRlbmN5QnVmZmVyKGZpbmFsIGJ5dGVbXSBiLCBmaW5hbCBpbnQgb2ZmLCBpbnQgbGVuKSB7CisgICAgICAgIGxlbiA9IE1hdGgubWluKGxlbiwgYmxvY2tEZXBlbmRlbmN5QnVmZmVyLmxlbmd0aCk7CisgICAgICAgIGlmIChsZW4gPiAwKSB7CisgICAgICAgICAgICBpbnQga2VlcCA9IGJsb2NrRGVwZW5kZW5jeUJ1ZmZlci5sZW5ndGggLSBsZW47CisgICAgICAgICAgICBpZiAoa2VlcCA+IDApIHsKKyAgICAgICAgICAgICAgICAvLyBtb3ZlIGxhc3Qga2VlcCBieXRlcyB0b3dhcmRzIHRoZSBzdGFydCBvZiB0aGUgYnVmZmVyCisgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShibG9ja0RlcGVuZGVuY3lCdWZmZXIsIGxlbiwgYmxvY2tEZXBlbmRlbmN5QnVmZmVyLCAwLCBrZWVwKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIGFwcGVuZCBuZXcgZGF0YQorICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShiLCBvZmYsIGJsb2NrRGVwZW5kZW5jeUJ1ZmZlciwga2VlcCwgbGVuKTsKKyAgICAgICAgICAgIGNvbGxlY3RlZEJsb2NrRGVwZW5kZW5jeUJ5dGVzID0gTWF0aC5taW4oY29sbGVjdGVkQmxvY2tEZXBlbmRlbmN5Qnl0ZXMgKyBsZW4sCisgICAgICAgICAgICAgICAgYmxvY2tEZXBlbmRlbmN5QnVmZmVyLmxlbmd0aCk7CisgICAgICAgIH0KKyAgICB9CisKK30KKwpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvbHo0L1hYSGFzaDMyLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9sejQvWFhIYXNoMzIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yM2QyOWI1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvbHo0L1hYSGFzaDMyLmphdmEKQEAgLTAsMCArMSwxNzkgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMubHo0OworCitpbXBvcnQgc3RhdGljIGphdmEubGFuZy5JbnRlZ2VyLnJvdGF0ZUxlZnQ7CisKK2ltcG9ydCBqYXZhLnV0aWwuemlwLkNoZWNrc3VtOworCitpbXBvcnQgc3RhdGljIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5CeXRlVXRpbHMuZnJvbUxpdHRsZUVuZGlhbjsKKworLyoqCisgKiBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgeHhoYXNoMzIgaGFzaCBhbGdvcml0aG0uCisgKgorICogQHNlZSA8YSBocmVmPSJodHRwOi8vY3lhbjQ5NzMuZ2l0aHViLmlvL3h4SGFzaC8iPnh4SGFzaDwvYT4KKyAqIEBOb3RUaHJlYWRTYWZlCisgKiBAc2luY2UgMS4xNAorICovCitwdWJsaWMgY2xhc3MgWFhIYXNoMzIgaW1wbGVtZW50cyBDaGVja3N1bSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQlVGX1NJWkUgPSAxNjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgUk9UQVRFX0JJVFMgPSAxMzsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBQUklNRTEgPSAoaW50KSAyNjU0NDM1NzYxTDsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgUFJJTUUyID0gKGludCkgMjI0NjgyMjUxOUw7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFBSSU1FMyA9IChpbnQpIDMyNjY0ODk5MTdMOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBQUklNRTQgPSAgNjY4MjY1MjYzOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBQUklNRTUgPSAgMzc0NzYxMzkzOworCisgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10gb25lQnl0ZSA9IG5ldyBieXRlWzFdOworICAgIHByaXZhdGUgZmluYWwgaW50W10gc3RhdGUgPSBuZXcgaW50WzRdOworICAgIC8vIE5vdGU6IHRoZSBjb2RlIHVzZWQgdG8gdXNlIEJ5dGVCdWZmZXIgYnV0IHRoZSBtYW51YWwgbWV0aG9kIGlzIDUwJSBmYXN0ZXIKKyAgICAvLyBTZWU6IGh0dHBzOi8vZ2l0LXdpcC11cy5hcGFjaGUub3JnL3JlcG9zL2FzZi9jb21tb25zLWNvbXByZXNzL2RpZmYvMmY1NmZiNWMKKyAgICBwcml2YXRlIGZpbmFsIGJ5dGVbXSBidWZmZXIgPSBuZXcgYnl0ZVtCVUZfU0laRV07CisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgc2VlZDsKKworICAgIHByaXZhdGUgaW50IHRvdGFsTGVuOworICAgIHByaXZhdGUgaW50IHBvczsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gWFhIYXNoMzIgaW5zdGFuY2Ugd2l0aCBhIHNlZWQgb2YgMC4KKyAgICAgKi8KKyAgICBwdWJsaWMgWFhIYXNoMzIoKSB7CisgICAgICAgIHRoaXMoMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBYWEhhc2gzMiBpbnN0YW5jZS4KKyAgICAgKiBAcGFyYW0gc2VlZCB0aGUgc2VlZCB0byB1c2UKKyAgICAgKi8KKyAgICBwdWJsaWMgWFhIYXNoMzIoaW50IHNlZWQpIHsKKyAgICAgICAgdGhpcy5zZWVkID0gc2VlZDsKKyAgICAgICAgaW5pdGlhbGl6ZVN0YXRlKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcmVzZXQoKSB7CisgICAgICAgIGluaXRpYWxpemVTdGF0ZSgpOworICAgICAgICB0b3RhbExlbiA9IDA7CisgICAgICAgIHBvcyA9IDA7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgdXBkYXRlKGludCBiKSB7CisgICAgICAgIG9uZUJ5dGVbMF0gPSAoYnl0ZSkgKGIgJiAweGZmKTsKKyAgICAgICAgdXBkYXRlKG9uZUJ5dGUsIDAsIDEpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHVwZGF0ZShieXRlW10gYiwgaW50IG9mZiwgZmluYWwgaW50IGxlbikgeworICAgICAgICBpZiAobGVuIDw9IDApIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICB0b3RhbExlbiArPSBsZW47CisKKyAgICAgICAgZmluYWwgaW50IGVuZCA9IG9mZiArIGxlbjsKKworICAgICAgICBpZiAocG9zICsgbGVuIDwgQlVGX1NJWkUpIHsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYiwgb2ZmLCBidWZmZXIsIHBvcywgbGVuKTsKKyAgICAgICAgICAgIHBvcyArPSBsZW47CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBpZiAocG9zID4gMCkgeworICAgICAgICAgICAgZmluYWwgaW50IHNpemUgPSBCVUZfU0laRSAtIHBvczsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYiwgb2ZmLCBidWZmZXIsIHBvcywgc2l6ZSk7CisgICAgICAgICAgICBwcm9jZXNzKGJ1ZmZlciwgMCk7CisgICAgICAgICAgICBvZmYgKz0gc2l6ZTsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIGludCBsaW1pdCA9IGVuZCAtIEJVRl9TSVpFOworICAgICAgICB3aGlsZSAob2ZmIDw9IGxpbWl0KSB7CisgICAgICAgICAgICBwcm9jZXNzKGIsIG9mZik7CisgICAgICAgICAgICBvZmYgKz0gQlVGX1NJWkU7CisgICAgICAgIH0KKworICAgICAgICBpZiAob2ZmIDwgZW5kKSB7CisgICAgICAgICAgICBwb3MgPSBlbmQgLSBvZmY7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGIsIG9mZiwgYnVmZmVyLCAwLCBwb3MpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGxvbmcgZ2V0VmFsdWUoKSB7CisgICAgICAgIGludCBoYXNoOworICAgICAgICBpZiAodG90YWxMZW4gPiBCVUZfU0laRSkgeworICAgICAgICAgICAgaGFzaCA9CisgICAgICAgICAgICAgICAgcm90YXRlTGVmdChzdGF0ZVswXSwgIDEpICsKKyAgICAgICAgICAgICAgICByb3RhdGVMZWZ0KHN0YXRlWzFdLCAgNykgKworICAgICAgICAgICAgICAgIHJvdGF0ZUxlZnQoc3RhdGVbMl0sIDEyKSArCisgICAgICAgICAgICAgICAgcm90YXRlTGVmdChzdGF0ZVszXSwgMTgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaGFzaCA9IHN0YXRlWzJdICsgUFJJTUU1OworICAgICAgICB9CisgICAgICAgIGhhc2ggKz0gdG90YWxMZW47CisKKyAgICAgICAgaW50IGlkeCA9IDA7CisgICAgICAgIGZpbmFsIGludCBsaW1pdCA9IHBvcyAtIDQ7CisgICAgICAgIGZvciAoOyBpZHggPD0gbGltaXQ7IGlkeCArPSA0KSB7CisgICAgICAgICAgICBoYXNoID0gcm90YXRlTGVmdChoYXNoICsgZ2V0SW50KGJ1ZmZlciwgaWR4KSAqIFBSSU1FMywgMTcpICogUFJJTUU0OworICAgICAgICB9CisgICAgICAgIHdoaWxlIChpZHggPCBwb3MpIHsKKyAgICAgICAgICAgIGhhc2ggPSByb3RhdGVMZWZ0KGhhc2ggKyAoYnVmZmVyW2lkeCsrXSAmIDB4ZmYpICogUFJJTUU1LCAxMSkgKiBQUklNRTE7CisgICAgICAgIH0KKworICAgICAgICBoYXNoIF49IGhhc2ggPj4+IDE1OworICAgICAgICBoYXNoICo9IFBSSU1FMjsKKyAgICAgICAgaGFzaCBePSBoYXNoID4+PiAxMzsKKyAgICAgICAgaGFzaCAqPSBQUklNRTM7CisgICAgICAgIGhhc2ggXj0gaGFzaCA+Pj4gMTY7CisgICAgICAgIHJldHVybiBoYXNoICYgMHhmZmZmZmZmZkw7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IGdldEludChieXRlW10gYnVmZmVyLCBpbnQgaWR4KSB7CisgICAgICAgIHJldHVybiAoaW50KSAoZnJvbUxpdHRsZUVuZGlhbihidWZmZXIsIGlkeCwgNCkgJiAweGZmZmZmZmZmTCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGluaXRpYWxpemVTdGF0ZSgpIHsKKyAgICAgICAgc3RhdGVbMF0gPSBzZWVkICsgUFJJTUUxICsgUFJJTUUyOworICAgICAgICBzdGF0ZVsxXSA9IHNlZWQgKyBQUklNRTI7CisgICAgICAgIHN0YXRlWzJdID0gc2VlZDsKKyAgICAgICAgc3RhdGVbM10gPSBzZWVkIC0gUFJJTUUxOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBwcm9jZXNzKGJ5dGVbXSBiLCBpbnQgb2Zmc2V0KSB7CisgICAgICAgIC8vIGxvY2FsIHNoYWRvd3MgZm9yIHBlcmZvcm1hbmNlCisgICAgICAgIGludCBzMCA9IHN0YXRlWzBdOworICAgICAgICBpbnQgczEgPSBzdGF0ZVsxXTsKKyAgICAgICAgaW50IHMyID0gc3RhdGVbMl07CisgICAgICAgIGludCBzMyA9IHN0YXRlWzNdOworCisgICAgICAgIHMwID0gcm90YXRlTGVmdChzMCArIGdldEludChiLCBvZmZzZXQpICogUFJJTUUyLCBST1RBVEVfQklUUykgKiBQUklNRTE7CisgICAgICAgIHMxID0gcm90YXRlTGVmdChzMSArIGdldEludChiLCBvZmZzZXQgKyA0KSAqIFBSSU1FMiwgUk9UQVRFX0JJVFMpICogUFJJTUUxOworICAgICAgICBzMiA9IHJvdGF0ZUxlZnQoczIgKyBnZXRJbnQoYiwgb2Zmc2V0ICsgOCkgKiBQUklNRTIsIFJPVEFURV9CSVRTKSAqIFBSSU1FMTsKKyAgICAgICAgczMgPSByb3RhdGVMZWZ0KHMzICsgZ2V0SW50KGIsIG9mZnNldCArIDEyKSAqIFBSSU1FMiwgUk9UQVRFX0JJVFMpICogUFJJTUUxOworCisgICAgICAgIHN0YXRlWzBdID0gczA7CisgICAgICAgIHN0YXRlWzFdID0gczE7CisgICAgICAgIHN0YXRlWzJdID0gczI7CisgICAgICAgIHN0YXRlWzNdID0gczM7CisKKyAgICAgICAgcG9zID0gMDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9sejQvcGFja2FnZS5odG1sIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvbHo0L3BhY2thZ2UuaHRtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NGRlNjJiCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvbHo0L3BhY2thZ2UuaHRtbApAQCAtMCwwICsxLDM3IEBACis8aHRtbD4KKzwhLS0KKworICAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAgIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAgIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKworICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorCisgICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKworLS0+CisgIDxib2R5PgorICAgIDxwPlByb3ZpZGVzIHN0cmVhbSBjbGFzc2VzIGZvciB0aGUKKyAgICAgIDxhIGhyZWY9Imh0dHA6Ly9sejQuZ2l0aHViLmlvL2x6NC8iPkxaNDwvYT4KKyAgICAgIGFsZ29yaXRobS48L3A+CisKKyAgICA8cD5UaGUgYmxvY2sgTFo0IGZvcm1hdCB3aGljaCBvbmx5IGNvbnRhaW5zIHRoZSBjb21wcmVzc2VkIGRhdGEgaXMKKyAgICAgIHN1cHBvcnRlZCBieSB0aGUgPGNvZGU+QmxvY2tMWjRDb21wcmVzc29yKnB1dFN0cmVhbTwvY29kZT4KKyAgICAgIGNsYXNzZXMgd2hpbGUgdGhlIGZyYW1lIGZvcm1hdCBpcyBpbXBsZW1lbnRlZAorICAgICAgYnkgPGNvZGU+RnJhbWVkTFo0Q29tcHJlc3NvcipwdXRTdHJlYW08L2NvZGU+LiAgVGhlCisgICAgICBpbXBsZW1lbnRhdGlvbiBpbiBDb21tb25zIENvbXByZXNzIGlzIGJhc2VkIG9uIHRoZQorICAgICAgc3BlY2lmaWNhdGlvbnMgIkxhc3QgcmV2aXNlZDogMjAxNS0wMy0yNiIgZm9yIHRoZSBibG9jayBmb3JtYXQKKyAgICAgIGFuZCB2ZXJzaW9uICIxLjUuMSAoMzEvMDMvMjAxNSkiIGZvciB0aGUgZnJhbWUgZm9ybWF0LjwvcD4KKworICAgIDxwPk9ubHkgdGhlIGZyYW1lIGZvcm1hdCBjYW4gYmUgYXV0by1kZXRlY3RlZCB0aGlzIG1lYW5zIHlvdSBoYXZlCisgICAgICB0byBzcGVmaWN5IHRoZSBmb3JtYXQgZXhwbGljaXRseSBpZiB5b3Ugd2FudCB0byByZWFkIGEgYmxvY2sgTFo0CisgICAgICBzdHJlYW0gdmlhIDxjb2RlPkNvbXByZXNzb3JTdHJlYW1GYWN0b3J5PC9jb2RlPi48L3A+CisgIDwvYm9keT4KKzwvaHRtbD4KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2x6NzdzdXBwb3J0L0Fic3RyYWN0TFo3N0NvbXByZXNzb3JJbnB1dFN0cmVhbS5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvbHo3N3N1cHBvcnQvQWJzdHJhY3RMWjc3Q29tcHJlc3NvcklucHV0U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGExMzcxYQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2x6NzdzdXBwb3J0L0Fic3RyYWN0TFo3N0NvbXByZXNzb3JJbnB1dFN0cmVhbS5qYXZhCkBAIC0wLDAgKzEsMzQzIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLmx6NzdzdXBwb3J0OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuQ29tcHJlc3NvcklucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5CeXRlVXRpbHM7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLkNvdW50aW5nSW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLklPVXRpbHM7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLklucHV0U3RyZWFtU3RhdGlzdGljczsKKworLyoqCisgKiBFbmNhcHN1bGF0ZXMgY29kZSBjb21tb24gdG8gTFo3NyBkZWNvbXByZXNzb3JzLgorICoKKyAqIDxwPkFzc3VtZXMgdGhlIHN0cmVhbSBjb25zaXN0cyBvZiBibG9ja3Mgb2YgbGl0ZXJhbCBkYXRhIGFuZAorICogYmFjay1yZWZlcmVuY2VzIChjYWxsZWQgY29waWVzKSBpbiBhbnkgb3JkZXIuIE9mIGNvdXJzZSB0aGUgZmlyc3QKKyAqIGJsb2NrIG11c3QgYmUgYSBsaXRlcmFsIGJsb2NrIGZvciB0aGUgc2NoZW1lIHRvIHdvcmsgLSB1bmxlc3MgdGhlCisgKiB7QGxpbmsgI3ByZWZpbGwgcHJlZmlsbH0gbWV0aG9kIGhhcyBiZWVuIHVzZWQgdG8gcHJvdmlkZSBpbml0aWFsCisgKiBkYXRhIHRoYXQgaXMgbmV2ZXIgcmV0dXJuZWQgYnkge0BsaW5rICNyZWFkIHJlYWR9IGJ1dCBvbmx5IHVzZWQgZm9yCisgKiBiYWNrLXJlZmVyZW5jZXMuPC9wPgorICoKKyAqIDxwPlN1YmNsYXNzZXMgbXVzdCBvdmVycmlkZSB0aGUgdGhyZWUtYXJnIHtAbGluayAjcmVhZCByZWFkfSBtZXRob2QKKyAqIGFzIHRoZSBuby1hcmcgdmVyc2lvbiBkZWxlZ2F0ZXMgdG8gaXQgYW5kIHRoZSBkZWZhdWx0CisgKiBpbXBsZW1lbnRhdGlvbiBkZWxlZ2F0ZXMgdG8gdGhlIG5vLWFyZyB2ZXJzaW9uLCBsZWFkaW5nIHRvIGluZmluaXRlCisgKiBtdXR1YWwgcmVjdXJzaW9uIGFuZCBhIHtAY29kZSBTdGFja092ZXJmbG93RXJyb3J9IG90aGVyd2lzZS48L3A+CisgKgorICogPHA+VGhlIGNvbnRyYWN0IGZvciBzdWJjbGFzc2VzJyB7QGNvZGUgcmVhZH0gaW1wbGVtZW50YXRpb24gaXM6PC9wPgorICogPHVsPgorICoKKyAqICA8bGk+a2VlcCB0cmFjayBvZiB0aGUgY3VycmVudCBzdGF0ZSBvZiB0aGUgc3RyZWFtLiBJcyBpdCBpbnNpZGUgYQorICogIGxpdGVyYWwgYmxvY2sgb3IgYSBiYWNrLXJlZmVyZW5jZSBvciBpbi1iZXR3ZWVuIGJsb2Nrcz88L2xpPgorICoKKyAqICA8bGk+VXNlIHtAbGluayAjcmVhZE9uZUJ5dGV9IHRvIGFjY2VzcyB0aGUgdW5kZXJseWluZyBzdHJlYW0KKyAqICBkaXJlY3RseS48L2xpPgorICoKKyAqICA8bGk+SWYgYSBuZXcgbGl0ZXJhbCBibG9jayBzdGFydHMsIHVzZSB7QGxpbmsgI3N0YXJ0TGl0ZXJhbH0gdG8KKyAqICB0ZWxsIHRoaXMgY2xhc3MgYWJvdXQgaXQgYW5kIHJlYWQgdGhlIGxpdGVyYWwgZGF0YSB1c2luZyB7QGxpbmsKKyAqICAjcmVhZExpdGVyYWx9IHVudGlsIGl0IHJldHVybnMge0Bjb2RlIDB9LiB7QGxpbmsKKyAqICAjaGFzTW9yZURhdGFJbkJsb2NrfSB3aWxsIHJldHVybiB7QGNvZGUgZmFsc2V9IGJlZm9yZSB0aGUgbmV4dAorICogIGNhbGwgdG8ge0BsaW5rICNyZWFkTGl0ZXJhbH0gd291bGQgcmV0dXJuIHtAY29kZSAwfS48L2xpPgorICoKKyAqICA8bGk+SWYgYSBuZXcgYmFjay1yZWZlcmVuY2Ugc3RhcnRzLCB1c2Uge0BsaW5rICNzdGFydEJhY2tSZWZlcmVuY2V9IHRvCisgKiAgdGVsbCB0aGlzIGNsYXNzIGFib3V0IGl0IGFuZCByZWFkIHRoZSBsaXRlcmFsIGRhdGEgdXNpbmcge0BsaW5rCisgKiAgI3JlYWRCYWNrUmVmZXJlbmNlfSB1bnRpbCBpdCByZXR1cm5zIHtAY29kZSAwfS4ge0BsaW5rCisgKiAgI2hhc01vcmVEYXRhSW5CbG9ja30gd2lsbCByZXR1cm4ge0Bjb2RlIGZhbHNlfSBiZWZvcmUgdGhlIG5leHQKKyAqICBjYWxsIHRvIHtAbGluayAjcmVhZEJhY2tSZWZlcmVuY2V9IHdvdWxkIHJldHVybiB7QGNvZGUgMH0uPC9saT4KKyAqCisgKiAgPGxpPklmIHRoZSBlbmQgb2YgdGhlIHN0cmVhbSBoYXMgYmVlbiByZWFjaGVkLCByZXR1cm4ge0Bjb2RlIC0xfQorICogIGFzIHRoaXMgY2xhc3MnIG1ldGhvZHMgd2lsbCBuZXZlciBkbyBzbyB0aGVtc2VsdmVzLjwvbGk+CisgKgorICogPC91bD4KKyAqCisgKiA8cD57QGxpbmsgI3JlYWRPbmVCeXRlfSBhbmQge0BsaW5rICNyZWFkTGl0ZXJhbH0gdXBkYXRlIHRoZSBjb3VudGVyCisgKiBmb3IgYnl0ZXMgcmVhZC48L3A+CisgKgorICogQHNpbmNlIDEuMTQKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEFic3RyYWN0TFo3N0NvbXByZXNzb3JJbnB1dFN0cmVhbSBleHRlbmRzIENvbXByZXNzb3JJbnB1dFN0cmVhbQorICAgIGltcGxlbWVudHMgSW5wdXRTdHJlYW1TdGF0aXN0aWNzIHsKKworICAgIC8qKiBTaXplIG9mIHRoZSB3aW5kb3cgLSBtdXN0IGJlIGJpZ2dlciB0aGFuIHRoZSBiaWdnZXN0IG9mZnNldCBleHBlY3RlZC4gKi8KKyAgICBwcml2YXRlIGZpbmFsIGludCB3aW5kb3dTaXplOworCisgICAgLyoqCisgICAgICogQnVmZmVyIHRvIHdyaXRlIGRlY29tcHJlc3NlZCBieXRlcyB0byBmb3IgYmFjay1yZWZlcmVuY2VzLCB3aWxsCisgICAgICogYmUgdGhyZWUgdGltZXMgd2luZG93U2l6ZSBiaWcuCisgICAgICoKKyAgICAgKiA8cD5UaHJlZSB0aW1lcyBzbyB3ZSBjYW4gc2xpZGUgdGhlIHdob2xlIGJ1ZmZlciBhIHdpbmRvd1NpemUgdG8KKyAgICAgKiB0aGUgbGVmdCBvbmNlIHdlJ3ZlIHJlYWQgdHdpY2Ugd2luZG93U2l6ZSBhbmQgc3RpbGwgaGF2ZSBlbm91Z2gKKyAgICAgKiBkYXRhIGluc2lkZSBvZiBpdCB0byBzYXRpc2Z5IGJhY2stcmVmZXJlbmNlcy48L3A+CisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10gYnVmOworCisgICAgLyoqIE9uZSBiZWhpbmQgdGhlIGluZGV4IG9mIHRoZSBsYXN0IGJ5dGUgaW4gdGhlIGJ1ZmZlciB0aGF0IHdhcyB3cml0dGVuLCBpLmUuIHRoZSBuZXh0IHBvc2l0aW9uIHRvIHdyaXRlIHRvICovCisgICAgcHJpdmF0ZSBpbnQgd3JpdGVJbmRleDsKKworICAgIC8qKiBJbmRleCBvZiB0aGUgbmV4dCBieXRlIHRvIGJlIHJlYWQuICovCisgICAgcHJpdmF0ZSBpbnQgcmVhZEluZGV4OworCisgICAgLyoqIFRoZSB1bmRlcmx5aW5nIHN0cmVhbSB0byByZWFkIGNvbXByZXNzZWQgZGF0YSBmcm9tICovCisgICAgcHJpdmF0ZSBmaW5hbCBDb3VudGluZ0lucHV0U3RyZWFtIGluOworCisgICAgLyoqIE51bWJlciBvZiBieXRlcyBzdGlsbCB0byBiZSByZWFkIGZyb20gdGhlIGN1cnJlbnQgbGl0ZXJhbCBvciBiYWNrLXJlZmVyZW5jZS4gKi8KKyAgICBwcml2YXRlIGxvbmcgYnl0ZXNSZW1haW5pbmc7CisKKyAgICAvKiogT2Zmc2V0IG9mIHRoZSBjdXJyZW50IGJhY2stcmVmZXJlbmNlLiAqLworICAgIHByaXZhdGUgaW50IGJhY2tSZWZlcmVuY2VPZmZzZXQ7CisKKyAgICAvKiogdW5jb21wcmVzc2VkIHNpemUgKi8KKyAgICBwcml2YXRlIGludCBzaXplID0gMDsKKworICAgIC8vIHVzZWQgaW4gbm8tYXJnIHJlYWQgbWV0aG9kCisgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10gb25lQnl0ZSA9IG5ldyBieXRlWzFdOworCisgICAgLyoqCisgICAgICogU3VwcGxpZXIgdGhhdCBkZWxlZ2F0ZXMgdG8ge0BsaW5rICNyZWFkT25lQnl0ZX0uCisgICAgICovCisgICAgcHJvdGVjdGVkIGZpbmFsIEJ5dGVVdGlscy5CeXRlU3VwcGxpZXIgc3VwcGxpZXIgPSBuZXcgQnl0ZVV0aWxzLkJ5dGVTdXBwbGllcigpIHsKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBpbnQgZ2V0QXNCeXRlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiByZWFkT25lQnl0ZSgpOworICAgICAgICB9CisgICAgfTsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgTFo3NyBpbnB1dCBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaXMKKyAgICAgKiAgICAgICAgICAgIEFuIElucHV0U3RyZWFtIHRvIHJlYWQgY29tcHJlc3NlZCBkYXRhIGZyb20KKyAgICAgKiBAcGFyYW0gd2luZG93U2l6ZQorICAgICAqICAgICAgICAgICAgU2l6ZSBvZiB0aGUgd2luZG93IGtlcHQgZm9yIGJhY2stcmVmZXJlbmNlcywgbXVzdCBiZSBiaWdnZXIgdGhhbiB0aGUgYmlnZ2VzdCBvZmZzZXQgZXhwZWN0ZWQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHJlYWRpbmcgZmFpbHMKKyAgICAgKi8KKyAgICBwdWJsaWMgQWJzdHJhY3RMWjc3Q29tcHJlc3NvcklucHV0U3RyZWFtKGZpbmFsIElucHV0U3RyZWFtIGlzLCBpbnQgd2luZG93U2l6ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcy5pbiA9IG5ldyBDb3VudGluZ0lucHV0U3RyZWFtKGlzKTsKKyAgICAgICAgdGhpcy53aW5kb3dTaXplID0gd2luZG93U2l6ZTsKKyAgICAgICAgYnVmID0gbmV3IGJ5dGVbMyAqIHdpbmRvd1NpemVdOworICAgICAgICB3cml0ZUluZGV4ID0gcmVhZEluZGV4ID0gMDsKKyAgICAgICAgYnl0ZXNSZW1haW5pbmcgPSAwOworICAgIH0KKworICAgIC8qKiB7QGluaGVyaXREb2N9ICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCByZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHJlYWQob25lQnl0ZSwgMCwgMSkgPT0gLTEgPyAtMSA6IG9uZUJ5dGVbMF0gJiAweEZGOworICAgIH0KKworICAgIC8qKiB7QGluaGVyaXREb2N9ICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbi5jbG9zZSgpOworICAgIH0KKworICAgIC8qKiB7QGluaGVyaXREb2N9ICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBhdmFpbGFibGUoKSB7CisgICAgICAgIHJldHVybiB3cml0ZUluZGV4IC0gcmVhZEluZGV4OworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgdW5jb21wcmVzc2VkIHNpemUgb2YgdGhlIHN0cmVhbQorICAgICAqCisgICAgICogQHJldHVybiB0aGUgdW5jb21wcmVzc2VkIHNpemUKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFNpemUoKSB7CisgICAgICAgIHJldHVybiBzaXplOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgc29tZSBpbml0aWFsIGRhdGEgdG8gZmlsbCB0aGUgd2luZG93IHdpdGguCisgICAgICoKKyAgICAgKiA8cD5UaGlzIGlzIHVzZWQgaWYgdGhlIHN0cmVhbSBoYXMgYmVlbiBjdXQgaW50byBibG9ja3MgYW5kCisgICAgICogYmFjay1yZWZlcmVuY2VzIG9mIG9uZSBibG9jayBtYXkgcmVmZXIgdG8gZGF0YSBvZiB0aGUgcHJldmlvdXMKKyAgICAgKiBibG9jayhzKS4gT25lIHN1Y2ggZXhhbXBsZSBpcyB0aGUgTFo0IGZyYW1lIGZvcm1hdCB1c2luZyBibG9jaworICAgICAqIGRlcGVuZGVuY3kuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGRhdGEgdGhlIGRhdGEgdG8gZmlsbCB0aGUgd2luZG93IHdpdGguCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhlIHN0cmVhbSBoYXMgYWxyZWFkeSBzdGFydGVkIHRvIHJlYWQgZGF0YQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHByZWZpbGwoYnl0ZVtdIGRhdGEpIHsKKyAgICAgICAgaWYgKHdyaXRlSW5kZXggIT0gMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigidGhlIHN0cmVhbSBoYXMgYWxyZWFkeSBiZWVuIHJlYWQgZnJvbSwgY2FuJ3QgcHJlZmlsbCBhbnltb3JlIik7CisgICAgICAgIH0KKyAgICAgICAgLy8gd2UgZG9uJ3QgbmVlZCBtb3JlIGRhdGEgdGhhbiB0aGUgYmlnIG9mZnNldCBjb3VsZCByZWZlciB0bywgc28gY2FwIGl0CisgICAgICAgIGludCBsZW4gPSBNYXRoLm1pbih3aW5kb3dTaXplLCBkYXRhLmxlbmd0aCk7CisgICAgICAgIC8vIHdlIG5lZWQgdGhlIGxhc3QgZGF0YSBhcyB3ZSBhcmUgZGVhbGluZyB3aXRoICpiYWNrKi1yZWZlcmVuY2VzCisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZGF0YSwgZGF0YS5sZW5ndGggLSBsZW4sIGJ1ZiwgMCwgbGVuKTsKKyAgICAgICAgd3JpdGVJbmRleCArPSBsZW47CisgICAgICAgIHJlYWRJbmRleCArPSBsZW47CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNpbmNlIDEuMTcKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgbG9uZyBnZXRDb21wcmVzc2VkQ291bnQoKSB7CisgICAgICAgIHJldHVybiBpbi5nZXRCeXRlc1JlYWQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVc2VkIGJ5IHN1YmNsYXNzZXMgdG8gc2lnbmFsIHRoZSBuZXh0IGJsb2NrIGNvbnRhaW5zIHRoZSBnaXZlbgorICAgICAqIGFtb3VudCBvZiBsaXRlcmFsIGRhdGEuCisgICAgICogQHBhcmFtIGxlbmd0aCB0aGUgbGVuZ3RoIG9mIHRoZSBibG9jaworICAgICAqLworICAgIHByb3RlY3RlZCBmaW5hbCB2b2lkIHN0YXJ0TGl0ZXJhbChsb25nIGxlbmd0aCkgeworICAgICAgICBieXRlc1JlbWFpbmluZyA9IGxlbmd0aDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJcyB0aGVyZSBzdGlsbCBkYXRhIHJlbWFpbmluZyBpbnNpZGUgdGhlIGN1cnJlbnQgYmxvY2s/CisgICAgICogQHJldHVybiB0cnVlIGlmIHRoZXJlIGlzIHN0aWxsIGRhdGEgcmVtYWluaW5nIGluc2lkZSB0aGUgY3VycmVudCBibG9jay4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgZmluYWwgYm9vbGVhbiBoYXNNb3JlRGF0YUluQmxvY2soKSB7CisgICAgICAgIHJldHVybiBieXRlc1JlbWFpbmluZyA+IDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgZGF0YSBmcm9tIHRoZSBjdXJyZW50IGxpdGVyYWwgYmxvY2suCisgICAgICogQHBhcmFtIGIgYnVmZmVyIHRvIHdyaXRlIGRhdGEgdG8KKyAgICAgKiBAcGFyYW0gb2ZmIG9mZnNldCB0byBzdGFydCB3cml0aW5nIHRvCisgICAgICogQHBhcmFtIGxlbiBtYXhpbXVtIGFtb3VudCBvZiBkYXRhIHRvIHJlYWQKKyAgICAgKiBAcmV0dXJuIG51bWJlciBvZiBieXRlcyByZWFkLCBtYXkgYmUgMC4gV2lsbCBuZXZlciByZXR1cm4gLTEgYXMKKyAgICAgKiBFT0YtZGV0ZWN0aW9uIGlzIHRoZSByZXNwb25zaWJpbGl0eSBvZiB0aGUgc3ViY2xhc3MKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHRoZSB1bmRlcmx5aW5nIHN0cmVhbSB0aHJvd3Mgb3Igc2lnbmFscworICAgICAqIGFuIEVPRiBiZWZvcmUgdGhlIGFtb3VudCBvZiBkYXRhIHByb21pc2VkIGZvciB0aGUgYmxvY2sgaGF2ZQorICAgICAqIGJlZW4gcmVhZAorICAgICAqLworICAgIHByb3RlY3RlZCBmaW5hbCBpbnQgcmVhZExpdGVyYWwoZmluYWwgYnl0ZVtdIGIsIGZpbmFsIGludCBvZmYsIGZpbmFsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIGludCBhdmFpbCA9IGF2YWlsYWJsZSgpOworICAgICAgICBpZiAobGVuID4gYXZhaWwpIHsKKyAgICAgICAgICAgIHRyeVRvUmVhZExpdGVyYWwobGVuIC0gYXZhaWwpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZWFkRnJvbUJ1ZmZlcihiLCBvZmYsIGxlbik7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRyeVRvUmVhZExpdGVyYWwoaW50IGJ5dGVzVG9SZWFkKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBtaW4gb2YgIndoYXQgaXMgc3RpbGwgaW5zaWRlIHRoZSBsaXRlcmFsIiwgIndoYXQgZG9lcyB0aGUgdXNlciB3YW50IiBhbmQgImhvdyBtdWMgY2FuIGZpdCBpbnRvIHRoZSBidWZmZXIiCisgICAgICAgIGZpbmFsIGludCByZWFsbHlUcnlUb1JlYWQgPSBNYXRoLm1pbigoaW50KSBNYXRoLm1pbihieXRlc1RvUmVhZCwgYnl0ZXNSZW1haW5pbmcpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnVmLmxlbmd0aCAtIHdyaXRlSW5kZXgpOworICAgICAgICBmaW5hbCBpbnQgYnl0ZXNSZWFkID0gcmVhbGx5VHJ5VG9SZWFkID4gMAorICAgICAgICAgICAgPyBJT1V0aWxzLnJlYWRGdWxseShpbiwgYnVmLCB3cml0ZUluZGV4LCByZWFsbHlUcnlUb1JlYWQpCisgICAgICAgICAgICA6IDAgLyogaGFwcGVucyBmb3IgYnl0ZXNSZW1haW5pbmcgPT0gMCAqLzsKKyAgICAgICAgY291bnQoYnl0ZXNSZWFkKTsKKyAgICAgICAgaWYgKHJlYWxseVRyeVRvUmVhZCAhPSBieXRlc1JlYWQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiUHJlbWF0dXJlIGVuZCBvZiBzdHJlYW0gcmVhZGluZyBsaXRlcmFsIik7CisgICAgICAgIH0KKyAgICAgICAgd3JpdGVJbmRleCArPSByZWFsbHlUcnlUb1JlYWQ7CisgICAgICAgIGJ5dGVzUmVtYWluaW5nIC09IHJlYWxseVRyeVRvUmVhZDsKKyAgICB9CisKKyAgICBwcml2YXRlIGludCByZWFkRnJvbUJ1ZmZlcihmaW5hbCBieXRlW10gYiwgZmluYWwgaW50IG9mZiwgZmluYWwgaW50IGxlbikgeworICAgICAgICBmaW5hbCBpbnQgcmVhZGFibGUgPSBNYXRoLm1pbihsZW4sIGF2YWlsYWJsZSgpKTsKKyAgICAgICAgaWYgKHJlYWRhYmxlID4gMCkgeworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShidWYsIHJlYWRJbmRleCwgYiwgb2ZmLCByZWFkYWJsZSk7CisgICAgICAgICAgICByZWFkSW5kZXggKz0gcmVhZGFibGU7CisgICAgICAgICAgICBpZiAocmVhZEluZGV4ID4gMiAqIHdpbmRvd1NpemUpIHsKKyAgICAgICAgICAgICAgICBzbGlkZUJ1ZmZlcigpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHNpemUgKz0gcmVhZGFibGU7CisgICAgICAgIHJldHVybiByZWFkYWJsZTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgc2xpZGVCdWZmZXIoKSB7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYnVmLCB3aW5kb3dTaXplLCBidWYsIDAsIHdpbmRvd1NpemUgKiAyKTsKKyAgICAgICAgd3JpdGVJbmRleCAtPSB3aW5kb3dTaXplOworICAgICAgICByZWFkSW5kZXggLT0gd2luZG93U2l6ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVc2VkIGJ5IHN1YmNsYXNzZXMgdG8gc2lnbmFsIHRoZSBuZXh0IGJsb2NrIGNvbnRhaW5zIGEgYmFjay1yZWZlcmVuY2Ugd2l0aCB0aGUgZ2l2ZW4gY29vcmRpbmF0ZXMuCisgICAgICogQHBhcmFtIG9mZnNldCB0aGUgb2Zmc2V0IG9mIHRoZSBiYWNrLXJlZmVyZW5jZQorICAgICAqIEBwYXJhbSBsZW5ndGggdGhlIGxlbmd0aCBvZiB0aGUgYmFjay1yZWZlcmVuY2UKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgZmluYWwgdm9pZCBzdGFydEJhY2tSZWZlcmVuY2UoaW50IG9mZnNldCwgbG9uZyBsZW5ndGgpIHsKKyAgICAgICAgYmFja1JlZmVyZW5jZU9mZnNldCA9IG9mZnNldDsKKyAgICAgICAgYnl0ZXNSZW1haW5pbmcgPSBsZW5ndGg7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgZGF0YSBmcm9tIHRoZSBjdXJyZW50IGJhY2stcmVmZXJlbmNlLgorICAgICAqIEBwYXJhbSBiIGJ1ZmZlciB0byB3cml0ZSBkYXRhIHRvCisgICAgICogQHBhcmFtIG9mZiBvZmZzZXQgdG8gc3RhcnQgd3JpdGluZyB0bworICAgICAqIEBwYXJhbSBsZW4gbWF4aW11bSBhbW91bnQgb2YgZGF0YSB0byByZWFkCisgICAgICogQHJldHVybiBudW1iZXIgb2YgYnl0ZXMgcmVhZCwgbWF5IGJlIDAuIFdpbGwgbmV2ZXIgcmV0dXJuIC0xIGFzCisgICAgICogRU9GLWRldGVjdGlvbiBpcyB0aGUgcmVzcG9uc2liaWxpdHkgb2YgdGhlIHN1YmNsYXNzCisgICAgICovCisgICAgcHJvdGVjdGVkIGZpbmFsIGludCByZWFkQmFja1JlZmVyZW5jZShmaW5hbCBieXRlW10gYiwgZmluYWwgaW50IG9mZiwgZmluYWwgaW50IGxlbikgeworICAgICAgICBmaW5hbCBpbnQgYXZhaWwgPSBhdmFpbGFibGUoKTsKKyAgICAgICAgaWYgKGxlbiA+IGF2YWlsKSB7CisgICAgICAgICAgICB0cnlUb0NvcHkobGVuIC0gYXZhaWwpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZWFkRnJvbUJ1ZmZlcihiLCBvZmYsIGxlbik7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRyeVRvQ29weShpbnQgYnl0ZXNUb0NvcHkpIHsKKyAgICAgICAgLy8gdGhpcyB3aWxsIGZpdCBpbnRvIHRoZSBidWZmZXIgd2l0aG91dCBzbGlkaW5nIGFuZCBub3QKKyAgICAgICAgLy8gcmVxdWlyZSBtb3JlIHRoYW4gaXMgYXZhaWxhYmxlIGluc2lkZSB0aGUgYmFjay1yZWZlcmVuY2UKKyAgICAgICAgaW50IGNvcHkgPSBNYXRoLm1pbigoaW50KSBNYXRoLm1pbihieXRlc1RvQ29weSwgYnl0ZXNSZW1haW5pbmcpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1Zi5sZW5ndGggLSB3cml0ZUluZGV4KTsKKyAgICAgICAgaWYgKGNvcHkgPT0gMCkgeworICAgICAgICAgICAgLy8gTk9QCisgICAgICAgIH0gZWxzZSBpZiAoYmFja1JlZmVyZW5jZU9mZnNldCA9PSAxKSB7IC8vIHByZXR0eSBjb21tb24gc3BlY2lhbCBjYXNlCisgICAgICAgICAgICBmaW5hbCBieXRlIGxhc3QgPSBidWZbd3JpdGVJbmRleCAtIDFdOworICAgICAgICAgICAgQXJyYXlzLmZpbGwoYnVmLCB3cml0ZUluZGV4LCB3cml0ZUluZGV4ICsgY29weSwgbGFzdCk7CisgICAgICAgICAgICB3cml0ZUluZGV4ICs9IGNvcHk7CisgICAgICAgIH0gZWxzZSBpZiAoY29weSA8IGJhY2tSZWZlcmVuY2VPZmZzZXQpIHsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYnVmLCB3cml0ZUluZGV4IC0gYmFja1JlZmVyZW5jZU9mZnNldCwgYnVmLCB3cml0ZUluZGV4LCBjb3B5KTsKKyAgICAgICAgICAgIHdyaXRlSW5kZXggKz0gY29weTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8vIGJhY2stcmVmZXJlbmNlIG92ZXJsYXBzIHdpdGggdGhlIGJ5dGVzIGNyZWF0ZWQgZnJvbSBpdAorICAgICAgICAgICAgLy8gbGlrZSBnbyBiYWNrIHR3byBieXRlcyBhbmQgdGhlbiBjb3B5IHNpeCAoYnkgY29weWluZworICAgICAgICAgICAgLy8gdGhlIGxhc3QgdHdvIGJ5dGVzIHRocmVlIHRpbWUpLgorICAgICAgICAgICAgZmluYWwgaW50IGZ1bGxSb3RzID0gY29weSAvIGJhY2tSZWZlcmVuY2VPZmZzZXQ7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZ1bGxSb3RzOyBpKyspIHsKKyAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGJ1Ziwgd3JpdGVJbmRleCAtIGJhY2tSZWZlcmVuY2VPZmZzZXQsIGJ1Ziwgd3JpdGVJbmRleCwgYmFja1JlZmVyZW5jZU9mZnNldCk7CisgICAgICAgICAgICAgICAgd3JpdGVJbmRleCArPSBiYWNrUmVmZXJlbmNlT2Zmc2V0OworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBmaW5hbCBpbnQgcGFkID0gY29weSAtIChiYWNrUmVmZXJlbmNlT2Zmc2V0ICogZnVsbFJvdHMpOworICAgICAgICAgICAgaWYgKHBhZCA+IDApIHsKKyAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGJ1Ziwgd3JpdGVJbmRleCAtIGJhY2tSZWZlcmVuY2VPZmZzZXQsIGJ1Ziwgd3JpdGVJbmRleCwgcGFkKTsKKyAgICAgICAgICAgICAgICB3cml0ZUluZGV4ICs9IHBhZDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBieXRlc1JlbWFpbmluZyAtPSBjb3B5OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGEgc2luZ2xlIGJ5dGUgZnJvbSB0aGUgcmVhbCBpbnB1dCBzdHJlYW0gYW5kIGVuc3VyZXMgdGhlIGRhdGEgaXMgYWNjb3VudGVkIGZvci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGJ5dGUgcmVhZCBhcyB2YWx1ZSBiZXR3ZWVuIDAgYW5kIDI1NSBvciAtMSBpZiBFT0YgaGFzIGJlZW4gcmVhY2hlZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHRoZSB1bmRlcmx5aW5nIHN0cmVhbSB0aHJvd3MKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgZmluYWwgaW50IHJlYWRPbmVCeXRlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgaW50IGIgPSBpbi5yZWFkKCk7CisgICAgICAgIGlmIChiICE9IC0xKSB7CisgICAgICAgICAgICBjb3VudCgxKTsKKyAgICAgICAgICAgIHJldHVybiBiICYgMHhGRjsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gLTE7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvbHo3N3N1cHBvcnQvTFo3N0NvbXByZXNzb3IuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2x6NzdzdXBwb3J0L0xaNzdDb21wcmVzc29yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjdmZWM4ZAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2x6NzdzdXBwb3J0L0xaNzdDb21wcmVzc29yLmphdmEKQEAgLTAsMCArMSw1NTkgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMubHo3N3N1cHBvcnQ7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CisKKy8qKgorICogSGVscGVyIGNsYXNzIGZvciBjb21wcmVzc2lvbiBhbGdvcml0aG1zIHRoYXQgdXNlIHRoZSBpZGVhcyBvZiBMWjc3LgorICoKKyAqIDxwPk1vc3QgTFo3NyBkZXJpdmVkIGFsZ29yaXRobXMgc3BsaXQgaW5wdXQgZGF0YSBpbnRvIGJsb2NrcyBvZgorICogdW5jb21wcmVzc2VkIGRhdGEgKGNhbGxlZCBsaXRlcmFsIGJsb2NrcykgYW5kIGJhY2stcmVmZXJlbmNlcworICogKHBhaXJzIG9mIG9mZnNldHMgYW5kIGxlbmd0aHMpIHRoYXQgc3RhdGUgImFkZCA8Y29kZT5sZW5ndGg8L2NvZGU+CisgKiBieXRlcyB0aGF0IGFyZSB0aGUgc2FtZSBhcyB0aG9zZSBhbHJlYWR5IHdyaXR0ZW4gc3RhcnRpbmcKKyAqIDxjb2RlPm9mZnNldDwvY29kZT4gYnl0ZXMgYmVmb3JlIHRoZSBjdXJyZW50IHBvc2l0aW9uLiBUaGUgZGV0YWlscworICogb2YgaG93IHRob3NlIGJsb2NrcyBhbmQgYmFjay1yZWZlcmVuY2VzIGFyZSBlbmNvZGVkIGFyZSBxdWl0ZQorICogZGlmZmVyZW50IGJldHdlZW4gdGhlIGFsZ29yaXRobXMgYW5kIHNvbWUgYWxnb3JpdGhtcyBwZXJmb3JtCisgKiBhZGRpdGlvbmFsIHN0ZXBzIChIdWZmbWFuIGVuY29kaW5nIGluIHRoZSBjYXNlIG9mIERFRkxBVEUgZm9yCisgKiBleGFtcGxlKS48L3A+CisgKgorICogPHA+VGhpcyBjbGFzcyBhdHRlbXB0cyB0byBleHRyYWN0IHRoZSBjb3JlIGxvZ2ljIC0gZmluZGluZworICogYmFjay1yZWZlcmVuY2VzIC0gc28gaXQgY2FuIGJlIHJlLXVzZWQuIEl0IGZvbGxvd3MgdGhlIGFsZ29yaXRobQorICogZXhwbGFpbmVkIGluIHNlY3Rpb24gNCBvZiBSRkMgMTk1MSAoREVGTEFURSkgYW5kIGN1cnJlbnRseSBkb2Vzbid0CisgKiBpbXBsZW1lbnQgdGhlICJsYXp5IG1hdGNoIiBvcHRpbWl6YXRpb24uIFRoZSB0aHJlZS1ieXRlIGhhc2gKKyAqIGZ1bmN0aW9uIHVzZWQgaW4gdGhpcyBjbGFzcyBpcyB0aGUgc2FtZSBhcyB0aGUgb25lIHVzZWQgYnkgemxpYiBhbmQKKyAqIEluZm9aSVAncyBaSVAgaW1wbGVtZW50YXRpb24gb2YgREVGTEFURS4gVGhlIHdob2xlIGNsYXNzIGlzCisgKiBzdHJvbmdseSBpbnNwaXJlZCBieSBJbmZvWklQJ3MgaW1wbGVtZW50YXRpb24uPC9wPgorICoKKyAqIDxwPkxaNzcgaXMgdXNlZCB2YWd1ZWx5IGhlcmUgKGFzIHdlbGwgYXMgbWFueSBvdGhlciBwbGFjZXMgdGhhdAorICogdGFsayBhYm91dCBpdCA6LSksIExaU1Mgd291bGQgbGlrZWx5IGJlIGNsb3NlciB0byB0aGUgdHJ1dGggYnV0CisgKiBMWjc3IGhhcyBiZWNvbWUgdGhlIHN5bm9ueW0gZm9yIGEgd2hvbGUgZmFtaWx5IG9mIGFsZ29yaXRobXMuPC9wPgorICoKKyAqIDxwPlRoZSBBUEkgY29uc2lzdHMgb2YgYSBjb21wcmVzc29yIHRoYXQgaXMgZmVkIDxjb2RlPmJ5dGU8L2NvZGU+cworICogYW5kIGVtaXRzIHtAbGluayBCbG9ja31zIHRvIGEgcmVnaXN0ZXJlZCBjYWxsYmFjayB3aGVyZSB0aGUgYmxvY2tzCisgKiByZXByZXNlbnQgZWl0aGVyIHtAbGluayBMaXRlcmFsQmxvY2sgbGl0ZXJhbCBibG9ja3N9LCB7QGxpbmsKKyAqIEJhY2tSZWZlcmVuY2UgYmFjay1yZWZlcmVuY2VzfSBvciB7QGxpbmsgRU9EIGVuZCBvZiBkYXRhCisgKiBtYXJrZXJzfS4gSW4gb3JkZXIgdG8gZW5zdXJlIHRoZSBjYWxsYmFjayByZWNlaXZlcyBhbGwgaW5mb3JtYXRpb24sCisgKiB0aGUge0Bjb2RlICNmaW5pc2h9IG1ldGhvZCBtdXN0IGJlIHVzZWQgb25jZSBhbGwgZGF0YSBoYXMgYmVlbiBmZWQKKyAqIGludG8gdGhlIGNvbXByZXNzb3IuPC9wPgorICoKKyAqIDxwPlNldmVyYWwgcGFyYW1ldGVycyBpbmZsdWVuY2UgdGhlIG91dGNvbWUgb2YgdGhlICJjb21wcmVzc2lvbiI6PC9wPgorICogPGRsPgorICoKKyAqICA8ZHQ+PGNvZGU+d2luZG93U2l6ZTwvY29kZT48L2R0PiA8ZGQ+dGhlIHNpemUgb2YgdGhlIHNsaWRpbmcKKyAqICB3aW5kb3csIG11c3QgYmUgYSBwb3dlciBvZiB0d28gLSB0aGlzIGRldGVybWluZXMgdGhlIG1heGltdW0KKyAqICBvZmZzZXQgYSBiYWNrLXJlZmVyZW5jZSBjYW4gdGFrZS4gVGhlIGNvbXByZXNzb3IgbWFpbnRhaW5zIGEKKyAqICBidWZmZXIgb2YgdHdpY2Ugb2YgPGNvZGU+d2luZG93U2l6ZTwvY29kZT4gLSByZWFsIHdvcmxkIHZhbHVlcyBhcmUKKyAqICBpbiB0aGUgYXJlYSBvZiAzMmsuPC9kZD4KKyAqCisgKiAgPGR0Pjxjb2RlPm1pbkJhY2tSZWZlcmVuY2VMZW5ndGg8L2NvZGU+PC9kdD4KKyAqICA8ZGQ+TWluaW1hbCBsZW5ndGggb2YgYSBiYWNrLXJlZmVyZW5jZSBmb3VuZC4gQSB0cnVlIG1pbmltdW0gb2YgMyBpcworICogIGhhcmQtY29kZWQgaW5zaWRlIG9mIHRoaXMgaW1wbGVtZW50aW9uIGJ1dCBiaWdnZXIgbGVuZ3RocyBjYW4gYmUKKyAqICBjb25maWd1cmVkLjwvZGQ+CisgKgorICogIDxkdD48Y29kZT5tYXhCYWNrUmVmZXJlbmNlTGVuZ3RoPC9jb2RlPjwvZHQ+CisgKiAgPGRkPk1heGltYWwgbGVuZ3RoIG9mIGEgYmFjay1yZWZlcmVuY2UgZm91bmQuPC9kZD4KKyAqCisgKiAgPGR0Pjxjb2RlPm1heE9mZnNldDwvY29kZT48L2R0PgorICogIDxkZD5NYXhpbWFsIG9mZnNldCBvZiBhIGJhY2stcmVmZXJlbmNlLjwvZGQ+CisgKgorICogIDxkdD48Y29kZT5tYXhMaXRlcmFsTGVuZ3RoPC9jb2RlPjwvZHQ+CisgKiAgPGRkPk1heGltYWwgbGVuZ3RoIG9mIGEgbGl0ZXJhbCBibG9jay48L2RkPgorICogPC9kbD4KKyAqCisgKiBAc2VlICJodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjMTk1MSNzZWN0aW9uLTQiCisgKiBAc2luY2UgMS4xNAorICogQE5vdFRocmVhZFNhZmUKKyAqLworcHVibGljIGNsYXNzIExaNzdDb21wcmVzc29yIHsKKworICAgIC8qKgorICAgICAqIEJhc2UgY2xhc3MgcmVwcmVzZW50aW5nIGJsb2NrcyB0aGUgY29tcHJlc3NvciBtYXkgZW1pdC4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgY2xhc3MgaXMgbm90IHN1cHBvc2VkIHRvIGJlIHN1YmNsYXNzZWQgYnkgY2xhc3NlcworICAgICAqIG91dHNpZGUgb2YgQ29tbW9ucyBDb21wcmVzcyBzbyBpdCBpcyBjb25zaWRlcmVkIGludGVybmFsIGFuZAorICAgICAqIGNoYW5nZWQgdGhhdCB3b3VsZCBicmVhayBzdWJjbGFzc2VzIG1heSBnZXQgaW50cm9kdWNlZCB3aXRoCisgICAgICogZnV0dXJlIHJlbGVhc2VzLjwvcD4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGFic3RyYWN0IGNsYXNzIEJsb2NrIHsKKyAgICAgICAgLyoqIEVudW1lcmF0aW9uIG9mIHRoZSBibG9jayB0eXBlcyB0aGUgY29tcHJlc3NvciBtYXkgZW1pdC4gKi8KKyAgICAgICAgcHVibGljIGVudW0gQmxvY2tUeXBlIHsKKyAgICAgICAgICAgIExJVEVSQUwsIEJBQ0tfUkVGRVJFTkNFLCBFT0QKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgYWJzdHJhY3QgQmxvY2tUeXBlIGdldFR5cGUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXByZXNlbnRzIGEgbGl0ZXJhbCBibG9jayBvZiBkYXRhLgorICAgICAqCisgICAgICogPHA+Rm9yIHBlcmZvcm1hbmNlIHJlYXNvbnMgdGhpcyBlbmNhcHN1bGF0ZXMgdGhlIHJlYWwgZGF0YSwgbm90CisgICAgICogYSBjb3B5IG9mIGl0LiBEb24ndCBtb2RpZnkgdGhlIGRhdGEgYW5kIHByb2Nlc3MgaXQgaW5zaWRlIG9mCisgICAgICoge0BsaW5rIENhbGxiYWNrI2FjY2VwdH0gaW1tZWRpYXRlbHkgYXMgaXQgd2lsbCBnZXQgb3ZlcndyaXR0ZW4KKyAgICAgKiBzb29uZXIgb3IgbGF0ZXIuPC9wPgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgTGl0ZXJhbEJsb2NrIGV4dGVuZHMgQmxvY2sgeworICAgICAgICBwcml2YXRlIGZpbmFsIGJ5dGVbXSBkYXRhOworICAgICAgICBwcml2YXRlIGZpbmFsIGludCBvZmZzZXQsIGxlbmd0aDsKKyAgICAgICAgcHVibGljIExpdGVyYWxCbG9jayhieXRlW10gZGF0YSwgaW50IG9mZnNldCwgaW50IGxlbmd0aCkgeworICAgICAgICAgICAgdGhpcy5kYXRhID0gZGF0YTsKKyAgICAgICAgICAgIHRoaXMub2Zmc2V0ID0gb2Zmc2V0OworICAgICAgICAgICAgdGhpcy5sZW5ndGggPSBsZW5ndGg7CisgICAgICAgIH0KKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBsaXRlcmFsIGRhdGEuCisgICAgICAgICAqCisgICAgICAgICAqIDxwPlRoaXMgcmV0dXJucyBhIGxpZmUgdmlldyBvZiB0aGUgYWN0dWFsIGRhdGEgaW4gb3JkZXIgdG8KKyAgICAgICAgICogYXZvaWQgY29weWluZywgbW9kaWZ5IHRoZSBhcnJheSBhdCB5b3VyIG93biByaXNrLjwvcD4KKyAgICAgICAgICogQHJldHVybiB0aGUgZGF0YQorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGJ5dGVbXSBnZXREYXRhKCkgeworICAgICAgICAgICAgcmV0dXJuIGRhdGE7CisgICAgICAgIH0KKyAgICAgICAgLyoqCisgICAgICAgICAqIE9mZnNldCBpbnRvIGRhdGEgd2hlcmUgdGhlIGxpdGVyYWwgYmxvY2sgc3RhcnRzLgorICAgICAgICAgKiBAcmV0dXJuIHRoZSBvZmZzZXQKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBpbnQgZ2V0T2Zmc2V0KCkgeworICAgICAgICAgICAgcmV0dXJuIG9mZnNldDsKKyAgICAgICAgfQorICAgICAgICAvKioKKyAgICAgICAgICogTGVuZ3RoIG9mIGxpdGVyYWwgYmxvY2suCisgICAgICAgICAqIEByZXR1cm4gdGhlIGxlbmd0aAorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGludCBnZXRMZW5ndGgoKSB7CisgICAgICAgICAgICByZXR1cm4gbGVuZ3RoOworICAgICAgICB9CisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgQmxvY2tUeXBlIGdldFR5cGUoKSB7CisgICAgICAgICAgICByZXR1cm4gQmxvY2tUeXBlLkxJVEVSQUw7CisgICAgICAgIH0KKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgICAgICByZXR1cm4gIkxpdGVyYWxCbG9jayBzdGFydGluZyBhdCAiICsgb2Zmc2V0ICsgIiB3aXRoIGxlbmd0aCAiICsgbGVuZ3RoOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVwcmVzZW50cyBhIGJhY2stcmVmZXJlbmNlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQmFja1JlZmVyZW5jZSBleHRlbmRzIEJsb2NrIHsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBpbnQgb2Zmc2V0LCBsZW5ndGg7CisgICAgICAgIHB1YmxpYyBCYWNrUmVmZXJlbmNlKGludCBvZmZzZXQsIGludCBsZW5ndGgpIHsKKyAgICAgICAgICAgIHRoaXMub2Zmc2V0ID0gb2Zmc2V0OworICAgICAgICAgICAgdGhpcy5sZW5ndGggPSBsZW5ndGg7CisgICAgICAgIH0KKyAgICAgICAgLyoqCisgICAgICAgICAqIFByb3ZpZGVzIHRoZSBvZmZzZXQgb2YgdGhlIGJhY2stcmVmZXJlbmNlLgorICAgICAgICAgKiBAcmV0dXJuIHRoZSBvZmZzZXQKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBpbnQgZ2V0T2Zmc2V0KCkgeworICAgICAgICAgICAgcmV0dXJuIG9mZnNldDsKKyAgICAgICAgfQorICAgICAgICAvKioKKyAgICAgICAgICogUHJvdmlkZXMgdGhlIGxlbmd0aCBvZiB0aGUgYmFjay1yZWZlcmVuY2UuCisgICAgICAgICAqIEByZXR1cm4gdGhlIGxlbmd0aAorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGludCBnZXRMZW5ndGgoKSB7CisgICAgICAgICAgICByZXR1cm4gbGVuZ3RoOworICAgICAgICB9CisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgQmxvY2tUeXBlIGdldFR5cGUoKSB7CisgICAgICAgICAgICByZXR1cm4gQmxvY2tUeXBlLkJBQ0tfUkVGRVJFTkNFOworICAgICAgICB9CisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICAgICAgcmV0dXJuICJCYWNrUmVmZXJlbmNlIHdpdGggb2Zmc2V0ICIgKyBvZmZzZXQgKyAiIGFuZCBsZW5ndGggIiArIGxlbmd0aDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKiBBIHNpbXBsZSAid2UgYXJlIGRvbmUiIG1hcmtlci4gKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEVPRCBleHRlbmRzIEJsb2NrIHsKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBCbG9ja1R5cGUgZ2V0VHlwZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBCbG9ja1R5cGUuRU9EOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQmxvY2sgVEhFX0VPRCA9IG5ldyBFT0QoKTsKKworICAgIC8qKgorICAgICAqIENhbGxiYWNrIGludm9rZWQgd2hpbGUgdGhlIGNvbXByZXNzb3IgcHJvY2Vzc2VzIGRhdGEuCisgICAgICoKKyAgICAgKiA8cD5UaGUgY2FsbGJhY2sgaXMgaW52b2tlZCBvbiB0aGUgc2FtZSB0aHJlYWQgdGhhdCByZWNlaXZlcyB0aGUKKyAgICAgKiBieXRlcyB0byBjb21wcmVzcyBhbmQgbWF5IGJlIGludm9rZWQgbXVsdGlwbGUgdGltZXMgZHVyaW5nIHRoZQorICAgICAqIGV4ZWN1dGlvbiBvZiB7QGxpbmsgI2NvbXByZXNzfSBvciB7QGxpbmsgI2ZpbmlzaH0uPC9wPgorICAgICAqLworICAgIHB1YmxpYyBpbnRlcmZhY2UgQ2FsbGJhY2sgeworICAgICAgICAvKioKKyAgICAgICAgICogQ29uc3VtZXMgYSBibG9jay4KKyAgICAgICAgICogQHBhcmFtIGIgdGhlIGJsb2NrIHRvIGNvbnN1bWUKKyAgICAgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpbiBjYXNlIG9mIGFuIGVycm9yCisgICAgICAgICAqLworICAgICAgICB2b2lkIGFjY2VwdChCbG9jayBiKSB0aHJvd3MgSU9FeGNlcHRpb247CisgICAgfQorCisgICAgc3RhdGljIGZpbmFsIGludCBOVU1CRVJfT0ZfQllURVNfSU5fSEFTSCA9IDM7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE5PX01BVENIID0gLTE7CisKKyAgICBwcml2YXRlIGZpbmFsIFBhcmFtZXRlcnMgcGFyYW1zOworICAgIHByaXZhdGUgZmluYWwgQ2FsbGJhY2sgY2FsbGJhY2s7CisKKyAgICAvLyB0aGUgc2xpZGluZyB3aW5kb3csIHR3aWNlIGFzIGJpZyBhcyAid2luZG93U2l6ZSIgcGFyYW1ldGVyCisgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10gd2luZG93OworICAgIC8vIHRoZSBoZWFkIG9mIGhhc2gtY2hhaW4gLSBpbmRleGVkIGJ5IGhhc2gtY29kZSwgcG9pbnRzIHRvIHRoZQorICAgIC8vIGxvY2F0aW9uIGluc2lkZSBvZiB3aW5kb3cgb2YgdGhlIGxhdGVzdCBzZXF1ZW5jZSBvZiBieXRlcyB3aXRoCisgICAgLy8gdGhlIGdpdmVuIGhhc2guCisgICAgcHJpdmF0ZSBmaW5hbCBpbnRbXSBoZWFkOworICAgIC8vIGZvciBlYWNoIHdpbmRvdy1sb2NhdGlvbiBwb2ludHMgdG8gdGhlIGxhdGVzdCBlYXJsaWVyIGxvY2F0aW9uCisgICAgLy8gd2l0aCB0aGUgc2FtZSBoYXNoLiBPbmx5IHN0b3JlcyB2YWx1ZXMgZm9yIHRoZSBsYXRlc3QKKyAgICAvLyAid2luZG93U2l6ZSIgZWxlbWVudHMsIHRoZSBpbmRleCBpcyAid2luZG93IGxvY2F0aW9uIG1vZHVsbworICAgIC8vIHdpbmRvd1NpemUiLgorICAgIHByaXZhdGUgZmluYWwgaW50W10gcHJldjsKKworICAgIC8vIGJpdCBtYXNrIHVzZWQgd2hlbiBpbmRleGluZyBpbnRvIHByZXYKKyAgICBwcml2YXRlIGZpbmFsIGludCB3TWFzazsKKworICAgIHByaXZhdGUgYm9vbGVhbiBpbml0aWFsaXplZCA9IGZhbHNlOworICAgIC8vIHRoZSBwb3NpdGlvbiBpbnNpZGUgb2Ygd2luZG93IHRoYXQgc2hhbGwgYmUgZW5jb2RlZCByaWdodCBub3cKKyAgICBwcml2YXRlIGludCBjdXJyZW50UG9zaXRpb247CisgICAgLy8gdGhlIG51bWJlciBvZiBieXRlcyBhdmFpbGFibGUgdG8gY29tcHJlc3MgaW5jbHVkaW5nIHRoZSBvbmUgYXQKKyAgICAvLyBjdXJyZW50UG9zaXRpb24KKyAgICBwcml2YXRlIGludCBsb29rYWhlYWQgPSAwOworICAgIC8vIHRoZSBoYXNoIG9mIHRoZSB0aHJlZSBieXRlcyBzdGF0aW5nIGF0IHRoZSBjdXJyZW50IHBvc2l0aW9uCisgICAgcHJpdmF0ZSBpbnQgaW5zZXJ0SGFzaCA9IDA7CisgICAgLy8gdGhlIHBvc2l0aW9uIGluc2lkZSBvZiB0aGUgd2luZG93IHdoZXJlIHRoZSBjdXJyZW50IGxpdGVyYWwKKyAgICAvLyBibG9jayBzdGFydHMgKGluIGNhc2Ugd2UgYXJlIGluc2lkZSBvZiBhIGxpdGVyYWwgYmxvY2spLgorICAgIHByaXZhdGUgaW50IGJsb2NrU3RhcnQgPSAwOworICAgIC8vIHBvc2l0aW9uIG9mIHRoZSBjdXJyZW50IG1hdGNoCisgICAgcHJpdmF0ZSBpbnQgbWF0Y2hTdGFydCA9IE5PX01BVENIOworICAgIC8vIG51bWJlciBvZiBtaXNzZWQgaW5zZXJ0U3RyaW5nIGNhbGxzIGZvciB0aGUgdXAgdG8gdGhyZWUgbGFzdAorICAgIC8vIGJ5dGVzIG9mIHRoZSBsYXN0IG1hdGNoIHRoYXQgY2FuIG9ubHkgYmUgcGVyZm9ybWVkIG9uY2UgbW9yZQorICAgIC8vIGRhdGEgaGFzIGJlZW4gcmVhZAorICAgIHByaXZhdGUgaW50IG1pc3NlZEluc2VydHMgPSAwOworCisgICAgLyoqCisgICAgICogSW5pdGlhbGl6ZXMgYSBjb21wcmVzc29yIHdpdGggcGFyYW1ldGVycyBhbmQgYSBjYWxsYmFjay4KKyAgICAgKiBAcGFyYW0gcGFyYW1zIHRoZSBwYXJhbWV0ZXJzCisgICAgICogQHBhcmFtIGNhbGxiYWNrIHRoZSBjYWxsYmFjaworICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgZWl0aGVyIHBhcmFtZXRlciBpcyA8Y29kZT5udWxsPC9jb2RlPgorICAgICAqLworICAgIHB1YmxpYyBMWjc3Q29tcHJlc3NvcihQYXJhbWV0ZXJzIHBhcmFtcywgQ2FsbGJhY2sgY2FsbGJhY2spIHsKKyAgICAgICAgaWYgKHBhcmFtcyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oInBhcmFtcyBtdXN0IG5vdCBiZSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGNhbGxiYWNrID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiY2FsbGJhY2sgbXVzdCBub3QgYmUgbnVsbCIpOworICAgICAgICB9CisgICAgICAgIHRoaXMucGFyYW1zID0gcGFyYW1zOworICAgICAgICB0aGlzLmNhbGxiYWNrID0gY2FsbGJhY2s7CisKKyAgICAgICAgZmluYWwgaW50IHdTaXplID0gcGFyYW1zLmdldFdpbmRvd1NpemUoKTsKKyAgICAgICAgd2luZG93ID0gbmV3IGJ5dGVbd1NpemUgKiAyXTsKKyAgICAgICAgd01hc2sgPSB3U2l6ZSAtIDE7CisgICAgICAgIGhlYWQgPSBuZXcgaW50W0hBU0hfU0laRV07CisgICAgICAgIEFycmF5cy5maWxsKGhlYWQsIE5PX01BVENIKTsKKyAgICAgICAgcHJldiA9IG5ldyBpbnRbd1NpemVdOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZlZWRzIGJ5dGVzIGludG8gdGhlIGNvbXByZXNzb3Igd2hpY2ggaW4gdHVybiBtYXkgZW1pdCB6ZXJvIG9yCisgICAgICogbW9yZSBibG9ja3MgdG8gdGhlIGNhbGxiYWNrIGR1cmluZyB0aGUgZXhlY3V0aW9uIG9mIHRoaXMKKyAgICAgKiBtZXRob2QuCisgICAgICogQHBhcmFtIGRhdGEgdGhlIGRhdGEgdG8gY29tcHJlc3MgLSBtdXN0IG5vdCBiZSBudWxsCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiB0aGUgY2FsbGJhY2sgdGhyb3dzIGFuIGV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNvbXByZXNzKGJ5dGVbXSBkYXRhKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjb21wcmVzcyhkYXRhLCAwLCBkYXRhLmxlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmVlZHMgYnl0ZXMgaW50byB0aGUgY29tcHJlc3NvciB3aGljaCBpbiB0dXJuIG1heSBlbWl0IHplcm8gb3IKKyAgICAgKiBtb3JlIGJsb2NrcyB0byB0aGUgY2FsbGJhY2sgZHVyaW5nIHRoZSBleGVjdXRpb24gb2YgdGhpcworICAgICAqIG1ldGhvZC4KKyAgICAgKiBAcGFyYW0gZGF0YSB0aGUgZGF0YSB0byBjb21wcmVzcyAtIG11c3Qgbm90IGJlIG51bGwKKyAgICAgKiBAcGFyYW0gb2ZmIHRoZSBzdGFydCBvZmZzZXQgb2YgdGhlIGRhdGEKKyAgICAgKiBAcGFyYW0gbGVuIHRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gY29tcHJlc3MKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHRoZSBjYWxsYmFjayB0aHJvd3MgYW4gZXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIHZvaWQgY29tcHJlc3MoYnl0ZVtdIGRhdGEsIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIGludCB3U2l6ZSA9IHBhcmFtcy5nZXRXaW5kb3dTaXplKCk7CisgICAgICAgIHdoaWxlIChsZW4gPiB3U2l6ZSkgeyAvLyBjaG9wIGludG8gd2luZG93U2l6ZSBzaXplZCBjaHVua3MKKyAgICAgICAgICAgIGRvQ29tcHJlc3MoZGF0YSwgb2ZmLCB3U2l6ZSk7CisgICAgICAgICAgICBvZmYgKz0gd1NpemU7CisgICAgICAgICAgICBsZW4gLT0gd1NpemU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGxlbiA+IDApIHsKKyAgICAgICAgICAgIGRvQ29tcHJlc3MoZGF0YSwgb2ZmLCBsZW4pOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVsbHMgdGhlIGNvbXByZXNzb3IgdG8gcHJvY2VzcyBhbGwgcmVtYWluaW5nIGRhdGEgYW5kIHNpZ25hbAorICAgICAqIGVuZCBvZiBkYXRhIHRvIHRoZSBjYWxsYmFjay4KKyAgICAgKgorICAgICAqIDxwPlRoZSBjb21wcmVzc29yIHdpbGwgaW4gdHVybiBlbWl0IGF0IGxlYXN0IG9uZSBibG9jayAoe0BsaW5rCisgICAgICogRU9EfSkgYnV0IHBvdGVudGlhbGx5IG11bHRpcGxlIGJsb2NrcyB0byB0aGUgY2FsbGJhY2sgZHVyaW5nCisgICAgICogdGhlIGV4ZWN1dGlvbiBvZiB0aGlzIG1ldGhvZC48L3A+CisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiB0aGUgY2FsbGJhY2sgdGhyb3dzIGFuIGV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGZpbmlzaCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChibG9ja1N0YXJ0ICE9IGN1cnJlbnRQb3NpdGlvbiB8fCBsb29rYWhlYWQgPiAwKSB7CisgICAgICAgICAgICBjdXJyZW50UG9zaXRpb24gKz0gbG9va2FoZWFkOworICAgICAgICAgICAgZmx1c2hMaXRlcmFsQmxvY2soKTsKKyAgICAgICAgfQorICAgICAgICBjYWxsYmFjay5hY2NlcHQoVEhFX0VPRCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkcyBzb21lIGluaXRpYWwgZGF0YSB0byBmaWxsIHRoZSB3aW5kb3cgd2l0aC4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgaXMgdXNlZCBpZiB0aGUgc3RyZWFtIGhhcyBiZWVuIGN1dCBpbnRvIGJsb2NrcyBhbmQKKyAgICAgKiBiYWNrLXJlZmVyZW5jZXMgb2Ygb25lIGJsb2NrIG1heSByZWZlciB0byBkYXRhIG9mIHRoZSBwcmV2aW91cworICAgICAqIGJsb2NrKHMpLiBPbmUgc3VjaCBleGFtcGxlIGlzIHRoZSBMWjQgZnJhbWUgZm9ybWF0IHVzaW5nIGJsb2NrCisgICAgICogZGVwZW5kZW5jeS48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gZGF0YSB0aGUgZGF0YSB0byBmaWxsIHRoZSB3aW5kb3cgd2l0aC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGUgY29tcHJlc3NvciBoYXMgYWxyZWFkeSBzdGFydGVkIHRvIGFjY2VwdCBkYXRhCisgICAgICovCisgICAgcHVibGljIHZvaWQgcHJlZmlsbChieXRlW10gZGF0YSkgeworICAgICAgICBpZiAoY3VycmVudFBvc2l0aW9uICE9IDAgfHwgbG9va2FoZWFkICE9IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oInRoZSBjb21wcmVzc29yIGhhcyBhbHJlYWR5IHN0YXJ0ZWQgdG8gYWNjZXB0IGRhdGEsIGNhbid0IHByZWZpbGwgYW55bW9yZSIpOworICAgICAgICB9CisKKyAgICAgICAgLy8gZG9uJ3QgbmVlZCBtb3JlIHRoYW4gd2luZG93U2l6ZSBmb3IgYmFjay1yZWZlcmVuY2VzCisgICAgICAgIGZpbmFsIGludCBsZW4gPSBNYXRoLm1pbihwYXJhbXMuZ2V0V2luZG93U2l6ZSgpLCBkYXRhLmxlbmd0aCk7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZGF0YSwgZGF0YS5sZW5ndGggLSBsZW4sIHdpbmRvdywgMCwgbGVuKTsKKworICAgICAgICBpZiAobGVuID49IE5VTUJFUl9PRl9CWVRFU19JTl9IQVNIKSB7CisgICAgICAgICAgICBpbml0aWFsaXplKCk7CisgICAgICAgICAgICBmaW5hbCBpbnQgc3RvcCA9IGxlbiAtIE5VTUJFUl9PRl9CWVRFU19JTl9IQVNIICsgMTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc3RvcDsgaSsrKSB7CisgICAgICAgICAgICAgICAgaW5zZXJ0U3RyaW5nKGkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgbWlzc2VkSW5zZXJ0cyA9IE5VTUJFUl9PRl9CWVRFU19JTl9IQVNIIC0gMTsKKyAgICAgICAgfSBlbHNlIHsgLy8gbm90IGVub3VnaCBkYXRhIHRvIGhhc2ggYW55dGhpbmcKKyAgICAgICAgICAgIG1pc3NlZEluc2VydHMgPSBsZW47CisgICAgICAgIH0KKyAgICAgICAgYmxvY2tTdGFydCA9IGN1cnJlbnRQb3NpdGlvbiA9IGxlbjsKKyAgICB9CisKKyAgICAvLyB3ZSB1c2UgYSAxNSBiaXQgaGFzaGNvZGUgYXMgY2FsY3VsYXRlZCBpbiB1cGRhdGVIYXNoCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEhBU0hfU0laRSA9IDEgPDwgMTU7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEhBU0hfTUFTSyA9IEhBU0hfU0laRSAtIDE7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEhfU0hJRlQgPSA1OworCisgICAgLyoqCisgICAgICogQXNzdW1lcyB3ZSBhcmUgY2FsY3VsYXRpbmcgdGhlIGhhc2ggZm9yIHRocmVlIGNvbnNlY3V0aXZlIGJ5dGVzCisgICAgICogYXMgYSByb2xsaW5nIGhhc2gsIGkuZS4gZm9yIGJ5dGVzIEFCQ0QgaWYgSCBpcyB0aGUgaGFzaCBvZiBBQkMKKyAgICAgKiB0aGUgbmV3IGhhc2ggZm9yIEJDRCBpcyBuZXh0SGFzaChILCBEKS4KKyAgICAgKgorICAgICAqIDxwPlRoZSBoYXNoIGlzIHNoaWZ0ZWQgYnkgZml2ZSBiaXRzIG9uIGVhY2ggdXBkYXRlIHNvIGFsbAorICAgICAqIGVmZmVjdHMgb2YgQSBoYXZlIGJlZW4gc3dhcHBlZCBhZnRlciB0aGUgdGhpcmQgdXBkYXRlLjwvcD4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBuZXh0SGFzaChpbnQgb2xkSGFzaCwgYnl0ZSBuZXh0Qnl0ZSkgeworICAgICAgICBmaW5hbCBpbnQgbmV4dFZhbCA9IG5leHRCeXRlICYgMHhGRjsKKyAgICAgICAgcmV0dXJuICgob2xkSGFzaCA8PCBIX1NISUZUKSBeIG5leHRWYWwpICYgSEFTSF9NQVNLOworICAgIH0KKworICAgIC8vIHBlcmZvcm1zIHRoZSBhY3R1YWwgYWxnb3JpdGhtIHdpdGggdGhlIHByZS1jb25kaXRpb24gbGVuIDw9IHdpbmRvd1NpemUKKyAgICBwcml2YXRlIHZvaWQgZG9Db21wcmVzcyhieXRlW10gZGF0YSwgaW50IG9mZiwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IHNwYWNlTGVmdCA9IHdpbmRvdy5sZW5ndGggLSBjdXJyZW50UG9zaXRpb24gLSBsb29rYWhlYWQ7CisgICAgICAgIGlmIChsZW4gPiBzcGFjZUxlZnQpIHsKKyAgICAgICAgICAgIHNsaWRlKCk7CisgICAgICAgIH0KKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShkYXRhLCBvZmYsIHdpbmRvdywgY3VycmVudFBvc2l0aW9uICsgbG9va2FoZWFkLCBsZW4pOworICAgICAgICBsb29rYWhlYWQgKz0gbGVuOworICAgICAgICBpZiAoIWluaXRpYWxpemVkICYmIGxvb2thaGVhZCA+PSBwYXJhbXMuZ2V0TWluQmFja1JlZmVyZW5jZUxlbmd0aCgpKSB7CisgICAgICAgICAgICBpbml0aWFsaXplKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGluaXRpYWxpemVkKSB7CisgICAgICAgICAgICBjb21wcmVzcygpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHNsaWRlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgaW50IHdTaXplID0gcGFyYW1zLmdldFdpbmRvd1NpemUoKTsKKyAgICAgICAgaWYgKGJsb2NrU3RhcnQgIT0gY3VycmVudFBvc2l0aW9uICYmIGJsb2NrU3RhcnQgPCB3U2l6ZSkgeworICAgICAgICAgICAgZmx1c2hMaXRlcmFsQmxvY2soKTsKKyAgICAgICAgICAgIGJsb2NrU3RhcnQgPSBjdXJyZW50UG9zaXRpb247CisgICAgICAgIH0KKyAgICAgICAgU3lzdGVtLmFycmF5Y29weSh3aW5kb3csIHdTaXplLCB3aW5kb3csIDAsIHdTaXplKTsKKyAgICAgICAgY3VycmVudFBvc2l0aW9uIC09IHdTaXplOworICAgICAgICBtYXRjaFN0YXJ0IC09IHdTaXplOworICAgICAgICBibG9ja1N0YXJ0IC09IHdTaXplOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IEhBU0hfU0laRTsgaSsrKSB7CisgICAgICAgICAgICBpbnQgaCA9IGhlYWRbaV07CisgICAgICAgICAgICBoZWFkW2ldID0gaCA+PSB3U2l6ZSA/IGggLSB3U2l6ZSA6IE5PX01BVENIOworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgd1NpemU7IGkrKykgeworICAgICAgICAgICAgaW50IHAgPSBwcmV2W2ldOworICAgICAgICAgICAgcHJldltpXSA9IHAgPj0gd1NpemUgPyBwIC0gd1NpemUgOiBOT19NQVRDSDsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBpbml0aWFsaXplKCkgeworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IE5VTUJFUl9PRl9CWVRFU19JTl9IQVNIIC0gMTsgaSsrKSB7CisgICAgICAgICAgICBpbnNlcnRIYXNoID0gbmV4dEhhc2goaW5zZXJ0SGFzaCwgd2luZG93W2ldKTsKKyAgICAgICAgfQorICAgICAgICBpbml0aWFsaXplZCA9IHRydWU7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNvbXByZXNzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgaW50IG1pbk1hdGNoID0gcGFyYW1zLmdldE1pbkJhY2tSZWZlcmVuY2VMZW5ndGgoKTsKKyAgICAgICAgZmluYWwgYm9vbGVhbiBsYXp5ID0gcGFyYW1zLmdldExhenlNYXRjaGluZygpOworICAgICAgICBmaW5hbCBpbnQgbGF6eVRocmVzaG9sZCA9IHBhcmFtcy5nZXRMYXp5TWF0Y2hpbmdUaHJlc2hvbGQoKTsKKworICAgICAgICB3aGlsZSAobG9va2FoZWFkID49IG1pbk1hdGNoKSB7CisgICAgICAgICAgICBjYXRjaFVwTWlzc2VkSW5zZXJ0cygpOworICAgICAgICAgICAgaW50IG1hdGNoTGVuZ3RoID0gMDsKKyAgICAgICAgICAgIGludCBoYXNoSGVhZCA9IGluc2VydFN0cmluZyhjdXJyZW50UG9zaXRpb24pOworICAgICAgICAgICAgaWYgKGhhc2hIZWFkICE9IE5PX01BVENIICYmIGhhc2hIZWFkIC0gY3VycmVudFBvc2l0aW9uIDw9IHBhcmFtcy5nZXRNYXhPZmZzZXQoKSkgeworICAgICAgICAgICAgICAgIC8vIHNldHMgbWF0Y2hTdGFydCBhcyBhIHNpZGUgZWZmZWN0CisgICAgICAgICAgICAgICAgbWF0Y2hMZW5ndGggPSBsb25nZXN0TWF0Y2goaGFzaEhlYWQpOworCisgICAgICAgICAgICAgICAgaWYgKGxhenkgJiYgbWF0Y2hMZW5ndGggPD0gbGF6eVRocmVzaG9sZCAmJiBsb29rYWhlYWQgPiBtaW5NYXRjaCkgeworICAgICAgICAgICAgICAgICAgICAvLyB0cnkgdG8gZmluZCBhIGxvbmdlciBtYXRjaCB1c2luZyB0aGUgbmV4dCBwb3NpdGlvbgorICAgICAgICAgICAgICAgICAgICBtYXRjaExlbmd0aCA9IGxvbmdlc3RNYXRjaEZvck5leHRQb3NpdGlvbihtYXRjaExlbmd0aCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKG1hdGNoTGVuZ3RoID49IG1pbk1hdGNoKSB7CisgICAgICAgICAgICAgICAgaWYgKGJsb2NrU3RhcnQgIT0gY3VycmVudFBvc2l0aW9uKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIGVtaXQgcHJlY2VlZGluZyBsaXRlcmFsIGJsb2NrCisgICAgICAgICAgICAgICAgICAgIGZsdXNoTGl0ZXJhbEJsb2NrKCk7CisgICAgICAgICAgICAgICAgICAgIGJsb2NrU3RhcnQgPSBOT19NQVRDSDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZmx1c2hCYWNrUmVmZXJlbmNlKG1hdGNoTGVuZ3RoKTsKKyAgICAgICAgICAgICAgICBpbnNlcnRTdHJpbmdzSW5NYXRjaChtYXRjaExlbmd0aCk7CisgICAgICAgICAgICAgICAgbG9va2FoZWFkIC09IG1hdGNoTGVuZ3RoOworICAgICAgICAgICAgICAgIGN1cnJlbnRQb3NpdGlvbiArPSBtYXRjaExlbmd0aDsKKyAgICAgICAgICAgICAgICBibG9ja1N0YXJ0ID0gY3VycmVudFBvc2l0aW9uOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAvLyBubyBtYXRjaCwgYXBwZW5kIHRvIGN1cnJlbnQgb3Igc3RhcnQgYSBuZXcgbGl0ZXJhbAorICAgICAgICAgICAgICAgIGxvb2thaGVhZC0tOworICAgICAgICAgICAgICAgIGN1cnJlbnRQb3NpdGlvbisrOworICAgICAgICAgICAgICAgIGlmIChjdXJyZW50UG9zaXRpb24gLSBibG9ja1N0YXJ0ID49IHBhcmFtcy5nZXRNYXhMaXRlcmFsTGVuZ3RoKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgZmx1c2hMaXRlcmFsQmxvY2soKTsKKyAgICAgICAgICAgICAgICAgICAgYmxvY2tTdGFydCA9IGN1cnJlbnRQb3NpdGlvbjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnNlcnRzIHRoZSBjdXJyZW50IHRocmVlIGJ5dGUgc2VxdWVuY2UgaW50byB0aGUgZGljdGlvbmFyeSBhbmQKKyAgICAgKiByZXR1cm5zIHRoZSBwcmV2aW91cyBoZWFkIG9mIHRoZSBoYXNoLWNoYWluLgorICAgICAqCisgICAgICogPHA+VXBkYXRlcyA8Y29kZT5pbnNlcnRIYXNoPC9jb2RlPiBhbmQgPGNvZGU+cHJldjwvY29kZT4gYXMgYQorICAgICAqIHNpZGUgZWZmZWN0LjwvcD4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBpbnNlcnRTdHJpbmcoaW50IHBvcykgeworICAgICAgICBpbnNlcnRIYXNoID0gbmV4dEhhc2goaW5zZXJ0SGFzaCwgd2luZG93W3BvcyAtIDEgKyBOVU1CRVJfT0ZfQllURVNfSU5fSEFTSF0pOworICAgICAgICBpbnQgaGFzaEhlYWQgPSBoZWFkW2luc2VydEhhc2hdOworICAgICAgICBwcmV2W3BvcyAmIHdNYXNrXSA9IGhhc2hIZWFkOworICAgICAgICBoZWFkW2luc2VydEhhc2hdID0gcG9zOworICAgICAgICByZXR1cm4gaGFzaEhlYWQ7CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnQgbG9uZ2VzdE1hdGNoRm9yTmV4dFBvc2l0aW9uKGZpbmFsIGludCBwcmV2TWF0Y2hMZW5ndGgpIHsKKyAgICAgICAgLy8gc2F2ZSBhIGJ1bmNoIG9mIHZhbHVlcyB0byByZXN0b3JlIHRoZW0gaWYgdGhlIG5leHQgbWF0Y2ggaXNuJ3QgYmV0dGVyIHRoYW4gdGhlIGN1cnJlbnQgb25lCisgICAgICAgIGZpbmFsIGludCBwcmV2TWF0Y2hTdGFydCA9IG1hdGNoU3RhcnQ7CisgICAgICAgIGZpbmFsIGludCBwcmV2SW5zZXJ0SGFzaCA9IGluc2VydEhhc2g7CisKKyAgICAgICAgbG9va2FoZWFkLS07CisgICAgICAgIGN1cnJlbnRQb3NpdGlvbisrOworICAgICAgICBpbnQgaGFzaEhlYWQgPSBpbnNlcnRTdHJpbmcoY3VycmVudFBvc2l0aW9uKTsKKyAgICAgICAgZmluYWwgaW50IHByZXZIYXNoSGVhZCA9IHByZXZbY3VycmVudFBvc2l0aW9uICYgd01hc2tdOworICAgICAgICBpbnQgbWF0Y2hMZW5ndGggPSBsb25nZXN0TWF0Y2goaGFzaEhlYWQpOworCisgICAgICAgIGlmIChtYXRjaExlbmd0aCA8PSBwcmV2TWF0Y2hMZW5ndGgpIHsKKyAgICAgICAgICAgIC8vIHVzZSB0aGUgZmlyc3QgbWF0Y2gsIGFzIHRoZSBuZXh0IG9uZSBpc24ndCBhbnkgYmV0dGVyCisgICAgICAgICAgICBtYXRjaExlbmd0aCA9IHByZXZNYXRjaExlbmd0aDsKKyAgICAgICAgICAgIG1hdGNoU3RhcnQgPSBwcmV2TWF0Y2hTdGFydDsKKworICAgICAgICAgICAgLy8gcmVzdG9yZSBtb2RpZmllZCB2YWx1ZXMKKyAgICAgICAgICAgIGhlYWRbaW5zZXJ0SGFzaF0gPSBwcmV2SGFzaEhlYWQ7CisgICAgICAgICAgICBpbnNlcnRIYXNoID0gcHJldkluc2VydEhhc2g7CisgICAgICAgICAgICBjdXJyZW50UG9zaXRpb24tLTsKKyAgICAgICAgICAgIGxvb2thaGVhZCsrOworICAgICAgICB9CisgICAgICAgIHJldHVybiBtYXRjaExlbmd0aDsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgaW5zZXJ0U3RyaW5nc0luTWF0Y2goaW50IG1hdGNoTGVuZ3RoKSB7CisgICAgICAgIC8vIGluc2VydHMgc3RyaW5ncyBjb250YWluZWQgaW4gY3VycmVudCBtYXRjaAorICAgICAgICAvLyBpbnNlcnRTdHJpbmcgaW5zZXJ0cyB0aGUgYnl0ZSAyIGJ5dGVzIGFmdGVyIHBvc2l0aW9uLCB3aGljaCBtYXkgbm90IHlldCBiZSBhdmFpbGFibGUgLT4gbWlzc2VkSW5zZXJ0cworICAgICAgICBmaW5hbCBpbnQgc3RvcCA9IE1hdGgubWluKG1hdGNoTGVuZ3RoIC0gMSwgbG9va2FoZWFkIC0gTlVNQkVSX09GX0JZVEVTX0lOX0hBU0gpOworICAgICAgICAvLyBjdXJyZW50UG9zaXRpb24gaGFzIGJlZW4gaW5zZXJ0ZWQgYWxyZWFkeQorICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8PSBzdG9wOyBpKyspIHsKKyAgICAgICAgICAgIGluc2VydFN0cmluZyhjdXJyZW50UG9zaXRpb24gKyBpKTsKKyAgICAgICAgfQorICAgICAgICBtaXNzZWRJbnNlcnRzID0gbWF0Y2hMZW5ndGggLSBzdG9wIC0gMTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY2F0Y2hVcE1pc3NlZEluc2VydHMoKSB7CisgICAgICAgIHdoaWxlIChtaXNzZWRJbnNlcnRzID4gMCkgeworICAgICAgICAgICAgaW5zZXJ0U3RyaW5nKGN1cnJlbnRQb3NpdGlvbiAtIG1pc3NlZEluc2VydHMtLSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgZmx1c2hCYWNrUmVmZXJlbmNlKGludCBtYXRjaExlbmd0aCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY2FsbGJhY2suYWNjZXB0KG5ldyBCYWNrUmVmZXJlbmNlKGN1cnJlbnRQb3NpdGlvbiAtIG1hdGNoU3RhcnQsIG1hdGNoTGVuZ3RoKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGZsdXNoTGl0ZXJhbEJsb2NrKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY2FsbGJhY2suYWNjZXB0KG5ldyBMaXRlcmFsQmxvY2sod2luZG93LCBibG9ja1N0YXJ0LCBjdXJyZW50UG9zaXRpb24gLSBibG9ja1N0YXJ0KSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2VhcmNoZXMgdGhlIGhhc2ggY2hhaW4gZm9yIHJlYWwgbWF0Y2hlcyBhbmQgcmV0dXJucyB0aGUgbGVuZ3RoCisgICAgICogb2YgdGhlIGxvbmdlc3QgbWF0Y2ggKDAgaWYgbm9uZSB3ZXJlIGZvdW5kKSB0aGF0IGlzbid0IHRvbyBmYXIKKyAgICAgKiBhd2F5IChXUlQgbWF4T2Zmc2V0KS4KKyAgICAgKgorICAgICAqIDxwPlNldHMgbWF0Y2hTdGFydCB0byB0aGUgaW5kZXggb2YgdGhlIHN0YXJ0IHBvc2l0aW9uIG9mIHRoZQorICAgICAqIGxvbmdlc3QgbWF0Y2ggYXMgYSBzaWRlIGVmZmVjdC48L3A+CisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgbG9uZ2VzdE1hdGNoKGludCBtYXRjaEhlYWQpIHsKKyAgICAgICAgZmluYWwgaW50IG1pbkxlbmd0aCA9IHBhcmFtcy5nZXRNaW5CYWNrUmVmZXJlbmNlTGVuZ3RoKCk7CisgICAgICAgIGludCBsb25nZXN0TWF0Y2hMZW5ndGggPSBtaW5MZW5ndGggLSAxOworICAgICAgICBmaW5hbCBpbnQgbWF4UG9zc2libGVMZW5ndGggPSBNYXRoLm1pbihwYXJhbXMuZ2V0TWF4QmFja1JlZmVyZW5jZUxlbmd0aCgpLCBsb29rYWhlYWQpOworICAgICAgICBmaW5hbCBpbnQgbWluSW5kZXggPSBNYXRoLm1heCgwLCBjdXJyZW50UG9zaXRpb24gLSBwYXJhbXMuZ2V0TWF4T2Zmc2V0KCkpOworICAgICAgICBmaW5hbCBpbnQgbmljZUJhY2tSZWZlcmVuY2VMZW5ndGggPSBNYXRoLm1pbihtYXhQb3NzaWJsZUxlbmd0aCwgcGFyYW1zLmdldE5pY2VCYWNrUmVmZXJlbmNlTGVuZ3RoKCkpOworICAgICAgICBmaW5hbCBpbnQgbWF4Q2FuZGlkYXRlcyA9IHBhcmFtcy5nZXRNYXhDYW5kaWRhdGVzKCk7CisgICAgICAgIGZvciAoaW50IGNhbmRpZGF0ZXMgPSAwOyBjYW5kaWRhdGVzIDwgbWF4Q2FuZGlkYXRlcyAmJiBtYXRjaEhlYWQgPj0gbWluSW5kZXg7IGNhbmRpZGF0ZXMrKykgeworICAgICAgICAgICAgaW50IGN1cnJlbnRMZW5ndGggPSAwOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtYXhQb3NzaWJsZUxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgaWYgKHdpbmRvd1ttYXRjaEhlYWQgKyBpXSAhPSB3aW5kb3dbY3VycmVudFBvc2l0aW9uICsgaV0pIHsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGN1cnJlbnRMZW5ndGgrKzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChjdXJyZW50TGVuZ3RoID4gbG9uZ2VzdE1hdGNoTGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgbG9uZ2VzdE1hdGNoTGVuZ3RoID0gY3VycmVudExlbmd0aDsKKyAgICAgICAgICAgICAgICBtYXRjaFN0YXJ0ID0gbWF0Y2hIZWFkOworICAgICAgICAgICAgICAgIGlmIChjdXJyZW50TGVuZ3RoID49IG5pY2VCYWNrUmVmZXJlbmNlTGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIG5vIG5lZWQgdG8gc2VhcmNoIGFueSBmdXJ0aGVyCisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIG1hdGNoSGVhZCA9IHByZXZbbWF0Y2hIZWFkICYgd01hc2tdOworICAgICAgICB9CisgICAgICAgIHJldHVybiBsb25nZXN0TWF0Y2hMZW5ndGg7IC8vIDwgbWluTGVuZ3RoIGlmIG5vIG1hdGNoZXMgaGF2ZSBiZWVuIGZvdW5kLCB3aWxsIGJlIGlnbm9yZWQgaW4gY29tcHJlc3MoKQorICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2x6NzdzdXBwb3J0L1BhcmFtZXRlcnMuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2x6NzdzdXBwb3J0L1BhcmFtZXRlcnMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mZTg5MmYzCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvbHo3N3N1cHBvcnQvUGFyYW1ldGVycy5qYXZhCkBAIC0wLDAgKzEsMzUwIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLmx6NzdzdXBwb3J0OworCisvKioKKyAqIFBhcmFtZXRlcnMgb2YgdGhlIHtAbGluayBMWjc3Q29tcHJlc3NvciBjb21wcmVzc29yfS4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFBhcmFtZXRlcnMgeworICAgIC8qKgorICAgICAqIFRoZSBoYXJkLWNvZGVkIGFic29sdXRlIG1pbmltYWwgbGVuZ3RoIG9mIGEgYmFjay1yZWZlcmVuY2UuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVFJVRV9NSU5fQkFDS19SRUZFUkVOQ0VfTEVOR1RIID0gTFo3N0NvbXByZXNzb3IuTlVNQkVSX09GX0JZVEVTX0lOX0hBU0g7CisKKyAgICAvKioKKyAgICAgKiBJbml0aWFsaXplcyB0aGUgYnVpbGRlciBmb3IgdGhlIGNvbXByZXNzb3IncyBwYXJhbWV0ZXJzIHdpdGggYQorICAgICAqIDxjb2RlPm1pbkJhY2tSZWZlcmVuY2VMZW5ndGg8L2NvZGU+IG9mIDMgYW5kIDxjb2RlPm1heCpMZW5ndGg8L2NvZGU+CisgICAgICogZXF1YWwgdG8gPGNvZGU+d2luZG93U2l6ZSAtIDE8L2NvZGU+LgorICAgICAqCisgICAgICogPHA+SXQgaXMgcmVjb21tZW5kZWQgdG8gbm90IHVzZSB0aGlzIG1ldGhvZCBkaXJlY3RseSBidXQgcmF0aGVyCisgICAgICogdHVuZSBhIHByZS1jb25maWd1cmVkIGJ1aWxkZXIgY3JlYXRlZCBieSBhIGZvcm1hdCBzcGVjaWZpYworICAgICAqIGZhY3RvcnkgbGlrZSB7QGxpbmsKKyAgICAgKiBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuc25hcHB5LlNuYXBweUNvbXByZXNzb3JPdXRwdXRTdHJlYW0jY3JlYXRlUGFyYW1ldGVyQnVpbGRlcn0uPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIHdpbmRvd1NpemUgdGhlIHNpemUgb2YgdGhlIHNsaWRpbmcgd2luZG93IC0gdGhpcworICAgICAqIGRldGVybWluZXMgdGhlIG1heGltdW0gb2Zmc2V0IGEgYmFjay1yZWZlcmVuY2UgY2FuIHRha2UuIE11c3QKKyAgICAgKiBiZSBhIHBvd2VyIG9mIHR3by4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB3aW5kb3dTaXplIGlzIG5vdCBhIHBvd2VyIG9mIHR3by4KKyAgICAgKiBAcmV0dXJuIGEgYnVpbGRlciBjb25maWd1cmVkIGZvciB0aGUgZ2l2ZW4gd2luZG93IHNpemUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgYnVpbGRlcihpbnQgd2luZG93U2l6ZSkgeworICAgICAgICByZXR1cm4gbmV3IEJ1aWxkZXIod2luZG93U2l6ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQnVpbGRlciBmb3Ige0BsaW5rIFBhcmFtZXRlcnN9IGluc3RhbmNlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEJ1aWxkZXIgeworICAgICAgICBwcml2YXRlIGZpbmFsIGludCB3aW5kb3dTaXplOworICAgICAgICBwcml2YXRlIGludCBtaW5CYWNrUmVmZXJlbmNlTGVuZ3RoLCBtYXhCYWNrUmVmZXJlbmNlTGVuZ3RoLCBtYXhPZmZzZXQsIG1heExpdGVyYWxMZW5ndGg7CisgICAgICAgIHByaXZhdGUgSW50ZWdlciBuaWNlQmFja1JlZmVyZW5jZUxlbmd0aCwgbWF4Q2FuZGlkYXRlcywgbGF6eVRocmVzaG9sZDsKKyAgICAgICAgcHJpdmF0ZSBCb29sZWFuIGxhenlNYXRjaGVzOworCisgICAgICAgIHByaXZhdGUgQnVpbGRlcihpbnQgd2luZG93U2l6ZSkgeworICAgICAgICAgICAgaWYgKHdpbmRvd1NpemUgPCAyIHx8ICFpc1Bvd2VyT2ZUd28od2luZG93U2l6ZSkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJ3aW5kb3dTaXplIG11c3QgYmUgYSBwb3dlciBvZiB0d28iKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRoaXMud2luZG93U2l6ZSA9IHdpbmRvd1NpemU7CisgICAgICAgICAgICBtaW5CYWNrUmVmZXJlbmNlTGVuZ3RoID0gVFJVRV9NSU5fQkFDS19SRUZFUkVOQ0VfTEVOR1RIOworICAgICAgICAgICAgbWF4QmFja1JlZmVyZW5jZUxlbmd0aCA9IHdpbmRvd1NpemUgLSAxOworICAgICAgICAgICAgbWF4T2Zmc2V0ID0gd2luZG93U2l6ZSAtIDE7CisgICAgICAgICAgICBtYXhMaXRlcmFsTGVuZ3RoID0gd2luZG93U2l6ZTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBTZXRzIHRoZSBtaW5pbmFsIGxlbmd0aCBvZiBhIGJhY2stcmVmZXJlbmNlLgorICAgICAgICAgKgorICAgICAgICAgKiA8cD5FbnN1cmVzIDxjb2RlPm1heEJhY2tSZWZlcmVuY2VMZW5ndGg8L2NvZGU+IGlzIG5vdAorICAgICAgICAgKiBzbWFsbGVyIHRoYW4gPGNvZGU+bWluQmFja1JlZmVyZW5jZUxlbmd0aDwvY29kZT4uCisgICAgICAgICAqCisgICAgICAgICAqIDxwPkl0IGlzIHJlY29tbWVuZGVkIHRvIG5vdCB1c2UgdGhpcyBtZXRob2QgZGlyZWN0bHkgYnV0CisgICAgICAgICAqIHJhdGhlciB0dW5lIGEgcHJlLWNvbmZpZ3VyZWQgYnVpbGRlciBjcmVhdGVkIGJ5IGEgZm9ybWF0CisgICAgICAgICAqIHNwZWNpZmljIGZhY3RvcnkgbGlrZSB7QGxpbmsKKyAgICAgICAgICogb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLnNuYXBweS5TbmFwcHlDb21wcmVzc29yT3V0cHV0U3RyZWFtI2NyZWF0ZVBhcmFtZXRlckJ1aWxkZXJ9LjwvcD4KKyAgICAgICAgICoKKyAgICAgICAgICogQHBhcmFtIG1pbkJhY2tSZWZlcmVuY2VMZW5ndGggdGhlIG1pbmltYWwgbGVuZ3RoIG9mIGEgYmFjay1yZWZlcmVuY2UgZm91bmQuIEEKKyAgICAgICAgICogdHJ1ZSBtaW5pbXVtIG9mIDMgaXMgaGFyZC1jb2RlZCBpbnNpZGUgb2YgdGhpcyBpbXBsZW1lbnRpb24KKyAgICAgICAgICogYnV0IGJpZ2dlciBsZW5ndGhzIGNhbiBiZSBjb25maWd1cmVkLgorICAgICAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiA8Y29kZT53aW5kb3dTaXplPC9jb2RlPgorICAgICAgICAgKiBpcyBzbWFsbGVyIHRoYW4gPGNvZGU+bWluQmFja1JlZmVyZW5jZUxlbmd0aDwvY29kZT4uCisgICAgICAgICAqIEByZXR1cm4gdGhlIGJ1aWxkZXIKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBCdWlsZGVyIHdpdGhNaW5CYWNrUmVmZXJlbmNlTGVuZ3RoKGludCBtaW5CYWNrUmVmZXJlbmNlTGVuZ3RoKSB7CisgICAgICAgICAgICB0aGlzLm1pbkJhY2tSZWZlcmVuY2VMZW5ndGggPSBNYXRoLm1heChUUlVFX01JTl9CQUNLX1JFRkVSRU5DRV9MRU5HVEgsIG1pbkJhY2tSZWZlcmVuY2VMZW5ndGgpOworICAgICAgICAgICAgaWYgKHdpbmRvd1NpemUgPCB0aGlzLm1pbkJhY2tSZWZlcmVuY2VMZW5ndGgpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJtaW5CYWNrUmVmZXJlbmNlTGVuZ3RoIGNhbid0IGJlIGJpZ2dlciB0aGFuIHdpbmRvd1NpemUiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChtYXhCYWNrUmVmZXJlbmNlTGVuZ3RoIDwgdGhpcy5taW5CYWNrUmVmZXJlbmNlTGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgbWF4QmFja1JlZmVyZW5jZUxlbmd0aCA9IHRoaXMubWluQmFja1JlZmVyZW5jZUxlbmd0aDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiB0aGlzOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFNldHMgdGhlIG1heGltYWwgbGVuZ3RoIG9mIGEgYmFjay1yZWZlcmVuY2UuCisgICAgICAgICAqCisgICAgICAgICAqIDxwPkl0IGlzIHJlY29tbWVuZGVkIHRvIG5vdCB1c2UgdGhpcyBtZXRob2QgZGlyZWN0bHkgYnV0CisgICAgICAgICAqIHJhdGhlciB0dW5lIGEgcHJlLWNvbmZpZ3VyZWQgYnVpbGRlciBjcmVhdGVkIGJ5IGEgZm9ybWF0CisgICAgICAgICAqIHNwZWNpZmljIGZhY3RvcnkgbGlrZSB7QGxpbmsKKyAgICAgICAgICogb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLnNuYXBweS5TbmFwcHlDb21wcmVzc29yT3V0cHV0U3RyZWFtI2NyZWF0ZVBhcmFtZXRlckJ1aWxkZXJ9LjwvcD4KKyAgICAgICAgICoKKyAgICAgICAgICogQHBhcmFtIG1heEJhY2tSZWZlcmVuY2VMZW5ndGggbWF4aW1hbCBsZW5ndGggb2YgYQorICAgICAgICAgKiBiYWNrLXJlZmVyZW5jZSBmb3VuZC4gQSB2YWx1ZSBzbWFsbGVyIHRoYW4KKyAgICAgICAgICogPGNvZGU+bWluQmFja1JlZmVyZW5jZUxlbmd0aDwvY29kZT4gaXMgaW50ZXJwcmV0ZWQgYXMKKyAgICAgICAgICogPGNvZGU+bWluQmFja1JlZmVyZW5jZUxlbmd0aDwvY29kZT4uIDxjb2RlPm1heEJhY2tSZWZlcmVuY2VMZW5ndGg8L2NvZGU+CisgICAgICAgICAqIGlzIGNhcHBlZCBhdCA8Y29kZT53aW5kb3dTaXplIC0gMTwvY29kZT4uCisgICAgICAgICAqIEByZXR1cm4gdGhlIGJ1aWxkZXIKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBCdWlsZGVyIHdpdGhNYXhCYWNrUmVmZXJlbmNlTGVuZ3RoKGludCBtYXhCYWNrUmVmZXJlbmNlTGVuZ3RoKSB7CisgICAgICAgICAgICB0aGlzLm1heEJhY2tSZWZlcmVuY2VMZW5ndGggPSBtYXhCYWNrUmVmZXJlbmNlTGVuZ3RoIDwgbWluQmFja1JlZmVyZW5jZUxlbmd0aCA/IG1pbkJhY2tSZWZlcmVuY2VMZW5ndGgKKyAgICAgICAgICAgICAgICA6IE1hdGgubWluKG1heEJhY2tSZWZlcmVuY2VMZW5ndGgsIHdpbmRvd1NpemUgLSAxKTsKKyAgICAgICAgICAgIHJldHVybiB0aGlzOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFNldHMgdGhlIG1heGltYWwgb2Zmc2V0IG9mIGEgYmFjay1yZWZlcmVuY2UuCisgICAgICAgICAqCisgICAgICAgICAqIDxwPkl0IGlzIHJlY29tbWVuZGVkIHRvIG5vdCB1c2UgdGhpcyBtZXRob2QgZGlyZWN0bHkgYnV0CisgICAgICAgICAqIHJhdGhlciB0dW5lIGEgcHJlLWNvbmZpZ3VyZWQgYnVpbGRlciBjcmVhdGVkIGJ5IGEgZm9ybWF0CisgICAgICAgICAqIHNwZWNpZmljIGZhY3RvcnkgbGlrZSB7QGxpbmsKKyAgICAgICAgICogb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLnNuYXBweS5TbmFwcHlDb21wcmVzc29yT3V0cHV0U3RyZWFtI2NyZWF0ZVBhcmFtZXRlckJ1aWxkZXJ9LjwvcD4KKyAgICAgICAgICoKKyAgICAgICAgICogQHBhcmFtIG1heE9mZnNldCBtYXhpbWFsIG9mZnNldCBvZiBhIGJhY2stcmVmZXJlbmNlLiBBCisgICAgICAgICAqIG5vbi1wb3NpdGl2ZSB2YWx1ZSBhcyB3ZWxsIGFzIHZhbHVlcyBiaWdnZXIgdGhhbgorICAgICAgICAgKiA8Y29kZT53aW5kb3dTaXplIC0gMTwvY29kZT4gYXJlIGludGVycHJldGVkIGFzIDxjb2RlPndpbmRvd1NpemUKKyAgICAgICAgICogLSAxPC9jb2RlPi4KKyAgICAgICAgICogQHJldHVybiB0aGUgYnVpbGRlcgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIEJ1aWxkZXIgd2l0aE1heE9mZnNldChpbnQgbWF4T2Zmc2V0KSB7CisgICAgICAgICAgICB0aGlzLm1heE9mZnNldCA9IG1heE9mZnNldCA8IDEgPyB3aW5kb3dTaXplIC0gMSA6IE1hdGgubWluKG1heE9mZnNldCwgd2luZG93U2l6ZSAtIDEpOworICAgICAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogU2V0cyB0aGUgbWF4aW1hbCBsZW5ndGggb2YgYSBsaXRlcmFsIGJsb2NrLgorICAgICAgICAgKgorICAgICAgICAgKiA8cD5JdCBpcyByZWNvbW1lbmRlZCB0byBub3QgdXNlIHRoaXMgbWV0aG9kIGRpcmVjdGx5IGJ1dAorICAgICAgICAgKiByYXRoZXIgdHVuZSBhIHByZS1jb25maWd1cmVkIGJ1aWxkZXIgY3JlYXRlZCBieSBhIGZvcm1hdAorICAgICAgICAgKiBzcGVjaWZpYyBmYWN0b3J5IGxpa2Uge0BsaW5rCisgICAgICAgICAqIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5zbmFwcHkuU25hcHB5Q29tcHJlc3Nvck91dHB1dFN0cmVhbSNjcmVhdGVQYXJhbWV0ZXJCdWlsZGVyfS48L3A+CisgICAgICAgICAqCisgICAgICAgICAqIEBwYXJhbSBtYXhMaXRlcmFsTGVuZ3RoIG1heGltYWwgbGVuZ3RoIG9mIGEgbGl0ZXJhbAorICAgICAgICAgKiBibG9jay4gTmVnYXRpdmUgbnVtYmVycyBhbmQgMCBhcyB3ZWxsIGFzIHZhbHVlcyBiaWdnZXIgdGhhbgorICAgICAgICAgKiA8Y29kZT53aW5kb3dTaXplPC9jb2RlPiBhcmUgaW50ZXJwcmV0ZWQgYXMKKyAgICAgICAgICogPGNvZGU+d2luZG93U2l6ZTwvY29kZT4uCisgICAgICAgICAqIEByZXR1cm4gdGhlIGJ1aWxkZXIKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBCdWlsZGVyIHdpdGhNYXhMaXRlcmFsTGVuZ3RoKGludCBtYXhMaXRlcmFsTGVuZ3RoKSB7CisgICAgICAgICAgICB0aGlzLm1heExpdGVyYWxMZW5ndGggPSBtYXhMaXRlcmFsTGVuZ3RoIDwgMSA/IHdpbmRvd1NpemUKKyAgICAgICAgICAgICAgICA6IE1hdGgubWluKG1heExpdGVyYWxMZW5ndGgsIHdpbmRvd1NpemUpOworICAgICAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogU2V0cyB0aGUgIm5pY2UgbGVuZ3RoIiBvZiBhIGJhY2stcmVmZXJlbmNlLgorICAgICAgICAgKgorICAgICAgICAgKiA8cD5XaGVuIGEgYmFjay1yZWZlcmVuY2VzIGlmIHRoaXMgc2l6ZSBoYXMgYmVlbiBmb3VuZCwgc3RvcCBzZWFyY2hpbmcgZm9yIGxvbmdlciBiYWNrLXJlZmVyZW5jZXMuPC9wPgorICAgICAgICAgKgorICAgICAgICAgKiA8cD5UaGlzIHNldHRpbmdzIGNhbiBiZSB1c2VkIHRvIHR1bmUgdGhlIHRyYWRlb2ZmIGJldHdlZW4gY29tcHJlc3Npb24gc3BlZWQgYW5kIGNvbXByZXNzaW9uIHJhdGlvLjwvcD4KKyAgICAgICAgICogQHBhcmFtIG5pY2VMZW4gdGhlICJuaWNlIGxlbmd0aCIgb2YgYSBiYWNrLXJlZmVyZW5jZQorICAgICAgICAgKiBAcmV0dXJuIHRoZSBidWlsZGVyCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgQnVpbGRlciB3aXRoTmljZUJhY2tSZWZlcmVuY2VMZW5ndGgoaW50IG5pY2VMZW4pIHsKKyAgICAgICAgICAgIG5pY2VCYWNrUmVmZXJlbmNlTGVuZ3RoID0gbmljZUxlbjsKKyAgICAgICAgICAgIHJldHVybiB0aGlzOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFNldHMgdGhlIG1heGltdW0gbnVtYmVyIG9mIGJhY2stcmVmZXJlbmNlIGNhbmRpZGF0ZXMgdGhhdCBzaG91bGQgYmUgY29uc3VsdGVkLgorICAgICAgICAgKgorICAgICAgICAgKiA8cD5UaGlzIHNldHRpbmdzIGNhbiBiZSB1c2VkIHRvIHR1bmUgdGhlIHRyYWRlb2ZmIGJldHdlZW4gY29tcHJlc3Npb24gc3BlZWQgYW5kIGNvbXByZXNzaW9uIHJhdGlvLjwvcD4KKyAgICAgICAgICogQHBhcmFtIG1heENhbmRpZGF0ZXMgbWF4aW11bSBudW1iZXIgb2YgYmFjay1yZWZlcmVuY2UgY2FuZGlkYXRlcworICAgICAgICAgKiBAcmV0dXJuIHRoZSBidWlsZGVyCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgQnVpbGRlciB3aXRoTWF4TnVtYmVyT2ZDYW5kaWRhdGVzKGludCBtYXhDYW5kaWRhdGVzKSB7CisgICAgICAgICAgICB0aGlzLm1heENhbmRpZGF0ZXMgPSBtYXhDYW5kaWRhdGVzOworICAgICAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogU2V0cyB3aGV0aGVyIGxhenkgbWF0Y2hpbmcgc2hvdWxkIGJlIHBlcmZvcm1lZC4KKyAgICAgICAgICoKKyAgICAgICAgICogPHA+TGF6eSBtYXRjaGluZyBtZWFucyB0aGF0IGFmdGVyIGEgYmFjay1yZWZlcmVuY2UgZm9yIGEgY2VydGFpbiBwb3NpdGlvbiBoYXMgYmVlbiBmb3VuZCB0aGUgY29tcHJlc3NvciB3aWxsCisgICAgICAgICAqIHRyeSB0byBmaW5kIGEgbG9uZ2VyIG1hdGNoIGZvciB0aGUgbmV4dCBwb3NpdGlvbi48L3A+CisgICAgICAgICAqCisgICAgICAgICAqIDxwPkxhenkgbWF0Y2hpbmcgaXMgZW5hYmxlZCBieSBkZWZhdWx0IGFuZCBkaXNhYmxlZCB3aGVuIHR1bmluZyBmb3Igc3BlZWQuPC9wPgorICAgICAgICAgKiBAcGFyYW0gbGF6eSB3aGV0aGVyIGxhenkgbWF0Y2hpbmcgc2hvdWxkIGJlIHBlcmZvcm1lZAorICAgICAgICAgKiBAcmV0dXJuIHRoZSBidWlsZGVyCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgQnVpbGRlciB3aXRoTGF6eU1hdGNoaW5nKGJvb2xlYW4gbGF6eSkgeworICAgICAgICAgICAgbGF6eU1hdGNoZXMgPSBsYXp5OworICAgICAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogU2V0cyB0aGUgdGhyZXNob2xkIGZvciBsYXp5IG1hdGNoaW5nLgorICAgICAgICAgKgorICAgICAgICAgKiA8cD5FdmVuIGlmIGxhenkgbWF0Y2hpbmcgaXMgZW5hYmxlZCBpdCB3aWxsIG5vdCBiZSBwZXJmb3JtZWQgaWYgdGhlIGxlbmd0aCBvZiB0aGUgYmFjay1yZWZlcmVuY2UgZm91bmQgZm9yCisgICAgICAgICAqIHRoZSBjdXJyZW50IHBvc2l0aW9uIGlzIGxvbmdlciB0aGFuIHRoaXMgdmFsdWUuPC9wPgorICAgICAgICAgKiBAcGFyYW0gdGhyZXNob2xkIHRoZSB0aHJlc2hvbGQgZm9yIGxhenkgbWF0Y2hpbmcKKyAgICAgICAgICogQHJldHVybiB0aGUgYnVpbGRlcgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIEJ1aWxkZXIgd2l0aExhenlUaHJlc2hvbGQoaW50IHRocmVzaG9sZCkgeworICAgICAgICAgICAgbGF6eVRocmVzaG9sZCA9IHRocmVzaG9sZDsKKyAgICAgICAgICAgIHJldHVybiB0aGlzOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIENoYW5nZXMgdGhlIGRlZmF1bHQgc2V0dGluZyBmb3IgIm5pY2UgYmFjay1yZWZlcmVuY2UgbGVuZ3RoIiBhbmQgIm1heGltdW0gbnVtYmVyIG9mIGNhbmRpZGF0ZXMiIGZvciBpbXByb3ZlZAorICAgICAgICAgKiBjb21wcmVzc2lvbiBzcGVlZCBhdCB0aGUgY29zdCBvZiBjb21wcmVzc2lvbiByYXRpby4KKyAgICAgICAgICoKKyAgICAgICAgICogPHA+VXNlIHRoaXMgbWV0aG9kIGFmdGVyIGNvbmZpZ3VyaW5nICJtYXhpbXVtIGJhY2stcmVmZXJlbmNlIGxlbmd0aCIuPC9wPgorICAgICAgICAgKiBAcmV0dXJuIHRoZSBidWlsZGVyCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgQnVpbGRlciB0dW5lZEZvclNwZWVkKCkgeworICAgICAgICAgICAgbmljZUJhY2tSZWZlcmVuY2VMZW5ndGggPSBNYXRoLm1heChtaW5CYWNrUmVmZXJlbmNlTGVuZ3RoLCBtYXhCYWNrUmVmZXJlbmNlTGVuZ3RoIC8gOCk7CisgICAgICAgICAgICBtYXhDYW5kaWRhdGVzID0gTWF0aC5tYXgoMzIsIHdpbmRvd1NpemUgLyAxMDI0KTsKKyAgICAgICAgICAgIGxhenlNYXRjaGVzID0gZmFsc2U7CisgICAgICAgICAgICBsYXp5VGhyZXNob2xkID0gbWluQmFja1JlZmVyZW5jZUxlbmd0aDsKKyAgICAgICAgICAgIHJldHVybiB0aGlzOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIENoYW5nZXMgdGhlIGRlZmF1bHQgc2V0dGluZyBmb3IgIm5pY2UgYmFjay1yZWZlcmVuY2UgbGVuZ3RoIiBhbmQgIm1heGltdW0gbnVtYmVyIG9mIGNhbmRpZGF0ZXMiIGZvciBpbXByb3ZlZAorICAgICAgICAgKiBjb21wcmVzc2lvbiByYXRpbyBhdCB0aGUgY29zdCBvZiBjb21wcmVzc2lvbiBzcGVlZC4KKyAgICAgICAgICoKKyAgICAgICAgICogPHA+VXNlIHRoaXMgbWV0aG9kIGFmdGVyIGNvbmZpZ3VyaW5nICJtYXhpbXVtIGJhY2stcmVmZXJlbmNlIGxlbmd0aCIuPC9wPgorICAgICAgICAgKiBAcmV0dXJuIHRoZSBidWlsZGVyCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgQnVpbGRlciB0dW5lZEZvckNvbXByZXNzaW9uUmF0aW8oKSB7CisgICAgICAgICAgICBuaWNlQmFja1JlZmVyZW5jZUxlbmd0aCA9IGxhenlUaHJlc2hvbGQgPSBtYXhCYWNrUmVmZXJlbmNlTGVuZ3RoOworICAgICAgICAgICAgbWF4Q2FuZGlkYXRlcyA9IE1hdGgubWF4KDMyLCB3aW5kb3dTaXplIC8gMTYpOworICAgICAgICAgICAgbGF6eU1hdGNoZXMgPSB0cnVlOworICAgICAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogQ3JlYXRlcyB0aGUge0BsaW5rIFBhcmFtZXRlcnN9IGluc3RhbmNlLgorICAgICAgICAgKiBAcmV0dXJuIHRoZSBjb25maWd1cmVkIHtAbGluayBQYXJhbWV0ZXJzfSBpbnN0YW5jZS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBQYXJhbWV0ZXJzIGJ1aWxkKCkgeworICAgICAgICAgICAgLy8gZGVmYXVsdCBzZXR0aW5ncyB0dW5lZCBmb3IgYSBjb21wcm9taXNlIG9mIGdvb2QgY29tcHJlc3Npb24gYW5kIGFjY2VwdGFibGUgc3BlZWQKKyAgICAgICAgICAgIGludCBuaWNlTGVuID0gbmljZUJhY2tSZWZlcmVuY2VMZW5ndGggIT0gbnVsbCA/IG5pY2VCYWNrUmVmZXJlbmNlTGVuZ3RoCisgICAgICAgICAgICAgICAgOiBNYXRoLm1heChtaW5CYWNrUmVmZXJlbmNlTGVuZ3RoLCBtYXhCYWNrUmVmZXJlbmNlTGVuZ3RoIC8gMik7CisgICAgICAgICAgICBpbnQgY2FuZGlkYXRlcyA9IG1heENhbmRpZGF0ZXMgIT0gbnVsbCA/IG1heENhbmRpZGF0ZXMgOiBNYXRoLm1heCgyNTYsIHdpbmRvd1NpemUgLyAxMjgpOworICAgICAgICAgICAgYm9vbGVhbiBsYXp5ID0gbGF6eU1hdGNoZXMgPT0gbnVsbCB8fCBsYXp5TWF0Y2hlczsKKyAgICAgICAgICAgIGludCB0aHJlc2hvbGQgPSBsYXp5ID8gKGxhenlUaHJlc2hvbGQgIT0gbnVsbCA/IGxhenlUaHJlc2hvbGQgOiBuaWNlTGVuKSA6IG1pbkJhY2tSZWZlcmVuY2VMZW5ndGg7CisKKyAgICAgICAgICAgIHJldHVybiBuZXcgUGFyYW1ldGVycyh3aW5kb3dTaXplLCBtaW5CYWNrUmVmZXJlbmNlTGVuZ3RoLCBtYXhCYWNrUmVmZXJlbmNlTGVuZ3RoLAorICAgICAgICAgICAgICAgIG1heE9mZnNldCwgbWF4TGl0ZXJhbExlbmd0aCwgbmljZUxlbiwgY2FuZGlkYXRlcywgbGF6eSwgdGhyZXNob2xkKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgZmluYWwgaW50IHdpbmRvd1NpemUsIG1pbkJhY2tSZWZlcmVuY2VMZW5ndGgsIG1heEJhY2tSZWZlcmVuY2VMZW5ndGgsIG1heE9mZnNldCwgbWF4TGl0ZXJhbExlbmd0aCwKKyAgICAgICAgbmljZUJhY2tSZWZlcmVuY2VMZW5ndGgsIG1heENhbmRpZGF0ZXMsIGxhenlUaHJlc2hvbGQ7CisgICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIGxhenlNYXRjaGluZzsKKworICAgIHByaXZhdGUgUGFyYW1ldGVycyhpbnQgd2luZG93U2l6ZSwgaW50IG1pbkJhY2tSZWZlcmVuY2VMZW5ndGgsIGludCBtYXhCYWNrUmVmZXJlbmNlTGVuZ3RoLCBpbnQgbWF4T2Zmc2V0LAorICAgICAgICAgICAgaW50IG1heExpdGVyYWxMZW5ndGgsIGludCBuaWNlQmFja1JlZmVyZW5jZUxlbmd0aCwgaW50IG1heENhbmRpZGF0ZXMsIGJvb2xlYW4gbGF6eU1hdGNoaW5nLAorICAgICAgICAgICAgaW50IGxhenlUaHJlc2hvbGQpIHsKKyAgICAgICAgdGhpcy53aW5kb3dTaXplID0gd2luZG93U2l6ZTsKKyAgICAgICAgdGhpcy5taW5CYWNrUmVmZXJlbmNlTGVuZ3RoID0gbWluQmFja1JlZmVyZW5jZUxlbmd0aDsKKyAgICAgICAgdGhpcy5tYXhCYWNrUmVmZXJlbmNlTGVuZ3RoID0gbWF4QmFja1JlZmVyZW5jZUxlbmd0aDsKKyAgICAgICAgdGhpcy5tYXhPZmZzZXQgPSBtYXhPZmZzZXQ7CisgICAgICAgIHRoaXMubWF4TGl0ZXJhbExlbmd0aCA9IG1heExpdGVyYWxMZW5ndGg7CisgICAgICAgIHRoaXMubmljZUJhY2tSZWZlcmVuY2VMZW5ndGggPSBuaWNlQmFja1JlZmVyZW5jZUxlbmd0aDsKKyAgICAgICAgdGhpcy5tYXhDYW5kaWRhdGVzID0gbWF4Q2FuZGlkYXRlczsKKyAgICAgICAgdGhpcy5sYXp5TWF0Y2hpbmcgPSBsYXp5TWF0Y2hpbmc7CisgICAgICAgIHRoaXMubGF6eVRocmVzaG9sZCA9IGxhenlUaHJlc2hvbGQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc2l6ZSBvZiB0aGUgc2xpZGluZyB3aW5kb3cgLSB0aGlzIGRldGVybWluZXMgdGhlCisgICAgICogbWF4aW11bSBvZmZzZXQgYSBiYWNrLXJlZmVyZW5jZSBjYW4gdGFrZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBzaXplIG9mIHRoZSBzbGlkaW5nIHdpbmRvdworICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0V2luZG93U2l6ZSgpIHsKKyAgICAgICAgcmV0dXJuIHdpbmRvd1NpemU7CisgICAgfQorICAgIC8qKgorICAgICAqIEdldHMgdGhlIG1pbmltYWwgbGVuZ3RoIG9mIGEgYmFjay1yZWZlcmVuY2UgZm91bmQuCisgICAgICogQHJldHVybiB0aGUgbWluaW1hbCBsZW5ndGggb2YgYSBiYWNrLXJlZmVyZW5jZSBmb3VuZAorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TWluQmFja1JlZmVyZW5jZUxlbmd0aCgpIHsKKyAgICAgICAgcmV0dXJuIG1pbkJhY2tSZWZlcmVuY2VMZW5ndGg7CisgICAgfQorICAgIC8qKgorICAgICAqIEdldHMgdGhlIG1heGltYWwgbGVuZ3RoIG9mIGEgYmFjay1yZWZlcmVuY2UgZm91bmQuCisgICAgICogQHJldHVybiB0aGUgbWF4aW1hbCBsZW5ndGggb2YgYSBiYWNrLXJlZmVyZW5jZSBmb3VuZAorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TWF4QmFja1JlZmVyZW5jZUxlbmd0aCgpIHsKKyAgICAgICAgcmV0dXJuIG1heEJhY2tSZWZlcmVuY2VMZW5ndGg7CisgICAgfQorICAgIC8qKgorICAgICAqIEdldHMgdGhlIG1heGltYWwgb2Zmc2V0IG9mIGEgYmFjay1yZWZlcmVuY2UgZm91bmQuCisgICAgICogQHJldHVybiB0aGUgbWF4aW1hbCBvZmZzZXQgb2YgYSBiYWNrLXJlZmVyZW5jZSBmb3VuZAorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TWF4T2Zmc2V0KCkgeworICAgICAgICByZXR1cm4gbWF4T2Zmc2V0OworICAgIH0KKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBtYXhpbWFsIGxlbmd0aCBvZiBhIGxpdGVyYWwgYmxvY2suCisgICAgICogQHJldHVybiB0aGUgbWF4aW1hbCBsZW5ndGggb2YgYSBsaXRlcmFsIGJsb2NrCisgICAgICovCisgICAgcHVibGljIGludCBnZXRNYXhMaXRlcmFsTGVuZ3RoKCkgeworICAgICAgICByZXR1cm4gbWF4TGl0ZXJhbExlbmd0aDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBsZW5ndGggb2YgYSBiYWNrLXJlZmVyZW5jZSB0aGF0IGlzIGNvbnNpZGVyZWQgbmljZSBlbm91Z2ggdG8gc3RvcCBzZWFyY2hpbmcgZm9yIGxvbmdlciBvbmVzLgorICAgICAqIEByZXR1cm4gdGhlIGxlbmd0aCBvZiBhIGJhY2stcmVmZXJlbmNlIHRoYXQgaXMgY29uc2lkZXJlZCBuaWNlIGVub3VnaCB0byBzdG9wIHNlYXJjaGluZworICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TmljZUJhY2tSZWZlcmVuY2VMZW5ndGgoKSB7CisgICAgICAgIHJldHVybiBuaWNlQmFja1JlZmVyZW5jZUxlbmd0aDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBtYXhpbXVtIG51bWJlciBvZiBiYWNrLXJlZmVyZW5jZSBjYW5kaWRhdGVzIHRvIGNvbnNpZGVyLgorICAgICAqIEByZXR1cm4gdGhlIG1heGltdW0gbnVtYmVyIG9mIGJhY2stcmVmZXJlbmNlIGNhbmRpZGF0ZXMgdG8gY29uc2lkZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldE1heENhbmRpZGF0ZXMoKSB7CisgICAgICAgIHJldHVybiBtYXhDYW5kaWRhdGVzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgd2hldGhlciB0byBwZXJmb3JtIGxhenkgbWF0Y2hpbmcuCisgICAgICogQHJldHVybiB3aGV0aGVyIHRvIHBlcmZvcm0gbGF6eSBtYXRjaGluZworICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGdldExhenlNYXRjaGluZygpIHsKKyAgICAgICAgcmV0dXJuIGxhenlNYXRjaGluZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB0aHJlc2hvbGQgZm9yIGxhenkgbWF0Y2hpbmcuCisgICAgICogQHJldHVybiB0aGUgdGhyZXNob2xkIGZvciBsYXp5IG1hdGNoaW5nCisgICAgICovCisgICAgcHVibGljIGludCBnZXRMYXp5TWF0Y2hpbmdUaHJlc2hvbGQoKSB7CisgICAgICAgIHJldHVybiBsYXp5VGhyZXNob2xkOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gaXNQb3dlck9mVHdvKGludCB4KSB7CisgICAgICAgIC8vIHByZS1jb25kaXRpb246IHggPiAwCisgICAgICAgIHJldHVybiAoeCAmICh4IC0gMSkpID09IDA7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvbHo3N3N1cHBvcnQvcGFja2FnZS5odG1sIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvbHo3N3N1cHBvcnQvcGFja2FnZS5odG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk1MWIxNDYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9sejc3c3VwcG9ydC9wYWNrYWdlLmh0bWwKQEAgLTAsMCArMSwyOCBAQAorPGh0bWw+Cis8IS0tCisKKyAgIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAgIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisKKyAgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKworICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAgIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisKKy0tPgorICA8Ym9keT4KKyAgICA8cD5Qcm92aWRlcyB1dGlsaXR5IGNsYXNzZXMgZm9yIExaNzcgYmFzZWQgYWxnb3JpdGhtcy48L3A+CisKKyAgICA8cD5UaGUgY2xhc3NlcyBpbiB0aGlzIHBhY2thZ2UgYXJlIGN1cnJlbnRseSB1c2VkIGJ5IHRoZSBMWjQgYW5kCisgICAgICBTbmFwcHkgaW1wbGVtZW50YXRpb25zIGJ1dCBtaWdodCBhbHNvIGhlbHAgaW1wbGVtZW50aW5nIG90aGVyCisgICAgICBhbGdvcml0aG1zIHRoYXQgZGVyaXZlIGZyb20gTFo3NyBhbmQgTFpTUy48L3A+CisKKyAgPC9ib2R5PgorPC9odG1sPgpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvbHptYS9MWk1BQ29tcHJlc3NvcklucHV0U3RyZWFtLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9sem1hL0xaTUFDb21wcmVzc29ySW5wdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43OTRlM2E1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvbHptYS9MWk1BQ29tcHJlc3NvcklucHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwxNDQgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMubHptYTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5NZW1vcnlMaW1pdEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcudHVrYWFuaS54ei5MWk1BSW5wdXRTdHJlYW07CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuQ29tcHJlc3NvcklucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5Db3VudGluZ0lucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5JT1V0aWxzOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5JbnB1dFN0cmVhbVN0YXRpc3RpY3M7CisKKy8qKgorICogTFpNQSBkZWNvbXByZXNzb3IuCisgKiBAc2luY2UgMS42CisgKi8KK3B1YmxpYyBjbGFzcyBMWk1BQ29tcHJlc3NvcklucHV0U3RyZWFtIGV4dGVuZHMgQ29tcHJlc3NvcklucHV0U3RyZWFtCisgICAgaW1wbGVtZW50cyBJbnB1dFN0cmVhbVN0YXRpc3RpY3MgeworCisgICAgcHJpdmF0ZSBmaW5hbCBDb3VudGluZ0lucHV0U3RyZWFtIGNvdW50aW5nU3RyZWFtOworICAgIHByaXZhdGUgZmluYWwgSW5wdXRTdHJlYW0gaW47CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IGlucHV0IHN0cmVhbSB0aGF0IGRlY29tcHJlc3NlcyBMWk1BLWNvbXByZXNzZWQgZGF0YQorICAgICAqIGZyb20gdGhlIHNwZWNpZmllZCBpbnB1dCBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gICAgICAgaW5wdXRTdHJlYW0gd2hlcmUgdG8gcmVhZCB0aGUgY29tcHJlc3NlZCBkYXRhCisgICAgICoKKyAgICAgKiBAdGhyb3dzICAgICAgSU9FeGNlcHRpb24gaWYgdGhlIGlucHV0IGlzIG5vdCBpbiB0aGUgLmx6bWEgZm9ybWF0LAorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICB0aGUgaW5wdXQgaXMgY29ycnVwdCBvciB0cnVuY2F0ZWQsIHRoZSAubHptYQorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICBoZWFkZXJzIHNwZWNpZnkgc2l6ZXMgdGhhdCBhcmUgbm90IHN1cHBvcnRlZAorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICBieSB0aGlzIGltcGxlbWVudGF0aW9uLCBvciB0aGUgdW5kZXJseWluZworICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICA8Y29kZT5pbnB1dFN0cmVhbTwvY29kZT4gdGhyb3dzIGFuIGV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBMWk1BQ29tcHJlc3NvcklucHV0U3RyZWFtKGZpbmFsIElucHV0U3RyZWFtIGlucHV0U3RyZWFtKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW4gPSBuZXcgTFpNQUlucHV0U3RyZWFtKGNvdW50aW5nU3RyZWFtID0gbmV3IENvdW50aW5nSW5wdXRTdHJlYW0oaW5wdXRTdHJlYW0pLCAtMSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBpbnB1dCBzdHJlYW0gdGhhdCBkZWNvbXByZXNzZXMgTFpNQS1jb21wcmVzc2VkIGRhdGEKKyAgICAgKiBmcm9tIHRoZSBzcGVjaWZpZWQgaW5wdXQgc3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtICAgICAgIGlucHV0U3RyZWFtIHdoZXJlIHRvIHJlYWQgdGhlIGNvbXByZXNzZWQgZGF0YQorICAgICAqCisgICAgICogQHBhcmFtICAgICAgIG1lbW9yeUxpbWl0SW5LYiBjYWxjdWxhdGVkIG1lbW9yeSB1c2UgdGhyZXNob2xkLiAgVGhyb3dzIE1lbW9yeUxpbWl0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgY2FsY3VsYXRlIG1lbW9yeSB1c2UgaXMgYWJvdmUgdGhpcyB0aHJlc2hvbGQKKyAgICAgKgorICAgICAqIEB0aHJvd3MgICAgICBJT0V4Y2VwdGlvbiBpZiB0aGUgaW5wdXQgaXMgbm90IGluIHRoZSAubHptYSBmb3JtYXQsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBpbnB1dCBpcyBjb3JydXB0IG9yIHRydW5jYXRlZCwgdGhlIC5sem1hCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIGhlYWRlcnMgc3BlY2lmeSBzaXplcyB0aGF0IGFyZSBub3Qgc3VwcG9ydGVkCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIGJ5IHRoaXMgaW1wbGVtZW50YXRpb24sIG9yIHRoZSB1bmRlcmx5aW5nCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIDxjb2RlPmlucHV0U3RyZWFtPC9jb2RlPiB0aHJvd3MgYW4gZXhjZXB0aW9uCisgICAgICoKKyAgICAgKiBAc2luY2UgMS4xNAorICAgICAqLworICAgIHB1YmxpYyBMWk1BQ29tcHJlc3NvcklucHV0U3RyZWFtKGZpbmFsIElucHV0U3RyZWFtIGlucHV0U3RyZWFtLCBpbnQgbWVtb3J5TGltaXRJbktiKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGluID0gbmV3IExaTUFJbnB1dFN0cmVhbShjb3VudGluZ1N0cmVhbSA9IG5ldyBDb3VudGluZ0lucHV0U3RyZWFtKGlucHV0U3RyZWFtKSwgbWVtb3J5TGltaXRJbktiKTsKKyAgICAgICAgfSBjYXRjaCAob3JnLnR1a2FhbmkueHouTWVtb3J5TGltaXRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9jb252ZXJ0IHRvIGNvbW1vbnMtY29tcHJlc3MgZXhjZXB0aW9uCisgICAgICAgICAgICB0aHJvdyBuZXcgTWVtb3J5TGltaXRFeGNlcHRpb24oZS5nZXRNZW1vcnlOZWVkZWQoKSwgZS5nZXRNZW1vcnlMaW1pdCgpLCBlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKiB7QGluaGVyaXREb2N9ICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCByZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgaW50IHJldCA9IGluLnJlYWQoKTsKKyAgICAgICAgY291bnQocmV0ID09IC0xID8gMCA6IDEpOworICAgICAgICByZXR1cm4gcmV0OworICAgIH0KKworICAgIC8qKiB7QGluaGVyaXREb2N9ICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCByZWFkKGZpbmFsIGJ5dGVbXSBidWYsIGZpbmFsIGludCBvZmYsIGZpbmFsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIGludCByZXQgPSBpbi5yZWFkKGJ1Ziwgb2ZmLCBsZW4pOworICAgICAgICBjb3VudChyZXQpOworICAgICAgICByZXR1cm4gcmV0OworICAgIH0KKworICAgIC8qKiB7QGluaGVyaXREb2N9ICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGxvbmcgc2tpcChmaW5hbCBsb25nIG4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBJT1V0aWxzLnNraXAoaW4sIG4pOworICAgIH0KKworICAgIC8qKiB7QGluaGVyaXREb2N9ICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBhdmFpbGFibGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gaW4uYXZhaWxhYmxlKCk7CisgICAgfQorCisgICAgLyoqIHtAaW5oZXJpdERvY30gKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGluLmNsb3NlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNpbmNlIDEuMTcKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgbG9uZyBnZXRDb21wcmVzc2VkQ291bnQoKSB7CisgICAgICAgIHJldHVybiBjb3VudGluZ1N0cmVhbS5nZXRCeXRlc1JlYWQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgaWYgdGhlIHNpZ25hdHVyZSBtYXRjaGVzIHdoYXQgaXMgZXhwZWN0ZWQgZm9yIGFuIGx6bWEgZmlsZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzaWduYXR1cmUKKyAgICAgKiAgICAgICAgICAgIHRoZSBieXRlcyB0byBjaGVjaworICAgICAqIEBwYXJhbSBsZW5ndGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gY2hlY2sKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoaXMgc3RyZWFtIGlzIGFuIGx6bWEgIGNvbXByZXNzZWQgc3RyZWFtLCBmYWxzZSBvdGhlcndpc2UKKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjEwCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIG1hdGNoZXMoZmluYWwgYnl0ZVtdIHNpZ25hdHVyZSwgZmluYWwgaW50IGxlbmd0aCkgeworICAgICAgICByZXR1cm4gc2lnbmF0dXJlICE9IG51bGwgJiYgbGVuZ3RoID49IDMgJiYKKyAgICAgICAgICAgICAgICBzaWduYXR1cmVbMF0gPT0gMHg1ZCAmJiBzaWduYXR1cmVbMV0gPT0gMCAmJgorICAgICAgICAgICAgICAgIHNpZ25hdHVyZVsyXSA9PSAwOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2x6bWEvTFpNQUNvbXByZXNzb3JPdXRwdXRTdHJlYW0uamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2x6bWEvTFpNQUNvbXByZXNzb3JPdXRwdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNmJkZmE0Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvbHptYS9MWk1BQ29tcHJlc3Nvck91dHB1dFN0cmVhbS5qYXZhCkBAIC0wLDAgKzEsNzkgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMubHptYTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgb3JnLnR1a2FhbmkueHouTFpNQTJPcHRpb25zOworaW1wb3J0IG9yZy50dWthYW5pLnh6LkxaTUFPdXRwdXRTdHJlYW07CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuQ29tcHJlc3Nvck91dHB1dFN0cmVhbTsKKworLyoqCisgKiBMWk1BIGNvbXByZXNzb3IuCisgKiBAc2luY2UgMS4xMworICovCitwdWJsaWMgY2xhc3MgTFpNQUNvbXByZXNzb3JPdXRwdXRTdHJlYW0gZXh0ZW5kcyBDb21wcmVzc29yT3V0cHV0U3RyZWFtIHsKKyAgICBwcml2YXRlIGZpbmFsIExaTUFPdXRwdXRTdHJlYW0gb3V0OworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIExaTUEgY29tcHJlc3Nvci4KKyAgICAgKgorICAgICAqIEBwYXJhbSAgICAgICBvdXRwdXRTdHJlYW0gdGhlIHN0cmVhbSB0byB3cmFwCisgICAgICogQHRocm93cyAgICAgIElPRXhjZXB0aW9uIG9uIGVycm9yCisgICAgICovCisgICAgcHVibGljIExaTUFDb21wcmVzc29yT3V0cHV0U3RyZWFtKGZpbmFsIE91dHB1dFN0cmVhbSBvdXRwdXRTdHJlYW0pCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvdXQgPSBuZXcgTFpNQU91dHB1dFN0cmVhbShvdXRwdXRTdHJlYW0sIG5ldyBMWk1BMk9wdGlvbnMoKSwgLTEpOworICAgIH0KKworICAgIC8qKiB7QGluaGVyaXREb2N9ICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGUoZmluYWwgaW50IGIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG91dC53cml0ZShiKTsKKyAgICB9CisKKyAgICAvKioge0Bpbmhlcml0RG9jfSAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGZpbmFsIGJ5dGVbXSBidWYsIGZpbmFsIGludCBvZmYsIGZpbmFsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG91dC53cml0ZShidWYsIG9mZiwgbGVuKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEb2Vzbid0IGRvIGFueXRoaW5nIGFzIHtAbGluayBMWk1BT3V0cHV0U3RyZWFtfSBkb2Vzbid0IHN1cHBvcnQgZmx1c2hpbmcuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZmx1c2goKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbmlzaGVzIGNvbXByZXNzaW9uIHdpdGhvdXQgY2xvc2luZyB0aGUgdW5kZXJseWluZyBzdHJlYW0uCisgICAgICogTm8gbW9yZSBkYXRhIGNhbiBiZSB3cml0dGVuIHRvIHRoaXMgc3RyZWFtIGFmdGVyIGZpbmlzaGluZy4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIG9uIGVycm9yCisgICAgICovCisgICAgcHVibGljIHZvaWQgZmluaXNoKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgb3V0LmZpbmlzaCgpOworICAgIH0KKworICAgIC8qKiB7QGluaGVyaXREb2N9ICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9sem1hL0xaTUFVdGlscy5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvbHptYS9MWk1BVXRpbHMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NzIyZTZkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvbHptYS9MWk1BVXRpbHMuamF2YQpAQCAtMCwwICsxLDE2MyBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5sem1hOworCitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuRmlsZU5hbWVVdGlsOworCisvKioKKyAqIFV0aWxpdHkgY29kZSBmb3IgdGhlIGx6bWEgY29tcHJlc3Npb24gZm9ybWF0LgorICogQFRocmVhZFNhZmUKKyAqIEBzaW5jZSAxLjEwCisgKi8KK3B1YmxpYyBjbGFzcyBMWk1BVXRpbHMgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRmlsZU5hbWVVdGlsIGZpbGVOYW1lVXRpbDsKKworICAgIC8qKgorICAgICAqIExaTUEgSGVhZGVyIE1hZ2ljIEJ5dGVzIGJlZ2luIGEgTFpNQSBmaWxlLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBIRUFERVJfTUFHSUMgPSB7CisgICAgICAgIChieXRlKSAweDVELCAwLCAwCisgICAgfTsKKworICAgIGVudW0gQ2FjaGVkQXZhaWxhYmlsaXR5IHsKKyAgICAgICAgRE9OVF9DQUNIRSwgQ0FDSEVEX0FWQUlMQUJMRSwgQ0FDSEVEX1VOQVZBSUxBQkxFCisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9sYXRpbGUgQ2FjaGVkQXZhaWxhYmlsaXR5IGNhY2hlZExaTUFBdmFpbGFiaWxpdHk7CisKKyAgICBzdGF0aWMgeworICAgICAgICBmaW5hbCBNYXA8U3RyaW5nLCBTdHJpbmc+IHVuY29tcHJlc3NTdWZmaXggPSBuZXcgSGFzaE1hcDw+KCk7CisgICAgICAgIHVuY29tcHJlc3NTdWZmaXgucHV0KCIubHptYSIsICIiKTsKKyAgICAgICAgdW5jb21wcmVzc1N1ZmZpeC5wdXQoIi1sem1hIiwgIiIpOworICAgICAgICBmaWxlTmFtZVV0aWwgPSBuZXcgRmlsZU5hbWVVdGlsKHVuY29tcHJlc3NTdWZmaXgsICIubHptYSIpOworICAgICAgICBjYWNoZWRMWk1BQXZhaWxhYmlsaXR5ID0gQ2FjaGVkQXZhaWxhYmlsaXR5LkRPTlRfQ0FDSEU7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDbGFzcy5mb3JOYW1lKCJvcmcub3NnaS5mcmFtZXdvcmsuQnVuZGxlRXZlbnQiKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzZXRDYWNoZUxaTUFBdmFpbGFibGl0eSh0cnVlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKiBQcml2YXRlIGNvbnN0cnVjdG9yIHRvIHByZXZlbnQgaW5zdGFudGlhdGlvbiBvZiB0aGlzIHV0aWxpdHkgY2xhc3MuICovCisgICAgcHJpdmF0ZSBMWk1BVXRpbHMoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIHRoZSBzaWduYXR1cmUgbWF0Y2hlcyB3aGF0IGlzIGV4cGVjdGVkIGZvciBhIC5sem1hIGZpbGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gICBzaWduYXR1cmUgICAgIHRoZSBieXRlcyB0byBjaGVjaworICAgICAqIEBwYXJhbSAgIGxlbmd0aCAgICAgICAgdGhlIG51bWJlciBvZiBieXRlcyB0byBjaGVjaworICAgICAqIEByZXR1cm4gIHRydWUgaWYgc2lnbmF0dXJlIG1hdGNoZXMgdGhlIC5sem1hIG1hZ2ljIGJ5dGVzLCBmYWxzZSBvdGhlcndpc2UKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gbWF0Y2hlcyhmaW5hbCBieXRlW10gc2lnbmF0dXJlLCBmaW5hbCBpbnQgbGVuZ3RoKSB7CisgICAgICAgIGlmIChsZW5ndGggPCBIRUFERVJfTUFHSUMubGVuZ3RoKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IEhFQURFUl9NQUdJQy5sZW5ndGg7ICsraSkgeworICAgICAgICAgICAgaWYgKHNpZ25hdHVyZVtpXSAhPSBIRUFERVJfTUFHSUNbaV0pIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBcmUgdGhlIGNsYXNzZXMgcmVxdWlyZWQgdG8gc3VwcG9ydCBMWk1BIGNvbXByZXNzaW9uIGF2YWlsYWJsZT8KKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGNsYXNzZXMgcmVxdWlyZWQgdG8gc3VwcG9ydCBMWk1BCisgICAgICogY29tcHJlc3Npb24gYXJlIGF2YWlsYWJsZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0xaTUFDb21wcmVzc2lvbkF2YWlsYWJsZSgpIHsKKyAgICAgICAgZmluYWwgQ2FjaGVkQXZhaWxhYmlsaXR5IGNhY2hlZFJlc3VsdCA9IGNhY2hlZExaTUFBdmFpbGFiaWxpdHk7CisgICAgICAgIGlmIChjYWNoZWRSZXN1bHQgIT0gQ2FjaGVkQXZhaWxhYmlsaXR5LkRPTlRfQ0FDSEUpIHsKKyAgICAgICAgICAgIHJldHVybiBjYWNoZWRSZXN1bHQgPT0gQ2FjaGVkQXZhaWxhYmlsaXR5LkNBQ0hFRF9BVkFJTEFCTEU7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGludGVybmFsSXNMWk1BQ29tcHJlc3Npb25BdmFpbGFibGUoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGludGVybmFsSXNMWk1BQ29tcHJlc3Npb25BdmFpbGFibGUoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBMWk1BQ29tcHJlc3NvcklucHV0U3RyZWFtLm1hdGNoZXMobnVsbCwgMCk7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgTm9DbGFzc0RlZkZvdW5kRXJyb3IgZXJyb3IpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIERldGVjdHMgY29tbW9uIGx6bWEgc3VmZml4ZXMgaW4gdGhlIGdpdmVuIGZpbGVuYW1lLgorICAgICAqCisgICAgICogQHBhcmFtIGZpbGVuYW1lIG5hbWUgb2YgYSBmaWxlCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIGZpbGVuYW1lIGhhcyBhIGNvbW1vbiBsem1hIHN1ZmZpeCwKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzQ29tcHJlc3NlZEZpbGVuYW1lKGZpbmFsIFN0cmluZyBmaWxlbmFtZSkgeworICAgICAgICByZXR1cm4gZmlsZU5hbWVVdGlsLmlzQ29tcHJlc3NlZEZpbGVuYW1lKGZpbGVuYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBNYXBzIHRoZSBnaXZlbiBuYW1lIG9mIGEgbHptYS1jb21wcmVzc2VkIGZpbGUgdG8gdGhlIG5hbWUgdGhhdAorICAgICAqIHRoZSBmaWxlIHNob3VsZCBoYXZlIGFmdGVyIHVuY29tcHJlc3Npb24uICBBbnkgZmlsZW5hbWVzIHdpdGgKKyAgICAgKiB0aGUgZ2VuZXJpYyAiLmx6bWEiIHN1ZmZpeCAob3IgYW55IG90aGVyIGdlbmVyaWMgbHptYSBzdWZmaXgpCisgICAgICogaXMgbWFwcGVkIHRvIGEgbmFtZSB3aXRob3V0IHRoYXQgc3VmZml4LiBJZiBubyBsem1hIHN1ZmZpeCBpcworICAgICAqIGRldGVjdGVkLCB0aGVuIHRoZSBmaWxlbmFtZSBpcyByZXR1cm5lZCB1bm1hcHBlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmaWxlbmFtZSBuYW1lIG9mIGEgZmlsZQorICAgICAqIEByZXR1cm4gbmFtZSBvZiB0aGUgY29ycmVzcG9uZGluZyB1bmNvbXByZXNzZWQgZmlsZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldFVuY29tcHJlc3NlZEZpbGVuYW1lKGZpbmFsIFN0cmluZyBmaWxlbmFtZSkgeworICAgICAgICByZXR1cm4gZmlsZU5hbWVVdGlsLmdldFVuY29tcHJlc3NlZEZpbGVuYW1lKGZpbGVuYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBNYXBzIHRoZSBnaXZlbiBmaWxlbmFtZSB0byB0aGUgbmFtZSB0aGF0IHRoZSBmaWxlIHNob3VsZCBoYXZlIGFmdGVyCisgICAgICogY29tcHJlc3Npb24gd2l0aCBsem1hLgorICAgICAqCisgICAgICogQHBhcmFtIGZpbGVuYW1lIG5hbWUgb2YgYSBmaWxlCisgICAgICogQHJldHVybiBuYW1lIG9mIHRoZSBjb3JyZXNwb25kaW5nIGNvbXByZXNzZWQgZmlsZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldENvbXByZXNzZWRGaWxlbmFtZShmaW5hbCBTdHJpbmcgZmlsZW5hbWUpIHsKKyAgICAgICAgcmV0dXJuIGZpbGVOYW1lVXRpbC5nZXRDb21wcmVzc2VkRmlsZW5hbWUoZmlsZW5hbWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdoZXRoZXIgdG8gY2FjaGUgdGhlIHJlc3VsdCBvZiB0aGUgTFpNQSBjaGVjay4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgZGVmYXVsdHMgdG8ge0Bjb2RlIGZhbHNlfSBpbiBhbiBPU0dpIGVudmlyb25tZW50IGFuZCB7QGNvZGUgdHJ1ZX0gb3RoZXJ3aXNlLjwvcD4KKyAgICAgKiBAcGFyYW0gZG9DYWNoZSB3aGV0aGVyIHRvIGNhY2hlIHRoZSByZXN1bHQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc2V0Q2FjaGVMWk1BQXZhaWxhYmxpdHkoZmluYWwgYm9vbGVhbiBkb0NhY2hlKSB7CisgICAgICAgIGlmICghZG9DYWNoZSkgeworICAgICAgICAgICAgY2FjaGVkTFpNQUF2YWlsYWJpbGl0eSA9IENhY2hlZEF2YWlsYWJpbGl0eS5ET05UX0NBQ0hFOworICAgICAgICB9IGVsc2UgaWYgKGNhY2hlZExaTUFBdmFpbGFiaWxpdHkgPT0gQ2FjaGVkQXZhaWxhYmlsaXR5LkRPTlRfQ0FDSEUpIHsKKyAgICAgICAgICAgIGZpbmFsIGJvb2xlYW4gaGFzTHptYSA9IGludGVybmFsSXNMWk1BQ29tcHJlc3Npb25BdmFpbGFibGUoKTsKKyAgICAgICAgICAgIGNhY2hlZExaTUFBdmFpbGFiaWxpdHkgPSBoYXNMem1hID8gQ2FjaGVkQXZhaWxhYmlsaXR5LkNBQ0hFRF9BVkFJTEFCTEUgLy8gTk9TT05BUgorICAgICAgICAgICAgICAgIDogQ2FjaGVkQXZhaWxhYmlsaXR5LkNBQ0hFRF9VTkFWQUlMQUJMRTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIG9ubHkgZXhpc3RzIHRvIHN1cHBvcnQgdW5pdCB0ZXN0cworICAgIHN0YXRpYyBDYWNoZWRBdmFpbGFiaWxpdHkgZ2V0Q2FjaGVkTFpNQUF2YWlsYWJpbGl0eSgpIHsKKyAgICAgICAgcmV0dXJuIGNhY2hlZExaTUFBdmFpbGFiaWxpdHk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvbHptYS9wYWNrYWdlLmh0bWwgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9sem1hL3BhY2thZ2UuaHRtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mM2I1NDczCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvbHptYS9wYWNrYWdlLmh0bWwKQEAgLTAsMCArMSwzMiBAQAorPGh0bWw+Cis8IS0tCisKKyAgIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAgIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisKKyAgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKworICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAgIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisKKy0tPgorICA8Ym9keT4KKyAgICA8cD5Qcm92aWRlcyBzdHJlYW0gY2xhc3NlcyB1c2luZyB0aGUgInN0YW5kLWFsb25lIiBMWk1BCisgICAgICBhbGdvcml0aG0uPC9wPgorCisgICAgPHA+VGhlIGNsYXNzZXMgaW4gdGhpcyBwYWNrYWdlIGFyZSB3cmFwcGVycyBhcm91bmQgc3RyZWFtIGNsYXNzZXMKKyAgICAgIHByb3ZpZGVkIGJ5IHRoZSBwdWJsaWMKKyAgICAgIGRvbWFpbiA8YSBocmVmPSJodHRwczovL3R1a2Fhbmkub3JnL3h6L2phdmEuaHRtbCI+WFogZm9yIEphdmE8L2E+CisgICAgICBsaWJyYXJ5LjwvcD4KKworICAgIDxwPkluIGdlbmVyYWwgeW91IHNob3VsZCBwcmVmZXIgdGhlIG1vcmUgbW9kZXJuIGFuZCByb2J1c3QgWFoKKyAgICAgIGZvcm1hdCBvdmVyIHN0YW5kLWFsb25lIExaTUEgY29tcHJlc3Npb24uPC9wPgorICA8L2JvZHk+Cis8L2h0bWw+CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9sencvTFpXSW5wdXRTdHJlYW0uamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2x6dy9MWldJbnB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE1ZTUxMmMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9sencvTFpXSW5wdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDI4MyBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5senc7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5uaW8uQnl0ZU9yZGVyOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLk1lbW9yeUxpbWl0RXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5Db21wcmVzc29ySW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLkJpdElucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5JbnB1dFN0cmVhbVN0YXRpc3RpY3M7CisKKy8qKgorICogPHA+R2VuZXJpYyBMWlcgaW1wbGVtZW50YXRpb24uIEl0IGlzIHVzZWQgaW50ZXJuYWxseSBmb3IKKyAqIHRoZSBaIGRlY29tcHJlc3NvciBhbmQgdGhlIFVuc2hyaW5raW5nIFppcCBmaWxlIGNvbXByZXNzaW9uIG1ldGhvZCwKKyAqIGJ1dCBtYXkgYmUgdXNlZnVsIGZvciB0aGlyZC1wYXJ0eSBwcm9qZWN0cyBpbiBpbXBsZW1lbnRpbmcgdGhlaXIgb3duIExaVyB2YXJpYXRpb25zLjwvcD4KKyAqCisgKiBATm90VGhyZWFkU2FmZQorICogQHNpbmNlIDEuMTAKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIExaV0lucHV0U3RyZWFtIGV4dGVuZHMgQ29tcHJlc3NvcklucHV0U3RyZWFtIGltcGxlbWVudHMgSW5wdXRTdHJlYW1TdGF0aXN0aWNzIHsKKyAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX0NPREVfU0laRSA9IDk7CisgICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgVU5VU0VEX1BSRUZJWCA9IC0xOworCisgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10gb25lQnl0ZSA9IG5ldyBieXRlWzFdOworCisgICAgcHJvdGVjdGVkIGZpbmFsIEJpdElucHV0U3RyZWFtIGluOworICAgIHByaXZhdGUgaW50IGNsZWFyQ29kZSA9IC0xOworICAgIHByaXZhdGUgaW50IGNvZGVTaXplID0gREVGQVVMVF9DT0RFX1NJWkU7CisgICAgcHJpdmF0ZSBieXRlIHByZXZpb3VzQ29kZUZpcnN0Q2hhcjsKKyAgICBwcml2YXRlIGludCBwcmV2aW91c0NvZGUgPSBVTlVTRURfUFJFRklYOworICAgIHByaXZhdGUgaW50IHRhYmxlU2l6ZTsKKyAgICBwcml2YXRlIGludFtdIHByZWZpeGVzOworICAgIHByaXZhdGUgYnl0ZVtdIGNoYXJhY3RlcnM7CisgICAgcHJpdmF0ZSBieXRlW10gb3V0cHV0U3RhY2s7CisgICAgcHJpdmF0ZSBpbnQgb3V0cHV0U3RhY2tMb2NhdGlvbjsKKworICAgIHByb3RlY3RlZCBMWldJbnB1dFN0cmVhbShmaW5hbCBJbnB1dFN0cmVhbSBpbnB1dFN0cmVhbSwgZmluYWwgQnl0ZU9yZGVyIGJ5dGVPcmRlcikgeworICAgICAgICB0aGlzLmluID0gbmV3IEJpdElucHV0U3RyZWFtKGlucHV0U3RyZWFtLCBieXRlT3JkZXIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW4uY2xvc2UoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHJlYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBpbnQgcmV0ID0gcmVhZChvbmVCeXRlKTsKKyAgICAgICAgaWYgKHJldCA8IDApIHsKKyAgICAgICAgICAgIHJldHVybiByZXQ7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIDB4ZmYgJiBvbmVCeXRlWzBdOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZChmaW5hbCBieXRlW10gYiwgZmluYWwgaW50IG9mZiwgZmluYWwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IGJ5dGVzUmVhZCA9IHJlYWRGcm9tU3RhY2soYiwgb2ZmLCBsZW4pOworICAgICAgICB3aGlsZSAobGVuIC0gYnl0ZXNSZWFkID4gMCkgeworICAgICAgICAgICAgZmluYWwgaW50IHJlc3VsdCA9IGRlY29tcHJlc3NOZXh0U3ltYm9sKCk7CisgICAgICAgICAgICBpZiAocmVzdWx0IDwgMCkgeworICAgICAgICAgICAgICAgIGlmIChieXRlc1JlYWQgPiAwKSB7CisgICAgICAgICAgICAgICAgICAgIGNvdW50KGJ5dGVzUmVhZCk7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBieXRlc1JlYWQ7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBieXRlc1JlYWQgKz0gcmVhZEZyb21TdGFjayhiLCBvZmYgKyBieXRlc1JlYWQsIGxlbiAtIGJ5dGVzUmVhZCk7CisgICAgICAgIH0KKyAgICAgICAgY291bnQoYnl0ZXNSZWFkKTsKKyAgICAgICAgcmV0dXJuIGJ5dGVzUmVhZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2luY2UgMS4xNworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBsb25nIGdldENvbXByZXNzZWRDb3VudCgpIHsKKyAgICAgICAgcmV0dXJuIGluLmdldEJ5dGVzUmVhZCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWQgdGhlIG5leHQgY29kZSBhbmQgZXhwYW5kIGl0LgorICAgICAqIEByZXR1cm4gdGhlIGV4cGFuZGVkIG5leHQgY29kZQorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gb24gZXJyb3IKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3QgaW50IGRlY29tcHJlc3NOZXh0U3ltYm9sKCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQWRkIGEgbmV3IGVudHJ5IHRvIHRoZSBkaWN0aW9uYXJ5LgorICAgICAqIEBwYXJhbSBwcmV2aW91c0NvZGUgdGhlIHByZXZpb3VzIGNvZGUKKyAgICAgKiBAcGFyYW0gY2hhcmFjdGVyIHRoZSBuZXh0IGNoYXJhY3RlciB0byBhcHBlbmQKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXcgY29kZQorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gb24gZXJyb3IKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3QgaW50IGFkZEVudHJ5KGludCBwcmV2aW91c0NvZGUsIGJ5dGUgY2hhcmFjdGVyKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBjbGVhciBjb2RlIGJhc2VkIG9uIHRoZSBjb2RlIHNpemUuCisgICAgICogQHBhcmFtIGNvZGVTaXplIGNvZGUgc2l6ZQorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHNldENsZWFyQ29kZShmaW5hbCBpbnQgY29kZVNpemUpIHsKKyAgICAgICAgY2xlYXJDb2RlID0gKDEgPDwgKGNvZGVTaXplIC0gMSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluaXRpYWxpemVzIHRoZSBhcnJheXMgYmFzZWQgb24gdGhlIG1heGltdW0gY29kZSBzaXplLgorICAgICAqIEZpcnN0IGNoZWNrcyB0aGF0IHRoZSBlc3RpbWF0ZWQgbWVtb3J5IHVzYWdlIGlzIGJlbG93IG1lbW9yeUxpbWl0SW5LYgorICAgICAqCisgICAgICogQHBhcmFtIG1heENvZGVTaXplIG1heGltdW0gY29kZSBzaXplCisgICAgICogQHBhcmFtIG1lbW9yeUxpbWl0SW5LYiBtYXhpbXVtIGFsbG93ZWQgZXN0aW1hdGVkIG1lbW9yeSB1c2FnZSBpbiBLYgorICAgICAqIEB0aHJvd3MgTWVtb3J5TGltaXRFeGNlcHRpb24gaWYgZXN0aW1hdGVkIG1lbW9yeSB1c2FnZSBpcyBncmVhdGVyIHRoYW4gbWVtb3J5TGltaXRJbktiCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgaW5pdGlhbGl6ZVRhYmxlcyhmaW5hbCBpbnQgbWF4Q29kZVNpemUsIGZpbmFsIGludCBtZW1vcnlMaW1pdEluS2IpCisgICAgICAgICAgICB0aHJvd3MgTWVtb3J5TGltaXRFeGNlcHRpb24geworCisgICAgICAgIGlmIChtZW1vcnlMaW1pdEluS2IgPiAtMSkgeworICAgICAgICAgICAgZmluYWwgaW50IG1heFRhYmxlU2l6ZSA9IDEgPDwgbWF4Q29kZVNpemU7CisgICAgICAgICAgICAvL2FjY291bnQgZm9yIHBvdGVudGlhbCBvdmVyZmxvdworICAgICAgICAgICAgbG9uZyBtZW1vcnlVc2FnZUluQnl0ZXMgPSAobG9uZykgbWF4VGFibGVTaXplICogNjsvLyg0IChwcmVmaXhlcykgKyAxIChjaGFyYWN0ZXJzKSArMSAob3V0cHV0U3RhY2spKQorICAgICAgICAgICAgbG9uZyBtZW1vcnlVc2FnZUluS2IgPSBtZW1vcnlVc2FnZUluQnl0ZXMgPj4gMTA7CisKKyAgICAgICAgICAgIGlmIChtZW1vcnlVc2FnZUluS2IgPiBtZW1vcnlMaW1pdEluS2IpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTWVtb3J5TGltaXRFeGNlcHRpb24obWVtb3J5VXNhZ2VJbktiLCBtZW1vcnlMaW1pdEluS2IpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGluaXRpYWxpemVUYWJsZXMobWF4Q29kZVNpemUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluaXRpYWxpemVzIHRoZSBhcnJheXMgYmFzZWQgb24gdGhlIG1heGltdW0gY29kZSBzaXplLgorICAgICAqIEBwYXJhbSBtYXhDb2RlU2l6ZSBtYXhpbXVtIGNvZGUgc2l6ZQorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIGluaXRpYWxpemVUYWJsZXMoZmluYWwgaW50IG1heENvZGVTaXplKSB7CisgICAgICAgIGZpbmFsIGludCBtYXhUYWJsZVNpemUgPSAxIDw8IG1heENvZGVTaXplOworICAgICAgICBwcmVmaXhlcyA9IG5ldyBpbnRbbWF4VGFibGVTaXplXTsKKyAgICAgICAgY2hhcmFjdGVycyA9IG5ldyBieXRlW21heFRhYmxlU2l6ZV07CisgICAgICAgIG91dHB1dFN0YWNrID0gbmV3IGJ5dGVbbWF4VGFibGVTaXplXTsKKyAgICAgICAgb3V0cHV0U3RhY2tMb2NhdGlvbiA9IG1heFRhYmxlU2l6ZTsKKyAgICAgICAgZmluYWwgaW50IG1heCA9IDEgPDwgODsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtYXg7IGkrKykgeworICAgICAgICAgICAgcHJlZml4ZXNbaV0gPSAtMTsKKyAgICAgICAgICAgIGNoYXJhY3RlcnNbaV0gPSAoYnl0ZSkgaTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIHRoZSBuZXh0IGNvZGUgZnJvbSB0aGUgc3RyZWFtLgorICAgICAqIEByZXR1cm4gdGhlIG5leHQgY29kZQorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gb24gZXJyb3IKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IHJlYWROZXh0Q29kZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChjb2RlU2l6ZSA+IDMxKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJjb2RlIHNpemUgbXVzdCBub3QgYmUgYmlnZ2VyIHRoYW4gMzEiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gKGludCkgaW4ucmVhZEJpdHMoY29kZVNpemUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgYSBuZXcgZW50cnkgaWYgdGhlIG1heGltdW0gdGFibGUgc2l6ZSBoYXNuJ3QgYmVlbiBleGNlZWRlZAorICAgICAqIGFuZCByZXR1cm5zIHRoZSBuZXcgaW5kZXguCisgICAgICogQHBhcmFtIHByZXZpb3VzQ29kZSB0aGUgcHJldmlvdXMgY29kZQorICAgICAqIEBwYXJhbSBjaGFyYWN0ZXIgdGhlIGNoYXJhY3RlciB0byBhcHBlbmQKKyAgICAgKiBAcGFyYW0gbWF4VGFibGVTaXplIHRoZSBtYXhpbXVtIHRhYmxlIHNpemUKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXcgY29kZQorICAgICAqLworICAgIHByb3RlY3RlZCBpbnQgYWRkRW50cnkoZmluYWwgaW50IHByZXZpb3VzQ29kZSwgZmluYWwgYnl0ZSBjaGFyYWN0ZXIsIGZpbmFsIGludCBtYXhUYWJsZVNpemUpIHsKKyAgICAgICAgaWYgKHRhYmxlU2l6ZSA8IG1heFRhYmxlU2l6ZSkgeworICAgICAgICAgICAgcHJlZml4ZXNbdGFibGVTaXplXSA9IHByZXZpb3VzQ29kZTsKKyAgICAgICAgICAgIGNoYXJhY3RlcnNbdGFibGVTaXplXSA9IGNoYXJhY3RlcjsKKyAgICAgICAgICAgIHJldHVybiB0YWJsZVNpemUrKzsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkIGVudHJ5IGZvciByZXBlYXQgb2YgcHJldmlvdXNDb2RlIHdlIGhhdmVuJ3QgYWRkZWQsIHlldC4KKyAgICAgKiBAcmV0dXJuIG5ldyBjb2RlIGZvciBhIHJlcGVhdCBvZiB0aGUgcHJldmlvdXMgY29kZQorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gb24gZXJyb3IKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IGFkZFJlcGVhdE9mUHJldmlvdXNDb2RlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHByZXZpb3VzQ29kZSA9PSAtMSkgeworICAgICAgICAgICAgLy8gY2FuJ3QgaGF2ZSBhIHJlcGVhdCBmb3IgdGhlIHZlcnkgZmlyc3QgY29kZQorICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJUaGUgZmlyc3QgY29kZSBjYW4ndCBiZSBhIHJlZmVyZW5jZSB0byBpdHMgcHJlY2VkaW5nIGNvZGUiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYWRkRW50cnkocHJldmlvdXNDb2RlLCBwcmV2aW91c0NvZGVGaXJzdENoYXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEV4cGFuZHMgdGhlIGVudHJ5IHdpdGggaW5kZXggY29kZSB0byB0aGUgb3V0cHV0IHN0YWNrIGFuZCBtYXkKKyAgICAgKiBjcmVhdGUgYSBuZXcgZW50cnkKKyAgICAgKiBAcGFyYW0gY29kZSB0aGUgY29kZQorICAgICAqIEBwYXJhbSBhZGRlZFVuZmluaXNoZWRFbnRyeSB3aGV0aGVyIHVuZmluaXNoZWQgZW50cmllcyBoYXZlIGJlZW4gYWRkZWQKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXcgbG9jYXRpb24gb2YgdGhlIG91dHB1dCBzdGFjaworICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gb24gZXJyb3IKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IGV4cGFuZENvZGVUb091dHB1dFN0YWNrKGZpbmFsIGludCBjb2RlLCBmaW5hbCBib29sZWFuIGFkZGVkVW5maW5pc2hlZEVudHJ5KQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmb3IgKGludCBlbnRyeSA9IGNvZGU7IGVudHJ5ID49IDA7IGVudHJ5ID0gcHJlZml4ZXNbZW50cnldKSB7CisgICAgICAgICAgICBvdXRwdXRTdGFja1stLW91dHB1dFN0YWNrTG9jYXRpb25dID0gY2hhcmFjdGVyc1tlbnRyeV07CisgICAgICAgIH0KKyAgICAgICAgaWYgKHByZXZpb3VzQ29kZSAhPSAtMSAmJiAhYWRkZWRVbmZpbmlzaGVkRW50cnkpIHsKKyAgICAgICAgICAgIGFkZEVudHJ5KHByZXZpb3VzQ29kZSwgb3V0cHV0U3RhY2tbb3V0cHV0U3RhY2tMb2NhdGlvbl0pOworICAgICAgICB9CisgICAgICAgIHByZXZpb3VzQ29kZSA9IGNvZGU7CisgICAgICAgIHByZXZpb3VzQ29kZUZpcnN0Q2hhciA9IG91dHB1dFN0YWNrW291dHB1dFN0YWNrTG9jYXRpb25dOworICAgICAgICByZXR1cm4gb3V0cHV0U3RhY2tMb2NhdGlvbjsKKyAgICB9CisKKyAgICBwcml2YXRlIGludCByZWFkRnJvbVN0YWNrKGZpbmFsIGJ5dGVbXSBiLCBmaW5hbCBpbnQgb2ZmLCBmaW5hbCBpbnQgbGVuKSB7CisgICAgICAgIGZpbmFsIGludCByZW1haW5pbmdJblN0YWNrID0gb3V0cHV0U3RhY2subGVuZ3RoIC0gb3V0cHV0U3RhY2tMb2NhdGlvbjsKKyAgICAgICAgaWYgKHJlbWFpbmluZ0luU3RhY2sgPiAwKSB7CisgICAgICAgICAgICBmaW5hbCBpbnQgbWF4TGVuZ3RoID0gTWF0aC5taW4ocmVtYWluaW5nSW5TdGFjaywgbGVuKTsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkob3V0cHV0U3RhY2ssIG91dHB1dFN0YWNrTG9jYXRpb24sIGIsIG9mZiwgbWF4TGVuZ3RoKTsKKyAgICAgICAgICAgIG91dHB1dFN0YWNrTG9jYXRpb24gKz0gbWF4TGVuZ3RoOworICAgICAgICAgICAgcmV0dXJuIG1heExlbmd0aDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgaW50IGdldENvZGVTaXplKCkgeworICAgICAgICByZXR1cm4gY29kZVNpemU7CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgcmVzZXRDb2RlU2l6ZSgpIHsKKyAgICAgICAgc2V0Q29kZVNpemUoREVGQVVMVF9DT0RFX1NJWkUpOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHNldENvZGVTaXplKGZpbmFsIGludCBjcykgeworICAgICAgICB0aGlzLmNvZGVTaXplID0gY3M7CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgaW5jcmVtZW50Q29kZVNpemUoKSB7CisgICAgICAgIGNvZGVTaXplKys7CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgcmVzZXRQcmV2aW91c0NvZGUoKSB7CisgICAgICAgIHRoaXMucHJldmlvdXNDb2RlID0gLTE7CisgICAgfQorCisgICAgcHJvdGVjdGVkIGludCBnZXRQcmVmaXgoZmluYWwgaW50IG9mZnNldCkgeworICAgICAgICByZXR1cm4gcHJlZml4ZXNbb2Zmc2V0XTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRQcmVmaXgoZmluYWwgaW50IG9mZnNldCwgZmluYWwgaW50IHZhbHVlKSB7CisgICAgICAgIHByZWZpeGVzW29mZnNldF0gPSB2YWx1ZTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgaW50IGdldFByZWZpeGVzTGVuZ3RoKCkgeworICAgICAgICByZXR1cm4gcHJlZml4ZXMubGVuZ3RoOworICAgIH0KKworICAgIHByb3RlY3RlZCBpbnQgZ2V0Q2xlYXJDb2RlKCkgeworICAgICAgICByZXR1cm4gY2xlYXJDb2RlOworICAgIH0KKworICAgIHByb3RlY3RlZCBpbnQgZ2V0VGFibGVTaXplKCkgeworICAgICAgICByZXR1cm4gdGFibGVTaXplOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHNldFRhYmxlU2l6ZShmaW5hbCBpbnQgbmV3U2l6ZSkgeworICAgICAgICB0YWJsZVNpemUgPSBuZXdTaXplOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvbHp3L3BhY2thZ2UuaHRtbCBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2x6dy9wYWNrYWdlLmh0bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2M0NWNhNgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2x6dy9wYWNrYWdlLmh0bWwKQEAgLTAsMCArMSwyMyBAQAorPGh0bWw+Cis8IS0tCisKKyAgIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAgIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisKKyAgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKworICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAgIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisKKy0tPgorICA8Ym9keT4KKyAgICA8cD5HZW5lcmljIExaVyBpbXBsZW1lbnRhdGlvbi48L3A+CisgIDwvYm9keT4KKzwvaHRtbD4KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL3BhY2syMDAvSW5NZW1vcnlDYWNoaW5nU3RyZWFtQnJpZGdlLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9wYWNrMjAwL0luTWVtb3J5Q2FjaGluZ1N0cmVhbUJyaWRnZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUxZmRjMmMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9wYWNrMjAwL0luTWVtb3J5Q2FjaGluZ1N0cmVhbUJyaWRnZS5qYXZhCkBAIC0wLDAgKzEsNDIgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5wYWNrMjAwOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CisKKy8qKgorICogU3RyZWFtU3dpdGNoZXIgdGhhdCBjYWNoZXMgYWxsIGRhdGEgd3JpdHRlbiB0byB0aGUgb3V0cHV0IHNpZGUgaW4KKyAqIG1lbW9yeS4KKyAqIEBzaW5jZSAxLjMKKyAqLworY2xhc3MgSW5NZW1vcnlDYWNoaW5nU3RyZWFtQnJpZGdlIGV4dGVuZHMgU3RyZWFtQnJpZGdlIHsKKyAgICBJbk1lbW9yeUNhY2hpbmdTdHJlYW1CcmlkZ2UoKSB7CisgICAgICAgIHN1cGVyKG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgSW5wdXRTdHJlYW0gZ2V0SW5wdXRWaWV3KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbSgoKEJ5dGVBcnJheU91dHB1dFN0cmVhbSkgb3V0KQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50b0J5dGVBcnJheSgpKTsKKyAgICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvcGFjazIwMC9QYWNrMjAwQ29tcHJlc3NvcklucHV0U3RyZWFtLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9wYWNrMjAwL1BhY2syMDBDb21wcmVzc29ySW5wdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wNGZkYzJiCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvcGFjazIwMC9QYWNrMjAwQ29tcHJlc3NvcklucHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwyODIgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5wYWNrMjAwOworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsdGVySW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLmphci5KYXJPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLmphci5QYWNrMjAwOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLkNvbXByZXNzb3JJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuSU9VdGlsczsKKworLyoqCisgKiBBbiBpbnB1dCBzdHJlYW0gdGhhdCBkZWNvbXByZXNzZXMgZnJvbSB0aGUgUGFjazIwMCBmb3JtYXQgdG8gYmUgcmVhZAorICogYXMgYW55IG90aGVyIHN0cmVhbS4KKyAqCisgKiA8cD5UaGUge0BsaW5rIENvbXByZXNzb3JJbnB1dFN0cmVhbSNnZXRDb3VudCBnZXRDb3VudH0gYW5kIHtAbGluaworICogQ29tcHJlc3NvcklucHV0U3RyZWFtI2dldEJ5dGVzUmVhZCBnZXRCeXRlc1JlYWR9IG1ldGhvZHMgYWx3YXlzCisgKiByZXR1cm4gMC48L3A+CisgKgorICogQE5vdFRocmVhZFNhZmUKKyAqIEBzaW5jZSAxLjMKKyAqLworcHVibGljIGNsYXNzIFBhY2syMDBDb21wcmVzc29ySW5wdXRTdHJlYW0gZXh0ZW5kcyBDb21wcmVzc29ySW5wdXRTdHJlYW0geworICAgIHByaXZhdGUgZmluYWwgSW5wdXRTdHJlYW0gb3JpZ2luYWxJbnB1dDsKKyAgICBwcml2YXRlIGZpbmFsIFN0cmVhbUJyaWRnZSBzdHJlYW1CcmlkZ2U7CisKKyAgICAvKioKKyAgICAgKiBEZWNvbXByZXNzZXMgdGhlIGdpdmVuIHN0cmVhbSwgY2FjaGluZyB0aGUgZGVjb21wcmVzc2VkIGRhdGEgaW4KKyAgICAgKiBtZW1vcnkuCisgICAgICoKKyAgICAgKiA8cD5XaGVuIHJlYWRpbmcgZnJvbSBhIGZpbGUgdGhlIEZpbGUtYXJnIGNvbnN0cnVjdG9yIG1heQorICAgICAqIHByb3ZpZGUgYmV0dGVyIHBlcmZvcm1hbmNlLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbiB0aGUgSW5wdXRTdHJlYW0gZnJvbSB3aGljaCB0aGlzIG9iamVjdCBzaG91bGQgYmUgY3JlYXRlZAorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgcmVhZGluZyBmYWlscworICAgICAqLworICAgIHB1YmxpYyBQYWNrMjAwQ29tcHJlc3NvcklucHV0U3RyZWFtKGZpbmFsIElucHV0U3RyZWFtIGluKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzKGluLCBQYWNrMjAwU3RyYXRlZ3kuSU5fTUVNT1JZKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZWNvbXByZXNzZXMgdGhlIGdpdmVuIHN0cmVhbSB1c2luZyB0aGUgZ2l2ZW4gc3RyYXRlZ3kgdG8gY2FjaGUKKyAgICAgKiB0aGUgcmVzdWx0cy4KKyAgICAgKgorICAgICAqIDxwPldoZW4gcmVhZGluZyBmcm9tIGEgZmlsZSB0aGUgRmlsZS1hcmcgY29uc3RydWN0b3IgbWF5CisgICAgICogcHJvdmlkZSBiZXR0ZXIgcGVyZm9ybWFuY2UuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGluIHRoZSBJbnB1dFN0cmVhbSBmcm9tIHdoaWNoIHRoaXMgb2JqZWN0IHNob3VsZCBiZSBjcmVhdGVkCisgICAgICogQHBhcmFtIG1vZGUgdGhlIHN0cmF0ZWd5IHRvIHVzZQorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgcmVhZGluZyBmYWlscworICAgICAqLworICAgIHB1YmxpYyBQYWNrMjAwQ29tcHJlc3NvcklucHV0U3RyZWFtKGZpbmFsIElucHV0U3RyZWFtIGluLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIFBhY2syMDBTdHJhdGVneSBtb2RlKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzKGluLCBudWxsLCBtb2RlLCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZWNvbXByZXNzZXMgdGhlIGdpdmVuIHN0cmVhbSwgY2FjaGluZyB0aGUgZGVjb21wcmVzc2VkIGRhdGEgaW4KKyAgICAgKiBtZW1vcnkgYW5kIHVzaW5nIHRoZSBnaXZlbiBwcm9wZXJ0aWVzLgorICAgICAqCisgICAgICogPHA+V2hlbiByZWFkaW5nIGZyb20gYSBmaWxlIHRoZSBGaWxlLWFyZyBjb25zdHJ1Y3RvciBtYXkKKyAgICAgKiBwcm92aWRlIGJldHRlciBwZXJmb3JtYW5jZS48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gaW4gdGhlIElucHV0U3RyZWFtIGZyb20gd2hpY2ggdGhpcyBvYmplY3Qgc2hvdWxkIGJlIGNyZWF0ZWQKKyAgICAgKiBAcGFyYW0gcHJvcHMgUGFjazIwMCBwcm9wZXJ0aWVzIHRvIHVzZQorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgcmVhZGluZyBmYWlscworICAgICAqLworICAgIHB1YmxpYyBQYWNrMjAwQ29tcHJlc3NvcklucHV0U3RyZWFtKGZpbmFsIElucHV0U3RyZWFtIGluLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIE1hcDxTdHJpbmcsIFN0cmluZz4gcHJvcHMpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMoaW4sIFBhY2syMDBTdHJhdGVneS5JTl9NRU1PUlksIHByb3BzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZWNvbXByZXNzZXMgdGhlIGdpdmVuIHN0cmVhbSB1c2luZyB0aGUgZ2l2ZW4gc3RyYXRlZ3kgdG8gY2FjaGUKKyAgICAgKiB0aGUgcmVzdWx0cyBhbmQgdGhlIGdpdmVuIHByb3BlcnRpZXMuCisgICAgICoKKyAgICAgKiA8cD5XaGVuIHJlYWRpbmcgZnJvbSBhIGZpbGUgdGhlIEZpbGUtYXJnIGNvbnN0cnVjdG9yIG1heQorICAgICAqIHByb3ZpZGUgYmV0dGVyIHBlcmZvcm1hbmNlLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbiB0aGUgSW5wdXRTdHJlYW0gZnJvbSB3aGljaCB0aGlzIG9iamVjdCBzaG91bGQgYmUgY3JlYXRlZAorICAgICAqIEBwYXJhbSBtb2RlIHRoZSBzdHJhdGVneSB0byB1c2UKKyAgICAgKiBAcGFyYW0gcHJvcHMgUGFjazIwMCBwcm9wZXJ0aWVzIHRvIHVzZQorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgcmVhZGluZyBmYWlscworICAgICAqLworICAgIHB1YmxpYyBQYWNrMjAwQ29tcHJlc3NvcklucHV0U3RyZWFtKGZpbmFsIElucHV0U3RyZWFtIGluLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIFBhY2syMDBTdHJhdGVneSBtb2RlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIE1hcDxTdHJpbmcsIFN0cmluZz4gcHJvcHMpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMoaW4sIG51bGwsIG1vZGUsIHByb3BzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZWNvbXByZXNzZXMgdGhlIGdpdmVuIGZpbGUsIGNhY2hpbmcgdGhlIGRlY29tcHJlc3NlZCBkYXRhIGluCisgICAgICogbWVtb3J5LgorICAgICAqCisgICAgICogQHBhcmFtIGYgdGhlIGZpbGUgdG8gZGVjb21wcmVzcworICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgcmVhZGluZyBmYWlscworICAgICAqLworICAgIHB1YmxpYyBQYWNrMjAwQ29tcHJlc3NvcklucHV0U3RyZWFtKGZpbmFsIEZpbGUgZikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcyhmLCBQYWNrMjAwU3RyYXRlZ3kuSU5fTUVNT1JZKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZWNvbXByZXNzZXMgdGhlIGdpdmVuIGZpbGUgdXNpbmcgdGhlIGdpdmVuIHN0cmF0ZWd5IHRvIGNhY2hlCisgICAgICogdGhlIHJlc3VsdHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZiB0aGUgZmlsZSB0byBkZWNvbXByZXNzCisgICAgICogQHBhcmFtIG1vZGUgdGhlIHN0cmF0ZWd5IHRvIHVzZQorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgcmVhZGluZyBmYWlscworICAgICAqLworICAgIHB1YmxpYyBQYWNrMjAwQ29tcHJlc3NvcklucHV0U3RyZWFtKGZpbmFsIEZpbGUgZiwgZmluYWwgUGFjazIwMFN0cmF0ZWd5IG1vZGUpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMobnVsbCwgZiwgbW9kZSwgbnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRGVjb21wcmVzc2VzIHRoZSBnaXZlbiBmaWxlLCBjYWNoaW5nIHRoZSBkZWNvbXByZXNzZWQgZGF0YSBpbgorICAgICAqIG1lbW9yeSBhbmQgdXNpbmcgdGhlIGdpdmVuIHByb3BlcnRpZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZiB0aGUgZmlsZSB0byBkZWNvbXByZXNzCisgICAgICogQHBhcmFtIHByb3BzIFBhY2syMDAgcHJvcGVydGllcyB0byB1c2UKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHJlYWRpbmcgZmFpbHMKKyAgICAgKi8KKyAgICBwdWJsaWMgUGFjazIwMENvbXByZXNzb3JJbnB1dFN0cmVhbShmaW5hbCBGaWxlIGYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgTWFwPFN0cmluZywgU3RyaW5nPiBwcm9wcykKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcyhmLCBQYWNrMjAwU3RyYXRlZ3kuSU5fTUVNT1JZLCBwcm9wcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRGVjb21wcmVzc2VzIHRoZSBnaXZlbiBmaWxlIHVzaW5nIHRoZSBnaXZlbiBzdHJhdGVneSB0byBjYWNoZQorICAgICAqIHRoZSByZXN1bHRzIGFuZCB0aGUgZ2l2ZW4gcHJvcGVydGllcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmIHRoZSBmaWxlIHRvIGRlY29tcHJlc3MKKyAgICAgKiBAcGFyYW0gbW9kZSB0aGUgc3RyYXRlZ3kgdG8gdXNlCisgICAgICogQHBhcmFtIHByb3BzIFBhY2syMDAgcHJvcGVydGllcyB0byB1c2UKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHJlYWRpbmcgZmFpbHMKKyAgICAgKi8KKyAgICBwdWJsaWMgUGFjazIwMENvbXByZXNzb3JJbnB1dFN0cmVhbShmaW5hbCBGaWxlIGYsIGZpbmFsIFBhY2syMDBTdHJhdGVneSBtb2RlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIE1hcDxTdHJpbmcsIFN0cmluZz4gcHJvcHMpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMobnVsbCwgZiwgbW9kZSwgcHJvcHMpOworICAgIH0KKworICAgIHByaXZhdGUgUGFjazIwMENvbXByZXNzb3JJbnB1dFN0cmVhbShmaW5hbCBJbnB1dFN0cmVhbSBpbiwgZmluYWwgRmlsZSBmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBQYWNrMjAwU3RyYXRlZ3kgbW9kZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgTWFwPFN0cmluZywgU3RyaW5nPiBwcm9wcykKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG9yaWdpbmFsSW5wdXQgPSBpbjsKKyAgICAgICAgc3RyZWFtQnJpZGdlID0gbW9kZS5uZXdTdHJlYW1CcmlkZ2UoKTsKKyAgICAgICAgdHJ5IChmaW5hbCBKYXJPdXRwdXRTdHJlYW0gamFyT3V0ID0gbmV3IEphck91dHB1dFN0cmVhbShzdHJlYW1CcmlkZ2UpKSB7CisgICAgICAgICAgICBmaW5hbCBQYWNrMjAwLlVucGFja2VyIHUgPSBQYWNrMjAwLm5ld1VucGFja2VyKCk7CisgICAgICAgICAgICBpZiAocHJvcHMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHUucHJvcGVydGllcygpLnB1dEFsbChwcm9wcyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoZiA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdS51bnBhY2sobmV3IEZpbHRlcklucHV0U3RyZWFtKGluKSB7CisgICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIHVucGFjayB3b3VsZCBjbG9zZSB0aGlzIHN0cmVhbSBidXQgd2UKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdhbnQgdG8gZ2l2ZSB0aGUgdXNlciBjb2RlIG1vcmUgY29udHJvbAorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSwgamFyT3V0KTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdS51bnBhY2soZiwgamFyT3V0KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBzdHJlYW1CcmlkZ2UuZ2V0SW5wdXQoKS5yZWFkKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCByZWFkKGZpbmFsIGJ5dGVbXSBiKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gc3RyZWFtQnJpZGdlLmdldElucHV0KCkucmVhZChiKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHJlYWQoZmluYWwgYnl0ZVtdIGIsIGZpbmFsIGludCBvZmYsIGZpbmFsIGludCBjb3VudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHN0cmVhbUJyaWRnZS5nZXRJbnB1dCgpLnJlYWQoYiwgb2ZmLCBjb3VudCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBhdmFpbGFibGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gc3RyZWFtQnJpZGdlLmdldElucHV0KCkuYXZhaWxhYmxlKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gbWFya1N1cHBvcnRlZCgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBzdHJlYW1CcmlkZ2UuZ2V0SW5wdXQoKS5tYXJrU3VwcG9ydGVkKCk7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIElPRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBtYXJrKGZpbmFsIGludCBsaW1pdCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3RyZWFtQnJpZGdlLmdldElucHV0KCkubWFyayhsaW1pdCk7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIElPRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihleCk7IC8vTk9TT05BUgorICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcmVzZXQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzdHJlYW1CcmlkZ2UuZ2V0SW5wdXQoKS5yZXNldCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBsb25nIHNraXAoZmluYWwgbG9uZyBjb3VudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIElPVXRpbHMuc2tpcChzdHJlYW1CcmlkZ2UuZ2V0SW5wdXQoKSwgY291bnQpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0cmVhbUJyaWRnZS5zdG9wKCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAob3JpZ2luYWxJbnB1dCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgb3JpZ2luYWxJbnB1dC5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIENBRkVfRE9PRCA9IG5ldyBieXRlW10geworICAgICAgICAoYnl0ZSkgMHhDQSwgKGJ5dGUpIDB4RkUsIChieXRlKSAweEQwLCAoYnl0ZSkgMHgwRAorICAgIH07CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFNJR19MRU5HVEggPSBDQUZFX0RPT0QubGVuZ3RoOworCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIHRoZSBzaWduYXR1cmUgbWF0Y2hlcyB3aGF0IGlzIGV4cGVjdGVkIGZvciBhIHBhY2syMDAKKyAgICAgKiBmaWxlICgweENBRkVEMDBEKS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzaWduYXR1cmUKKyAgICAgKiAgICAgICAgICAgIHRoZSBieXRlcyB0byBjaGVjaworICAgICAqIEBwYXJhbSBsZW5ndGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gY2hlY2sKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoaXMgc3RyZWFtIGlzIGEgcGFjazIwMCBjb21wcmVzc2VkIHN0cmVhbSwKKyAgICAgKiBmYWxzZSBvdGhlcndpc2UKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gbWF0Y2hlcyhmaW5hbCBieXRlW10gc2lnbmF0dXJlLCBmaW5hbCBpbnQgbGVuZ3RoKSB7CisgICAgICAgIGlmIChsZW5ndGggPCBTSUdfTEVOR1RIKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IFNJR19MRU5HVEg7IGkrKykgeworICAgICAgICAgICAgaWYgKHNpZ25hdHVyZVtpXSAhPSBDQUZFX0RPT0RbaV0pIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9wYWNrMjAwL1BhY2syMDBDb21wcmVzc29yT3V0cHV0U3RyZWFtLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9wYWNrMjAwL1BhY2syMDBDb21wcmVzc29yT3V0cHV0U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTViZTg3YgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL3BhY2syMDAvUGFjazIwMENvbXByZXNzb3JPdXRwdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDE0MCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLnBhY2syMDA7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLmphci5KYXJJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuamFyLlBhY2syMDA7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuQ29tcHJlc3Nvck91dHB1dFN0cmVhbTsKKworLyoqCisgKiBBbiBvdXRwdXQgc3RyZWFtIHRoYXQgY29tcHJlc3NlcyB1c2luZyB0aGUgUGFjazIwMCBmb3JtYXQuCisgKgorICogQE5vdFRocmVhZFNhZmUKKyAqIEBzaW5jZSAxLjMKKyAqLworcHVibGljIGNsYXNzIFBhY2syMDBDb21wcmVzc29yT3V0cHV0U3RyZWFtIGV4dGVuZHMgQ29tcHJlc3Nvck91dHB1dFN0cmVhbSB7CisgICAgcHJpdmF0ZSBib29sZWFuIGZpbmlzaGVkID0gZmFsc2U7CisgICAgcHJpdmF0ZSBmaW5hbCBPdXRwdXRTdHJlYW0gb3JpZ2luYWxPdXRwdXQ7CisgICAgcHJpdmF0ZSBmaW5hbCBTdHJlYW1CcmlkZ2Ugc3RyZWFtQnJpZGdlOworICAgIHByaXZhdGUgZmluYWwgTWFwPFN0cmluZywgU3RyaW5nPiBwcm9wZXJ0aWVzOworCisgICAgLyoqCisgICAgICogQ29tcHJlc3NlcyB0aGUgZ2l2ZW4gc3RyZWFtLCBjYWNoaW5nIHRoZSBjb21wcmVzc2VkIGRhdGEgaW4KKyAgICAgKiBtZW1vcnkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3V0IHRoZSBzdHJlYW0gdG8gd3JpdGUgdG8KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHdyaXRpbmcgZmFpbHMKKyAgICAgKi8KKyAgICBwdWJsaWMgUGFjazIwMENvbXByZXNzb3JPdXRwdXRTdHJlYW0oZmluYWwgT3V0cHV0U3RyZWFtIG91dCkKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcyhvdXQsIFBhY2syMDBTdHJhdGVneS5JTl9NRU1PUlkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXByZXNzZXMgdGhlIGdpdmVuIHN0cmVhbSB1c2luZyB0aGUgZ2l2ZW4gc3RyYXRlZ3kgdG8gY2FjaGUKKyAgICAgKiB0aGUgcmVzdWx0cy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvdXQgdGhlIHN0cmVhbSB0byB3cml0ZSB0bworICAgICAqIEBwYXJhbSBtb2RlIHRoZSBzdHJhdGVneSB0byB1c2UKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHdyaXRpbmcgZmFpbHMKKyAgICAgKi8KKyAgICBwdWJsaWMgUGFjazIwMENvbXByZXNzb3JPdXRwdXRTdHJlYW0oZmluYWwgT3V0cHV0U3RyZWFtIG91dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgUGFjazIwMFN0cmF0ZWd5IG1vZGUpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMob3V0LCBtb2RlLCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wcmVzc2VzIHRoZSBnaXZlbiBzdHJlYW0sIGNhY2hpbmcgdGhlIGNvbXByZXNzZWQgZGF0YSBpbgorICAgICAqIG1lbW9yeSBhbmQgdXNpbmcgdGhlIGdpdmVuIHByb3BlcnRpZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3V0IHRoZSBzdHJlYW0gdG8gd3JpdGUgdG8KKyAgICAgKiBAcGFyYW0gcHJvcHMgUGFjazIwMCBwcm9wZXJ0aWVzIHRvIHVzZQorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgd3JpdGluZyBmYWlscworICAgICAqLworICAgIHB1YmxpYyBQYWNrMjAwQ29tcHJlc3Nvck91dHB1dFN0cmVhbShmaW5hbCBPdXRwdXRTdHJlYW0gb3V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBNYXA8U3RyaW5nLCBTdHJpbmc+IHByb3BzKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzKG91dCwgUGFjazIwMFN0cmF0ZWd5LklOX01FTU9SWSwgcHJvcHMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXByZXNzZXMgdGhlIGdpdmVuIHN0cmVhbSB1c2luZyB0aGUgZ2l2ZW4gc3RyYXRlZ3kgdG8gY2FjaGUKKyAgICAgKiB0aGUgcmVzdWx0cyBhbmQgdGhlIGdpdmVuIHByb3BlcnRpZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3V0IHRoZSBzdHJlYW0gdG8gd3JpdGUgdG8KKyAgICAgKiBAcGFyYW0gbW9kZSB0aGUgc3RyYXRlZ3kgdG8gdXNlCisgICAgICogQHBhcmFtIHByb3BzIFBhY2syMDAgcHJvcGVydGllcyB0byB1c2UKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHdyaXRpbmcgZmFpbHMKKyAgICAgKi8KKyAgICBwdWJsaWMgUGFjazIwMENvbXByZXNzb3JPdXRwdXRTdHJlYW0oZmluYWwgT3V0cHV0U3RyZWFtIG91dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgUGFjazIwMFN0cmF0ZWd5IG1vZGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIE1hcDxTdHJpbmcsIFN0cmluZz4gcHJvcHMpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG9yaWdpbmFsT3V0cHV0ID0gb3V0OworICAgICAgICBzdHJlYW1CcmlkZ2UgPSBtb2RlLm5ld1N0cmVhbUJyaWRnZSgpOworICAgICAgICBwcm9wZXJ0aWVzID0gcHJvcHM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGUoZmluYWwgaW50IGIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN0cmVhbUJyaWRnZS53cml0ZShiKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShmaW5hbCBieXRlW10gYikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3RyZWFtQnJpZGdlLndyaXRlKGIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGZpbmFsIGJ5dGVbXSBiLCBmaW5hbCBpbnQgZnJvbSwgZmluYWwgaW50IGxlbmd0aCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3RyZWFtQnJpZGdlLndyaXRlKGIsIGZyb20sIGxlbmd0aCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmluaXNoKCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHN0cmVhbUJyaWRnZS5zdG9wKCk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIG9yaWdpbmFsT3V0cHV0LmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBmaW5pc2goKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoIWZpbmlzaGVkKSB7CisgICAgICAgICAgICBmaW5pc2hlZCA9IHRydWU7CisgICAgICAgICAgICBmaW5hbCBQYWNrMjAwLlBhY2tlciBwID0gUGFjazIwMC5uZXdQYWNrZXIoKTsKKyAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBwLnByb3BlcnRpZXMoKS5wdXRBbGwocHJvcGVydGllcyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgKEphcklucHV0U3RyZWFtIGppID0gbmV3IEphcklucHV0U3RyZWFtKHN0cmVhbUJyaWRnZS5nZXRJbnB1dCgpKSkgeworICAgICAgICAgICAgICAgIHAucGFjayhqaSwgb3JpZ2luYWxPdXRwdXQpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvcGFjazIwMC9QYWNrMjAwU3RyYXRlZ3kuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL3BhY2syMDAvUGFjazIwMFN0cmF0ZWd5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGJhMTk5MgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL3BhY2syMDAvUGFjazIwMFN0cmF0ZWd5LmphdmEKQEAgLTAsMCArMSw0NiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLnBhY2syMDA7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCisvKioKKyAqIFRoZSBkaWZmZXJlbnQgbW9kZXMgdGhlIFBhY2syMDAgc3RyZWFtcyBjYW4gdXNlIHRvIHdyYXAgaW5wdXQgYW5kCisgKiBvdXRwdXQuCisgKiBAc2luY2UgMS4zCisgKi8KK3B1YmxpYyBlbnVtIFBhY2syMDBTdHJhdGVneSB7CisgICAgLyoqIENhY2hlIG91dHB1dCBpbiBtZW1vcnkgKi8KKyAgICBJTl9NRU1PUlkoKSB7CisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBTdHJlYW1CcmlkZ2UgbmV3U3RyZWFtQnJpZGdlKCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBJbk1lbW9yeUNhY2hpbmdTdHJlYW1CcmlkZ2UoKTsKKyAgICAgICAgfQorICAgIH0sCisgICAgLyoqIENhY2hlIG91dHB1dCBpbiBhIHRlbXBvcmFyeSBmaWxlICovCisgICAgVEVNUF9GSUxFKCkgeworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgU3RyZWFtQnJpZGdlIG5ld1N0cmVhbUJyaWRnZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gbmV3IFRlbXBGaWxlQ2FjaGluZ1N0cmVhbUJyaWRnZSgpOworICAgICAgICB9CisgICAgfTsKKworICAgIGFic3RyYWN0IFN0cmVhbUJyaWRnZSBuZXdTdHJlYW1CcmlkZ2UoKSB0aHJvd3MgSU9FeGNlcHRpb247Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvcGFjazIwMC9QYWNrMjAwVXRpbHMuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL3BhY2syMDAvUGFjazIwMFV0aWxzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTFhNTRjYQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL3BhY2syMDAvUGFjazIwMFV0aWxzLmphdmEKQEAgLTAsMCArMSwxNTEgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5wYWNrMjAwOworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLmphci5KYXJGaWxlOworaW1wb3J0IGphdmEudXRpbC5qYXIuSmFyT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5qYXIuUGFjazIwMDsKKworLyoqCisgKiBVdGlsaXR5IG1ldGhvZHMgZm9yIFBhY2syMDAuCisgKgorICogQFRocmVhZFNhZmUKKyAqIEBzaW5jZSAxLjMKKyAqLworcHVibGljIGNsYXNzIFBhY2syMDBVdGlscyB7CisgICAgcHJpdmF0ZSBQYWNrMjAwVXRpbHMoKSB7IH0KKworICAgIC8qKgorICAgICAqIE5vcm1hbGl6ZXMgYSBKQVIgYXJjaGl2ZSBpbi1wbGFjZSBzbyBpdCBjYW4gYmUgc2FmZWx5IHNpZ25lZAorICAgICAqIGFuZCBwYWNrZWQuCisgICAgICoKKyAgICAgKiA8cD5BcyBzdGF0ZWQgaW4gPGEKKyAgICAgKiBocmVmPSJodHRwczovL2Rvd25sb2FkLm9yYWNsZS5jb20vamF2YXNlLzEuNS4wL2RvY3MvYXBpL2phdmEvdXRpbC9qYXIvUGFjazIwMC5QYWNrZXIuaHRtbCI+UGFjazIwMC5QYWNrZXInczwvYT4KKyAgICAgKiBqYXZhZG9jcyBhcHBseWluZyBhIFBhY2syMDAgY29tcHJlc3Npb24gdG8gYSBKQVIgYXJjaGl2ZSB3aWxsCisgICAgICogaW4gZ2VuZXJhbCBtYWtlIGl0cyBzaWdhbnR1cmVzIGludmFsaWQuICBJbiBvcmRlciB0byBwcmVwYXJlIGEKKyAgICAgKiBKQVIgZm9yIHNpZ25pbmcgaXQgc2hvdWxkIGJlICJub3JtYWxpemVkIiBieSBwYWNraW5nIGFuZAorICAgICAqIHVucGFja2luZyBpdC4gIFRoaXMgaXMgd2hhdCB0aGlzIG1ldGhvZCBkb2VzLjwvcD4KKyAgICAgKgorICAgICAqIDxwPk5vdGUgdGhpcyBtZXRob2RzIGltcGxpY2l0bHkgc2V0cyB0aGUgc2VnbWVudCBsZW5ndGggdG8KKyAgICAgKiAtMS48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gamFyIHRoZSBKQVIgYXJjaGl2ZSB0byBub3JtYWxpemUKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHJlYWRpbmcgb3Igd3JpdGluZyBmYWlscworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBub3JtYWxpemUoZmluYWwgRmlsZSBqYXIpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG5vcm1hbGl6ZShqYXIsIGphciwgbnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogTm9ybWFsaXplcyBhIEpBUiBhcmNoaXZlIGluLXBsYWNlIHNvIGl0IGNhbiBiZSBzYWZlbHkgc2lnbmVkCisgICAgICogYW5kIHBhY2tlZC4KKyAgICAgKgorICAgICAqIDxwPkFzIHN0YXRlZCBpbiA8YQorICAgICAqIGhyZWY9Imh0dHBzOi8vZG93bmxvYWQub3JhY2xlLmNvbS9qYXZhc2UvMS41LjAvZG9jcy9hcGkvamF2YS91dGlsL2phci9QYWNrMjAwLlBhY2tlci5odG1sIj5QYWNrMjAwLlBhY2tlcidzPC9hPgorICAgICAqIGphdmFkb2NzIGFwcGx5aW5nIGEgUGFjazIwMCBjb21wcmVzc2lvbiB0byBhIEpBUiBhcmNoaXZlIHdpbGwKKyAgICAgKiBpbiBnZW5lcmFsIG1ha2UgaXRzIHNpZ2FudHVyZXMgaW52YWxpZC4gIEluIG9yZGVyIHRvIHByZXBhcmUgYQorICAgICAqIEpBUiBmb3Igc2lnbmluZyBpdCBzaG91bGQgYmUgIm5vcm1hbGl6ZWQiIGJ5IHBhY2tpbmcgYW5kCisgICAgICogdW5wYWNraW5nIGl0LiAgVGhpcyBpcyB3aGF0IHRoaXMgbWV0aG9kIGRvZXMuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGphciB0aGUgSkFSIGFyY2hpdmUgdG8gbm9ybWFsaXplCisgICAgICogQHBhcmFtIHByb3BzIHByb3BlcnRpZXMgdG8gc2V0IGZvciB0aGUgcGFjayBvcGVyYXRpb24uICBUaGlzCisgICAgICogbWV0aG9kIHdpbGwgaW1wbGljaXRseSBzZXQgdGhlIHNlZ21lbnQgbGltaXQgdG8gLTEuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiByZWFkaW5nIG9yIHdyaXRpbmcgZmFpbHMKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgbm9ybWFsaXplKGZpbmFsIEZpbGUgamFyLCBmaW5hbCBNYXA8U3RyaW5nLCBTdHJpbmc+IHByb3BzKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBub3JtYWxpemUoamFyLCBqYXIsIHByb3BzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBOb3JtYWxpemVzIGEgSkFSIGFyY2hpdmUgc28gaXQgY2FuIGJlIHNhZmVseSBzaWduZWQgYW5kIHBhY2tlZC4KKyAgICAgKgorICAgICAqIDxwPkFzIHN0YXRlZCBpbiA8YQorICAgICAqIGhyZWY9Imh0dHBzOi8vZG93bmxvYWQub3JhY2xlLmNvbS9qYXZhc2UvMS41LjAvZG9jcy9hcGkvamF2YS91dGlsL2phci9QYWNrMjAwLlBhY2tlci5odG1sIj5QYWNrMjAwLlBhY2tlcidzPC9hPgorICAgICAqIGphdmFkb2NzIGFwcGx5aW5nIGEgUGFjazIwMCBjb21wcmVzc2lvbiB0byBhIEpBUiBhcmNoaXZlIHdpbGwKKyAgICAgKiBpbiBnZW5lcmFsIG1ha2UgaXRzIHNpZ2FudHVyZXMgaW52YWxpZC4gIEluIG9yZGVyIHRvIHByZXBhcmUgYQorICAgICAqIEpBUiBmb3Igc2lnbmluZyBpdCBzaG91bGQgYmUgIm5vcm1hbGl6ZWQiIGJ5IHBhY2tpbmcgYW5kCisgICAgICogdW5wYWNraW5nIGl0LiAgVGhpcyBpcyB3aGF0IHRoaXMgbWV0aG9kIGRvZXMuPC9wPgorICAgICAqCisgICAgICogPHA+VGhpcyBtZXRob2QgZG9lcyBub3QgcmVwbGFjZSB0aGUgZXhpc3RpbmcgYXJjaGl2ZSBidXQgY3JlYXRlcworICAgICAqIGEgbmV3IG9uZS48L3A+CisgICAgICoKKyAgICAgKiA8cD5Ob3RlIHRoaXMgbWV0aG9kcyBpbXBsaWNpdGx5IHNldHMgdGhlIHNlZ21lbnQgbGVuZ3RoIHRvCisgICAgICogLTEuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGZyb20gdGhlIEpBUiBhcmNoaXZlIHRvIG5vcm1hbGl6ZQorICAgICAqIEBwYXJhbSB0byB0aGUgbm9ybWFsaXplZCBhcmNoaXZlCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiByZWFkaW5nIG9yIHdyaXRpbmcgZmFpbHMKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgbm9ybWFsaXplKGZpbmFsIEZpbGUgZnJvbSwgZmluYWwgRmlsZSB0bykKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgbm9ybWFsaXplKGZyb20sIHRvLCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBOb3JtYWxpemVzIGEgSkFSIGFyY2hpdmUgc28gaXQgY2FuIGJlIHNhZmVseSBzaWduZWQgYW5kIHBhY2tlZC4KKyAgICAgKgorICAgICAqIDxwPkFzIHN0YXRlZCBpbiA8YQorICAgICAqIGhyZWY9Imh0dHBzOi8vZG93bmxvYWQub3JhY2xlLmNvbS9qYXZhc2UvMS41LjAvZG9jcy9hcGkvamF2YS91dGlsL2phci9QYWNrMjAwLlBhY2tlci5odG1sIj5QYWNrMjAwLlBhY2tlcidzPC9hPgorICAgICAqIGphdmFkb2NzIGFwcGx5aW5nIGEgUGFjazIwMCBjb21wcmVzc2lvbiB0byBhIEpBUiBhcmNoaXZlIHdpbGwKKyAgICAgKiBpbiBnZW5lcmFsIG1ha2UgaXRzIHNpZ2FudHVyZXMgaW52YWxpZC4gIEluIG9yZGVyIHRvIHByZXBhcmUgYQorICAgICAqIEpBUiBmb3Igc2lnbmluZyBpdCBzaG91bGQgYmUgIm5vcm1hbGl6ZWQiIGJ5IHBhY2tpbmcgYW5kCisgICAgICogdW5wYWNraW5nIGl0LiAgVGhpcyBpcyB3aGF0IHRoaXMgbWV0aG9kIGRvZXMuPC9wPgorICAgICAqCisgICAgICogPHA+VGhpcyBtZXRob2QgZG9lcyBub3QgcmVwbGFjZSB0aGUgZXhpc3RpbmcgYXJjaGl2ZSBidXQgY3JlYXRlcworICAgICAqIGEgbmV3IG9uZS48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gZnJvbSB0aGUgSkFSIGFyY2hpdmUgdG8gbm9ybWFsaXplCisgICAgICogQHBhcmFtIHRvIHRoZSBub3JtYWxpemVkIGFyY2hpdmUKKyAgICAgKiBAcGFyYW0gcHJvcHMgcHJvcGVydGllcyB0byBzZXQgZm9yIHRoZSBwYWNrIG9wZXJhdGlvbi4gIFRoaXMKKyAgICAgKiBtZXRob2Qgd2lsbCBpbXBsaWNpdGx5IHNldCB0aGUgc2VnbWVudCBsaW1pdCB0byAtMS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHJlYWRpbmcgb3Igd3JpdGluZyBmYWlscworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBub3JtYWxpemUoZmluYWwgRmlsZSBmcm9tLCBmaW5hbCBGaWxlIHRvLCBNYXA8U3RyaW5nLCBTdHJpbmc+IHByb3BzKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHByb3BzID09IG51bGwpIHsKKyAgICAgICAgICAgIHByb3BzID0gbmV3IEhhc2hNYXA8PigpOworICAgICAgICB9CisgICAgICAgIHByb3BzLnB1dChQYWNrMjAwLlBhY2tlci5TRUdNRU5UX0xJTUlULCAiLTEiKTsKKyAgICAgICAgZmluYWwgRmlsZSB0ZW1wRmlsZSA9IEZpbGUuY3JlYXRlVGVtcEZpbGUoImNvbW1vbnMtY29tcHJlc3MiLCAicGFjazIwMG5vcm1hbGl6ZSIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdHJ5IChGaWxlT3V0cHV0U3RyZWFtIGZvcyA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKHRlbXBGaWxlKTsKKyAgICAgICAgICAgICAgICAgICAgSmFyRmlsZSBqYXJGaWxlID0gbmV3IEphckZpbGUoZnJvbSkpIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBQYWNrMjAwLlBhY2tlciBwYWNrZXIgPSBQYWNrMjAwLm5ld1BhY2tlcigpOworICAgICAgICAgICAgICAgIHBhY2tlci5wcm9wZXJ0aWVzKCkucHV0QWxsKHByb3BzKTsKKyAgICAgICAgICAgICAgICBwYWNrZXIucGFjayhqYXJGaWxlLCBmb3MpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZmluYWwgUGFjazIwMC5VbnBhY2tlciB1bnBhY2tlciA9IFBhY2syMDAubmV3VW5wYWNrZXIoKTsKKyAgICAgICAgICAgIHRyeSAoSmFyT3V0cHV0U3RyZWFtIGpvcyA9IG5ldyBKYXJPdXRwdXRTdHJlYW0obmV3IEZpbGVPdXRwdXRTdHJlYW0odG8pKSkgeworICAgICAgICAgICAgICAgIHVucGFja2VyLnVucGFjayh0ZW1wRmlsZSwgam9zKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmICghdGVtcEZpbGUuZGVsZXRlKCkpIHsKKyAgICAgICAgICAgICAgICB0ZW1wRmlsZS5kZWxldGVPbkV4aXQoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL3BhY2syMDAvU3RyZWFtQnJpZGdlLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9wYWNrMjAwL1N0cmVhbUJyaWRnZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjlkZTM1NjcKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9wYWNrMjAwL1N0cmVhbUJyaWRnZS5qYXZhCkBAIC0wLDAgKzEsNzUgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5wYWNrMjAwOworCitpbXBvcnQgamF2YS5pby5GaWx0ZXJPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworCisvKioKKyAqIFByb3ZpZGVzIGFuIElucHV0U3RyZWFtIHRvIHJlYWQgYWxsIGRhdGEgd3JpdHRlbiB0byB0aGlzCisgKiBPdXRwdXRTdHJlYW0uCisgKgorICogQFRocmVhZFNhZmUKKyAqIEBzaW5jZSAxLjMKKyAqLworYWJzdHJhY3QgY2xhc3MgU3RyZWFtQnJpZGdlIGV4dGVuZHMgRmlsdGVyT3V0cHV0U3RyZWFtIHsKKyAgICBwcml2YXRlIElucHV0U3RyZWFtIGlucHV0OworICAgIHByaXZhdGUgZmluYWwgT2JqZWN0IGlucHV0TG9jayA9IG5ldyBPYmplY3QoKTsKKworICAgIHByb3RlY3RlZCBTdHJlYW1CcmlkZ2UoZmluYWwgT3V0cHV0U3RyZWFtIG91dCkgeworICAgICAgICBzdXBlcihvdXQpOworICAgIH0KKworICAgIHByb3RlY3RlZCBTdHJlYW1CcmlkZ2UoKSB7CisgICAgICAgIHRoaXMobnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJvdmlkZXMgdGhlIGlucHV0IHZpZXcuCisgICAgICovCisgICAgSW5wdXRTdHJlYW0gZ2V0SW5wdXQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzeW5jaHJvbml6ZWQgKGlucHV0TG9jaykgeworICAgICAgICAgICAgaWYgKGlucHV0ID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBpbnB1dCA9IGdldElucHV0VmlldygpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBpbnB1dDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIHRoZSBpbnB1dCB2aWV3LgorICAgICAqLworICAgIGFic3RyYWN0IElucHV0U3RyZWFtIGdldElucHV0VmlldygpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIENsb3NlcyBpbnB1dCBhbmQgb3V0cHV0IGFuZCByZWxlYXNlcyBhbGwgYXNzb2NpYXRlZCByZXNvdXJjZXMuCisgICAgICovCisgICAgdm9pZCBzdG9wKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY2xvc2UoKTsKKyAgICAgICAgc3luY2hyb25pemVkIChpbnB1dExvY2spIHsKKyAgICAgICAgICAgIGlmIChpbnB1dCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgaW5wdXQuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICBpbnB1dCA9IG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9wYWNrMjAwL1RlbXBGaWxlQ2FjaGluZ1N0cmVhbUJyaWRnZS5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvcGFjazIwMC9UZW1wRmlsZUNhY2hpbmdTdHJlYW1CcmlkZ2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yN2VkMjExCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvcGFjazIwMC9UZW1wRmlsZUNhY2hpbmdTdHJlYW1CcmlkZ2UuamF2YQpAQCAtMCwwICsxLDU2IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMucGFjazIwMDsKKworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbHRlcklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLm5pby5maWxlLkZpbGVzOworCisvKioKKyAqIFN0cmVhbVN3aXRjaGVyIHRoYXQgY2FjaGVzIGFsbCBkYXRhIHdyaXR0ZW4gdG8gdGhlIG91dHB1dCBzaWRlIGluCisgKiBhIHRlbXBvcmFyeSBmaWxlLgorICogQHNpbmNlIDEuMworICovCitjbGFzcyBUZW1wRmlsZUNhY2hpbmdTdHJlYW1CcmlkZ2UgZXh0ZW5kcyBTdHJlYW1CcmlkZ2UgeworICAgIHByaXZhdGUgZmluYWwgRmlsZSBmOworCisgICAgVGVtcEZpbGVDYWNoaW5nU3RyZWFtQnJpZGdlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZiA9IEZpbGUuY3JlYXRlVGVtcEZpbGUoImNvbW1vbnMtY29tcHJlc3MiLCAicGFja3RlbXAiKTsKKyAgICAgICAgZi5kZWxldGVPbkV4aXQoKTsKKyAgICAgICAgb3V0ID0gRmlsZXMubmV3T3V0cHV0U3RyZWFtKGYudG9QYXRoKCkpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIElucHV0U3RyZWFtIGdldElucHV0VmlldygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICByZXR1cm4gbmV3IEZpbHRlcklucHV0U3RyZWFtKEZpbGVzLm5ld0lucHV0U3RyZWFtKGYudG9QYXRoKCkpKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBzdXBlci5jbG9zZSgpOworICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgICAgIGYuZGVsZXRlKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9OworICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL3BhY2syMDAvcGFja2FnZS5odG1sIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvcGFjazIwMC9wYWNrYWdlLmh0bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWRiZjJhMAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL3BhY2syMDAvcGFja2FnZS5odG1sCkBAIC0wLDAgKzEsODIgQEAKKzxodG1sPgorPCEtLQorCisgICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAgIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAgICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorCisgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisKKyAgIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAgIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAgIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAgIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorCistLT4KKyAgPGJvZHk+CisgICAgPHA+UHJvdmlkZXMgc3RyZWFtIGNsYXNzZXMgZm9yIGNvbXByZXNzaW5nIGFuZCBkZWNvbXByZXNzaW5nCisgICAgICBzdHJlYW1zIHVzaW5nIHRoZSBQYWNrMjAwIGFsZ29yaXRobSB1c2VkIHRvIGNvbXByZXNzIEphdmEKKyAgICAgIGFyY2hpdmVzLjwvcD4KKworICAgIDxwPlRoZSBzdHJlYW1zIG9mIHRoaXMgcGFja2FnZSBvbmx5IHdvcmsgb24gSkFSIGFyY2hpdmVzLCBpLmUuIGEKKyAgICAgIHtAbGluaworICAgICAgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLnBhY2syMDAuUGFjazIwMENvbXByZXNzb3JPdXRwdXRTdHJlYW0KKyAgICAgIFBhY2syMDBDb21wcmVzc29yT3V0cHV0U3RyZWFtfSBleHBlY3RzIHRvIGJlIHdyYXBwZWQgYXJvdW5kIGEKKyAgICAgIHN0cmVhbSB0aGF0IGEgdmFsaWQgSkFSIGFyY2hpdmUgd2lsbCBiZSB3cml0dGVuIHRvIGFuZCBhIHtAbGluaworICAgICAgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLnBhY2syMDAuUGFjazIwMENvbXByZXNzb3JJbnB1dFN0cmVhbQorICAgICAgUGFjazIwMENvbXByZXNzb3JJbnB1dFN0cmVhbX0gcHJvdmlkZXMgYSBzdHJlYW0gdG8gcmVhZCBmcm9tIGEKKyAgICAgIEpBUiBhcmNoaXZlLjwvcD4KKworICAgIDxwPkpBUiBhcmNoaXZlcyBjb21wcmVzc2VkIHdpdGggUGFjazIwMCB3aWxsIGluIGdlbmVyYWwgYmUKKyAgICAgIGRpZmZlcmVudCBmcm9tIHRoZSBvcmlnaW5hbCBhcmNoaXZlIHdoZW4gZGVjb21wcmVzc2VkIGFnYWluLgorICAgICAgRm9yIGRldGFpbHMgc2VlCisgICAgICB0aGUgPGEgaHJlZj0iaHR0cHM6Ly9kb3dubG9hZC5vcmFjbGUuY29tL2phdmFzZS8xLjUuMC9kb2NzL2FwaS9qYXZhL3V0aWwvamFyL1BhY2syMDAuaHRtbCI+QVBJCisgICAgICBkb2N1bWVudGF0aW9uIG9mIFBhY2syMDA8L2E+LjwvcD4KKworICAgIDxwPlRoZSBzdHJlYW1zIG9mIHRoaXMgcGFja2FnZSB3b3JrIG9uIG5vbi1kZWZsYXRlZCBzdHJlYW1zLAorICAgICAgaS5lLiBhcmNoaXZlcyBsaWtlIHRob3NlIGNyZWF0ZWQgd2l0aCB0aGUgPGNvZGU+LS1uby1nemlwPC9jb2RlPgorICAgICAgb3B0aW9uIG9mIHRoZSBKREsncyA8Y29kZT5wYWNrMjAwPC9jb2RlPiBjb21tYW5kIGxpbmUgdG9vbC4gIElmCisgICAgICB5b3Ugd2FudCB0byB3b3JrIG9uIGRlZmxhdGVkIHN0cmVhbXMgeW91IG11c3QgdXNlIGFuIGFkZGl0aW9uYWwKKyAgICAgIHN0cmVhbSBsYXllciAtIGZvciBleGFtcGxlIGJ5IHVzaW5nIEFwYWNoZSBDb21tb25zIENvbXByZXNzJworICAgICAgZ3ppcCBwYWNrYWdlLjwvcD4KKworICAgIDxwPlRoZSBQYWNrMjAwIEFQSSBwcm92aWRlZCBieSB0aGUgSmF2YSBjbGFzcyBsaWJyYXJ5IGRvZXNuJ3QgbGVuZAorICAgICAgaXRzZWxmIHRvIHJlYWwgc3RyZWFtCisgICAgICBwcm9jZXNzaW5nLiAgPGNvZGU+UGFjazIwMENvbXByZXNzb3JJbnB1dFN0cmVhbTwvY29kZT4gd2lsbAorICAgICAgdW5jb21wcmVzcyBpdHMgaW5wdXQgaW1tZWRpYXRlbHkgYW5kIHRoZW4gcHJvdmlkZQorICAgICAgYW4gPGNvZGU+SW5wdXRTdHJlYW08L2NvZGU+IHRvIGEgY2FjaGVkIHJlc3VsdC4KKyAgICAgIExpa2V3aXNlIDxjb2RlPlBhY2syMDBDb21wcmVzc29yT3V0cHV0U3RyZWFtPC9jb2RlPiB3aWxsIG5vdAorICAgICAgd3JpdGUgYW55dGhpbmcgdG8gdGhlIGdpdmVuIE91dHB1dFN0cmVhbQorICAgICAgdW50aWwgPGNvZGU+ZmluaXNoPC9jb2RlPiBvciA8Y29kZT5jbG9zZTwvY29kZT4gaXMgY2FsbGVkIC0gYXQKKyAgICAgIHdoaWNoIHBvaW50IHRoZSBjYWNoZWQgb3V0cHV0IHdyaXR0ZW4gc28gZmFyIGdldHMKKyAgICAgIGNvbXByZXNzZWQuPC9wPgorCisgICAgPHA+VHdvIGRpZmZlcmVudCBjYWNoaW5nIG1vZGVzIGFyZSBhdmFpbGFibGUgLSAiaW4gbWVtb3J5Iiwgd2hpY2gKKyAgICAgIGlzIHRoZSBkZWZhdWx0LCBhbmQgInRlbXBvcmFyeSBmaWxlIi4gIEJ5IGRlZmF1bHQgZGF0YSBpcyBjYWNoZWQKKyAgICAgIGluIG1lbW9yeSBidXQgeW91IHNob3VsZCBzd2l0Y2ggdG8gdGhlIHRlbXBvcmFyeSBmaWxlIG9wdGlvbiBpZgorICAgICAgeW91ciBhcmNoaXZlcyBhcmUgcmVhbGx5IGJpZy48L3A+CisKKyAgICA8cD5HaXZlbiB0aGVyZSBhbHdheXMgaXMgYW4gaW50ZXJtZWRpYXRlIHJlc3VsdAorICAgICAgdGhlIDxjb2RlPmdldEJ5dGVzUmVhZDwvY29kZT4gYW5kIDxjb2RlPmdldENvdW50PC9jb2RlPiBtZXRob2RzCisgICAgICBvZiA8Y29kZT5QYWNrMjAwQ29tcHJlc3NvcklucHV0U3RyZWFtPC9jb2RlPiBhcmUgbWVhbmluZ2xlc3MKKyAgICAgIChyZWFkIGZyb20gdGhlIHJlYWwgc3RyZWFtIG9yIGZyb20gdGhlIGludGVybWVkaWF0ZSByZXN1bHQ/KQorICAgICAgYW5kIGFsd2F5cyByZXR1cm4gMC48L3A+CisKKyAgICA8cD5EdXJpbmcgZGV2ZWxvcG1lbnQgb2YgdGhlIGluaXRpYWwgdmVyc2lvbiBzZXZlcmFsIGF0dGVtcHRzIGhhdmUKKyAgICAgIGJlZW4gbWFkZSB0byB1c2UgYSByZWFsIHN0cmVhbWluZyBBUEkgYmFzZWQgZm9yIGV4YW1wbGUKKyAgICAgIG9uIDxjb2RlPlBpcGVkKElufE91dClwdXRTdHJlYW08L2NvZGU+IG9yIGV4cGxpY2l0IHN0cmVhbQorICAgICAgcHVtcGluZyBsaWtlIENvbW1vbnMgRXhlYydzIDxjb2RlPklucHV0U3RyZWFtUHVtcGVyPC9jb2RlPiBidXQKKyAgICAgIHRoZXkgaGF2ZSBhbGwgZmFpbGVkIGJlY2F1c2UgdGhleSByZWx5IG9uIHRoZSBvdXRwdXQgZW5kIHRvIGJlCisgICAgICBjb25zdW1lZCBjb21wbGV0ZWx5IG9yIGVsc2UgdGhlIDxjb2RlPih1bilwYWNrPC9jb2RlPiB3aWxsIGJsb2NrCisgICAgICBmb3JldmVyLiAgRXNwZWNpYWxseSBmb3IgPGNvZGU+UGFjazIwMElucHV0U3RyZWFtPC9jb2RlPiBpdCBpcworICAgICAgdmVyeSBsaWtlbHkgdGhhdCBpdCB3aWxsIGJlIHdyYXBwZWQgaW4KKyAgICAgIGEgPGNvZGU+WmlwQXJjaGl2ZUlucHV0U3RyZWFtPC9jb2RlPiB3aGljaCB3aWxsIG5ldmVyIHJlYWQgdGhlCisgICAgICBhcmNoaXZlIGNvbXBsZXRlbHkgYXMgaXQgaXMgbm90IGludGVyZXN0ZWQgaW4gdGhlIFpJUCBjZW50cmFsCisgICAgICBkaXJlY3RvcnkgZGF0YSBhdCB0aGUgZW5kIG9mIHRoZSBKQVIgYXJjaGl2ZS48L3A+CisKKyAgPC9ib2R5PgorPC9odG1sPgpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvcGFja2FnZS5odG1sIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvcGFja2FnZS5odG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdiN2Q1MDQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9wYWNrYWdlLmh0bWwKQEAgLTAsMCArMSwyNCBAQAorPGh0bWw+Cis8IS0tCisKKyAgIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAgIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisKKyAgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKworICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAgIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisKKy0tPgorICA8Ym9keT4KKyAgICA8cD5Qcm92aWRlcyBhIHVuaWZpZWQgQVBJIGFuZCBmYWN0b3JpZXMgZm9yIGRlYWxpbmcgd2l0aAorICAgICAgY29tcHJlc3NlZCBzdHJlYW1zLjwvcD4KKyAgPC9ib2R5PgorPC9odG1sPgpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvc25hcHB5L0ZyYW1lZFNuYXBweUNvbXByZXNzb3JJbnB1dFN0cmVhbS5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvc25hcHB5L0ZyYW1lZFNuYXBweUNvbXByZXNzb3JJbnB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY2ZGMzMGMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9zbmFwcHkvRnJhbWVkU25hcHB5Q29tcHJlc3NvcklucHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwzNTAgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuc25hcHB5OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uUHVzaGJhY2tJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLkNvbXByZXNzb3JJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuQm91bmRlZElucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5CeXRlVXRpbHM7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLkNvdW50aW5nSW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLklPVXRpbHM7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLklucHV0U3RyZWFtU3RhdGlzdGljczsKKworLyoqCisgKiBDb21wcmVzc29ySW5wdXRTdHJlYW0gZm9yIHRoZSBmcmFtaW5nIFNuYXBweSBmb3JtYXQuCisgKgorICogPHA+QmFzZWQgb24gdGhlICJzcGVjIiBpbiB0aGUgdmVyc2lvbiAiTGFzdCByZXZpc2VkOiAyMDEzLTEwLTI1IjwvcD4KKyAqCisgKiBAc2VlIDxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvc25hcHB5L2Jsb2IvbWFzdGVyL2ZyYW1pbmdfZm9ybWF0LnR4dCI+U25hcHB5IGZyYW1pbmcgZm9ybWF0IGRlc2NyaXB0aW9uPC9hPgorICogQHNpbmNlIDEuNworICovCitwdWJsaWMgY2xhc3MgRnJhbWVkU25hcHB5Q29tcHJlc3NvcklucHV0U3RyZWFtIGV4dGVuZHMgQ29tcHJlc3NvcklucHV0U3RyZWFtCisgICAgaW1wbGVtZW50cyBJbnB1dFN0cmVhbVN0YXRpc3RpY3MgeworCisgICAgLyoqCisgICAgICogcGFja2FnZSBwcml2YXRlIGZvciB0ZXN0cyBvbmx5LgorICAgICAqLworICAgIHN0YXRpYyBmaW5hbCBsb25nIE1BU0tfT0ZGU0VUID0gMHhhMjgyZWFkOEw7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgU1RSRUFNX0lERU5USUZJRVJfVFlQRSA9IDB4ZmY7CisgICAgc3RhdGljIGZpbmFsIGludCBDT01QUkVTU0VEX0NIVU5LX1RZUEUgPSAwOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBVTkNPTVBSRVNTRURfQ0hVTktfVFlQRSA9IDE7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFBBRERJTkdfQ0hVTktfVFlQRSA9IDB4ZmU7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE1JTl9VTlNLSVBQQUJMRV9UWVBFID0gMjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTUFYX1VOU0tJUFBBQkxFX1RZUEUgPSAweDdmOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNQVhfU0tJUFBBQkxFX1RZUEUgPSAweGZkOworCisgICAgLy8gdXNlZCBieSBGcmFtZWRTbmFwcHlDb21wcmVzc29yT3V0cHV0U3RyZWFtIGFzIHdlbGwKKyAgICBzdGF0aWMgZmluYWwgYnl0ZVtdIFNaX1NJR05BVFVSRSA9IG5ldyBieXRlW10geyAvL05PU09OQVIKKyAgICAgICAgKGJ5dGUpIFNUUkVBTV9JREVOVElGSUVSX1RZUEUsIC8vIHRhZworICAgICAgICA2LCAwLCAwLCAvLyBsZW5ndGgKKyAgICAgICAgJ3MnLCAnTicsICdhJywgJ1AnLCAncCcsICdZJworICAgIH07CisKKyAgICBwcml2YXRlIGxvbmcgdW5yZWFkQnl0ZXM7CisgICAgcHJpdmF0ZSBmaW5hbCBDb3VudGluZ0lucHV0U3RyZWFtIGNvdW50aW5nU3RyZWFtOworCisgICAgLyoqIFRoZSB1bmRlcmx5aW5nIHN0cmVhbSB0byByZWFkIGNvbXByZXNzZWQgZGF0YSBmcm9tICovCisgICAgcHJpdmF0ZSBmaW5hbCBQdXNoYmFja0lucHV0U3RyZWFtIGluOworCisgICAgLyoqIFRoZSBkaWFsZWN0IHRvIGV4cGVjdCAqLworICAgIHByaXZhdGUgZmluYWwgRnJhbWVkU25hcHB5RGlhbGVjdCBkaWFsZWN0OworCisgICAgcHJpdmF0ZSBTbmFwcHlDb21wcmVzc29ySW5wdXRTdHJlYW0gY3VycmVudENvbXByZXNzZWRDaHVuazsKKworICAgIC8vIHVzZWQgaW4gbm8tYXJnIHJlYWQgbWV0aG9kCisgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10gb25lQnl0ZSA9IG5ldyBieXRlWzFdOworCisgICAgcHJpdmF0ZSBib29sZWFuIGVuZFJlYWNoZWQsIGluVW5jb21wcmVzc2VkQ2h1bms7CisKKyAgICBwcml2YXRlIGludCB1bmNvbXByZXNzZWRCeXRlc1JlbWFpbmluZzsKKyAgICBwcml2YXRlIGxvbmcgZXhwZWN0ZWRDaGVja3N1bSA9IC0xOworICAgIHByaXZhdGUgZmluYWwgaW50IGJsb2NrU2l6ZTsKKyAgICBwcml2YXRlIGZpbmFsIFB1cmVKYXZhQ3JjMzJDIGNoZWNrc3VtID0gbmV3IFB1cmVKYXZhQ3JjMzJDKCk7CisKKyAgICBwcml2YXRlIGZpbmFsIEJ5dGVVdGlscy5CeXRlU3VwcGxpZXIgc3VwcGxpZXIgPSBuZXcgQnl0ZVV0aWxzLkJ5dGVTdXBwbGllcigpIHsKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBpbnQgZ2V0QXNCeXRlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiByZWFkT25lQnl0ZSgpOworICAgICAgICB9CisgICAgfTsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5wdXQgc3RyZWFtIHRoYXQgZGVjb21wcmVzc2VzCisgICAgICogc25hcHB5LWZyYW1lZC1jb21wcmVzc2VkIGRhdGEgZnJvbSB0aGUgc3BlY2lmaWVkIGlucHV0IHN0cmVhbQorICAgICAqIHVzaW5nIHRoZSB7QGxpbmsgRnJhbWVkU25hcHB5RGlhbGVjdCNTVEFOREFSRH0gZGlhbGVjdC4KKyAgICAgKiBAcGFyYW0gaW4gIHRoZSBJbnB1dFN0cmVhbSBmcm9tIHdoaWNoIHRvIHJlYWQgdGhlIGNvbXByZXNzZWQgZGF0YQorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgcmVhZGluZyBmYWlscworICAgICAqLworICAgIHB1YmxpYyBGcmFtZWRTbmFwcHlDb21wcmVzc29ySW5wdXRTdHJlYW0oZmluYWwgSW5wdXRTdHJlYW0gaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMoaW4sIEZyYW1lZFNuYXBweURpYWxlY3QuU1RBTkRBUkQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5wdXQgc3RyZWFtIHRoYXQgZGVjb21wcmVzc2VzIHNuYXBweS1mcmFtZWQtY29tcHJlc3NlZCBkYXRhCisgICAgICogZnJvbSB0aGUgc3BlY2lmaWVkIGlucHV0IHN0cmVhbS4KKyAgICAgKiBAcGFyYW0gaW4gIHRoZSBJbnB1dFN0cmVhbSBmcm9tIHdoaWNoIHRvIHJlYWQgdGhlIGNvbXByZXNzZWQgZGF0YQorICAgICAqIEBwYXJhbSBkaWFsZWN0IHRoZSBkaWFsZWN0IHVzZWQgYnkgdGhlIGNvbXByZXNzZWQgc3RyZWFtCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiByZWFkaW5nIGZhaWxzCisgICAgICovCisgICAgcHVibGljIEZyYW1lZFNuYXBweUNvbXByZXNzb3JJbnB1dFN0cmVhbShmaW5hbCBJbnB1dFN0cmVhbSBpbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEZyYW1lZFNuYXBweURpYWxlY3QgZGlhbGVjdCkKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcyhpbiwgU25hcHB5Q29tcHJlc3NvcklucHV0U3RyZWFtLkRFRkFVTFRfQkxPQ0tfU0laRSwgZGlhbGVjdCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnB1dCBzdHJlYW0gdGhhdCBkZWNvbXByZXNzZXMgc25hcHB5LWZyYW1lZC1jb21wcmVzc2VkIGRhdGEKKyAgICAgKiBmcm9tIHRoZSBzcGVjaWZpZWQgaW5wdXQgc3RyZWFtLgorICAgICAqIEBwYXJhbSBpbiAgdGhlIElucHV0U3RyZWFtIGZyb20gd2hpY2ggdG8gcmVhZCB0aGUgY29tcHJlc3NlZCBkYXRhCisgICAgICogQHBhcmFtIGJsb2NrU2l6ZSB0aGUgYmxvY2sgc2l6ZSB0byB1c2UgZm9yIHRoZSBjb21wcmVzc2VkIHN0cmVhbQorICAgICAqIEBwYXJhbSBkaWFsZWN0IHRoZSBkaWFsZWN0IHVzZWQgYnkgdGhlIGNvbXByZXNzZWQgc3RyZWFtCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiByZWFkaW5nIGZhaWxzCisgICAgICogQHNpbmNlIDEuMTQKKyAgICAgKi8KKyAgICBwdWJsaWMgRnJhbWVkU25hcHB5Q29tcHJlc3NvcklucHV0U3RyZWFtKGZpbmFsIElucHV0U3RyZWFtIGluLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGJsb2NrU2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEZyYW1lZFNuYXBweURpYWxlY3QgZGlhbGVjdCkKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY291bnRpbmdTdHJlYW0gPSBuZXcgQ291bnRpbmdJbnB1dFN0cmVhbShpbik7CisgICAgICAgIHRoaXMuaW4gPSBuZXcgUHVzaGJhY2tJbnB1dFN0cmVhbShjb3VudGluZ1N0cmVhbSwgMSk7CisgICAgICAgIHRoaXMuYmxvY2tTaXplID0gYmxvY2tTaXplOworICAgICAgICB0aGlzLmRpYWxlY3QgPSBkaWFsZWN0OworICAgICAgICBpZiAoZGlhbGVjdC5oYXNTdHJlYW1JZGVudGlmaWVyKCkpIHsKKyAgICAgICAgICAgIHJlYWRTdHJlYW1JZGVudGlmaWVyKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioge0Bpbmhlcml0RG9jfSAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiByZWFkKG9uZUJ5dGUsIDAsIDEpID09IC0xID8gLTEgOiBvbmVCeXRlWzBdICYgMHhGRjsKKyAgICB9CisKKyAgICAvKioge0Bpbmhlcml0RG9jfSAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlmIChjdXJyZW50Q29tcHJlc3NlZENodW5rICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBjdXJyZW50Q29tcHJlc3NlZENodW5rLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgY3VycmVudENvbXByZXNzZWRDaHVuayA9IG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqIHtAaW5oZXJpdERvY30gKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHJlYWQoZmluYWwgYnl0ZVtdIGIsIGZpbmFsIGludCBvZmYsIGZpbmFsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCByZWFkID0gcmVhZE9uY2UoYiwgb2ZmLCBsZW4pOworICAgICAgICBpZiAocmVhZCA9PSAtMSkgeworICAgICAgICAgICAgcmVhZE5leHRCbG9jaygpOworICAgICAgICAgICAgaWYgKGVuZFJlYWNoZWQpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZWFkID0gcmVhZE9uY2UoYiwgb2ZmLCBsZW4pOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZWFkOworICAgIH0KKworICAgIC8qKiB7QGluaGVyaXREb2N9ICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBhdmFpbGFibGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoaW5VbmNvbXByZXNzZWRDaHVuaykgeworICAgICAgICAgICAgcmV0dXJuIE1hdGgubWluKHVuY29tcHJlc3NlZEJ5dGVzUmVtYWluaW5nLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluLmF2YWlsYWJsZSgpKTsKKyAgICAgICAgfSBlbHNlIGlmIChjdXJyZW50Q29tcHJlc3NlZENodW5rICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBjdXJyZW50Q29tcHJlc3NlZENodW5rLmF2YWlsYWJsZSgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzaW5jZSAxLjE3CisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGxvbmcgZ2V0Q29tcHJlc3NlZENvdW50KCkgeworICAgICAgICByZXR1cm4gY291bnRpbmdTdHJlYW0uZ2V0Qnl0ZXNSZWFkKCkgLSB1bnJlYWRCeXRlczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkIGZyb20gdGhlIGN1cnJlbnQgY2h1bmsgaW50byB0aGUgZ2l2ZW4gYXJyYXkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIC0xIGlmIHRoZXJlIGlzIG5vIGN1cnJlbnQgY2h1bmsgb3IgdGhlIG51bWJlciBvZiBieXRlcworICAgICAqIHJlYWQgZnJvbSB0aGUgY3VycmVudCBjaHVuayAod2hpY2ggbWF5IGJlIC0xIGlmIHRoZSBlbmQgb2YgdGhlCisgICAgICogY2h1bmsgaXMgcmVhY2hlZCkuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgcmVhZE9uY2UoZmluYWwgYnl0ZVtdIGIsIGZpbmFsIGludCBvZmYsIGZpbmFsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCByZWFkID0gLTE7CisgICAgICAgIGlmIChpblVuY29tcHJlc3NlZENodW5rKSB7CisgICAgICAgICAgICBmaW5hbCBpbnQgYW1vdW50ID0gTWF0aC5taW4odW5jb21wcmVzc2VkQnl0ZXNSZW1haW5pbmcsIGxlbik7CisgICAgICAgICAgICBpZiAoYW1vdW50ID09IDApIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZWFkID0gaW4ucmVhZChiLCBvZmYsIGFtb3VudCk7CisgICAgICAgICAgICBpZiAocmVhZCAhPSAtMSkgeworICAgICAgICAgICAgICAgIHVuY29tcHJlc3NlZEJ5dGVzUmVtYWluaW5nIC09IHJlYWQ7CisgICAgICAgICAgICAgICAgY291bnQocmVhZCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSBpZiAoY3VycmVudENvbXByZXNzZWRDaHVuayAhPSBudWxsKSB7CisgICAgICAgICAgICBmaW5hbCBsb25nIGJlZm9yZSA9IGN1cnJlbnRDb21wcmVzc2VkQ2h1bmsuZ2V0Qnl0ZXNSZWFkKCk7CisgICAgICAgICAgICByZWFkID0gY3VycmVudENvbXByZXNzZWRDaHVuay5yZWFkKGIsIG9mZiwgbGVuKTsKKyAgICAgICAgICAgIGlmIChyZWFkID09IC0xKSB7CisgICAgICAgICAgICAgICAgY3VycmVudENvbXByZXNzZWRDaHVuay5jbG9zZSgpOworICAgICAgICAgICAgICAgIGN1cnJlbnRDb21wcmVzc2VkQ2h1bmsgPSBudWxsOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBjb3VudChjdXJyZW50Q29tcHJlc3NlZENodW5rLmdldEJ5dGVzUmVhZCgpIC0gYmVmb3JlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAocmVhZCA+IDApIHsKKyAgICAgICAgICAgIGNoZWNrc3VtLnVwZGF0ZShiLCBvZmYsIHJlYWQpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZWFkOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByZWFkTmV4dEJsb2NrKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdmVyaWZ5TGFzdENoZWNrc3VtQW5kUmVzZXQoKTsKKyAgICAgICAgaW5VbmNvbXByZXNzZWRDaHVuayA9IGZhbHNlOworICAgICAgICBmaW5hbCBpbnQgdHlwZSA9IHJlYWRPbmVCeXRlKCk7CisgICAgICAgIGlmICh0eXBlID09IC0xKSB7CisgICAgICAgICAgICBlbmRSZWFjaGVkID0gdHJ1ZTsKKyAgICAgICAgfSBlbHNlIGlmICh0eXBlID09IFNUUkVBTV9JREVOVElGSUVSX1RZUEUpIHsKKyAgICAgICAgICAgIGluLnVucmVhZCh0eXBlKTsKKyAgICAgICAgICAgIHVucmVhZEJ5dGVzKys7CisgICAgICAgICAgICBwdXNoZWRCYWNrQnl0ZXMoMSk7CisgICAgICAgICAgICByZWFkU3RyZWFtSWRlbnRpZmllcigpOworICAgICAgICAgICAgcmVhZE5leHRCbG9jaygpOworICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gUEFERElOR19DSFVOS19UWVBFCisgICAgICAgICAgICAgICAgICAgfHwgKHR5cGUgPiBNQVhfVU5TS0lQUEFCTEVfVFlQRSAmJiB0eXBlIDw9IE1BWF9TS0lQUEFCTEVfVFlQRSkpIHsKKyAgICAgICAgICAgIHNraXBCbG9jaygpOworICAgICAgICAgICAgcmVhZE5leHRCbG9jaygpOworICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPj0gTUlOX1VOU0tJUFBBQkxFX1RZUEUgJiYgdHlwZSA8PSBNQVhfVU5TS0lQUEFCTEVfVFlQRSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJ1bnNraXBwYWJsZSBjaHVuayB3aXRoIHR5cGUgIiArIHR5cGUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgKGhleCAiICsgSW50ZWdlci50b0hleFN0cmluZyh0eXBlKSArICIpIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiBkZXRlY3RlZC4iKTsKKyAgICAgICAgfSBlbHNlIGlmICh0eXBlID09IFVOQ09NUFJFU1NFRF9DSFVOS19UWVBFKSB7CisgICAgICAgICAgICBpblVuY29tcHJlc3NlZENodW5rID0gdHJ1ZTsKKyAgICAgICAgICAgIHVuY29tcHJlc3NlZEJ5dGVzUmVtYWluaW5nID0gcmVhZFNpemUoKSAtIDQgLyogQ1JDICovOworICAgICAgICAgICAgZXhwZWN0ZWRDaGVja3N1bSA9IHVubWFzayhyZWFkQ3JjKCkpOworICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gQ09NUFJFU1NFRF9DSFVOS19UWVBFKSB7CisgICAgICAgICAgICBmaW5hbCBib29sZWFuIGV4cGVjdENoZWNrc3VtID0gZGlhbGVjdC51c2VzQ2hlY2tzdW1XaXRoQ29tcHJlc3NlZENodW5rcygpOworICAgICAgICAgICAgZmluYWwgbG9uZyBzaXplID0gcmVhZFNpemUoKSAtIChleHBlY3RDaGVja3N1bSA/IDRMIDogMEwpOworICAgICAgICAgICAgaWYgKGV4cGVjdENoZWNrc3VtKSB7CisgICAgICAgICAgICAgICAgZXhwZWN0ZWRDaGVja3N1bSA9IHVubWFzayhyZWFkQ3JjKCkpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBleHBlY3RlZENoZWNrc3VtID0gLTE7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjdXJyZW50Q29tcHJlc3NlZENodW5rID0KKyAgICAgICAgICAgICAgICBuZXcgU25hcHB5Q29tcHJlc3NvcklucHV0U3RyZWFtKG5ldyBCb3VuZGVkSW5wdXRTdHJlYW0oaW4sIHNpemUpLCBibG9ja1NpemUpOworICAgICAgICAgICAgLy8gY29uc3RydWN0b3IgcmVhZHMgdW5jb21wcmVzc2VkIHNpemUKKyAgICAgICAgICAgIGNvdW50KGN1cnJlbnRDb21wcmVzc2VkQ2h1bmsuZ2V0Qnl0ZXNSZWFkKCkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gaW1wb3NzaWJsZSBhcyBhbGwgcG90ZW50aWFsIGJ5dGUgdmFsdWVzIGhhdmUgYmVlbiBjb3ZlcmVkCisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oInVua25vd24gY2h1bmsgdHlwZSAiICsgdHlwZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiBkZXRlY3RlZC4iKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgbG9uZyByZWFkQ3JjKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGIgPSBuZXcgYnl0ZVs0XTsKKyAgICAgICAgZmluYWwgaW50IHJlYWQgPSBJT1V0aWxzLnJlYWRGdWxseShpbiwgYik7CisgICAgICAgIGNvdW50KHJlYWQpOworICAgICAgICBpZiAocmVhZCAhPSA0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oInByZW1hdHVyZSBlbmQgb2Ygc3RyZWFtIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIEJ5dGVVdGlscy5mcm9tTGl0dGxlRW5kaWFuKGIpOworICAgIH0KKworICAgIHN0YXRpYyBsb25nIHVubWFzayhsb25nIHgpIHsKKyAgICAgICAgLy8gdWdseSwgbWF5YmUgd2Ugc2hvdWxkIGp1c3QgaGF2ZSB1c2VkIGludHMgYW5kIGRlYWwgd2l0aCB0aGUKKyAgICAgICAgLy8gb3ZlcmZsb3cKKyAgICAgICAgeCAtPSBNQVNLX09GRlNFVDsKKyAgICAgICAgeCAmPSAweGZmZmZGRkZGTDsKKyAgICAgICAgcmV0dXJuICgoeCA+PiAxNykgfCAoeCA8PCAxNSkpICYgMHhmZmZmRkZGRkw7CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnQgcmVhZFNpemUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gKGludCkgQnl0ZVV0aWxzLmZyb21MaXR0bGVFbmRpYW4oc3VwcGxpZXIsIDMpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBza2lwQmxvY2soKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBpbnQgc2l6ZSA9IHJlYWRTaXplKCk7CisgICAgICAgIGZpbmFsIGxvbmcgcmVhZCA9IElPVXRpbHMuc2tpcChpbiwgc2l6ZSk7CisgICAgICAgIGNvdW50KHJlYWQpOworICAgICAgICBpZiAocmVhZCAhPSBzaXplKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oInByZW1hdHVyZSBlbmQgb2Ygc3RyZWFtIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcmVhZFN0cmVhbUlkZW50aWZpZXIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBieXRlW10gYiA9IG5ldyBieXRlWzEwXTsKKyAgICAgICAgZmluYWwgaW50IHJlYWQgPSBJT1V0aWxzLnJlYWRGdWxseShpbiwgYik7CisgICAgICAgIGNvdW50KHJlYWQpOworICAgICAgICBpZiAoMTAgIT0gcmVhZCB8fCAhbWF0Y2hlcyhiLCAxMCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiTm90IGEgZnJhbWVkIFNuYXBweSBzdHJlYW0iKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgaW50IHJlYWRPbmVCeXRlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgaW50IGIgPSBpbi5yZWFkKCk7CisgICAgICAgIGlmIChiICE9IC0xKSB7CisgICAgICAgICAgICBjb3VudCgxKTsKKyAgICAgICAgICAgIHJldHVybiBiICYgMHhGRjsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHZlcmlmeUxhc3RDaGVja3N1bUFuZFJlc2V0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGV4cGVjdGVkQ2hlY2tzdW0gPj0gMCAmJiBleHBlY3RlZENoZWNrc3VtICE9IGNoZWNrc3VtLmdldFZhbHVlKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiQ2hlY2tzdW0gdmVyaWZpY2F0aW9uIGZhaWxlZCIpOworICAgICAgICB9CisgICAgICAgIGV4cGVjdGVkQ2hlY2tzdW0gPSAtMTsKKyAgICAgICAgY2hlY2tzdW0ucmVzZXQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgaWYgdGhlIHNpZ25hdHVyZSBtYXRjaGVzIHdoYXQgaXMgZXhwZWN0ZWQgZm9yIGEgLnN6IGZpbGUuCisgICAgICoKKyAgICAgKiA8cD4uc3ogZmlsZXMgc3RhcnQgd2l0aCBhIGNodW5rIHdpdGggdGFnIDB4ZmYgYW5kIGNvbnRlbnQgc05hUHBZLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzaWduYXR1cmUgdGhlIGJ5dGVzIHRvIGNoZWNrCisgICAgICogQHBhcmFtIGxlbmd0aCAgICB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRvIGNoZWNrCisgICAgICogQHJldHVybiAgICAgICAgICB0cnVlIGlmIHRoaXMgaXMgYSAuc3ogc3RyZWFtLCBmYWxzZSBvdGhlcndpc2UKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gbWF0Y2hlcyhmaW5hbCBieXRlW10gc2lnbmF0dXJlLCBmaW5hbCBpbnQgbGVuZ3RoKSB7CisKKyAgICAgICAgaWYgKGxlbmd0aCA8IFNaX1NJR05BVFVSRS5sZW5ndGgpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIGJ5dGVbXSBzaG9ydGVuZWRTaWcgPSBzaWduYXR1cmU7CisgICAgICAgIGlmIChzaWduYXR1cmUubGVuZ3RoID4gU1pfU0lHTkFUVVJFLmxlbmd0aCkgeworICAgICAgICAgICAgc2hvcnRlbmVkU2lnID0gbmV3IGJ5dGVbU1pfU0lHTkFUVVJFLmxlbmd0aF07CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHNpZ25hdHVyZSwgMCwgc2hvcnRlbmVkU2lnLCAwLCBTWl9TSUdOQVRVUkUubGVuZ3RoKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBBcnJheXMuZXF1YWxzKHNob3J0ZW5lZFNpZywgU1pfU0lHTkFUVVJFKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL3NuYXBweS9GcmFtZWRTbmFwcHlDb21wcmVzc29yT3V0cHV0U3RyZWFtLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9zbmFwcHkvRnJhbWVkU25hcHB5Q29tcHJlc3Nvck91dHB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ0NDliMjgKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9zbmFwcHkvRnJhbWVkU25hcHB5Q29tcHJlc3Nvck91dHB1dFN0cmVhbS5qYXZhCkBAIC0wLDAgKzEsMTU0IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLnNuYXBweTsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuQ29tcHJlc3Nvck91dHB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMubHo3N3N1cHBvcnQuUGFyYW1ldGVyczsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuQnl0ZVV0aWxzOworCisvKioKKyAqIENvbXByZXNzb3JPdXRwdXRTdHJlYW0gZm9yIHRoZSBmcmFtaW5nIFNuYXBweSBmb3JtYXQuCisgKgorICogPHA+QmFzZWQgb24gdGhlICJzcGVjIiBpbiB0aGUgdmVyc2lvbiAiTGFzdCByZXZpc2VkOiAyMDEzLTEwLTI1IjwvcD4KKyAqCisgKiBAc2VlIDxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvc25hcHB5L2Jsb2IvbWFzdGVyL2ZyYW1pbmdfZm9ybWF0LnR4dCI+U25hcHB5IGZyYW1pbmcgZm9ybWF0IGRlc2NyaXB0aW9uPC9hPgorICogQHNpbmNlIDEuMTQKKyAqIEBOb3RUaHJlYWRTYWZlCisgKi8KK3B1YmxpYyBjbGFzcyBGcmFtZWRTbmFwcHlDb21wcmVzc29yT3V0cHV0U3RyZWFtIGV4dGVuZHMgQ29tcHJlc3Nvck91dHB1dFN0cmVhbSB7CisgICAgLy8gc2VlIHNwZWM6CisgICAgLy8gPiBIb3dldmVyLCB3ZSBwbGFjZSBhbiBhZGRpdGlvbmFsIHJlc3RyaWN0aW9uIHRoYXQgdGhlIHVuY29tcHJlc3NlZCBkYXRhCisgICAgLy8gPiBpbiBhIGNodW5rIG11c3QgYmUgbm8gbG9uZ2VyIHRoYW4gNjU1MzYgYnl0ZXMuIFRoaXMgYWxsb3dzIGNvbnN1bWVycyB0bworICAgIC8vID4gZWFzaWx5IHVzZSBzbWFsbCBmaXhlZC1zaXplIGJ1ZmZlcnMuCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE1BWF9DT01QUkVTU0VEX0JVRkZFUl9TSVpFID0gMSA8PCAxNjsKKworICAgIHByaXZhdGUgZmluYWwgT3V0cHV0U3RyZWFtIG91dDsKKyAgICBwcml2YXRlIGZpbmFsIFBhcmFtZXRlcnMgcGFyYW1zOworICAgIHByaXZhdGUgZmluYWwgUHVyZUphdmFDcmMzMkMgY2hlY2tzdW0gPSBuZXcgUHVyZUphdmFDcmMzMkMoKTsKKyAgICAvLyB1c2VkIGluIG9uZS1hcmcgd3JpdGUgbWV0aG9kCisgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10gb25lQnl0ZSA9IG5ldyBieXRlWzFdOworICAgIHByaXZhdGUgZmluYWwgYnl0ZVtdIGJ1ZmZlciA9IG5ldyBieXRlW01BWF9DT01QUkVTU0VEX0JVRkZFUl9TSVpFXTsKKyAgICBwcml2YXRlIGludCBjdXJyZW50SW5kZXggPSAwOworCisgICAgcHJpdmF0ZSBmaW5hbCBCeXRlVXRpbHMuQnl0ZUNvbnN1bWVyIGNvbnN1bWVyOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBvdXRwdXQgc3RyZWFtIHRoYXQgY29tcHJlc3NlcworICAgICAqIHNuYXBweS1mcmFtZWQtY29tcHJlc3NlZCBkYXRhIHRvIHRoZSBzcGVjaWZpZWQgb3V0cHV0IHN0cmVhbS4KKyAgICAgKiBAcGFyYW0gb3V0IHRoZSBPdXRwdXRTdHJlYW0gdG8gd2hpY2ggdG8gd3JpdGUgdGhlIGNvbXByZXNzZWQgZGF0YQorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgd3JpdGluZyB0aGUgc2lnbmF0dXJlIGZhaWxzCisgICAgICovCisgICAgcHVibGljIEZyYW1lZFNuYXBweUNvbXByZXNzb3JPdXRwdXRTdHJlYW0oZmluYWwgT3V0cHV0U3RyZWFtIG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcyhvdXQsIFNuYXBweUNvbXByZXNzb3JPdXRwdXRTdHJlYW0uY3JlYXRlUGFyYW1ldGVyQnVpbGRlcihTbmFwcHlDb21wcmVzc29ySW5wdXRTdHJlYW0uREVGQVVMVF9CTE9DS19TSVpFKQorICAgICAgICAgICAgIC5idWlsZCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IG91dHB1dCBzdHJlYW0gdGhhdCBjb21wcmVzc2VzCisgICAgICogc25hcHB5LWZyYW1lZC1jb21wcmVzc2VkIGRhdGEgdG8gdGhlIHNwZWNpZmllZCBvdXRwdXQgc3RyZWFtLgorICAgICAqIEBwYXJhbSBvdXQgdGhlIE91dHB1dFN0cmVhbSB0byB3aGljaCB0byB3cml0ZSB0aGUgY29tcHJlc3NlZCBkYXRhCisgICAgICogQHBhcmFtIHBhcmFtcyBwYXJhbWV0ZXJzIHVzZWQgdG8gZmluZS10dW5lIGNvbXByZXNzaW9uLCBpbgorICAgICAqIHBhcnRpY3VsYXIgdG8gYmFsYW5jZSBjb21wcmVzc2lvbiByYXRpbyB2cyBjb21wcmVzc2lvbiBzcGVlZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHdyaXRpbmcgdGhlIHNpZ25hdHVyZSBmYWlscworICAgICAqLworICAgIHB1YmxpYyBGcmFtZWRTbmFwcHlDb21wcmVzc29yT3V0cHV0U3RyZWFtKGZpbmFsIE91dHB1dFN0cmVhbSBvdXQsIFBhcmFtZXRlcnMgcGFyYW1zKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzLm91dCA9IG91dDsKKyAgICAgICAgdGhpcy5wYXJhbXMgPSBwYXJhbXM7CisgICAgICAgIGNvbnN1bWVyID0gbmV3IEJ5dGVVdGlscy5PdXRwdXRTdHJlYW1CeXRlQ29uc3VtZXIob3V0KTsKKyAgICAgICAgb3V0LndyaXRlKEZyYW1lZFNuYXBweUNvbXByZXNzb3JJbnB1dFN0cmVhbS5TWl9TSUdOQVRVUkUpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGludCBiKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvbmVCeXRlWzBdID0gKGJ5dGUpIChiICYgMHhmZik7CisgICAgICAgIHdyaXRlKG9uZUJ5dGUpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGJ5dGVbXSBkYXRhLCBpbnQgb2ZmLCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoY3VycmVudEluZGV4ICsgbGVuID4gTUFYX0NPTVBSRVNTRURfQlVGRkVSX1NJWkUpIHsKKyAgICAgICAgICAgIGZsdXNoQnVmZmVyKCk7CisgICAgICAgICAgICB3aGlsZSAobGVuID4gTUFYX0NPTVBSRVNTRURfQlVGRkVSX1NJWkUpIHsKKyAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGRhdGEsIG9mZiwgYnVmZmVyLCAwLCBNQVhfQ09NUFJFU1NFRF9CVUZGRVJfU0laRSk7CisgICAgICAgICAgICAgICAgb2ZmICs9IE1BWF9DT01QUkVTU0VEX0JVRkZFUl9TSVpFOworICAgICAgICAgICAgICAgIGxlbiAtPSBNQVhfQ09NUFJFU1NFRF9CVUZGRVJfU0laRTsKKyAgICAgICAgICAgICAgICBjdXJyZW50SW5kZXggPSBNQVhfQ09NUFJFU1NFRF9CVUZGRVJfU0laRTsKKyAgICAgICAgICAgICAgICBmbHVzaEJ1ZmZlcigpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZGF0YSwgb2ZmLCBidWZmZXIsIGN1cnJlbnRJbmRleCwgbGVuKTsKKyAgICAgICAgY3VycmVudEluZGV4ICs9IGxlbjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmaW5pc2goKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcHJlc3NlcyBhbGwgcmVtYWluaW5nIGRhdGEgYW5kIHdyaXRlcyBpdCB0byB0aGUgc3RyZWFtLAorICAgICAqIGRvZXNuJ3QgY2xvc2UgdGhlIHVuZGVybHlpbmcgc3RyZWFtLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgYW4gZXJyb3Igb2NjdXJzCisgICAgICovCisgICAgcHVibGljIHZvaWQgZmluaXNoKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGN1cnJlbnRJbmRleCA+IDApIHsKKyAgICAgICAgICAgIGZsdXNoQnVmZmVyKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgZmx1c2hCdWZmZXIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvdXQud3JpdGUoRnJhbWVkU25hcHB5Q29tcHJlc3NvcklucHV0U3RyZWFtLkNPTVBSRVNTRURfQ0hVTktfVFlQRSk7CisgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBiYW9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICB0cnkgKE91dHB1dFN0cmVhbSBvID0gbmV3IFNuYXBweUNvbXByZXNzb3JPdXRwdXRTdHJlYW0oYmFvcywgY3VycmVudEluZGV4LCBwYXJhbXMpKSB7CisgICAgICAgICAgICBvLndyaXRlKGJ1ZmZlciwgMCwgY3VycmVudEluZGV4KTsKKyAgICAgICAgfQorICAgICAgICBieXRlW10gYiA9IGJhb3MudG9CeXRlQXJyYXkoKTsKKyAgICAgICAgd3JpdGVMaXR0bGVFbmRpYW4oMywgYi5sZW5ndGggKyA0TCAvKiBDUkMgKi8pOworICAgICAgICB3cml0ZUNyYygpOworICAgICAgICBvdXQud3JpdGUoYik7CisgICAgICAgIGN1cnJlbnRJbmRleCA9IDA7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlTGl0dGxlRW5kaWFuKGZpbmFsIGludCBudW1CeXRlcywgbG9uZyBudW0pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEJ5dGVVdGlscy50b0xpdHRsZUVuZGlhbihjb25zdW1lciwgbnVtLCBudW1CeXRlcyk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlQ3JjKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tzdW0udXBkYXRlKGJ1ZmZlciwgMCwgY3VycmVudEluZGV4KTsKKyAgICAgICAgd3JpdGVMaXR0bGVFbmRpYW4oNCwgbWFzayhjaGVja3N1bS5nZXRWYWx1ZSgpKSk7CisgICAgICAgIGNoZWNrc3VtLnJlc2V0KCk7CisgICAgfQorCisgICAgc3RhdGljIGxvbmcgbWFzayhsb25nIHgpIHsKKyAgICAgICAgLy8gdWdseSwgbWF5YmUgd2Ugc2hvdWxkIGp1c3QgaGF2ZSB1c2VkIGludHMgYW5kIGRlYWwgd2l0aCB0aGUKKyAgICAgICAgLy8gb3ZlcmZsb3cKKyAgICAgICAgeCA9ICgoeCA+PiAxNSkgfCAoeCA8PCAxNykpOworICAgICAgICB4ICs9IEZyYW1lZFNuYXBweUNvbXByZXNzb3JJbnB1dFN0cmVhbS5NQVNLX09GRlNFVDsKKyAgICAgICAgeCAmPSAweGZmZmZGRkZGTDsKKyAgICAgICAgcmV0dXJuIHg7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvc25hcHB5L0ZyYW1lZFNuYXBweURpYWxlY3QuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL3NuYXBweS9GcmFtZWRTbmFwcHlEaWFsZWN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjgzYjdhNQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL3NuYXBweS9GcmFtZWRTbmFwcHlEaWFsZWN0LmphdmEKQEAgLTAsMCArMSw1MiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5zbmFwcHk7CisKKy8qKgorICogRGlhbGVjdHMgb2YgdGhlIGZyYW1pbmcgZm9ybWF0IHRoYXQge0BsaW5rIEZyYW1lZFNuYXBweUNvbXByZXNzb3JJbnB1dFN0cmVhbX0gY2FuIGRlYWwgd2l0aC4KKyAqIEBzaW5jZSAxLjEyCisgKi8KK3B1YmxpYyBlbnVtIEZyYW1lZFNuYXBweURpYWxlY3QgeworICAgIC8qKgorICAgICAqIFRoZSBzdGFuZGFyZCBhcyBkZWZpbmVkIGJ5IHRoZSA8YQorICAgICAqIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvc25hcHB5L2Jsb2IvbWFzdGVyL2ZyYW1pbmdfZm9ybWF0LnR4dCI+U25hcHB5CisgICAgICogZnJhbWluZyBmb3JtYXQgZGVzY3JpcHRpb248L2E+CisgICAgICovCisgICAgU1RBTkRBUkQodHJ1ZSwgdHJ1ZSksCisgICAgLyoqCisgICAgICogVGhlIGZvcm1hdCB1c2VkIGJ5IEFwcGxlJ3MgaVdvcmsgQXJjaGl2ZXMgKC5pd2EgZmlsZXMpLgorICAgICAqLworICAgIElXT1JLX0FSQ0hJVkUoZmFsc2UsIGZhbHNlKTsKKworICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiBzdHJlYW1JZGVudGlmaWVyLCBjaGVja3N1bVdpdGhDb21wcmVzc2VkQ2h1bmtzOworCisgICAgRnJhbWVkU25hcHB5RGlhbGVjdChmaW5hbCBib29sZWFuIGhhc1N0cmVhbUlkZW50aWZpZXIsCisgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBib29sZWFuIHVzZXNDaGVja3N1bVdpdGhDb21wcmVzc2VkQ2h1bmtzKSB7CisgICAgICAgIHRoaXMuc3RyZWFtSWRlbnRpZmllciA9IGhhc1N0cmVhbUlkZW50aWZpZXI7CisgICAgICAgIHRoaXMuY2hlY2tzdW1XaXRoQ29tcHJlc3NlZENodW5rcyA9IHVzZXNDaGVja3N1bVdpdGhDb21wcmVzc2VkQ2h1bmtzOworICAgIH0KKworICAgIGJvb2xlYW4gaGFzU3RyZWFtSWRlbnRpZmllcigpIHsKKyAgICAgICAgcmV0dXJuIHN0cmVhbUlkZW50aWZpZXI7CisgICAgfQorCisgICAgYm9vbGVhbiB1c2VzQ2hlY2tzdW1XaXRoQ29tcHJlc3NlZENodW5rcygpIHsKKyAgICAgICAgcmV0dXJuIGNoZWNrc3VtV2l0aENvbXByZXNzZWRDaHVua3M7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvc25hcHB5L1B1cmVKYXZhQ3JjMzJDLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9zbmFwcHkvUHVyZUphdmFDcmMzMkMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40Yzk3MzhiCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvc25hcHB5L1B1cmVKYXZhQ3JjMzJDLmphdmEKQEAgLTAsMCArMSw2MzggQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICoKKyAqIFNvbWUgcG9ydGlvbnMgb2YgdGhpcyBmaWxlIENvcHlyaWdodCAoYykgMjAwNC0yMDA2IEludGVsIENvcnBvcnRhdGlvbgorICogYW5kIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0QgbGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuc25hcHB5OworCitpbXBvcnQgamF2YS51dGlsLnppcC5DaGVja3N1bTsKKworLyoqCisgKiBBIHB1cmUtamF2YSBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgQ1JDMzIgY2hlY2tzdW0gdGhhdCB1c2VzCisgKiB0aGUgQ1JDMzItQyBwb2x5bm9taWFsLCB0aGUgc2FtZSBwb2x5bm9taWFsIHVzZWQgYnkgaVNDU0kKKyAqIGFuZCBpbXBsZW1lbnRlZCBvbiBtYW55IEludGVsIGNoaXBzZXRzIHN1cHBvcnRpbmcgU1NFNC4yLgorICoKKyAqIDxwPlRoaXMgZmlsZSBpcyBhIGNvcHkgb2YgdGhlIGltcGxlbWVudGF0aW9uIGF0IHRoZSBBcGFjaGUgSGFkb29wIHByb2plY3QuPC9wPgorICogQHNlZSAiaHR0cHM6Ly9zdm4uYXBhY2hlLm9yZy9yZXBvcy9hc2YvaGFkb29wL2NvbW1vbi90cnVuay9oYWRvb3AtY29tbW9uLXByb2plY3QvaGFkb29wLWNvbW1vbi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFkb29wL3V0aWwvUHVyZUphdmFDcmMzMkMuamF2YSIKKyAqIEBOb3RUaHJlYWRTYWZlCisgKiBAc2luY2UgMS43CisgKi8KK2ZpbmFsIGNsYXNzIFB1cmVKYXZhQ3JjMzJDIGltcGxlbWVudHMgQ2hlY2tzdW0geworCisgIC8qKiB0aGUgY3VycmVudCBDUkMgdmFsdWUsIGJpdC1mbGlwcGVkICovCisgIHByaXZhdGUgaW50IGNyYzsKKworICAvKiogQ3JlYXRlIGEgbmV3IFB1cmVKYXZhQ3JjMzIgb2JqZWN0LiAqLworICBwdWJsaWMgUHVyZUphdmFDcmMzMkMoKSB7CisgICAgcmVzZXQoKTsgLy8gbm9uLXByaXZhdGUsIGJ1dCB0aGUgY2xhc3MgaXMgbm93IGZpbmFsCisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGxvbmcgZ2V0VmFsdWUoKSB7CisgICAgZmluYWwgbG9uZyByZXQgPSBjcmM7CisgICAgcmV0dXJuICh+cmV0KSAmIDB4ZmZmZmZmZmZMOworICB9CisKKyAgQE92ZXJyaWRlCisgIC8vIGNhbGxlZCBieSBjdG9yIGJ1dCB0aGUgY2xhc3MgaXMgZmluYWwgc28gdGhpcyBpcyBzYWZlCisgIHB1YmxpYyB2b2lkIHJlc2V0KCkgeworICAgIGNyYyA9IDB4ZmZmZmZmZmY7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgdXBkYXRlKGZpbmFsIGJ5dGVbXSBiLCBpbnQgb2ZmLCBpbnQgbGVuKSB7CisgICAgaW50IGxvY2FsQ3JjID0gY3JjOworCisgICAgd2hpbGUobGVuID4gNykgeworICAgICAgZmluYWwgaW50IGMwID0oYltvZmYrMF0gXiBsb2NhbENyYykgJiAweGZmOworICAgICAgZmluYWwgaW50IGMxID0oYltvZmYrMV0gXiAobG9jYWxDcmMgPj4+PSA4KSkgJiAweGZmOyAvL05PU09OQVIKKyAgICAgIGZpbmFsIGludCBjMiA9KGJbb2ZmKzJdIF4gKGxvY2FsQ3JjID4+Pj0gOCkpICYgMHhmZjsgLy9OT1NPTkFSCisgICAgICBmaW5hbCBpbnQgYzMgPShiW29mZiszXSBeIChsb2NhbENyYyA+Pj49IDgpKSAmIDB4ZmY7IC8vTk9TT05BUgorICAgICAgbG9jYWxDcmMgPSAoVFtUOF83X1NUQVJUICsgYzBdIF4gVFtUOF82X1NUQVJUICsgYzFdKQorICAgICAgICAgIF4gKFRbVDhfNV9TVEFSVCArIGMyXSBeIFRbVDhfNF9TVEFSVCArIGMzXSk7CisKKyAgICAgIGZpbmFsIGludCBjNCA9IGJbb2ZmKzRdICYgMHhmZjsKKyAgICAgIGZpbmFsIGludCBjNSA9IGJbb2ZmKzVdICYgMHhmZjsKKyAgICAgIGZpbmFsIGludCBjNiA9IGJbb2ZmKzZdICYgMHhmZjsKKyAgICAgIGZpbmFsIGludCBjNyA9IGJbb2ZmKzddICYgMHhmZjsKKworICAgICAgbG9jYWxDcmMgXj0gKFRbVDhfM19TVEFSVCArIGM0XSBeIFRbVDhfMl9TVEFSVCArIGM1XSkKKyAgICAgICAgICAgXiAoVFtUOF8xX1NUQVJUICsgYzZdIF4gVFtUOF8wX1NUQVJUICsgYzddKTsKKworICAgICAgb2ZmICs9IDg7CisgICAgICBsZW4gLT0gODsKKyAgICB9CisKKyAgICAvKiBsb29wIHVucm9sbCAtIGR1ZmYncyBkZXZpY2Ugc3R5bGUgKi8KKyAgICBzd2l0Y2gobGVuKSB7CisgICAgICBjYXNlIDc6IGxvY2FsQ3JjID0gKGxvY2FsQ3JjID4+PiA4KSBeIFRbVDhfMF9TVEFSVCArICgobG9jYWxDcmMgXiBiW29mZisrXSkgJiAweGZmKV07CisgICAgICBjYXNlIDY6IGxvY2FsQ3JjID0gKGxvY2FsQ3JjID4+PiA4KSBeIFRbVDhfMF9TVEFSVCArICgobG9jYWxDcmMgXiBiW29mZisrXSkgJiAweGZmKV07CisgICAgICBjYXNlIDU6IGxvY2FsQ3JjID0gKGxvY2FsQ3JjID4+PiA4KSBeIFRbVDhfMF9TVEFSVCArICgobG9jYWxDcmMgXiBiW29mZisrXSkgJiAweGZmKV07CisgICAgICBjYXNlIDQ6IGxvY2FsQ3JjID0gKGxvY2FsQ3JjID4+PiA4KSBeIFRbVDhfMF9TVEFSVCArICgobG9jYWxDcmMgXiBiW29mZisrXSkgJiAweGZmKV07CisgICAgICBjYXNlIDM6IGxvY2FsQ3JjID0gKGxvY2FsQ3JjID4+PiA4KSBeIFRbVDhfMF9TVEFSVCArICgobG9jYWxDcmMgXiBiW29mZisrXSkgJiAweGZmKV07CisgICAgICBjYXNlIDI6IGxvY2FsQ3JjID0gKGxvY2FsQ3JjID4+PiA4KSBeIFRbVDhfMF9TVEFSVCArICgobG9jYWxDcmMgXiBiW29mZisrXSkgJiAweGZmKV07CisgICAgICBjYXNlIDE6IGxvY2FsQ3JjID0gKGxvY2FsQ3JjID4+PiA4KSBeIFRbVDhfMF9TVEFSVCArICgobG9jYWxDcmMgXiBiW29mZisrXSkgJiAweGZmKV07CisgICAgICBkZWZhdWx0OgorICAgICAgICAvKiBub3RoaW5nICovCisgICAgfQorCisgICAgLy8gUHVibGlzaCBjcmMgb3V0IHRvIG9iamVjdAorICAgIGNyYyA9IGxvY2FsQ3JjOworICB9CisKKyAgQE92ZXJyaWRlCisgIGZpbmFsIHB1YmxpYyB2b2lkIHVwZGF0ZShmaW5hbCBpbnQgYikgeworICAgIGNyYyA9IChjcmMgPj4+IDgpIF4gVFtUOF8wX1NUQVJUICsgKChjcmMgXiBiKSAmIDB4ZmYpXTsKKyAgfQorCisgIC8vIENSQyBwb2x5bm9taWFsIHRhYmxlcyBnZW5lcmF0ZWQgYnk6CisgIC8vIGphdmEgLWNwIGJ1aWxkL3Rlc3QvY2xhc3Nlcy86YnVpbGQvY2xhc3Nlcy8gXAorICAvLyAgIG9yZy5hcGFjaGUuaGFkb29wLnV0aWwuVGVzdFB1cmVKYXZhQ3JjMzJcJFRhYmxlIDgyRjYzQjc4CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFQ4XzBfU1RBUlQgPSAwKjI1NjsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFQ4XzFfU1RBUlQgPSAxKjI1NjsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFQ4XzJfU1RBUlQgPSAyKjI1NjsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFQ4XzNfU1RBUlQgPSAzKjI1NjsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFQ4XzRfU1RBUlQgPSA0KjI1NjsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFQ4XzVfU1RBUlQgPSA1KjI1NjsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFQ4XzZfU1RBUlQgPSA2KjI1NjsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFQ4XzdfU1RBUlQgPSA3KjI1NjsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnRbXSBUID0gbmV3IGludFtdIHsKKyAgICAvKiBUOF8wICovCisgICAgMHgwMDAwMDAwMCwgMHhGMjZCODMwMywgMHhFMTNCNzBGNywgMHgxMzUwRjNGNCwKKyAgICAweEM3OUE5NzFGLCAweDM1RjExNDFDLCAweDI2QTFFN0U4LCAweEQ0Q0E2NEVCLAorICAgIDB4OEFEOTU4Q0YsIDB4NzhCMkRCQ0MsIDB4NkJFMjI4MzgsIDB4OTk4OUFCM0IsCisgICAgMHg0RDQzQ0ZEMCwgMHhCRjI4NENEMywgMHhBQzc4QkYyNywgMHg1RTEzM0MyNCwKKyAgICAweDEwNUVDNzZGLCAweEUyMzU0NDZDLCAweEYxNjVCNzk4LCAweDAzMEUzNDlCLAorICAgIDB4RDdDNDUwNzAsIDB4MjVBRkQzNzMsIDB4MzZGRjIwODcsIDB4QzQ5NEEzODQsCisgICAgMHg5QTg3OUZBMCwgMHg2OEVDMUNBMywgMHg3QkJDRUY1NywgMHg4OUQ3NkM1NCwKKyAgICAweDVEMUQwOEJGLCAweEFGNzY4QkJDLCAweEJDMjY3ODQ4LCAweDRFNERGQjRCLAorICAgIDB4MjBCRDhFREUsIDB4RDJENjBEREQsIDB4QzE4NkZFMjksIDB4MzNFRDdEMkEsCisgICAgMHhFNzI3MTlDMSwgMHgxNTRDOUFDMiwgMHgwNjFDNjkzNiwgMHhGNDc3RUEzNSwKKyAgICAweEFBNjRENjExLCAweDU4MEY1NTEyLCAweDRCNUZBNkU2LCAweEI5MzQyNUU1LAorICAgIDB4NkRGRTQxMEUsIDB4OUY5NUMyMEQsIDB4OENDNTMxRjksIDB4N0VBRUIyRkEsCisgICAgMHgzMEUzNDlCMSwgMHhDMjg4Q0FCMiwgMHhEMUQ4Mzk0NiwgMHgyM0IzQkE0NSwKKyAgICAweEY3NzlERUFFLCAweDA1MTI1REFELCAweDE2NDJBRTU5LCAweEU0MjkyRDVBLAorICAgIDB4QkEzQTExN0UsIDB4NDg1MTkyN0QsIDB4NUIwMTYxODksIDB4QTk2QUUyOEEsCisgICAgMHg3REEwODY2MSwgMHg4RkNCMDU2MiwgMHg5QzlCRjY5NiwgMHg2RUYwNzU5NSwKKyAgICAweDQxN0IxREJDLCAweEIzMTA5RUJGLCAweEEwNDA2RDRCLCAweDUyMkJFRTQ4LAorICAgIDB4ODZFMThBQTMsIDB4NzQ4QTA5QTAsIDB4NjdEQUZBNTQsIDB4OTVCMTc5NTcsCisgICAgMHhDQkEyNDU3MywgMHgzOUM5QzY3MCwgMHgyQTk5MzU4NCwgMHhEOEYyQjY4NywKKyAgICAweDBDMzhEMjZDLCAweEZFNTM1MTZGLCAweEVEMDNBMjlCLCAweDFGNjgyMTk4LAorICAgIDB4NTEyNURBRDMsIDB4QTM0RTU5RDAsIDB4QjAxRUFBMjQsIDB4NDI3NTI5MjcsCisgICAgMHg5NkJGNERDQywgMHg2NEQ0Q0VDRiwgMHg3Nzg0M0QzQiwgMHg4NUVGQkUzOCwKKyAgICAweERCRkM4MjFDLCAweDI5OTcwMTFGLCAweDNBQzdGMkVCLCAweEM4QUM3MUU4LAorICAgIDB4MUM2NjE1MDMsIDB4RUUwRDk2MDAsIDB4RkQ1RDY1RjQsIDB4MEYzNkU2RjcsCisgICAgMHg2MUM2OTM2MiwgMHg5M0FEMTA2MSwgMHg4MEZERTM5NSwgMHg3Mjk2NjA5NiwKKyAgICAweEE2NUMwNDdELCAweDU0Mzc4NzdFLCAweDQ3Njc3NDhBLCAweEI1MENGNzg5LAorICAgIDB4RUIxRkNCQUQsIDB4MTk3NDQ4QUUsIDB4MEEyNEJCNUEsIDB4Rjg0RjM4NTksCisgICAgMHgyQzg1NUNCMiwgMHhERUVFREZCMSwgMHhDREJFMkM0NSwgMHgzRkQ1QUY0NiwKKyAgICAweDcxOTg1NDBELCAweDgzRjNENzBFLCAweDkwQTMyNEZBLCAweDYyQzhBN0Y5LAorICAgIDB4QjYwMkMzMTIsIDB4NDQ2OTQwMTEsIDB4NTczOUIzRTUsIDB4QTU1MjMwRTYsCisgICAgMHhGQjQxMENDMiwgMHgwOTJBOEZDMSwgMHgxQTdBN0MzNSwgMHhFODExRkYzNiwKKyAgICAweDNDREI5QkRELCAweENFQjAxOERFLCAweERERTBFQjJBLCAweDJGOEI2ODI5LAorICAgIDB4ODJGNjNCNzgsIDB4NzA5REI4N0IsIDB4NjNDRDRCOEYsIDB4OTFBNkM4OEMsCisgICAgMHg0NTZDQUM2NywgMHhCNzA3MkY2NCwgMHhBNDU3REM5MCwgMHg1NjNDNUY5MywKKyAgICAweDA4MkY2M0I3LCAweEZBNDRFMEI0LCAweEU5MTQxMzQwLCAweDFCN0Y5MDQzLAorICAgIDB4Q0ZCNUY0QTgsIDB4M0RERTc3QUIsIDB4MkU4RTg0NUYsIDB4RENFNTA3NUMsCisgICAgMHg5MkE4RkMxNywgMHg2MEMzN0YxNCwgMHg3MzkzOENFMCwgMHg4MUY4MEZFMywKKyAgICAweDU1MzI2QjA4LCAweEE3NTlFODBCLCAweEI0MDkxQkZGLCAweDQ2NjI5OEZDLAorICAgIDB4MTg3MUE0RDgsIDB4RUExQTI3REIsIDB4Rjk0QUQ0MkYsIDB4MEIyMTU3MkMsCisgICAgMHhERkVCMzNDNywgMHgyRDgwQjBDNCwgMHgzRUQwNDMzMCwgMHhDQ0JCQzAzMywKKyAgICAweEEyNEJCNUE2LCAweDUwMjAzNkE1LCAweDQzNzBDNTUxLCAweEIxMUI0NjUyLAorICAgIDB4NjVEMTIyQjksIDB4OTdCQUExQkEsIDB4ODRFQTUyNEUsIDB4NzY4MUQxNEQsCisgICAgMHgyODkyRUQ2OSwgMHhEQUY5NkU2QSwgMHhDOUE5OUQ5RSwgMHgzQkMyMUU5RCwKKyAgICAweEVGMDg3QTc2LCAweDFENjNGOTc1LCAweDBFMzMwQTgxLCAweEZDNTg4OTgyLAorICAgIDB4QjIxNTcyQzksIDB4NDA3RUYxQ0EsIDB4NTMyRTAyM0UsIDB4QTE0NTgxM0QsCisgICAgMHg3NThGRTVENiwgMHg4N0U0NjZENSwgMHg5NEI0OTUyMSwgMHg2NkRGMTYyMiwKKyAgICAweDM4Q0MyQTA2LCAweENBQTdBOTA1LCAweEQ5Rjc1QUYxLCAweDJCOUNEOUYyLAorICAgIDB4RkY1NkJEMTksIDB4MEQzRDNFMUEsIDB4MUU2RENERUUsIDB4RUMwNjRFRUQsCisgICAgMHhDMzhEMjZDNCwgMHgzMUU2QTVDNywgMHgyMkI2NTYzMywgMHhEMERERDUzMCwKKyAgICAweDA0MTdCMURCLCAweEY2N0MzMkQ4LCAweEU1MkNDMTJDLCAweDE3NDc0MjJGLAorICAgIDB4NDk1NDdFMEIsIDB4QkIzRkZEMDgsIDB4QTg2RjBFRkMsIDB4NUEwNDhERkYsCisgICAgMHg4RUNFRTkxNCwgMHg3Q0E1NkExNywgMHg2RkY1OTlFMywgMHg5RDlFMUFFMCwKKyAgICAweEQzRDNFMUFCLCAweDIxQjg2MkE4LCAweDMyRTg5MTVDLCAweEMwODMxMjVGLAorICAgIDB4MTQ0OTc2QjQsIDB4RTYyMkY1QjcsIDB4RjU3MjA2NDMsIDB4MDcxOTg1NDAsCisgICAgMHg1OTBBQjk2NCwgMHhBQjYxM0E2NywgMHhCODMxQzk5MywgMHg0QTVBNEE5MCwKKyAgICAweDlFOTAyRTdCLCAweDZDRkJBRDc4LCAweDdGQUI1RThDLCAweDhEQzBERDhGLAorICAgIDB4RTMzMEE4MUEsIDB4MTE1QjJCMTksIDB4MDIwQkQ4RUQsIDB4RjA2MDVCRUUsCisgICAgMHgyNEFBM0YwNSwgMHhENkMxQkMwNiwgMHhDNTkxNEZGMiwgMHgzN0ZBQ0NGMSwKKyAgICAweDY5RTlGMEQ1LCAweDlCODI3M0Q2LCAweDg4RDI4MDIyLCAweDdBQjkwMzIxLAorICAgIDB4QUU3MzY3Q0EsIDB4NUMxOEU0QzksIDB4NEY0ODE3M0QsIDB4QkQyMzk0M0UsCisgICAgMHhGMzZFNkY3NSwgMHgwMTA1RUM3NiwgMHgxMjU1MUY4MiwgMHhFMDNFOUM4MSwKKyAgICAweDM0RjRGODZBLCAweEM2OUY3QjY5LCAweEQ1Q0Y4ODlELCAweDI3QTQwQjlFLAorICAgIDB4NzlCNzM3QkEsIDB4OEJEQ0I0QjksIDB4OTg4QzQ3NEQsIDB4NkFFN0M0NEUsCisgICAgMHhCRTJEQTBBNSwgMHg0QzQ2MjNBNiwgMHg1RjE2RDA1MiwgMHhBRDdENTM1MSwKKyAgICAvKiBUOF8xICovCisgICAgMHgwMDAwMDAwMCwgMHgxM0EyOTg3NywgMHgyNzQ1MzBFRSwgMHgzNEU3QTg5OSwKKyAgICAweDRFOEE2MURDLCAweDVEMjhGOUFCLCAweDY5Q0Y1MTMyLCAweDdBNkRDOTQ1LAorICAgIDB4OUQxNEMzQjgsIDB4OEVCNjVCQ0YsIDB4QkE1MUYzNTYsIDB4QTlGMzZCMjEsCisgICAgMHhEMzlFQTI2NCwgMHhDMDNDM0ExMywgMHhGNERCOTI4QSwgMHhFNzc5MEFGRCwKKyAgICAweDNGQzVGMTgxLCAweDJDNjc2OUY2LCAweDE4ODBDMTZGLCAweDBCMjI1OTE4LAorICAgIDB4NzE0RjkwNUQsIDB4NjJFRDA4MkEsIDB4NTYwQUEwQjMsIDB4NDVBODM4QzQsCisgICAgMHhBMkQxMzIzOSwgMHhCMTczQUE0RSwgMHg4NTk0MDJENywgMHg5NjM2OUFBMCwKKyAgICAweEVDNUI1M0U1LCAweEZGRjlDQjkyLCAweENCMUU2MzBCLCAweEQ4QkNGQjdDLAorICAgIDB4N0Y4QkUzMDIsIDB4NkMyOTdCNzUsIDB4NThDRUQzRUMsIDB4NEI2QzRCOUIsCisgICAgMHgzMTAxODJERSwgMHgyMkEzMUFBOSwgMHgxNjQ0QjIzMCwgMHgwNUU2MkE0NywKKyAgICAweEUyOUYyMEJBLCAweEYxM0RCOENELCAweEM1REExMDU0LCAweEQ2Nzg4ODIzLAorICAgIDB4QUMxNTQxNjYsIDB4QkZCN0Q5MTEsIDB4OEI1MDcxODgsIDB4OThGMkU5RkYsCisgICAgMHg0MDRFMTI4MywgMHg1M0VDOEFGNCwgMHg2NzBCMjI2RCwgMHg3NEE5QkExQSwKKyAgICAweDBFQzQ3MzVGLCAweDFENjZFQjI4LCAweDI5ODE0M0IxLCAweDNBMjNEQkM2LAorICAgIDB4REQ1QUQxM0IsIDB4Q0VGODQ5NEMsIDB4RkExRkUxRDUsIDB4RTlCRDc5QTIsCisgICAgMHg5M0QwQjBFNywgMHg4MDcyMjg5MCwgMHhCNDk1ODAwOSwgMHhBNzM3MTg3RSwKKyAgICAweEZGMTdDNjA0LCAweEVDQjU1RTczLCAweEQ4NTJGNkVBLCAweENCRjA2RTlELAorICAgIDB4QjE5REE3RDgsIDB4QTIzRjNGQUYsIDB4OTZEODk3MzYsIDB4ODU3QTBGNDEsCisgICAgMHg2MjAzMDVCQywgMHg3MUExOURDQiwgMHg0NTQ2MzU1MiwgMHg1NkU0QUQyNSwKKyAgICAweDJDODk2NDYwLCAweDNGMkJGQzE3LCAweDBCQ0M1NDhFLCAweDE4NkVDQ0Y5LAorICAgIDB4QzBEMjM3ODUsIDB4RDM3MEFGRjIsIDB4RTc5NzA3NkIsIDB4RjQzNTlGMUMsCisgICAgMHg4RTU4NTY1OSwgMHg5REZBQ0UyRSwgMHhBOTFENjZCNywgMHhCQUJGRkVDMCwKKyAgICAweDVEQzZGNDNELCAweDRFNjQ2QzRBLCAweDdBODNDNEQzLCAweDY5MjE1Q0E0LAorICAgIDB4MTM0Qzk1RTEsIDB4MDBFRTBEOTYsIDB4MzQwOUE1MEYsIDB4MjdBQjNENzgsCisgICAgMHg4MDlDMjUwNiwgMHg5MzNFQkQ3MSwgMHhBN0Q5MTVFOCwgMHhCNDdCOEQ5RiwKKyAgICAweENFMTY0NERBLCAweEREQjREQ0FELCAweEU5NTM3NDM0LCAweEZBRjFFQzQzLAorICAgIDB4MUQ4OEU2QkUsIDB4MEUyQTdFQzksIDB4M0FDREQ2NTAsIDB4Mjk2RjRFMjcsCisgICAgMHg1MzAyODc2MiwgMHg0MEEwMUYxNSwgMHg3NDQ3Qjc4QywgMHg2N0U1MkZGQiwKKyAgICAweEJGNTlENDg3LCAweEFDRkI0Q0YwLCAweDk4MUNFNDY5LCAweDhCQkU3QzFFLAorICAgIDB4RjFEM0I1NUIsIDB4RTI3MTJEMkMsIDB4RDY5Njg1QjUsIDB4QzUzNDFEQzIsCisgICAgMHgyMjREMTczRiwgMHgzMUVGOEY0OCwgMHgwNTA4MjdEMSwgMHgxNkFBQkZBNiwKKyAgICAweDZDQzc3NkUzLCAweDdGNjVFRTk0LCAweDRCODI0NjBELCAweDU4MjBERTdBLAorICAgIDB4RkJDM0ZBRjksIDB4RTg2MTYyOEUsIDB4REM4NkNBMTcsIDB4Q0YyNDUyNjAsCisgICAgMHhCNTQ5OUIyNSwgMHhBNkVCMDM1MiwgMHg5MjBDQUJDQiwgMHg4MUFFMzNCQywKKyAgICAweDY2RDczOTQxLCAweDc1NzVBMTM2LCAweDQxOTIwOUFGLCAweDUyMzA5MUQ4LAorICAgIDB4Mjg1RDU4OUQsIDB4M0JGRkMwRUEsIDB4MEYxODY4NzMsIDB4MUNCQUYwMDQsCisgICAgMHhDNDA2MEI3OCwgMHhEN0E0OTMwRiwgMHhFMzQzM0I5NiwgMHhGMEUxQTNFMSwKKyAgICAweDhBOEM2QUE0LCAweDk5MkVGMkQzLCAweEFEQzk1QTRBLCAweEJFNkJDMjNELAorICAgIDB4NTkxMkM4QzAsIDB4NEFCMDUwQjcsIDB4N0U1N0Y4MkUsIDB4NkRGNTYwNTksCisgICAgMHgxNzk4QTkxQywgMHgwNDNBMzE2QiwgMHgzMEREOTlGMiwgMHgyMzdGMDE4NSwKKyAgICAweDg0NDgxOUZCLCAweDk3RUE4MThDLCAweEEzMEQyOTE1LCAweEIwQUZCMTYyLAorICAgIDB4Q0FDMjc4MjcsIDB4RDk2MEUwNTAsIDB4RUQ4NzQ4QzksIDB4RkUyNUQwQkUsCisgICAgMHgxOTVDREE0MywgMHgwQUZFNDIzNCwgMHgzRTE5RUFBRCwgMHgyREJCNzJEQSwKKyAgICAweDU3RDZCQjlGLCAweDQ0NzQyM0U4LCAweDcwOTM4QjcxLCAweDYzMzExMzA2LAorICAgIDB4QkI4REU4N0EsIDB4QTgyRjcwMEQsIDB4OUNDOEQ4OTQsIDB4OEY2QTQwRTMsCisgICAgMHhGNTA3ODlBNiwgMHhFNkE1MTFEMSwgMHhEMjQyQjk0OCwgMHhDMUUwMjEzRiwKKyAgICAweDI2OTkyQkMyLCAweDM1M0JCM0I1LCAweDAxREMxQjJDLCAweDEyN0U4MzVCLAorICAgIDB4NjgxMzRBMUUsIDB4N0JCMUQyNjksIDB4NEY1NjdBRjAsIDB4NUNGNEUyODcsCisgICAgMHgwNEQ0M0NGRCwgMHgxNzc2QTQ4QSwgMHgyMzkxMEMxMywgMHgzMDMzOTQ2NCwKKyAgICAweDRBNUU1RDIxLCAweDU5RkNDNTU2LCAweDZEMUI2RENGLCAweDdFQjlGNUI4LAorICAgIDB4OTlDMEZGNDUsIDB4OEE2MjY3MzIsIDB4QkU4NUNGQUIsIDB4QUQyNzU3REMsCisgICAgMHhENzRBOUU5OSwgMHhDNEU4MDZFRSwgMHhGMDBGQUU3NywgMHhFM0FEMzYwMCwKKyAgICAweDNCMTFDRDdDLCAweDI4QjM1NTBCLCAweDFDNTRGRDkyLCAweDBGRjY2NUU1LAorICAgIDB4NzU5QkFDQTAsIDB4NjYzOTM0RDcsIDB4NTJERTlDNEUsIDB4NDE3QzA0MzksCisgICAgMHhBNjA1MEVDNCwgMHhCNUE3OTZCMywgMHg4MTQwM0UyQSwgMHg5MkUyQTY1RCwKKyAgICAweEU4OEY2RjE4LCAweEZCMkRGNzZGLCAweENGQ0E1RkY2LCAweERDNjhDNzgxLAorICAgIDB4N0I1RkRGRkYsIDB4NjhGRDQ3ODgsIDB4NUMxQUVGMTEsIDB4NEZCODc3NjYsCisgICAgMHgzNUQ1QkUyMywgMHgyNjc3MjY1NCwgMHgxMjkwOEVDRCwgMHgwMTMyMTZCQSwKKyAgICAweEU2NEIxQzQ3LCAweEY1RTk4NDMwLCAweEMxMEUyQ0E5LCAweEQyQUNCNERFLAorICAgIDB4QThDMTdEOUIsIDB4QkI2M0U1RUMsIDB4OEY4NDRENzUsIDB4OUMyNkQ1MDIsCisgICAgMHg0NDlBMkU3RSwgMHg1NzM4QjYwOSwgMHg2M0RGMUU5MCwgMHg3MDdEODZFNywKKyAgICAweDBBMTA0RkEyLCAweDE5QjJEN0Q1LCAweDJENTU3RjRDLCAweDNFRjdFNzNCLAorICAgIDB4RDk4RUVEQzYsIDB4Q0EyQzc1QjEsIDB4RkVDQkREMjgsIDB4RUQ2OTQ1NUYsCisgICAgMHg5NzA0OEMxQSwgMHg4NEE2MTQ2RCwgMHhCMDQxQkNGNCwgMHhBM0UzMjQ4MywKKyAgICAvKiBUOF8yICovCisgICAgMHgwMDAwMDAwMCwgMHhBNTQxOTI3RSwgMHg0RjZGNTIwRCwgMHhFQTJFQzA3MywKKyAgICAweDlFREVBNDFBLCAweDNCOUYzNjY0LCAweEQxQjFGNjE3LCAweDc0RjA2NDY5LAorICAgIDB4Mzg1MTNFQzUsIDB4OUQxMEFDQkIsIDB4NzczRTZDQzgsIDB4RDI3RkZFQjYsCisgICAgMHhBNjhGOUFERiwgMHgwM0NFMDhBMSwgMHhFOUUwQzhEMiwgMHg0Q0ExNUFBQywKKyAgICAweDcwQTI3RDhBLCAweEQ1RTNFRkY0LCAweDNGQ0QyRjg3LCAweDlBOENCREY5LAorICAgIDB4RUU3Q0Q5OTAsIDB4NEIzRDRCRUUsIDB4QTExMzhCOUQsIDB4MDQ1MjE5RTMsCisgICAgMHg0OEYzNDM0RiwgMHhFREIyRDEzMSwgMHgwNzlDMTE0MiwgMHhBMkREODMzQywKKyAgICAweEQ2MkRFNzU1LCAweDczNkM3NTJCLCAweDk5NDJCNTU4LCAweDNDMDMyNzI2LAorICAgIDB4RTE0NEZCMTQsIDB4NDQwNTY5NkEsIDB4QUUyQkE5MTksIDB4MEI2QTNCNjcsCisgICAgMHg3RjlBNUYwRSwgMHhEQURCQ0Q3MCwgMHgzMEY1MEQwMywgMHg5NUI0OUY3RCwKKyAgICAweEQ5MTVDNUQxLCAweDdDNTQ1N0FGLCAweDk2N0E5N0RDLCAweDMzM0IwNUEyLAorICAgIDB4NDdDQjYxQ0IsIDB4RTI4QUYzQjUsIDB4MDhBNDMzQzYsIDB4QURFNUExQjgsCisgICAgMHg5MUU2ODY5RSwgMHgzNEE3MTRFMCwgMHhERTg5RDQ5MywgMHg3QkM4NDZFRCwKKyAgICAweDBGMzgyMjg0LCAweEFBNzlCMEZBLCAweDQwNTc3MDg5LCAweEU1MTZFMkY3LAorICAgIDB4QTlCN0I4NUIsIDB4MENGNjJBMjUsIDB4RTZEOEVBNTYsIDB4NDM5OTc4MjgsCisgICAgMHgzNzY5MUM0MSwgMHg5MjI4OEUzRiwgMHg3ODA2NEU0QywgMHhERDQ3REMzMiwKKyAgICAweEM3NjU4MEQ5LCAweDYyMjQxMkE3LCAweDg4MEFEMkQ0LCAweDJENEI0MEFBLAorICAgIDB4NTlCQjI0QzMsIDB4RkNGQUI2QkQsIDB4MTZENDc2Q0UsIDB4QjM5NUU0QjAsCisgICAgMHhGRjM0QkUxQywgMHg1QTc1MkM2MiwgMHhCMDVCRUMxMSwgMHgxNTFBN0U2RiwKKyAgICAweDYxRUExQTA2LCAweEM0QUI4ODc4LCAweDJFODU0ODBCLCAweDhCQzREQTc1LAorICAgIDB4QjdDN0ZENTMsIDB4MTI4NjZGMkQsIDB4RjhBOEFGNUUsIDB4NURFOTNEMjAsCisgICAgMHgyOTE5NTk0OSwgMHg4QzU4Q0IzNywgMHg2Njc2MEI0NCwgMHhDMzM3OTkzQSwKKyAgICAweDhGOTZDMzk2LCAweDJBRDc1MUU4LCAweEMwRjk5MTlCLCAweDY1QjgwM0U1LAorICAgIDB4MTE0ODY3OEMsIDB4QjQwOUY1RjIsIDB4NUUyNzM1ODEsIDB4RkI2NkE3RkYsCisgICAgMHgyNjIxN0JDRCwgMHg4MzYwRTlCMywgMHg2OTRFMjlDMCwgMHhDQzBGQkJCRSwKKyAgICAweEI4RkZERkQ3LCAweDFEQkU0REE5LCAweEY3OTA4RERBLCAweDUyRDExRkE0LAorICAgIDB4MUU3MDQ1MDgsIDB4QkIzMUQ3NzYsIDB4NTExRjE3MDUsIDB4RjQ1RTg1N0IsCisgICAgMHg4MEFFRTExMiwgMHgyNUVGNzM2QywgMHhDRkMxQjMxRiwgMHg2QTgwMjE2MSwKKyAgICAweDU2ODMwNjQ3LCAweEYzQzI5NDM5LCAweDE5RUM1NDRBLCAweEJDQURDNjM0LAorICAgIDB4Qzg1REEyNUQsIDB4NkQxQzMwMjMsIDB4ODczMkYwNTAsIDB4MjI3MzYyMkUsCisgICAgMHg2RUQyMzg4MiwgMHhDQjkzQUFGQywgMHgyMUJENkE4RiwgMHg4NEZDRjhGMSwKKyAgICAweEYwMEM5Qzk4LCAweDU1NEQwRUU2LCAweEJGNjNDRTk1LCAweDFBMjI1Q0VCLAorICAgIDB4OEIyNzc3NDMsIDB4MkU2NkU1M0QsIDB4QzQ0ODI1NEUsIDB4NjEwOUI3MzAsCisgICAgMHgxNUY5RDM1OSwgMHhCMEI4NDEyNywgMHg1QTk2ODE1NCwgMHhGRkQ3MTMyQSwKKyAgICAweEIzNzY0OTg2LCAweDE2MzdEQkY4LCAweEZDMTkxQjhCLCAweDU5NTg4OUY1LAorICAgIDB4MkRBOEVEOUMsIDB4ODhFOTdGRTIsIDB4NjJDN0JGOTEsIDB4Qzc4NjJERUYsCisgICAgMHhGQjg1MEFDOSwgMHg1RUM0OThCNywgMHhCNEVBNThDNCwgMHgxMUFCQ0FCQSwKKyAgICAweDY1NUJBRUQzLCAweEMwMUEzQ0FELCAweDJBMzRGQ0RFLCAweDhGNzU2RUEwLAorICAgIDB4QzNENDM0MEMsIDB4NjY5NUE2NzIsIDB4OENCQjY2MDEsIDB4MjlGQUY0N0YsCisgICAgMHg1RDBBOTAxNiwgMHhGODRCMDI2OCwgMHgxMjY1QzIxQiwgMHhCNzI0NTA2NSwKKyAgICAweDZBNjM4QzU3LCAweENGMjIxRTI5LCAweDI1MENERTVBLCAweDgwNEQ0QzI0LAorICAgIDB4RjRCRDI4NEQsIDB4NTFGQ0JBMzMsIDB4QkJEMjdBNDAsIDB4MUU5M0U4M0UsCisgICAgMHg1MjMyQjI5MiwgMHhGNzczMjBFQywgMHgxRDVERTA5RiwgMHhCODFDNzJFMSwKKyAgICAweENDRUMxNjg4LCAweDY5QUQ4NEY2LCAweDgzODM0NDg1LCAweDI2QzJENkZCLAorICAgIDB4MUFDMUYxREQsIDB4QkY4MDYzQTMsIDB4NTVBRUEzRDAsIDB4RjBFRjMxQUUsCisgICAgMHg4NDFGNTVDNywgMHgyMTVFQzdCOSwgMHhDQjcwMDdDQSwgMHg2RTMxOTVCNCwKKyAgICAweDIyOTBDRjE4LCAweDg3RDE1RDY2LCAweDZERkY5RDE1LCAweEM4QkUwRjZCLAorICAgIDB4QkM0RTZCMDIsIDB4MTkwRkY5N0MsIDB4RjMyMTM5MEYsIDB4NTY2MEFCNzEsCisgICAgMHg0QzQyRjc5QSwgMHhFOTAzNjVFNCwgMHgwMzJEQTU5NywgMHhBNjZDMzdFOSwKKyAgICAweEQyOUM1MzgwLCAweDc3RERDMUZFLCAweDlERjMwMThELCAweDM4QjI5M0YzLAorICAgIDB4NzQxM0M5NUYsIDB4RDE1MjVCMjEsIDB4M0I3QzlCNTIsIDB4OUUzRDA5MkMsCisgICAgMHhFQUNENkQ0NSwgMHg0RjhDRkYzQiwgMHhBNUEyM0Y0OCwgMHgwMEUzQUQzNiwKKyAgICAweDNDRTA4QTEwLCAweDk5QTExODZFLCAweDczOEZEODFELCAweEQ2Q0U0QTYzLAorICAgIDB4QTIzRTJFMEEsIDB4MDc3RkJDNzQsIDB4RUQ1MTdDMDcsIDB4NDgxMEVFNzksCisgICAgMHgwNEIxQjRENSwgMHhBMUYwMjZBQiwgMHg0QkRFRTZEOCwgMHhFRTlGNzRBNiwKKyAgICAweDlBNkYxMENGLCAweDNGMkU4MkIxLCAweEQ1MDA0MkMyLCAweDcwNDFEMEJDLAorICAgIDB4QUQwNjBDOEUsIDB4MDg0NzlFRjAsIDB4RTI2OTVFODMsIDB4NDcyOENDRkQsCisgICAgMHgzM0Q4QTg5NCwgMHg5Njk5M0FFQSwgMHg3Q0I3RkE5OSwgMHhEOUY2NjhFNywKKyAgICAweDk1NTczMjRCLCAweDMwMTZBMDM1LCAweERBMzg2MDQ2LCAweDdGNzlGMjM4LAorICAgIDB4MEI4OTk2NTEsIDB4QUVDODA0MkYsIDB4NDRFNkM0NUMsIDB4RTFBNzU2MjIsCisgICAgMHhEREE0NzEwNCwgMHg3OEU1RTM3QSwgMHg5MkNCMjMwOSwgMHgzNzhBQjE3NywKKyAgICAweDQzN0FENTFFLCAweEU2M0I0NzYwLCAweDBDMTU4NzEzLCAweEE5NTQxNTZELAorICAgIDB4RTVGNTRGQzEsIDB4NDBCNEREQkYsIDB4QUE5QTFEQ0MsIDB4MEZEQjhGQjIsCisgICAgMHg3QjJCRUJEQiwgMHhERTZBNzlBNSwgMHgzNDQ0QjlENiwgMHg5MTA1MkJBOCwKKyAgICAvKiBUOF8zICovCisgICAgMHgwMDAwMDAwMCwgMHhERDQ1QUFCOCwgMHhCRjY3MjM4MSwgMHg2MjIyODkzOSwKKyAgICAweDdCMjIzMUYzLCAweEE2Njc5QjRCLCAweEM0NDUxMjcyLCAweDE5MDBCOENBLAorICAgIDB4RjY0NDYzRTYsIDB4MkIwMUM5NUUsIDB4NDkyMzQwNjcsIDB4OTQ2NkVBREYsCisgICAgMHg4RDY2NTIxNSwgMHg1MDIzRjhBRCwgMHgzMjAxNzE5NCwgMHhFRjQ0REIyQywKKyAgICAweEU5NjRCMTNELCAweDM0MjExQjg1LCAweDU2MDM5MkJDLCAweDhCNDYzODA0LAorICAgIDB4OTI0NjgwQ0UsIDB4NEYwMzJBNzYsIDB4MkQyMUEzNEYsIDB4RjA2NDA5RjcsCisgICAgMHgxRjIwRDJEQiwgMHhDMjY1Nzg2MywgMHhBMDQ3RjE1QSwgMHg3RDAyNUJFMiwKKyAgICAweDY0MDJFMzI4LCAweEI5NDc0OTkwLCAweERCNjVDMEE5LCAweDA2MjA2QTExLAorICAgIDB4RDcyNTE0OEIsIDB4MEE2MEJFMzMsIDB4Njg0MjM3MEEsIDB4QjUwNzlEQjIsCisgICAgMHhBQzA3MjU3OCwgMHg3MTQyOEZDMCwgMHgxMzYwMDZGOSwgMHhDRTI1QUM0MSwKKyAgICAweDIxNjE3NzZELCAweEZDMjREREQ1LCAweDlFMDY1NEVDLCAweDQzNDNGRTU0LAorICAgIDB4NUE0MzQ2OUUsIDB4ODcwNkVDMjYsIDB4RTUyNDY1MUYsIDB4Mzg2MUNGQTcsCisgICAgMHgzRTQxQTVCNiwgMHhFMzA0MEYwRSwgMHg4MTI2ODYzNywgMHg1QzYzMkM4RiwKKyAgICAweDQ1NjM5NDQ1LCAweDk4MjYzRUZELCAweEZBMDRCN0M0LCAweDI3NDExRDdDLAorICAgIDB4QzgwNUM2NTAsIDB4MTU0MDZDRTgsIDB4Nzc2MkU1RDEsIDB4QUEyNzRGNjksCisgICAgMHhCMzI3RjdBMywgMHg2RTYyNUQxQiwgMHgwQzQwRDQyMiwgMHhEMTA1N0U5QSwKKyAgICAweEFCQTY1RkU3LCAweDc2RTNGNTVGLCAweDE0QzE3QzY2LCAweEM5ODRENkRFLAorICAgIDB4RDA4NDZFMTQsIDB4MERDMUM0QUMsIDB4NkZFMzREOTUsIDB4QjJBNkU3MkQsCisgICAgMHg1REUyM0MwMSwgMHg4MEE3OTZCOSwgMHhFMjg1MUY4MCwgMHgzRkMwQjUzOCwKKyAgICAweDI2QzAwREYyLCAweEZCODVBNzRBLCAweDk5QTcyRTczLCAweDQ0RTI4NENCLAorICAgIDB4NDJDMkVFREEsIDB4OUY4NzQ0NjIsIDB4RkRBNUNENUIsIDB4MjBFMDY3RTMsCisgICAgMHgzOUUwREYyOSwgMHhFNEE1NzU5MSwgMHg4Njg3RkNBOCwgMHg1QkMyNTYxMCwKKyAgICAweEI0ODY4RDNDLCAweDY5QzMyNzg0LCAweDBCRTFBRUJELCAweEQ2QTQwNDA1LAorICAgIDB4Q0ZBNEJDQ0YsIDB4MTJFMTE2NzcsIDB4NzBDMzlGNEUsIDB4QUQ4NjM1RjYsCisgICAgMHg3QzgzNEI2QywgMHhBMUM2RTFENCwgMHhDM0U0NjhFRCwgMHgxRUExQzI1NSwKKyAgICAweDA3QTE3QTlGLCAweERBRTREMDI3LCAweEI4QzY1OTFFLCAweDY1ODNGM0E2LAorICAgIDB4OEFDNzI4OEEsIDB4NTc4MjgyMzIsIDB4MzVBMDBCMEIsIDB4RThFNUExQjMsCisgICAgMHhGMUU1MTk3OSwgMHgyQ0EwQjNDMSwgMHg0RTgyM0FGOCwgMHg5M0M3OTA0MCwKKyAgICAweDk1RTdGQTUxLCAweDQ4QTI1MEU5LCAweDJBODBEOUQwLCAweEY3QzU3MzY4LAorICAgIDB4RUVDNUNCQTIsIDB4MzM4MDYxMUEsIDB4NTFBMkU4MjMsIDB4OENFNzQyOUIsCisgICAgMHg2M0EzOTlCNywgMHhCRUU2MzMwRiwgMHhEQ0M0QkEzNiwgMHgwMTgxMTA4RSwKKyAgICAweDE4ODFBODQ0LCAweEM1QzQwMkZDLCAweEE3RTY4QkM1LCAweDdBQTMyMTdELAorICAgIDB4NTJBMEM5M0YsIDB4OEZFNTYzODcsIDB4RURDN0VBQkUsIDB4MzA4MjQwMDYsCisgICAgMHgyOTgyRjhDQywgMHhGNEM3NTI3NCwgMHg5NkU1REI0RCwgMHg0QkEwNzFGNSwKKyAgICAweEE0RTRBQUQ5LCAweDc5QTEwMDYxLCAweDFCODM4OTU4LCAweEM2QzYyM0UwLAorICAgIDB4REZDNjlCMkEsIDB4MDI4MzMxOTIsIDB4NjBBMUI4QUIsIDB4QkRFNDEyMTMsCisgICAgMHhCQkM0NzgwMiwgMHg2NjgxRDJCQSwgMHgwNEEzNUI4MywgMHhEOUU2RjEzQiwKKyAgICAweEMwRTY0OUYxLCAweDFEQTNFMzQ5LCAweDdGODE2QTcwLCAweEEyQzRDMEM4LAorICAgIDB4NEQ4MDFCRTQsIDB4OTBDNUIxNUMsIDB4RjJFNzM4NjUsIDB4MkZBMjkyREQsCisgICAgMHgzNkEyMkExNywgMHhFQkU3ODBBRiwgMHg4OUM1MDk5NiwgMHg1NDgwQTMyRSwKKyAgICAweDg1ODVEREI0LCAweDU4QzA3NzBDLCAweDNBRTJGRTM1LCAweEU3QTc1NDhELAorICAgIDB4RkVBN0VDNDcsIDB4MjNFMjQ2RkYsIDB4NDFDMENGQzYsIDB4OUM4NTY1N0UsCisgICAgMHg3M0MxQkU1MiwgMHhBRTg0MTRFQSwgMHhDQ0E2OUREMywgMHgxMUUzMzc2QiwKKyAgICAweDA4RTM4RkExLCAweEQ1QTYyNTE5LCAweEI3ODRBQzIwLCAweDZBQzEwNjk4LAorICAgIDB4NkNFMTZDODksIDB4QjFBNEM2MzEsIDB4RDM4NjRGMDgsIDB4MEVDM0U1QjAsCisgICAgMHgxN0MzNUQ3QSwgMHhDQTg2RjdDMiwgMHhBOEE0N0VGQiwgMHg3NUUxRDQ0MywKKyAgICAweDlBQTUwRjZGLCAweDQ3RTBBNUQ3LCAweDI1QzIyQ0VFLCAweEY4ODc4NjU2LAorICAgIDB4RTE4NzNFOUMsIDB4M0NDMjk0MjQsIDB4NUVFMDFEMUQsIDB4ODNBNUI3QTUsCisgICAgMHhGOTA2OTZEOCwgMHgyNDQzM0M2MCwgMHg0NjYxQjU1OSwgMHg5QjI0MUZFMSwKKyAgICAweDgyMjRBNzJCLCAweDVGNjEwRDkzLCAweDNENDM4NEFBLCAweEUwMDYyRTEyLAorICAgIDB4MEY0MkY1M0UsIDB4RDIwNzVGODYsIDB4QjAyNUQ2QkYsIDB4NkQ2MDdDMDcsCisgICAgMHg3NDYwQzRDRCwgMHhBOTI1NkU3NSwgMHhDQjA3RTc0QywgMHgxNjQyNERGNCwKKyAgICAweDEwNjIyN0U1LCAweENEMjc4RDVELCAweEFGMDUwNDY0LCAweDcyNDBBRURDLAorICAgIDB4NkI0MDE2MTYsIDB4QjYwNUJDQUUsIDB4RDQyNzM1OTcsIDB4MDk2MjlGMkYsCisgICAgMHhFNjI2NDQwMywgMHgzQjYzRUVCQiwgMHg1OTQxNjc4MiwgMHg4NDA0Q0QzQSwKKyAgICAweDlEMDQ3NUYwLCAweDQwNDFERjQ4LCAweDIyNjM1NjcxLCAweEZGMjZGQ0M5LAorICAgIDB4MkUyMzgyNTMsIDB4RjM2NjI4RUIsIDB4OTE0NEExRDIsIDB4NEMwMTBCNkEsCisgICAgMHg1NTAxQjNBMCwgMHg4ODQ0MTkxOCwgMHhFQTY2OTAyMSwgMHgzNzIzM0E5OSwKKyAgICAweEQ4NjdFMUI1LCAweDA1MjI0QjBELCAweDY3MDBDMjM0LCAweEJBNDU2ODhDLAorICAgIDB4QTM0NUQwNDYsIDB4N0UwMDdBRkUsIDB4MUMyMkYzQzcsIDB4QzE2NzU5N0YsCisgICAgMHhDNzQ3MzM2RSwgMHgxQTAyOTlENiwgMHg3ODIwMTBFRiwgMHhBNTY1QkE1NywKKyAgICAweEJDNjUwMjlELCAweDYxMjBBODI1LCAweDAzMDIyMTFDLCAweERFNDc4QkE0LAorICAgIDB4MzEwMzUwODgsIDB4RUM0NkZBMzAsIDB4OEU2NDczMDksIDB4NTMyMUQ5QjEsCisgICAgMHg0QTIxNjE3QiwgMHg5NzY0Q0JDMywgMHhGNTQ2NDJGQSwgMHgyODAzRTg0MiwKKyAgICAvKiBUOF80ICovCisgICAgMHgwMDAwMDAwMCwgMHgzODExNkZBQywgMHg3MDIyREY1OCwgMHg0ODMzQjBGNCwKKyAgICAweEUwNDVCRUIwLCAweEQ4NTREMTFDLCAweDkwNjc2MUU4LCAweEE4NzYwRTQ0LAorICAgIDB4QzU2NzBCOTEsIDB4RkQ3NjY0M0QsIDB4QjU0NUQ0QzksIDB4OEQ1NEJCNjUsCisgICAgMHgyNTIyQjUyMSwgMHgxRDMzREE4RCwgMHg1NTAwNkE3OSwgMHg2RDExMDVENSwKKyAgICAweDhGMjI2MUQzLCAweEI3MzMwRTdGLCAweEZGMDBCRThCLCAweEM3MTFEMTI3LAorICAgIDB4NkY2N0RGNjMsIDB4NTc3NkIwQ0YsIDB4MUY0NTAwM0IsIDB4Mjc1NDZGOTcsCisgICAgMHg0QTQ1NkE0MiwgMHg3MjU0MDVFRSwgMHgzQTY3QjUxQSwgMHgwMjc2REFCNiwKKyAgICAweEFBMDBENEYyLCAweDkyMTFCQjVFLCAweERBMjIwQkFBLCAweEUyMzM2NDA2LAorICAgIDB4MUJBOEI1NTcsIDB4MjNCOURBRkIsIDB4NkI4QTZBMEYsIDB4NTM5QjA1QTMsCisgICAgMHhGQkVEMEJFNywgMHhDM0ZDNjQ0QiwgMHg4QkNGRDRCRiwgMHhCM0RFQkIxMywKKyAgICAweERFQ0ZCRUM2LCAweEU2REVEMTZBLCAweEFFRUQ2MTlFLCAweDk2RkMwRTMyLAorICAgIDB4M0U4QTAwNzYsIDB4MDY5QjZGREEsIDB4NEVBOERGMkUsIDB4NzZCOUIwODIsCisgICAgMHg5NDhBRDQ4NCwgMHhBQzlCQkIyOCwgMHhFNEE4MEJEQywgMHhEQ0I5NjQ3MCwKKyAgICAweDc0Q0Y2QTM0LCAweDRDREUwNTk4LCAweDA0RURCNTZDLCAweDNDRkNEQUMwLAorICAgIDB4NTFFRERGMTUsIDB4NjlGQ0IwQjksIDB4MjFDRjAwNEQsIDB4MTlERTZGRTEsCisgICAgMHhCMUE4NjFBNSwgMHg4OUI5MEUwOSwgMHhDMThBQkVGRCwgMHhGOTlCRDE1MSwKKyAgICAweDM3NTE2QUFFLCAweDBGNDAwNTAyLCAweDQ3NzNCNUY2LCAweDdGNjJEQTVBLAorICAgIDB4RDcxNEQ0MUUsIDB4RUYwNUJCQjIsIDB4QTczNjBCNDYsIDB4OUYyNzY0RUEsCisgICAgMHhGMjM2NjEzRiwgMHhDQTI3MEU5MywgMHg4MjE0QkU2NywgMHhCQTA1RDFDQiwKKyAgICAweDEyNzNERjhGLCAweDJBNjJCMDIzLCAweDYyNTEwMEQ3LCAweDVBNDA2RjdCLAorICAgIDB4Qjg3MzBCN0QsIDB4ODA2MjY0RDEsIDB4Qzg1MUQ0MjUsIDB4RjA0MEJCODksCisgICAgMHg1ODM2QjVDRCwgMHg2MDI3REE2MSwgMHgyODE0NkE5NSwgMHgxMDA1MDUzOSwKKyAgICAweDdEMTQwMEVDLCAweDQ1MDU2RjQwLCAweDBEMzZERkI0LCAweDM1MjdCMDE4LAorICAgIDB4OUQ1MUJFNUMsIDB4QTU0MEQxRjAsIDB4RUQ3MzYxMDQsIDB4RDU2MjBFQTgsCisgICAgMHgyQ0Y5REZGOSwgMHgxNEU4QjA1NSwgMHg1Q0RCMDBBMSwgMHg2NENBNkYwRCwKKyAgICAweENDQkM2MTQ5LCAweEY0QUQwRUU1LCAweEJDOUVCRTExLCAweDg0OEZEMUJELAorICAgIDB4RTk5RUQ0NjgsIDB4RDE4RkJCQzQsIDB4OTlCQzBCMzAsIDB4QTFBRDY0OUMsCisgICAgMHgwOURCNkFEOCwgMHgzMUNBMDU3NCwgMHg3OUY5QjU4MCwgMHg0MUU4REEyQywKKyAgICAweEEzREJCRTJBLCAweDlCQ0FEMTg2LCAweEQzRjk2MTcyLCAweEVCRTgwRURFLAorICAgIDB4NDM5RTAwOUEsIDB4N0I4RjZGMzYsIDB4MzNCQ0RGQzIsIDB4MEJBREIwNkUsCisgICAgMHg2NkJDQjVCQiwgMHg1RUFEREExNywgMHgxNjlFNkFFMywgMHgyRThGMDU0RiwKKyAgICAweDg2RjkwQjBCLCAweEJFRTg2NEE3LCAweEY2REJENDUzLCAweENFQ0FCQkZGLAorICAgIDB4NkVBMkQ1NUMsIDB4NTZCM0JBRjAsIDB4MUU4MDBBMDQsIDB4MjY5MTY1QTgsCisgICAgMHg4RUU3NkJFQywgMHhCNkY2MDQ0MCwgMHhGRUM1QjRCNCwgMHhDNkQ0REIxOCwKKyAgICAweEFCQzVERUNELCAweDkzRDRCMTYxLCAweERCRTcwMTk1LCAweEUzRjY2RTM5LAorICAgIDB4NEI4MDYwN0QsIDB4NzM5MTBGRDEsIDB4M0JBMkJGMjUsIDB4MDNCM0QwODksCisgICAgMHhFMTgwQjQ4RiwgMHhEOTkxREIyMywgMHg5MUEyNkJENywgMHhBOUIzMDQ3QiwKKyAgICAweDAxQzUwQTNGLCAweDM5RDQ2NTkzLCAweDcxRTdENTY3LCAweDQ5RjZCQUNCLAorICAgIDB4MjRFN0JGMUUsIDB4MUNGNkQwQjIsIDB4NTRDNTYwNDYsIDB4NkNENDBGRUEsCisgICAgMHhDNEEyMDFBRSwgMHhGQ0IzNkUwMiwgMHhCNDgwREVGNiwgMHg4QzkxQjE1QSwKKyAgICAweDc1MEE2MDBCLCAweDREMUIwRkE3LCAweDA1MjhCRjUzLCAweDNEMzlEMEZGLAorICAgIDB4OTU0RkRFQkIsIDB4QUQ1RUIxMTcsIDB4RTU2RDAxRTMsIDB4REQ3QzZFNEYsCisgICAgMHhCMDZENkI5QSwgMHg4ODdDMDQzNiwgMHhDMDRGQjRDMiwgMHhGODVFREI2RSwKKyAgICAweDUwMjhENTJBLCAweDY4MzlCQTg2LCAweDIwMEEwQTcyLCAweDE4MUI2NURFLAorICAgIDB4RkEyODAxRDgsIDB4QzIzOTZFNzQsIDB4OEEwQURFODAsIDB4QjIxQkIxMkMsCisgICAgMHgxQTZEQkY2OCwgMHgyMjdDRDBDNCwgMHg2QTRGNjAzMCwgMHg1MjVFMEY5QywKKyAgICAweDNGNEYwQTQ5LCAweDA3NUU2NUU1LCAweDRGNkRENTExLCAweDc3N0NCQUJELAorICAgIDB4REYwQUI0RjksIDB4RTcxQkRCNTUsIDB4QUYyODZCQTEsIDB4OTczOTA0MEQsCisgICAgMHg1OUYzQkZGMiwgMHg2MUUyRDA1RSwgMHgyOUQxNjBBQSwgMHgxMUMwMEYwNiwKKyAgICAweEI5QjYwMTQyLCAweDgxQTc2RUVFLCAweEM5OTRERTFBLCAweEYxODVCMUI2LAorICAgIDB4OUM5NEI0NjMsIDB4QTQ4NURCQ0YsIDB4RUNCNjZCM0IsIDB4RDRBNzA0OTcsCisgICAgMHg3Q0QxMEFEMywgMHg0NEMwNjU3RiwgMHgwQ0YzRDU4QiwgMHgzNEUyQkEyNywKKyAgICAweEQ2RDFERTIxLCAweEVFQzBCMThELCAweEE2RjMwMTc5LCAweDlFRTI2RUQ1LAorICAgIDB4MzY5NDYwOTEsIDB4MEU4NTBGM0QsIDB4NDZCNkJGQzksIDB4N0VBN0QwNjUsCisgICAgMHgxM0I2RDVCMCwgMHgyQkE3QkExQywgMHg2Mzk0MEFFOCwgMHg1Qjg1NjU0NCwKKyAgICAweEYzRjM2QjAwLCAweENCRTIwNEFDLCAweDgzRDFCNDU4LCAweEJCQzBEQkY0LAorICAgIDB4NDI1QjBBQTUsIDB4N0E0QTY1MDksIDB4MzI3OUQ1RkQsIDB4MEE2OEJBNTEsCisgICAgMHhBMjFFQjQxNSwgMHg5QTBGREJCOSwgMHhEMjNDNkI0RCwgMHhFQTJEMDRFMSwKKyAgICAweDg3M0MwMTM0LCAweEJGMkQ2RTk4LCAweEY3MUVERTZDLCAweENGMEZCMUMwLAorICAgIDB4Njc3OUJGODQsIDB4NUY2OEQwMjgsIDB4MTc1QjYwREMsIDB4MkY0QTBGNzAsCisgICAgMHhDRDc5NkI3NiwgMHhGNTY4MDREQSwgMHhCRDVCQjQyRSwgMHg4NTRBREI4MiwKKyAgICAweDJEM0NENUM2LCAweDE1MkRCQTZBLCAweDVEMUUwQTlFLCAweDY1MEY2NTMyLAorICAgIDB4MDgxRTYwRTcsIDB4MzAwRjBGNEIsIDB4NzgzQ0JGQkYsIDB4NDAyREQwMTMsCisgICAgMHhFODVCREU1NywgMHhEMDRBQjFGQiwgMHg5ODc5MDEwRiwgMHhBMDY4NkVBMywKKyAgICAvKiBUOF81ICovCisgICAgMHgwMDAwMDAwMCwgMHhFRjMwNkIxOSwgMHhEQjhDQTBDMywgMHgzNEJDQ0JEQSwKKyAgICAweEIyRjUzNzc3LCAweDVEQzU1QzZFLCAweDY5Nzk5N0I0LCAweDg2NDlGQ0FELAorICAgIDB4NjAwNjE4MUYsIDB4OEYzNjczMDYsIDB4QkI4QUI4REMsIDB4NTRCQUQzQzUsCisgICAgMHhEMkYzMkY2OCwgMHgzREMzNDQ3MSwgMHgwOTdGOEZBQiwgMHhFNjRGRTRCMiwKKyAgICAweEMwMEMzMDNFLCAweDJGM0M1QjI3LCAweDFCODA5MEZELCAweEY0QjBGQkU0LAorICAgIDB4NzJGOTA3NDksIDB4OURDOTZDNTAsIDB4QTk3NUE3OEEsIDB4NDY0NUNDOTMsCisgICAgMHhBMDBBMjgyMSwgMHg0RjNBNDMzOCwgMHg3Qjg2ODhFMiwgMHg5NEI2RTNGQiwKKyAgICAweDEyRkYxRjU2LCAweEZEQ0Y3NDRGLCAweEM5NzNCRjk1LCAweDI2NDNENDhDLAorICAgIDB4ODVGNDE2OEQsIDB4NkFDNDdEOTQsIDB4NUU3OEI2NEUsIDB4QjE0OERENTcsCisgICAgMHgzNzAxMjFGQSwgMHhEODMxNEFFMywgMHhFQzhEODEzOSwgMHgwM0JERUEyMCwKKyAgICAweEU1RjIwRTkyLCAweDBBQzI2NThCLCAweDNFN0VBRTUxLCAweEQxNEVDNTQ4LAorICAgIDB4NTcwNzM5RTUsIDB4QjgzNzUyRkMsIDB4OEM4Qjk5MjYsIDB4NjNCQkYyM0YsCisgICAgMHg0NUY4MjZCMywgMHhBQUM4NERBQSwgMHg5RTc0ODY3MCwgMHg3MTQ0RUQ2OSwKKyAgICAweEY3MEQxMUM0LCAweDE4M0Q3QURELCAweDJDODFCMTA3LCAweEMzQjFEQTFFLAorICAgIDB4MjVGRTNFQUMsIDB4Q0FDRTU1QjUsIDB4RkU3MjlFNkYsIDB4MTE0MkY1NzYsCisgICAgMHg5NzBCMDlEQiwgMHg3ODNCNjJDMiwgMHg0Qzg3QTkxOCwgMHhBM0I3QzIwMSwKKyAgICAweDBFMDQ1QkVCLCAweEUxMzQzMEYyLCAweEQ1ODhGQjI4LCAweDNBQjg5MDMxLAorICAgIDB4QkNGMTZDOUMsIDB4NTNDMTA3ODUsIDB4Njc3RENDNUYsIDB4ODg0REE3NDYsCisgICAgMHg2RTAyNDNGNCwgMHg4MTMyMjhFRCwgMHhCNThFRTMzNywgMHg1QUJFODgyRSwKKyAgICAweERDRjc3NDgzLCAweDMzQzcxRjlBLCAweDA3N0JENDQwLCAweEU4NEJCRjU5LAorICAgIDB4Q0UwODZCRDUsIDB4MjEzODAwQ0MsIDB4MTU4NENCMTYsIDB4RkFCNEEwMEYsCisgICAgMHg3Q0ZENUNBMiwgMHg5M0NEMzdCQiwgMHhBNzcxRkM2MSwgMHg0ODQxOTc3OCwKKyAgICAweEFFMEU3M0NBLCAweDQxM0UxOEQzLCAweDc1ODJEMzA5LCAweDlBQjJCODEwLAorICAgIDB4MUNGQjQ0QkQsIDB4RjNDQjJGQTQsIDB4Qzc3N0U0N0UsIDB4Mjg0NzhGNjcsCisgICAgMHg4QkYwNEQ2NiwgMHg2NEMwMjY3RiwgMHg1MDdDRURBNSwgMHhCRjRDODZCQywKKyAgICAweDM5MDU3QTExLCAweEQ2MzUxMTA4LCAweEUyODlEQUQyLCAweDBEQjlCMUNCLAorICAgIDB4RUJGNjU1NzksIDB4MDRDNjNFNjAsIDB4MzA3QUY1QkEsIDB4REY0QTlFQTMsCisgICAgMHg1OTAzNjIwRSwgMHhCNjMzMDkxNywgMHg4MjhGQzJDRCwgMHg2REJGQTlENCwKKyAgICAweDRCRkM3RDU4LCAweEE0Q0MxNjQxLCAweDkwNzBERDlCLCAweDdGNDBCNjgyLAorICAgIDB4RjkwOTRBMkYsIDB4MTYzOTIxMzYsIDB4MjI4NUVBRUMsIDB4Q0RCNTgxRjUsCisgICAgMHgyQkZBNjU0NywgMHhDNENBMEU1RSwgMHhGMDc2QzU4NCwgMHgxRjQ2QUU5RCwKKyAgICAweDk5MEY1MjMwLCAweDc2M0YzOTI5LCAweDQyODNGMkYzLCAweEFEQjM5OUVBLAorICAgIDB4MUMwOEI3RDYsIDB4RjMzOERDQ0YsIDB4Qzc4NDE3MTUsIDB4MjhCNDdDMEMsCisgICAgMHhBRUZEODBBMSwgMHg0MUNERUJCOCwgMHg3NTcxMjA2MiwgMHg5QTQxNEI3QiwKKyAgICAweDdDMEVBRkM5LCAweDkzM0VDNEQwLCAweEE3ODIwRjBBLCAweDQ4QjI2NDEzLAorICAgIDB4Q0VGQjk4QkUsIDB4MjFDQkYzQTcsIDB4MTU3NzM4N0QsIDB4RkE0NzUzNjQsCisgICAgMHhEQzA0ODdFOCwgMHgzMzM0RUNGMSwgMHgwNzg4MjcyQiwgMHhFOEI4NEMzMiwKKyAgICAweDZFRjFCMDlGLCAweDgxQzFEQjg2LCAweEI1N0QxMDVDLCAweDVBNEQ3QjQ1LAorICAgIDB4QkMwMjlGRjcsIDB4NTMzMkY0RUUsIDB4Njc4RTNGMzQsIDB4ODhCRTU0MkQsCisgICAgMHgwRUY3QTg4MCwgMHhFMUM3QzM5OSwgMHhENTdCMDg0MywgMHgzQTRCNjM1QSwKKyAgICAweDk5RkNBMTVCLCAweDc2Q0NDQTQyLCAweDQyNzAwMTk4LCAweEFENDA2QTgxLAorICAgIDB4MkIwOTk2MkMsIDB4QzQzOUZEMzUsIDB4RjA4NTM2RUYsIDB4MUZCNTVERjYsCisgICAgMHhGOUZBQjk0NCwgMHgxNkNBRDI1RCwgMHgyMjc2MTk4NywgMHhDRDQ2NzI5RSwKKyAgICAweDRCMEY4RTMzLCAweEE0M0ZFNTJBLCAweDkwODMyRUYwLCAweDdGQjM0NUU5LAorICAgIDB4NTlGMDkxNjUsIDB4QjZDMEZBN0MsIDB4ODI3QzMxQTYsIDB4NkQ0QzVBQkYsCisgICAgMHhFQjA1QTYxMiwgMHgwNDM1Q0QwQiwgMHgzMDg5MDZEMSwgMHhERkI5NkRDOCwKKyAgICAweDM5RjY4OTdBLCAweEQ2QzZFMjYzLCAweEUyN0EyOUI5LCAweDBENEE0MkEwLAorICAgIDB4OEIwM0JFMEQsIDB4NjQzM0Q1MTQsIDB4NTA4RjFFQ0UsIDB4QkZCRjc1RDcsCisgICAgMHgxMjBDRUMzRCwgMHhGRDNDODcyNCwgMHhDOTgwNENGRSwgMHgyNkIwMjdFNywKKyAgICAweEEwRjlEQjRBLCAweDRGQzlCMDUzLCAweDdCNzU3Qjg5LCAweDk0NDUxMDkwLAorICAgIDB4NzIwQUY0MjIsIDB4OUQzQTlGM0IsIDB4QTk4NjU0RTEsIDB4NDZCNjNGRjgsCisgICAgMHhDMEZGQzM1NSwgMHgyRkNGQTg0QywgMHgxQjczNjM5NiwgMHhGNDQzMDg4RiwKKyAgICAweEQyMDBEQzAzLCAweDNEMzBCNzFBLCAweDA5OEM3Q0MwLCAweEU2QkMxN0Q5LAorICAgIDB4NjBGNUVCNzQsIDB4OEZDNTgwNkQsIDB4QkI3OTRCQjcsIDB4NTQ0OTIwQUUsCisgICAgMHhCMjA2QzQxQywgMHg1RDM2QUYwNSwgMHg2OThBNjRERiwgMHg4NkJBMEZDNiwKKyAgICAweDAwRjNGMzZCLCAweEVGQzM5ODcyLCAweERCN0Y1M0E4LCAweDM0NEYzOEIxLAorICAgIDB4OTdGOEZBQjAsIDB4NzhDODkxQTksIDB4NEM3NDVBNzMsIDB4QTM0NDMxNkEsCisgICAgMHgyNTBEQ0RDNywgMHhDQTNEQTZERSwgMHhGRTgxNkQwNCwgMHgxMUIxMDYxRCwKKyAgICAweEY3RkVFMkFGLCAweDE4Q0U4OUI2LCAweDJDNzI0MjZDLCAweEMzNDIyOTc1LAorICAgIDB4NDUwQkQ1RDgsIDB4QUEzQkJFQzEsIDB4OUU4Nzc1MUIsIDB4NzFCNzFFMDIsCisgICAgMHg1N0Y0Q0E4RSwgMHhCOEM0QTE5NywgMHg4Qzc4NkE0RCwgMHg2MzQ4MDE1NCwKKyAgICAweEU1MDFGREY5LCAweDBBMzE5NkUwLCAweDNFOEQ1RDNBLCAweEQxQkQzNjIzLAorICAgIDB4MzdGMkQyOTEsIDB4RDhDMkI5ODgsIDB4RUM3RTcyNTIsIDB4MDM0RTE5NEIsCisgICAgMHg4NTA3RTVFNiwgMHg2QTM3OEVGRiwgMHg1RThCNDUyNSwgMHhCMUJCMkUzQywKKyAgICAvKiBUOF82ICovCisgICAgMHgwMDAwMDAwMCwgMHg2ODAzMkNDOCwgMHhEMDA2NTk5MCwgMHhCODA1NzU1OCwKKyAgICAweEE1RTBDNUQxLCAweENERTNFOTE5LCAweDc1RTY5QzQxLCAweDFERTVCMDg5LAorICAgIDB4NEUyREZENTMsIDB4MjYyRUQxOUIsIDB4OUUyQkE0QzMsIDB4RjYyODg4MEIsCisgICAgMHhFQkNEMzg4MiwgMHg4M0NFMTQ0QSwgMHgzQkNCNjExMiwgMHg1M0M4NEREQSwKKyAgICAweDlDNUJGQUE2LCAweEY0NThENjZFLCAweDRDNURBMzM2LCAweDI0NUU4RkZFLAorICAgIDB4MzlCQjNGNzcsIDB4NTFCODEzQkYsIDB4RTlCRDY2RTcsIDB4ODFCRTRBMkYsCisgICAgMHhEMjc2MDdGNSwgMHhCQTc1MkIzRCwgMHgwMjcwNUU2NSwgMHg2QTczNzJBRCwKKyAgICAweDc3OTZDMjI0LCAweDFGOTVFRUVDLCAweEE3OTA5QkI0LCAweENGOTNCNzdDLAorICAgIDB4M0Q1QjgzQkQsIDB4NTU1OEFGNzUsIDB4RUQ1RERBMkQsIDB4ODU1RUY2RTUsCisgICAgMHg5OEJCNDY2QywgMHhGMEI4NkFBNCwgMHg0OEJEMUZGQywgMHgyMEJFMzMzNCwKKyAgICAweDczNzY3RUVFLCAweDFCNzU1MjI2LCAweEEzNzAyNzdFLCAweENCNzMwQkI2LAorICAgIDB4RDY5NkJCM0YsIDB4QkU5NTk3RjcsIDB4MDY5MEUyQUYsIDB4NkU5M0NFNjcsCisgICAgMHhBMTAwNzkxQiwgMHhDOTAzNTVEMywgMHg3MTA2MjA4QiwgMHgxOTA1MEM0MywKKyAgICAweDA0RTBCQ0NBLCAweDZDRTM5MDAyLCAweEQ0RTZFNTVBLCAweEJDRTVDOTkyLAorICAgIDB4RUYyRDg0NDgsIDB4ODcyRUE4ODAsIDB4M0YyQkRERDgsIDB4NTcyOEYxMTAsCisgICAgMHg0QUNENDE5OSwgMHgyMkNFNkQ1MSwgMHg5QUNCMTgwOSwgMHhGMkM4MzRDMSwKKyAgICAweDdBQjcwNzdBLCAweDEyQjQyQkIyLCAweEFBQjE1RUVBLCAweEMyQjI3MjIyLAorICAgIDB4REY1N0MyQUIsIDB4Qjc1NEVFNjMsIDB4MEY1MTlCM0IsIDB4Njc1MkI3RjMsCisgICAgMHgzNDlBRkEyOSwgMHg1Qzk5RDZFMSwgMHhFNDlDQTNCOSwgMHg4QzlGOEY3MSwKKyAgICAweDkxN0EzRkY4LCAweEY5NzkxMzMwLCAweDQxN0M2NjY4LCAweDI5N0Y0QUEwLAorICAgIDB4RTZFQ0ZEREMsIDB4OEVFRkQxMTQsIDB4MzZFQUE0NEMsIDB4NUVFOTg4ODQsCisgICAgMHg0MzBDMzgwRCwgMHgyQjBGMTRDNSwgMHg5MzBBNjE5RCwgMHhGQjA5NEQ1NSwKKyAgICAweEE4QzEwMDhGLCAweEMwQzIyQzQ3LCAweDc4Qzc1OTFGLCAweDEwQzQ3NUQ3LAorICAgIDB4MEQyMUM1NUUsIDB4NjUyMkU5OTYsIDB4REQyNzlDQ0UsIDB4QjUyNEIwMDYsCisgICAgMHg0N0VDODRDNywgMHgyRkVGQTgwRiwgMHg5N0VBREQ1NywgMHhGRkU5RjE5RiwKKyAgICAweEUyMEM0MTE2LCAweDhBMEY2RERFLCAweDMyMEExODg2LCAweDVBMDkzNDRFLAorICAgIDB4MDlDMTc5OTQsIDB4NjFDMjU1NUMsIDB4RDlDNzIwMDQsIDB4QjFDNDBDQ0MsCisgICAgMHhBQzIxQkM0NSwgMHhDNDIyOTA4RCwgMHg3QzI3RTVENSwgMHgxNDI0QzkxRCwKKyAgICAweERCQjc3RTYxLCAweEIzQjQ1MkE5LCAweDBCQjEyN0YxLCAweDYzQjIwQjM5LAorICAgIDB4N0U1N0JCQjAsIDB4MTY1NDk3NzgsIDB4QUU1MUUyMjAsIDB4QzY1MkNFRTgsCisgICAgMHg5NTlBODMzMiwgMHhGRDk5QUZGQSwgMHg0NTlDREFBMiwgMHgyRDlGRjY2QSwKKyAgICAweDMwN0E0NkUzLCAweDU4Nzk2QTJCLCAweEUwN0MxRjczLCAweDg4N0YzM0JCLAorICAgIDB4RjU2RTBFRjQsIDB4OUQ2RDIyM0MsIDB4MjU2ODU3NjQsIDB4NEQ2QjdCQUMsCisgICAgMHg1MDhFQ0IyNSwgMHgzODhERTdFRCwgMHg4MDg4OTJCNSwgMHhFODhCQkU3RCwKKyAgICAweEJCNDNGM0E3LCAweEQzNDBERjZGLCAweDZCNDVBQTM3LCAweDAzNDY4NkZGLAorICAgIDB4MUVBMzM2NzYsIDB4NzZBMDFBQkUsIDB4Q0VBNTZGRTYsIDB4QTZBNjQzMkUsCisgICAgMHg2OTM1RjQ1MiwgMHgwMTM2RDg5QSwgMHhCOTMzQURDMiwgMHhEMTMwODEwQSwKKyAgICAweENDRDUzMTgzLCAweEE0RDYxRDRCLCAweDFDRDM2ODEzLCAweDc0RDA0NERCLAorICAgIDB4MjcxODA5MDEsIDB4NEYxQjI1QzksIDB4RjcxRTUwOTEsIDB4OUYxRDdDNTksCisgICAgMHg4MkY4Q0NEMCwgMHhFQUZCRTAxOCwgMHg1MkZFOTU0MCwgMHgzQUZEQjk4OCwKKyAgICAweEM4MzU4RDQ5LCAweEEwMzZBMTgxLCAweDE4MzNENEQ5LCAweDcwMzBGODExLAorICAgIDB4NkRENTQ4OTgsIDB4MDVENjY0NTAsIDB4QkREMzExMDgsIDB4RDVEMDNEQzAsCisgICAgMHg4NjE4NzAxQSwgMHhFRTFCNUNEMiwgMHg1NjFFMjk4QSwgMHgzRTFEMDU0MiwKKyAgICAweDIzRjhCNUNCLCAweDRCRkI5OTAzLCAweEYzRkVFQzVCLCAweDlCRkRDMDkzLAorICAgIDB4NTQ2RTc3RUYsIDB4M0M2RDVCMjcsIDB4ODQ2ODJFN0YsIDB4RUM2QjAyQjcsCisgICAgMHhGMThFQjIzRSwgMHg5OThEOUVGNiwgMHgyMTg4RUJBRSwgMHg0OThCQzc2NiwKKyAgICAweDFBNDM4QUJDLCAweDcyNDBBNjc0LCAweENBNDVEMzJDLCAweEEyNDZGRkU0LAorICAgIDB4QkZBMzRGNkQsIDB4RDdBMDYzQTUsIDB4NkZBNTE2RkQsIDB4MDdBNjNBMzUsCisgICAgMHg4RkQ5MDk4RSwgMHhFN0RBMjU0NiwgMHg1RkRGNTAxRSwgMHgzN0RDN0NENiwKKyAgICAweDJBMzlDQzVGLCAweDQyM0FFMDk3LCAweEZBM0Y5NUNGLCAweDkyM0NCOTA3LAorICAgIDB4QzFGNEY0REQsIDB4QTlGN0Q4MTUsIDB4MTFGMkFENEQsIDB4NzlGMTgxODUsCisgICAgMHg2NDE0MzEwQywgMHgwQzE3MURDNCwgMHhCNDEyNjg5QywgMHhEQzExNDQ1NCwKKyAgICAweDEzODJGMzI4LCAweDdCODFERkUwLCAweEMzODRBQUI4LCAweEFCODc4NjcwLAorICAgIDB4QjY2MjM2RjksIDB4REU2MTFBMzEsIDB4NjY2NDZGNjksIDB4MEU2NzQzQTEsCisgICAgMHg1REFGMEU3QiwgMHgzNUFDMjJCMywgMHg4REE5NTdFQiwgMHhFNUFBN0IyMywKKyAgICAweEY4NEZDQkFBLCAweDkwNENFNzYyLCAweDI4NDk5MjNBLCAweDQwNEFCRUYyLAorICAgIDB4QjI4MjhBMzMsIDB4REE4MUE2RkIsIDB4NjI4NEQzQTMsIDB4MEE4N0ZGNkIsCisgICAgMHgxNzYyNEZFMiwgMHg3RjYxNjMyQSwgMHhDNzY0MTY3MiwgMHhBRjY3M0FCQSwKKyAgICAweEZDQUY3NzYwLCAweDk0QUM1QkE4LCAweDJDQTkyRUYwLCAweDQ0QUEwMjM4LAorICAgIDB4NTk0RkIyQjEsIDB4MzE0QzlFNzksIDB4ODk0OUVCMjEsIDB4RTE0QUM3RTksCisgICAgMHgyRUQ5NzA5NSwgMHg0NkRBNUM1RCwgMHhGRURGMjkwNSwgMHg5NkRDMDVDRCwKKyAgICAweDhCMzlCNTQ0LCAweEUzM0E5OThDLCAweDVCM0ZFQ0Q0LCAweDMzM0NDMDFDLAorICAgIDB4NjBGNDhEQzYsIDB4MDhGN0ExMEUsIDB4QjBGMkQ0NTYsIDB4RDhGMUY4OUUsCisgICAgMHhDNTE0NDgxNywgMHhBRDE3NjRERiwgMHgxNTEyMTE4NywgMHg3RDExM0Q0RiwKKyAgICAvKiBUOF83ICovCisgICAgMHgwMDAwMDAwMCwgMHg0OTNDN0QyNywgMHg5Mjc4RkE0RSwgMHhEQjQ0ODc2OSwKKyAgICAweDIxMUQ4MjZELCAweDY4MjFGRjRBLCAweEIzNjU3ODIzLCAweEZBNTkwNTA0LAorICAgIDB4NDIzQjA0REEsIDB4MEIwNzc5RkQsIDB4RDA0M0ZFOTQsIDB4OTk3RjgzQjMsCisgICAgMHg2MzI2ODZCNywgMHgyQTFBRkI5MCwgMHhGMTVFN0NGOSwgMHhCODYyMDFERSwKKyAgICAweDg0NzYwOUI0LCAweENENEE3NDkzLCAweDE2MEVGM0ZBLCAweDVGMzI4RURELAorICAgIDB4QTU2QjhCRDksIDB4RUM1N0Y2RkUsIDB4MzcxMzcxOTcsIDB4N0UyRjBDQjAsCisgICAgMHhDNjREMEQ2RSwgMHg4RjcxNzA0OSwgMHg1NDM1RjcyMCwgMHgxRDA5OEEwNywKKyAgICAweEU3NTA4RjAzLCAweEFFNkNGMjI0LCAweDc1Mjg3NTRELCAweDNDMTQwODZBLAorICAgIDB4MEQwMDY1OTksIDB4NDQzQzE4QkUsIDB4OUY3ODlGRDcsIDB4RDY0NEUyRjAsCisgICAgMHgyQzFERTdGNCwgMHg2NTIxOUFEMywgMHhCRTY1MURCQSwgMHhGNzU5NjA5RCwKKyAgICAweDRGM0I2MTQzLCAweDA2MDcxQzY0LCAweERENDM5QjBELCAweDk0N0ZFNjJBLAorICAgIDB4NkUyNkUzMkUsIDB4MjcxQTlFMDksIDB4RkM1RTE5NjAsIDB4QjU2MjY0NDcsCisgICAgMHg4OTc2NkMyRCwgMHhDMDRBMTEwQSwgMHgxQjBFOTY2MywgMHg1MjMyRUI0NCwKKyAgICAweEE4NkJFRTQwLCAweEUxNTc5MzY3LCAweDNBMTMxNDBFLCAweDczMkY2OTI5LAorICAgIDB4Q0I0RDY4RjcsIDB4ODI3MTE1RDAsIDB4NTkzNTkyQjksIDB4MTAwOUVGOUUsCisgICAgMHhFQTUwRUE5QSwgMHhBMzZDOTdCRCwgMHg3ODI4MTBENCwgMHgzMTE0NkRGMywKKyAgICAweDFBMDBDQjMyLCAweDUzM0NCNjE1LCAweDg4NzgzMTdDLCAweEMxNDQ0QzVCLAorICAgIDB4M0IxRDQ5NUYsIDB4NzIyMTM0NzgsIDB4QTk2NUIzMTEsIDB4RTA1OUNFMzYsCisgICAgMHg1ODNCQ0ZFOCwgMHgxMTA3QjJDRiwgMHhDQTQzMzVBNiwgMHg4MzdGNDg4MSwKKyAgICAweDc5MjY0RDg1LCAweDMwMUEzMEEyLCAweEVCNUVCN0NCLCAweEEyNjJDQUVDLAorICAgIDB4OUU3NkMyODYsIDB4RDc0QUJGQTEsIDB4MEMwRTM4QzgsIDB4NDUzMjQ1RUYsCisgICAgMHhCRjZCNDBFQiwgMHhGNjU3M0RDQywgMHgyRDEzQkFBNSwgMHg2NDJGQzc4MiwKKyAgICAweERDNERDNjVDLCAweDk1NzFCQjdCLCAweDRFMzUzQzEyLCAweDA3MDk0MTM1LAorICAgIDB4RkQ1MDQ0MzEsIDB4QjQ2QzM5MTYsIDB4NkYyOEJFN0YsIDB4MjYxNEMzNTgsCisgICAgMHgxNzAwQUVBQiwgMHg1RTNDRDM4QywgMHg4NTc4NTRFNSwgMHhDQzQ0MjlDMiwKKyAgICAweDM2MUQyQ0M2LCAweDdGMjE1MUUxLCAweEE0NjVENjg4LCAweEVENTlBQkFGLAorICAgIDB4NTUzQkFBNzEsIDB4MUMwN0Q3NTYsIDB4Qzc0MzUwM0YsIDB4OEU3RjJEMTgsCisgICAgMHg3NDI2MjgxQywgMHgzRDFBNTUzQiwgMHhFNjVFRDI1MiwgMHhBRjYyQUY3NSwKKyAgICAweDkzNzZBNzFGLCAweERBNEFEQTM4LCAweDAxMEU1RDUxLCAweDQ4MzIyMDc2LAorICAgIDB4QjI2QjI1NzIsIDB4RkI1NzU4NTUsIDB4MjAxM0RGM0MsIDB4NjkyRkEyMUIsCisgICAgMHhEMTREQTNDNSwgMHg5ODcxREVFMiwgMHg0MzM1NTk4QiwgMHgwQTA5MjRBQywKKyAgICAweEYwNTAyMUE4LCAweEI5NkM1QzhGLCAweDYyMjhEQkU2LCAweDJCMTRBNkMxLAorICAgIDB4MzQwMTk2NjQsIDB4N0QzREVCNDMsIDB4QTY3OTZDMkEsIDB4RUY0NTExMEQsCisgICAgMHgxNTFDMTQwOSwgMHg1QzIwNjkyRSwgMHg4NzY0RUU0NywgMHhDRTU4OTM2MCwKKyAgICAweDc2M0E5MkJFLCAweDNGMDZFRjk5LCAweEU0NDI2OEYwLCAweEFEN0UxNUQ3LAorICAgIDB4NTcyNzEwRDMsIDB4MUUxQjZERjQsIDB4QzU1RkVBOUQsIDB4OEM2Mzk3QkEsCisgICAgMHhCMDc3OUZEMCwgMHhGOTRCRTJGNywgMHgyMjBGNjU5RSwgMHg2QjMzMThCOSwKKyAgICAweDkxNkExREJELCAweEQ4NTY2MDlBLCAweDAzMTJFN0YzLCAweDRBMkU5QUQ0LAorICAgIDB4RjI0QzlCMEEsIDB4QkI3MEU2MkQsIDB4NjAzNDYxNDQsIDB4MjkwODFDNjMsCisgICAgMHhEMzUxMTk2NywgMHg5QTZENjQ0MCwgMHg0MTI5RTMyOSwgMHgwODE1OUUwRSwKKyAgICAweDM5MDFGM0ZELCAweDcwM0Q4RURBLCAweEFCNzkwOUIzLCAweEUyNDU3NDk0LAorICAgIDB4MTgxQzcxOTAsIDB4NTEyMDBDQjcsIDB4OEE2NDhCREUsIDB4QzM1OEY2RjksCisgICAgMHg3QjNBRjcyNywgMHgzMjA2OEEwMCwgMHhFOTQyMEQ2OSwgMHhBMDdFNzA0RSwKKyAgICAweDVBMjc3NTRBLCAweDEzMUIwODZELCAweEM4NUY4RjA0LCAweDgxNjNGMjIzLAorICAgIDB4QkQ3N0ZBNDksIDB4RjQ0Qjg3NkUsIDB4MkYwRjAwMDcsIDB4NjYzMzdEMjAsCisgICAgMHg5QzZBNzgyNCwgMHhENTU2MDUwMywgMHgwRTEyODI2QSwgMHg0NzJFRkY0RCwKKyAgICAweEZGNENGRTkzLCAweEI2NzA4M0I0LCAweDZEMzQwNERELCAweDI0MDg3OUZBLAorICAgIDB4REU1MTdDRkUsIDB4OTc2RDAxRDksIDB4NEMyOTg2QjAsIDB4MDUxNUZCOTcsCisgICAgMHgyRTAxNUQ1NiwgMHg2NzNEMjA3MSwgMHhCQzc5QTcxOCwgMHhGNTQ1REEzRiwKKyAgICAweDBGMUNERjNCLCAweDQ2MjBBMjFDLCAweDlENjQyNTc1LCAweEQ0NTg1ODUyLAorICAgIDB4NkMzQTU5OEMsIDB4MjUwNjI0QUIsIDB4RkU0MkEzQzIsIDB4Qjc3RURFRTUsCisgICAgMHg0RDI3REJFMSwgMHgwNDFCQTZDNiwgMHhERjVGMjFBRiwgMHg5NjYzNUM4OCwKKyAgICAweEFBNzc1NEUyLCAweEUzNEIyOUM1LCAweDM4MEZBRUFDLCAweDcxMzNEMzhCLAorICAgIDB4OEI2QUQ2OEYsIDB4QzI1NkFCQTgsIDB4MTkxMjJDQzEsIDB4NTAyRTUxRTYsCisgICAgMHhFODRDNTAzOCwgMHhBMTcwMkQxRiwgMHg3QTM0QUE3NiwgMHgzMzA4RDc1MSwKKyAgICAweEM5NTFEMjU1LCAweDgwNkRBRjcyLCAweDVCMjkyODFCLCAweDEyMTU1NTNDLAorICAgIDB4MjMwMTM4Q0YsIDB4NkEzRDQ1RTgsIDB4QjE3OUMyODEsIDB4Rjg0NUJGQTYsCisgICAgMHgwMjFDQkFBMiwgMHg0QjIwQzc4NSwgMHg5MDY0NDBFQywgMHhEOTU4M0RDQiwKKyAgICAweDYxM0EzQzE1LCAweDI4MDY0MTMyLCAweEYzNDJDNjVCLCAweEJBN0VCQjdDLAorICAgIDB4NDAyN0JFNzgsIDB4MDkxQkMzNUYsIDB4RDI1RjQ0MzYsIDB4OUI2MzM5MTEsCisgICAgMHhBNzc3MzE3QiwgMHhFRTRCNEM1QywgMHgzNTBGQ0IzNSwgMHg3QzMzQjYxMiwKKyAgICAweDg2NkFCMzE2LCAweENGNTZDRTMxLCAweDE0MTI0OTU4LCAweDVEMkUzNDdGLAorICAgIDB4RTU0QzM1QTEsIDB4QUM3MDQ4ODYsIDB4NzczNENGRUYsIDB4M0UwOEIyQzgsCisgICAgMHhDNDUxQjdDQywgMHg4RDZEQ0FFQiwgMHg1NjI5NEQ4MiwgMHgxRjE1MzBBNQorICB9OworfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvc25hcHB5L1NuYXBweUNvbXByZXNzb3JJbnB1dFN0cmVhbS5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvc25hcHB5L1NuYXBweUNvbXByZXNzb3JJbnB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ2NTBjYjgKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9zbmFwcHkvU25hcHB5Q29tcHJlc3NvcklucHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwyODYgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuc25hcHB5OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLmx6NzdzdXBwb3J0LkFic3RyYWN0TFo3N0NvbXByZXNzb3JJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuQnl0ZVV0aWxzOworCisvKioKKyAqIENvbXByZXNzb3JJbnB1dFN0cmVhbSBmb3IgdGhlIHJhdyBTbmFwcHkgZm9ybWF0LgorICoKKyAqIDxwPlRoaXMgaW1wbGVtZW50YXRpb24gdXNlcyBhbiBpbnRlcm5hbCBidWZmZXIgaW4gb3JkZXIgdG8gaGFuZGxlCisgKiB0aGUgYmFjay1yZWZlcmVuY2VzIHRoYXQgYXJlIGF0IHRoZSBoZWFydCBvZiB0aGUgTFo3NyBhbGdvcml0aG0uCisgKiBUaGUgc2l6ZSBvZiB0aGUgYnVmZmVyIG11c3QgYmUgYXQgbGVhc3QgYXMgYmlnIGFzIHRoZSBiaWdnZXN0CisgKiBvZmZzZXQgdXNlZCBpbiB0aGUgY29tcHJlc3NlZCBzdHJlYW0uICBUaGUgY3VycmVudCB2ZXJzaW9uIG9mIHRoZQorICogU25hcHB5IGFsZ29yaXRobSBhcyBkZWZpbmVkIGJ5IEdvb2dsZSB3b3JrcyBvbiAzMmsgYmxvY2tzIGFuZAorICogZG9lc24ndCBjb250YWluIG9mZnNldHMgYmlnZ2VyIHRoYW4gMzJrIHdoaWNoIGlzIHRoZSBkZWZhdWx0IGJsb2NrCisgKiBzaXplIHVzZWQgYnkgdGhpcyBjbGFzcy48L3A+CisgKgorICogQHNlZSA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL3NuYXBweS9ibG9iL21hc3Rlci9mb3JtYXRfZGVzY3JpcHRpb24udHh0Ij5TbmFwcHkgY29tcHJlc3NlZCBmb3JtYXQgZGVzY3JpcHRpb248L2E+CisgKiBAc2luY2UgMS43CisgKi8KK3B1YmxpYyBjbGFzcyBTbmFwcHlDb21wcmVzc29ySW5wdXRTdHJlYW0gZXh0ZW5kcyBBYnN0cmFjdExaNzdDb21wcmVzc29ySW5wdXRTdHJlYW0geworCisgICAgLyoqIE1hc2sgdXNlZCB0byBkZXRlcm1pbmUgdGhlIHR5cGUgb2YgInRhZyIgaXMgYmVpbmcgcHJvY2Vzc2VkICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFRBR19NQVNLID0gMHgwMzsKKworICAgIC8qKiBEZWZhdWx0IGJsb2NrIHNpemUgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX0JMT0NLX1NJWkUgPSAzMjc2ODsKKworICAgIC8qKiBUaGUgc2l6ZSBvZiB0aGUgdW5jb21wcmVzc2VkIGRhdGEgKi8KKyAgICBwcml2YXRlIGZpbmFsIGludCBzaXplOworCisgICAgLyoqIE51bWJlciBvZiB1bmNvbXByZXNzZWQgYnl0ZXMgc3RpbGwgdG8gYmUgcmVhZC4gKi8KKyAgICBwcml2YXRlIGludCB1bmNvbXByZXNzZWRCeXRlc1JlbWFpbmluZzsKKworICAgIC8qKiBDdXJyZW50IHN0YXRlIG9mIHRoZSBzdHJlYW0gKi8KKyAgICBwcml2YXRlIFN0YXRlIHN0YXRlID0gU3RhdGUuTk9fQkxPQ0s7CisKKyAgICBwcml2YXRlIGJvb2xlYW4gZW5kUmVhY2hlZCA9IGZhbHNlOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IgdXNpbmcgdGhlIGRlZmF1bHQgYnVmZmVyIHNpemUgb2YgMzJrLgorICAgICAqCisgICAgICogQHBhcmFtIGlzCisgICAgICogICAgICAgICAgICBBbiBJbnB1dFN0cmVhbSB0byByZWFkIGNvbXByZXNzZWQgZGF0YSBmcm9tCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHJlYWRpbmcgZmFpbHMKKyAgICAgKi8KKyAgICBwdWJsaWMgU25hcHB5Q29tcHJlc3NvcklucHV0U3RyZWFtKGZpbmFsIElucHV0U3RyZWFtIGlzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzKGlzLCBERUZBVUxUX0JMT0NLX1NJWkUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yIHVzaW5nIGEgY29uZmlndXJhYmxlIGJ1ZmZlciBzaXplLgorICAgICAqCisgICAgICogQHBhcmFtIGlzCisgICAgICogICAgICAgICAgICBBbiBJbnB1dFN0cmVhbSB0byByZWFkIGNvbXByZXNzZWQgZGF0YSBmcm9tCisgICAgICogQHBhcmFtIGJsb2NrU2l6ZQorICAgICAqICAgICAgICAgICAgVGhlIGJsb2NrIHNpemUgdXNlZCBpbiBjb21wcmVzc2lvbgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiByZWFkaW5nIGZhaWxzCisgICAgICovCisgICAgcHVibGljIFNuYXBweUNvbXByZXNzb3JJbnB1dFN0cmVhbShmaW5hbCBJbnB1dFN0cmVhbSBpcywgZmluYWwgaW50IGJsb2NrU2l6ZSkKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyKGlzLCBibG9ja1NpemUpOworICAgICAgICB1bmNvbXByZXNzZWRCeXRlc1JlbWFpbmluZyA9IHNpemUgPSAoaW50KSByZWFkU2l6ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIHtAaW5oZXJpdERvY30KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHJlYWQoZmluYWwgYnl0ZVtdIGIsIGZpbmFsIGludCBvZmYsIGZpbmFsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChlbmRSZWFjaGVkKSB7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICAgICAgc3dpdGNoIChzdGF0ZSkgeworICAgICAgICBjYXNlIE5PX0JMT0NLOgorICAgICAgICAgICAgZmlsbCgpOworICAgICAgICAgICAgcmV0dXJuIHJlYWQoYiwgb2ZmLCBsZW4pOworICAgICAgICBjYXNlIElOX0xJVEVSQUw6CisgICAgICAgICAgICBpbnQgbGl0TGVuID0gcmVhZExpdGVyYWwoYiwgb2ZmLCBsZW4pOworICAgICAgICAgICAgaWYgKCFoYXNNb3JlRGF0YUluQmxvY2soKSkgeworICAgICAgICAgICAgICAgIHN0YXRlID0gU3RhdGUuTk9fQkxPQ0s7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbGl0TGVuID4gMCA/IGxpdExlbiA6IHJlYWQoYiwgb2ZmLCBsZW4pOworICAgICAgICBjYXNlIElOX0JBQ0tfUkVGRVJFTkNFOgorICAgICAgICAgICAgaW50IGJhY2tSZWZlcmVuY2VMZW4gPSByZWFkQmFja1JlZmVyZW5jZShiLCBvZmYsIGxlbik7CisgICAgICAgICAgICBpZiAoIWhhc01vcmVEYXRhSW5CbG9jaygpKSB7CisgICAgICAgICAgICAgICAgc3RhdGUgPSBTdGF0ZS5OT19CTE9DSzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBiYWNrUmVmZXJlbmNlTGVuID4gMCA/IGJhY2tSZWZlcmVuY2VMZW4gOiByZWFkKGIsIG9mZiwgbGVuKTsKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiVW5rbm93biBzdHJlYW0gc3RhdGUgIiArIHN0YXRlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRyeSB0byBmaWxsIHRoZSBidWZmZXIgd2l0aCB0aGUgbmV4dCBibG9jayBvZiBkYXRhLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBmaWxsKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHVuY29tcHJlc3NlZEJ5dGVzUmVtYWluaW5nID09IDApIHsKKyAgICAgICAgICAgIGVuZFJlYWNoZWQgPSB0cnVlOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgaW50IGIgPSByZWFkT25lQnl0ZSgpOworICAgICAgICBpZiAoYiA9PSAtMSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJQcmVtYXR1cmUgZW5kIG9mIHN0cmVhbSByZWFkaW5nIGJsb2NrIHN0YXJ0Iik7CisgICAgICAgIH0KKyAgICAgICAgaW50IGxlbmd0aCA9IDA7CisgICAgICAgIGludCBvZmZzZXQgPSAwOworCisgICAgICAgIHN3aXRjaCAoYiAmIFRBR19NQVNLKSB7CisKKyAgICAgICAgY2FzZSAweDAwOgorCisgICAgICAgICAgICBsZW5ndGggPSByZWFkTGl0ZXJhbExlbmd0aChiKTsKKyAgICAgICAgICAgIHVuY29tcHJlc3NlZEJ5dGVzUmVtYWluaW5nIC09IGxlbmd0aDsKKyAgICAgICAgICAgIHN0YXJ0TGl0ZXJhbChsZW5ndGgpOworICAgICAgICAgICAgc3RhdGUgPSBTdGF0ZS5JTl9MSVRFUkFMOworICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgY2FzZSAweDAxOgorCisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogVGhlc2UgZWxlbWVudHMgY2FuIGVuY29kZSBsZW5ndGhzIGJldHdlZW4gWzQuLjExXSBieXRlcyBhbmQKKyAgICAgICAgICAgICAqIG9mZnNldHMgYmV0d2VlbiBbMC4uMjA0N10gYnl0ZXMuIChsZW4tNCkgb2NjdXBpZXMgdGhyZWUgYml0cworICAgICAgICAgICAgICogYW5kIGlzIHN0b3JlZCBpbiBiaXRzIFsyLi40XSBvZiB0aGUgdGFnIGJ5dGUuIFRoZSBvZmZzZXQKKyAgICAgICAgICAgICAqIG9jY3VwaWVzIDExIGJpdHMsIG9mIHdoaWNoIHRoZSB1cHBlciB0aHJlZSBhcmUgc3RvcmVkIGluIHRoZQorICAgICAgICAgICAgICogdXBwZXIgdGhyZWUgYml0cyAoWzUuLjddKSBvZiB0aGUgdGFnIGJ5dGUsIGFuZCB0aGUgbG93ZXIKKyAgICAgICAgICAgICAqIGVpZ2h0IGFyZSBzdG9yZWQgaW4gYSBieXRlIGZvbGxvd2luZyB0aGUgdGFnIGJ5dGUuCisgICAgICAgICAgICAgKi8KKworICAgICAgICAgICAgbGVuZ3RoID0gNCArICgoYiA+PiAyKSAmIDB4MDcpOworICAgICAgICAgICAgdW5jb21wcmVzc2VkQnl0ZXNSZW1haW5pbmcgLT0gbGVuZ3RoOworICAgICAgICAgICAgb2Zmc2V0ID0gKGIgJiAweEUwKSA8PCAzOworICAgICAgICAgICAgYiA9IHJlYWRPbmVCeXRlKCk7CisgICAgICAgICAgICBpZiAoYiA9PSAtMSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiUHJlbWF0dXJlIGVuZCBvZiBzdHJlYW0gcmVhZGluZyBiYWNrLXJlZmVyZW5jZSBsZW5ndGgiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIG9mZnNldCB8PSBiOworCisgICAgICAgICAgICBzdGFydEJhY2tSZWZlcmVuY2Uob2Zmc2V0LCBsZW5ndGgpOworICAgICAgICAgICAgc3RhdGUgPSBTdGF0ZS5JTl9CQUNLX1JFRkVSRU5DRTsKKyAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgIGNhc2UgMHgwMjoKKworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIFRoZXNlIGVsZW1lbnRzIGNhbiBlbmNvZGUgbGVuZ3RocyBiZXR3ZWVuIFsxLi42NF0gYW5kIG9mZnNldHMKKyAgICAgICAgICAgICAqIGZyb20gWzAuLjY1NTM1XS4gKGxlbi0xKSBvY2N1cGllcyBzaXggYml0cyBhbmQgaXMgc3RvcmVkIGluCisgICAgICAgICAgICAgKiB0aGUgdXBwZXIgc2l4IGJpdHMgKFsyLi43XSkgb2YgdGhlIHRhZyBieXRlLiBUaGUgb2Zmc2V0IGlzCisgICAgICAgICAgICAgKiBzdG9yZWQgYXMgYSBsaXR0bGUtZW5kaWFuIDE2LWJpdCBpbnRlZ2VyIGluIHRoZSB0d28gYnl0ZXMKKyAgICAgICAgICAgICAqIGZvbGxvd2luZyB0aGUgdGFnIGJ5dGUuCisgICAgICAgICAgICAgKi8KKworICAgICAgICAgICAgbGVuZ3RoID0gKGIgPj4gMikgKyAxOworICAgICAgICAgICAgdW5jb21wcmVzc2VkQnl0ZXNSZW1haW5pbmcgLT0gbGVuZ3RoOworCisgICAgICAgICAgICBvZmZzZXQgPSAoaW50KSBCeXRlVXRpbHMuZnJvbUxpdHRsZUVuZGlhbihzdXBwbGllciwgMik7CisKKyAgICAgICAgICAgIHN0YXJ0QmFja1JlZmVyZW5jZShvZmZzZXQsIGxlbmd0aCk7CisgICAgICAgICAgICBzdGF0ZSA9IFN0YXRlLklOX0JBQ0tfUkVGRVJFTkNFOworICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgY2FzZSAweDAzOgorCisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogVGhlc2UgYXJlIGxpa2UgdGhlIGNvcGllcyB3aXRoIDItYnl0ZSBvZmZzZXRzIChzZWUgcHJldmlvdXMKKyAgICAgICAgICAgICAqIHN1YnNlY3Rpb24pLCBleGNlcHQgdGhhdCB0aGUgb2Zmc2V0IGlzIHN0b3JlZCBhcyBhIDMyLWJpdAorICAgICAgICAgICAgICogaW50ZWdlciBpbnN0ZWFkIG9mIGEgMTYtYml0IGludGVnZXIgKGFuZCB0aHVzIHdpbGwgb2NjdXB5CisgICAgICAgICAgICAgKiBmb3VyIGJ5dGVzKS4KKyAgICAgICAgICAgICAqLworCisgICAgICAgICAgICBsZW5ndGggPSAoYiA+PiAyKSArIDE7CisgICAgICAgICAgICB1bmNvbXByZXNzZWRCeXRlc1JlbWFpbmluZyAtPSBsZW5ndGg7CisKKyAgICAgICAgICAgIG9mZnNldCA9IChpbnQpIEJ5dGVVdGlscy5mcm9tTGl0dGxlRW5kaWFuKHN1cHBsaWVyLCA0KSAmIDB4N2ZmZmZmZmY7CisKKyAgICAgICAgICAgIHN0YXJ0QmFja1JlZmVyZW5jZShvZmZzZXQsIGxlbmd0aCk7CisgICAgICAgICAgICBzdGF0ZSA9IFN0YXRlLklOX0JBQ0tfUkVGRVJFTkNFOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAvLyBpbXBvc3NpYmxlIGFzIFRBR19NQVNLIGlzIHR3byBiaXRzIGFuZCBhbGwgZm91ciBwb3NzaWJsZSBjYXNlcyBoYXZlIGJlZW4gY292ZXJlZAorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKgorICAgICAqIEZvciBsaXRlcmFscyB1cCB0byBhbmQgaW5jbHVkaW5nIDYwIGJ5dGVzIGluIGxlbmd0aCwgdGhlCisgICAgICogdXBwZXIgc2l4IGJpdHMgb2YgdGhlIHRhZyBieXRlIGNvbnRhaW4gKGxlbi0xKS4gVGhlIGxpdGVyYWwKKyAgICAgKiBmb2xsb3dzIGltbWVkaWF0ZWx5IHRoZXJlYWZ0ZXIgaW4gdGhlIGJ5dGVzdHJlYW0uIC0gRm9yCisgICAgICogbG9uZ2VyIGxpdGVyYWxzLCB0aGUgKGxlbi0xKSB2YWx1ZSBpcyBzdG9yZWQgYWZ0ZXIgdGhlIHRhZworICAgICAqIGJ5dGUsIGxpdHRsZS1lbmRpYW4uIFRoZSB1cHBlciBzaXggYml0cyBvZiB0aGUgdGFnIGJ5dGUKKyAgICAgKiBkZXNjcmliZSBob3cgbWFueSBieXRlcyBhcmUgdXNlZCBmb3IgdGhlIGxlbmd0aDsgNjAsIDYxLCA2MgorICAgICAqIG9yIDYzIGZvciAxLTQgYnl0ZXMsIHJlc3BlY3RpdmVseS4gVGhlIGxpdGVyYWwgaXRzZWxmIGZvbGxvd3MKKyAgICAgKiBhZnRlciB0aGUgbGVuZ3RoLgorICAgICAqLworICAgIHByaXZhdGUgaW50IHJlYWRMaXRlcmFsTGVuZ3RoKGZpbmFsIGludCBiKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgbGVuZ3RoOworICAgICAgICBzd2l0Y2ggKGIgPj4gMikgeworICAgICAgICBjYXNlIDYwOgorICAgICAgICAgICAgbGVuZ3RoID0gcmVhZE9uZUJ5dGUoKTsKKyAgICAgICAgICAgIGlmIChsZW5ndGggPT0gLTEpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlByZW1hdHVyZSBlbmQgb2Ygc3RyZWFtIHJlYWRpbmcgbGl0ZXJhbCBsZW5ndGgiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIDYxOgorICAgICAgICAgICAgbGVuZ3RoID0gKGludCkgQnl0ZVV0aWxzLmZyb21MaXR0bGVFbmRpYW4oc3VwcGxpZXIsIDIpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgNjI6CisgICAgICAgICAgICBsZW5ndGggPSAoaW50KSBCeXRlVXRpbHMuZnJvbUxpdHRsZUVuZGlhbihzdXBwbGllciwgMyk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSA2MzoKKyAgICAgICAgICAgIGxlbmd0aCA9IChpbnQpIEJ5dGVVdGlscy5mcm9tTGl0dGxlRW5kaWFuKHN1cHBsaWVyLCA0KTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgbGVuZ3RoID0gYiA+PiAyOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gbGVuZ3RoICsgMTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgc3RyZWFtIHN0YXJ0cyB3aXRoIHRoZSB1bmNvbXByZXNzZWQgbGVuZ3RoICh1cCB0byBhIG1heGltdW0gb2YgMl4zMiAtCisgICAgICogMSksIHN0b3JlZCBhcyBhIGxpdHRsZS1lbmRpYW4gdmFyaW50LiBWYXJpbnRzIGNvbnNpc3Qgb2YgYSBzZXJpZXMgb2YKKyAgICAgKiBieXRlcywgd2hlcmUgdGhlIGxvd2VyIDcgYml0cyBhcmUgZGF0YSBhbmQgdGhlIHVwcGVyIGJpdCBpcyBzZXQgaWZmIHRoZXJlCisgICAgICogYXJlIG1vcmUgYnl0ZXMgdG8gYmUgcmVhZC4gSW4gb3RoZXIgd29yZHMsIGFuIHVuY29tcHJlc3NlZCBsZW5ndGggb2YgNjQKKyAgICAgKiB3b3VsZCBiZSBzdG9yZWQgYXMgMHg0MCwgYW5kIGFuIHVuY29tcHJlc3NlZCBsZW5ndGggb2YgMjA5NzE1MCAoMHgxRkZGRkUpCisgICAgICogd291bGQgYmUgc3RvcmVkIGFzIDB4RkUgMHhGRiAweDdGLgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgc2l6ZSBvZiB0aGUgdW5jb21wcmVzc2VkIGRhdGEKKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBDb3VsZCBub3QgcmVhZCBhIGJ5dGUKKyAgICAgKi8KKyAgICBwcml2YXRlIGxvbmcgcmVhZFNpemUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgaW5kZXggPSAwOworICAgICAgICBsb25nIHN6ID0gMDsKKyAgICAgICAgaW50IGIgPSAwOworCisgICAgICAgIGRvIHsKKyAgICAgICAgICAgIGIgPSByZWFkT25lQnl0ZSgpOworICAgICAgICAgICAgaWYgKGIgPT0gLTEpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlByZW1hdHVyZSBlbmQgb2Ygc3RyZWFtIHJlYWRpbmcgc2l6ZSIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgc3ogfD0gKGIgJiAweDdmKSA8PCAoaW5kZXgrKyAqIDcpOworICAgICAgICB9IHdoaWxlICgwICE9IChiICYgMHg4MCkpOworICAgICAgICByZXR1cm4gc3o7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSB1bmNvbXByZXNzZWQgc2l6ZSBvZiB0aGUgc3RyZWFtCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB1bmNvbXByZXNzZWQgc2l6ZQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0U2l6ZSgpIHsKKyAgICAgICAgcmV0dXJuIHNpemU7CisgICAgfQorCisgICAgcHJpdmF0ZSBlbnVtIFN0YXRlIHsKKyAgICAgICAgTk9fQkxPQ0ssIElOX0xJVEVSQUwsIElOX0JBQ0tfUkVGRVJFTkNFCisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvc25hcHB5L1NuYXBweUNvbXByZXNzb3JPdXRwdXRTdHJlYW0uamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL3NuYXBweS9TbmFwcHlDb21wcmVzc29yT3V0cHV0U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGM3YjNiMQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL3NuYXBweS9TbmFwcHlDb21wcmVzc29yT3V0cHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwyODggQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuc25hcHB5OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5Db21wcmVzc29yT3V0cHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5sejc3c3VwcG9ydC5MWjc3Q29tcHJlc3NvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMubHo3N3N1cHBvcnQuUGFyYW1ldGVyczsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuQnl0ZVV0aWxzOworCisvKioKKyAqIENvbXByZXNzb3JPdXRwdXRTdHJlYW0gZm9yIHRoZSByYXcgU25hcHB5IGZvcm1hdC4KKyAqCisgKiA8cD5UaGlzIGltcGxlbWVudGF0aW9uIHVzZXMgYW4gaW50ZXJuYWwgYnVmZmVyIGluIG9yZGVyIHRvIGhhbmRsZQorICogdGhlIGJhY2stcmVmZXJlbmNlcyB0aGF0IGFyZSBhdCB0aGUgaGVhcnQgb2YgdGhlIExaNzcgYWxnb3JpdGhtLgorICogVGhlIHNpemUgb2YgdGhlIGJ1ZmZlciBtdXN0IGJlIGF0IGxlYXN0IGFzIGJpZyBhcyB0aGUgYmlnZ2VzdAorICogb2Zmc2V0IHVzZWQgaW4gdGhlIGNvbXByZXNzZWQgc3RyZWFtLiAgVGhlIGN1cnJlbnQgdmVyc2lvbiBvZiB0aGUKKyAqIFNuYXBweSBhbGdvcml0aG0gYXMgZGVmaW5lZCBieSBHb29nbGUgd29ya3Mgb24gMzJrIGJsb2NrcyBhbmQKKyAqIGRvZXNuJ3QgY29udGFpbiBvZmZzZXRzIGJpZ2dlciB0aGFuIDMyayB3aGljaCBpcyB0aGUgZGVmYXVsdCBibG9jaworICogc2l6ZSB1c2VkIGJ5IHRoaXMgY2xhc3MuPC9wPgorICoKKyAqIDxwPlRoZSByYXcgU25hcHB5IGZvcm1hdCByZXF1aXJlcyB0aGUgdW5jb21wcmVzc2VkIHNpemUgdG8gYmUKKyAqIHdyaXR0ZW4gYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgc3RyZWFtIHVzaW5nIGEgdmFyaW50CisgKiByZXByZXNlbnRhdGlvbiwgaS5lLiB0aGUgbnVtYmVyIG9mIGJ5dGVzIG5lZWRlZCB0byB3cml0ZSB0aGUKKyAqIGluZm9ybWF0aW9uIGlzIG5vdCBrbm93biBiZWZvcmUgdGhlIHVuY29tcHJlc3NlZCBzaXplIGlzCisgKiBrbm93bi4gV2UndmUgY2hvc2VuIHRvIG1ha2UgdGhlIHVuY29tcHJlc3NlZFNpemUgYSBwYXJhbWV0ZXIgb2YgdGhlCisgKiBjb25zdHJ1Y3RvciBpbiBmYXZvciBvZiBidWZmZXJpbmcgdGhlIHdob2xlIG91dHB1dCB1bnRpbCB0aGUgc2l6ZQorICogaXMga25vd24uIFdoZW4gdXNpbmcgdGhlIHtAbGluayBGcmFtZWRTbmFwcHlDb21wcmVzc29yT3V0cHV0U3RyZWFtfQorICogdGhpcyBsaW1pdGF0aW9uIGlzIHRha2VuIGNhcmUgb2YgYnkgdGhlIHdhcnBwaW5nIGZyYW1pbmcKKyAqIGZvcm1hdC48L3A+CisgKgorICogQHNlZSA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL3NuYXBweS9ibG9iL21hc3Rlci9mb3JtYXRfZGVzY3JpcHRpb24udHh0Ij5TbmFwcHkgY29tcHJlc3NlZCBmb3JtYXQgZGVzY3JpcHRpb248L2E+CisgKiBAc2luY2UgMS4xNAorICogQE5vdFRocmVhZFNhZmUKKyAqLworcHVibGljIGNsYXNzIFNuYXBweUNvbXByZXNzb3JPdXRwdXRTdHJlYW0gZXh0ZW5kcyBDb21wcmVzc29yT3V0cHV0U3RyZWFtIHsKKyAgICBwcml2YXRlIGZpbmFsIExaNzdDb21wcmVzc29yIGNvbXByZXNzb3I7CisgICAgcHJpdmF0ZSBmaW5hbCBPdXRwdXRTdHJlYW0gb3M7CisgICAgcHJpdmF0ZSBmaW5hbCBCeXRlVXRpbHMuQnl0ZUNvbnN1bWVyIGNvbnN1bWVyOworCisgICAgLy8gdXNlZCBpbiBvbmUtYXJnIHdyaXRlIG1ldGhvZAorICAgIHByaXZhdGUgZmluYWwgYnl0ZVtdIG9uZUJ5dGUgPSBuZXcgYnl0ZVsxXTsKKworICAgIHByaXZhdGUgYm9vbGVhbiBmaW5pc2hlZCA9IGZhbHNlOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IgdXNpbmcgdGhlIGRlZmF1bHQgYmxvY2sgc2l6ZSBvZiAzMmsuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3MgdGhlIG91dHB1dHN0cmVhbSB0byB3cml0ZSBjb21wcmVzc2VkIGRhdGEgdG8KKyAgICAgKiBAcGFyYW0gdW5jb21wcmVzc2VkU2l6ZSB0aGUgdW5jb21wcmVzc2VkIHNpemUgb2YgZGF0YQorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgd3JpdGluZyBvZiB0aGUgc2l6ZSBmYWlscworICAgICAqLworICAgIHB1YmxpYyBTbmFwcHlDb21wcmVzc29yT3V0cHV0U3RyZWFtKGZpbmFsIE91dHB1dFN0cmVhbSBvcywgZmluYWwgbG9uZyB1bmNvbXByZXNzZWRTaXplKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzKG9zLCB1bmNvbXByZXNzZWRTaXplLCBTbmFwcHlDb21wcmVzc29ySW5wdXRTdHJlYW0uREVGQVVMVF9CTE9DS19TSVpFKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvciB1c2luZyBhIGNvbmZpZ3VyYWJsZSBibG9jayBzaXplLgorICAgICAqCisgICAgICogQHBhcmFtIG9zIHRoZSBvdXRwdXRzdHJlYW0gdG8gd3JpdGUgY29tcHJlc3NlZCBkYXRhIHRvCisgICAgICogQHBhcmFtIHVuY29tcHJlc3NlZFNpemUgdGhlIHVuY29tcHJlc3NlZCBzaXplIG9mIGRhdGEKKyAgICAgKiBAcGFyYW0gYmxvY2tTaXplIHRoZSBibG9jayBzaXplIHVzZWQgLSBtdXN0IGJlIGEgcG93ZXIgb2YgdHdvCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiB3cml0aW5nIG9mIHRoZSBzaXplIGZhaWxzCisgICAgICovCisgICAgcHVibGljIFNuYXBweUNvbXByZXNzb3JPdXRwdXRTdHJlYW0oZmluYWwgT3V0cHV0U3RyZWFtIG9zLCBmaW5hbCBsb25nIHVuY29tcHJlc3NlZFNpemUsIGZpbmFsIGludCBibG9ja1NpemUpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMob3MsIHVuY29tcHJlc3NlZFNpemUsIGNyZWF0ZVBhcmFtZXRlckJ1aWxkZXIoYmxvY2tTaXplKS5idWlsZCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvciBwcm92aWRpbmcgZnVsbCBjb250cm9sIG92ZXIgdGhlIHVuZGVybHlpbmcgTFo3NyBjb21wcmVzc29yLgorICAgICAqCisgICAgICogQHBhcmFtIG9zIHRoZSBvdXRwdXRzdHJlYW0gdG8gd3JpdGUgY29tcHJlc3NlZCBkYXRhIHRvCisgICAgICogQHBhcmFtIHVuY29tcHJlc3NlZFNpemUgdGhlIHVuY29tcHJlc3NlZCBzaXplIG9mIGRhdGEKKyAgICAgKiBAcGFyYW0gcGFyYW1zIHRoZSBwYXJhbWV0ZXJzIHRvIHVzZSBieSB0aGUgY29tcHJlc3NvciAtIG5vdGUKKyAgICAgKiB0aGF0IHRoZSBmb3JtYXQgaXRzZWxmIGltcG9zZXMgc29tZSBsaW1pdHMgbGlrZSBhIG1heGltdW0gbWF0Y2gKKyAgICAgKiBsZW5ndGggb2YgNjQgYnl0ZXMKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHdyaXRpbmcgb2YgdGhlIHNpemUgZmFpbHMKKyAgICAgKi8KKyAgICBwdWJsaWMgU25hcHB5Q29tcHJlc3Nvck91dHB1dFN0cmVhbShmaW5hbCBPdXRwdXRTdHJlYW0gb3MsIGZpbmFsIGxvbmcgdW5jb21wcmVzc2VkU2l6ZSwgUGFyYW1ldGVycyBwYXJhbXMpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMub3MgPSBvczsKKyAgICAgICAgY29uc3VtZXIgPSBuZXcgQnl0ZVV0aWxzLk91dHB1dFN0cmVhbUJ5dGVDb25zdW1lcihvcyk7CisgICAgICAgIGNvbXByZXNzb3IgPSBuZXcgTFo3N0NvbXByZXNzb3IocGFyYW1zLCBuZXcgTFo3N0NvbXByZXNzb3IuQ2FsbGJhY2soKSB7CisgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgYWNjZXB0KExaNzdDb21wcmVzc29yLkJsb2NrIGJsb2NrKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGJsb2NrLmdldFR5cGUoKSkgeworICAgICAgICAgICAgICAgICAgICBjYXNlIExJVEVSQUw6CisgICAgICAgICAgICAgICAgICAgICAgICB3cml0ZUxpdGVyYWxCbG9jaygoTFo3N0NvbXByZXNzb3IuTGl0ZXJhbEJsb2NrKSBibG9jayk7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSBCQUNLX1JFRkVSRU5DRToKKyAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlQmFja1JlZmVyZW5jZSgoTFo3N0NvbXByZXNzb3IuQmFja1JlZmVyZW5jZSkgYmxvY2spOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIGNhc2UgRU9EOgorICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9KTsKKyAgICAgICAgd3JpdGVVbmNvbXByZXNzZWRTaXplKHVuY29tcHJlc3NlZFNpemUpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGludCBiKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvbmVCeXRlWzBdID0gKGJ5dGUpIChiICYgMHhmZik7CisgICAgICAgIHdyaXRlKG9uZUJ5dGUpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGJ5dGVbXSBkYXRhLCBpbnQgb2ZmLCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjb21wcmVzc29yLmNvbXByZXNzKGRhdGEsIG9mZiwgbGVuKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmaW5pc2goKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIG9zLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wcmVzc2VzIGFsbCByZW1haW5pbmcgZGF0YSBhbmQgd3JpdGVzIGl0IHRvIHRoZSBzdHJlYW0sCisgICAgICogZG9lc24ndCBjbG9zZSB0aGUgdW5kZXJseWluZyBzdHJlYW0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiBhbiBlcnJvciBvY2N1cnMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBmaW5pc2goKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoIWZpbmlzaGVkKSB7CisgICAgICAgICAgICBjb21wcmVzc29yLmZpbmlzaCgpOworICAgICAgICAgICAgZmluaXNoZWQgPSB0cnVlOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlVW5jb21wcmVzc2VkU2l6ZShsb25nIHVuY29tcHJlc3NlZFNpemUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJvb2xlYW4gbW9yZSA9IGZhbHNlOworICAgICAgICBkbyB7CisgICAgICAgICAgICBpbnQgY3VycmVudEJ5dGUgPSAoaW50KSAodW5jb21wcmVzc2VkU2l6ZSAmIDB4N0YpOworICAgICAgICAgICAgbW9yZSA9IHVuY29tcHJlc3NlZFNpemUgPiBjdXJyZW50Qnl0ZTsKKyAgICAgICAgICAgIGlmIChtb3JlKSB7CisgICAgICAgICAgICAgICAgY3VycmVudEJ5dGUgfD0gMHg4MDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIG9zLndyaXRlKGN1cnJlbnRCeXRlKTsKKyAgICAgICAgICAgIHVuY29tcHJlc3NlZFNpemUgPj49IDc7CisgICAgICAgIH0gd2hpbGUgKG1vcmUpOworICAgIH0KKworICAgIC8vIGxpdGVyYWwgbGVuZ3RoIGlzIHN0b3JlZCBhcyAobGVuIC0gMSkgZWl0aGVyIGluc2lkZSB0aGUgdGFnCisgICAgLy8gKHNpeCBiaXRzIG1pbnVzIGZvdXIgZmxhZ3MpIG9yIGluIDEgdG8gNCBieXRlcyBhZnRlciB0aGUgdGFnCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE1BWF9MSVRFUkFMX1NJWkVfV0lUSE9VVF9TSVpFX0JZVEVTID0gNjA7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE1BWF9MSVRFUkFMX1NJWkVfV0lUSF9PTkVfU0laRV9CWVRFID0gMSA8PCA4OworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNQVhfTElURVJBTF9TSVpFX1dJVEhfVFdPX1NJWkVfQllURVMgPSAxIDw8IDE2OworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNQVhfTElURVJBTF9TSVpFX1dJVEhfVEhSRUVfU0laRV9CWVRFUyA9IDEgPDwgMjQ7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgT05FX1NJWkVfQllURV9NQVJLRVIgPSA2MCA8PCAyOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBUV09fU0laRV9CWVRFX01BUktFUiA9IDYxIDw8IDI7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFRIUkVFX1NJWkVfQllURV9NQVJLRVIgPSA2MiA8PCAyOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBGT1VSX1NJWkVfQllURV9NQVJLRVIgPSA2MyA8PCAyOworCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlTGl0ZXJhbEJsb2NrKExaNzdDb21wcmVzc29yLkxpdGVyYWxCbG9jayBibG9jaykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IGxlbiA9IGJsb2NrLmdldExlbmd0aCgpOworICAgICAgICBpZiAobGVuIDw9IE1BWF9MSVRFUkFMX1NJWkVfV0lUSE9VVF9TSVpFX0JZVEVTKSB7CisgICAgICAgICAgICB3cml0ZUxpdGVyYWxCbG9ja05vU2l6ZUJ5dGVzKGJsb2NrLCBsZW4pOworICAgICAgICB9IGVsc2UgaWYgKGxlbiA8PSBNQVhfTElURVJBTF9TSVpFX1dJVEhfT05FX1NJWkVfQllURSkgeworICAgICAgICAgICAgd3JpdGVMaXRlcmFsQmxvY2tPbmVTaXplQnl0ZShibG9jaywgbGVuKTsKKyAgICAgICAgfSBlbHNlIGlmIChsZW4gPD0gTUFYX0xJVEVSQUxfU0laRV9XSVRIX1RXT19TSVpFX0JZVEVTKSB7CisgICAgICAgICAgICB3cml0ZUxpdGVyYWxCbG9ja1R3b1NpemVCeXRlcyhibG9jaywgbGVuKTsKKyAgICAgICAgfSBlbHNlIGlmIChsZW4gPD0gTUFYX0xJVEVSQUxfU0laRV9XSVRIX1RIUkVFX1NJWkVfQllURVMpIHsKKyAgICAgICAgICAgIHdyaXRlTGl0ZXJhbEJsb2NrVGhyZWVTaXplQnl0ZXMoYmxvY2ssIGxlbik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB3cml0ZUxpdGVyYWxCbG9ja0ZvdXJTaXplQnl0ZXMoYmxvY2ssIGxlbik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgd3JpdGVMaXRlcmFsQmxvY2tOb1NpemVCeXRlcyhMWjc3Q29tcHJlc3Nvci5MaXRlcmFsQmxvY2sgYmxvY2ssIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHdyaXRlTGl0ZXJhbEJsb2NrV2l0aFNpemUobGVuIC0gMSA8PCAyLCAwLCBsZW4sIGJsb2NrKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgd3JpdGVMaXRlcmFsQmxvY2tPbmVTaXplQnl0ZShMWjc3Q29tcHJlc3Nvci5MaXRlcmFsQmxvY2sgYmxvY2ssIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHdyaXRlTGl0ZXJhbEJsb2NrV2l0aFNpemUoT05FX1NJWkVfQllURV9NQVJLRVIsIDEsIGxlbiwgYmxvY2spOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB3cml0ZUxpdGVyYWxCbG9ja1R3b1NpemVCeXRlcyhMWjc3Q29tcHJlc3Nvci5MaXRlcmFsQmxvY2sgYmxvY2ssIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHdyaXRlTGl0ZXJhbEJsb2NrV2l0aFNpemUoVFdPX1NJWkVfQllURV9NQVJLRVIsIDIsIGxlbiwgYmxvY2spOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB3cml0ZUxpdGVyYWxCbG9ja1RocmVlU2l6ZUJ5dGVzKExaNzdDb21wcmVzc29yLkxpdGVyYWxCbG9jayBibG9jaywgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgd3JpdGVMaXRlcmFsQmxvY2tXaXRoU2l6ZShUSFJFRV9TSVpFX0JZVEVfTUFSS0VSLCAzLCBsZW4sIGJsb2NrKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgd3JpdGVMaXRlcmFsQmxvY2tGb3VyU2l6ZUJ5dGVzKExaNzdDb21wcmVzc29yLkxpdGVyYWxCbG9jayBibG9jaywgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgd3JpdGVMaXRlcmFsQmxvY2tXaXRoU2l6ZShGT1VSX1NJWkVfQllURV9NQVJLRVIsIDQsIGxlbiwgYmxvY2spOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB3cml0ZUxpdGVyYWxCbG9ja1dpdGhTaXplKGludCB0YWdCeXRlLCBpbnQgc2l6ZUJ5dGVzLCBpbnQgbGVuLCBMWjc3Q29tcHJlc3Nvci5MaXRlcmFsQmxvY2sgYmxvY2spCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG9zLndyaXRlKHRhZ0J5dGUpOworICAgICAgICB3cml0ZUxpdHRsZUVuZGlhbihzaXplQnl0ZXMsIGxlbiAtIDEpOworICAgICAgICBvcy53cml0ZShibG9jay5nZXREYXRhKCksIGJsb2NrLmdldE9mZnNldCgpLCBsZW4pOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB3cml0ZUxpdHRsZUVuZGlhbihmaW5hbCBpbnQgbnVtQnl0ZXMsIGludCBudW0pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEJ5dGVVdGlscy50b0xpdHRsZUVuZGlhbihjb25zdW1lciwgbnVtLCBudW1CeXRlcyk7CisgICAgfQorCisgICAgLy8gQmFjay1yZWZlcmVuY2VzICgiY29waWVzIikgaGF2ZSB0aGVpciBvZmZzZXQvc2l6ZSBpbmZvcm1hdGlvbgorICAgIC8vIGluIHR3bywgdGhyZWUgb3IgZml2ZSBieXRlcy4KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTUlOX01BVENIX0xFTkdUSF9XSVRIX09ORV9PRkZTRVRfQllURSA9IDQ7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE1BWF9NQVRDSF9MRU5HVEhfV0lUSF9PTkVfT0ZGU0VUX0JZVEUgPSAxMTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTUFYX09GRlNFVF9XSVRIX09ORV9PRkZTRVRfQllURSA9IDEgPDwgMTEgLSAxOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNQVhfT0ZGU0VUX1dJVEhfVFdPX09GRlNFVF9CWVRFUyA9IDEgPDwgMTYgLSAxOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE9ORV9CWVRFX0NPUFlfVEFHID0gMTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVFdPX0JZVEVfQ09QWV9UQUcgPSAyOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBGT1VSX0JZVEVfQ09QWV9UQUcgPSAzOworCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlQmFja1JlZmVyZW5jZShMWjc3Q29tcHJlc3Nvci5CYWNrUmVmZXJlbmNlIGJsb2NrKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBpbnQgbGVuID0gYmxvY2suZ2V0TGVuZ3RoKCk7CisgICAgICAgIGZpbmFsIGludCBvZmZzZXQgPSBibG9jay5nZXRPZmZzZXQoKTsKKyAgICAgICAgaWYgKGxlbiA+PSBNSU5fTUFUQ0hfTEVOR1RIX1dJVEhfT05FX09GRlNFVF9CWVRFICYmIGxlbiA8PSBNQVhfTUFUQ0hfTEVOR1RIX1dJVEhfT05FX09GRlNFVF9CWVRFCisgICAgICAgICAgICAmJiBvZmZzZXQgPD0gTUFYX09GRlNFVF9XSVRIX09ORV9PRkZTRVRfQllURSkgeworICAgICAgICAgICAgd3JpdGVCYWNrUmVmZXJlbmNlV2l0aE9uZU9mZnNldEJ5dGUobGVuLCBvZmZzZXQpOworICAgICAgICB9IGVsc2UgaWYgKG9mZnNldCA8IE1BWF9PRkZTRVRfV0lUSF9UV09fT0ZGU0VUX0JZVEVTKSB7CisgICAgICAgICAgICB3cml0ZUJhY2tSZWZlcmVuY2VXaXRoVHdvT2Zmc2V0Qnl0ZXMobGVuLCBvZmZzZXQpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgd3JpdGVCYWNrUmVmZXJlbmNlV2l0aEZvdXJPZmZzZXRCeXRlcyhsZW4sIG9mZnNldCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgd3JpdGVCYWNrUmVmZXJlbmNlV2l0aE9uZU9mZnNldEJ5dGUoaW50IGxlbiwgaW50IG9mZnNldCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgb3Mud3JpdGUoT05FX0JZVEVfQ09QWV9UQUcgfCAoKGxlbiAtIDQpIDw8IDIpIHwgKChvZmZzZXQgJiAweDcwMCkgPj4gMykpOworICAgICAgICBvcy53cml0ZShvZmZzZXQgJiAweGZmKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgd3JpdGVCYWNrUmVmZXJlbmNlV2l0aFR3b09mZnNldEJ5dGVzKGludCBsZW4sIGludCBvZmZzZXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHdyaXRlQmFja1JlZmVyZW5jZVdpdGhMaXR0bGVFbmRpYW5PZmZzZXQoVFdPX0JZVEVfQ09QWV9UQUcsIDIsIGxlbiwgb2Zmc2V0KTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgd3JpdGVCYWNrUmVmZXJlbmNlV2l0aEZvdXJPZmZzZXRCeXRlcyhpbnQgbGVuLCBpbnQgb2Zmc2V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB3cml0ZUJhY2tSZWZlcmVuY2VXaXRoTGl0dGxlRW5kaWFuT2Zmc2V0KEZPVVJfQllURV9DT1BZX1RBRywgNCwgbGVuLCBvZmZzZXQpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB3cml0ZUJhY2tSZWZlcmVuY2VXaXRoTGl0dGxlRW5kaWFuT2Zmc2V0KGludCB0YWcsIGludCBvZmZzZXRCeXRlcywgaW50IGxlbiwgaW50IG9mZnNldCkKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgb3Mud3JpdGUodGFnIHwgKChsZW4gLSAxKSA8PCAyKSk7CisgICAgICAgIHdyaXRlTGl0dGxlRW5kaWFuKG9mZnNldEJ5dGVzLCBvZmZzZXQpOworICAgIH0KKworICAgIC8vIHRlY2huaWNhbGx5IHRoZSBmb3JtYXQgY291bGQgdXNlIHNob3J0ZXIgbWF0Y2hlcyBidXQgd2l0aCBhCisgICAgLy8gbGVuZ3RoIG9mIHRocmVlIHRoZSBvZmZzZXQgd291bGQgYmUgZW5jb2RlZCBhcyBhdCBsZWFzdCB0d28KKyAgICAvLyBieXRlcyBpbiBhZGRpdGlvbiB0byB0aGUgdGFnLCBzbyB5aWVsZCBubyBjb21wcmVzc2lvbiBhdCBhbGwKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTUlOX01BVENIX0xFTkdUSCA9IDQ7CisgICAgLy8gU25hcHB5IHN0b3JlcyB0aGUgbWF0Y2ggbGVuZ3RoIGluIHNpeCBiaXRzIG9mIHRoZSB0YWcKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTUFYX01BVENIX0xFTkdUSCA9IDY0OworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGJ1aWxkZXIgY29ycmVjdGx5IGNvbmZpZ3VyZWQgZm9yIHRoZSBTbmFwcHkgYWxnb3JpdGhtIHVzaW5nIHRoZSBndmVuIGJsb2NrIHNpemUuCisgICAgICogQHBhcmFtIGJsb2NrU2l6ZSB0aGUgYmxvY2sgc2l6ZS4KKyAgICAgKiBAcmV0dXJuIGEgYnVpbGRlciBjb3JyZWN0bHkgY29uZmlndXJlZCBmb3IgdGhlIFNuYXBweSBhbGdvcml0aG0gdXNpbmcgdGhlIGd2ZW4gYmxvY2sgc2l6ZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgUGFyYW1ldGVycy5CdWlsZGVyIGNyZWF0ZVBhcmFtZXRlckJ1aWxkZXIoaW50IGJsb2NrU2l6ZSkgeworICAgICAgICAvLyB0aGUgbWF4IG9mZnNldCBhbmQgbWF4IGxpdGVyYWwgbGVuZ3RoIGRlZmluZWQgYnkgdGhlIGZvcm1hdAorICAgICAgICAvLyBhcmUgMl4zMiAtIDEgYW5kIDJeMzIgcmVzcGVjdGl2ZWx5IC0gd2l0aCBibG9ja1NpemUgYmVpbmcKKyAgICAgICAgLy8gYW4gaW50ZWdlciB3ZSB3aWxsIG5ldmVyIGV4Y2VlZCB0aGF0CisgICAgICAgIHJldHVybiBQYXJhbWV0ZXJzLmJ1aWxkZXIoYmxvY2tTaXplKQorICAgICAgICAgICAgLndpdGhNaW5CYWNrUmVmZXJlbmNlTGVuZ3RoKE1JTl9NQVRDSF9MRU5HVEgpCisgICAgICAgICAgICAud2l0aE1heEJhY2tSZWZlcmVuY2VMZW5ndGgoTUFYX01BVENIX0xFTkdUSCkKKyAgICAgICAgICAgIC53aXRoTWF4T2Zmc2V0KGJsb2NrU2l6ZSkKKyAgICAgICAgICAgIC53aXRoTWF4TGl0ZXJhbExlbmd0aChibG9ja1NpemUpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL3NuYXBweS9wYWNrYWdlLmh0bWwgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9zbmFwcHkvcGFja2FnZS5odG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVmZWYwNzEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9zbmFwcHkvcGFja2FnZS5odG1sCkBAIC0wLDAgKzEsMzggQEAKKzxodG1sPgorPCEtLQorCisgICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAgIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAgICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorCisgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisKKyAgIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAgIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAgIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAgIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorCistLT4KKyAgPGJvZHk+CisgICAgPHA+UHJvdmlkZXMgc3RyZWFtIGNsYXNzZXMgZm9yIHRoZQorICAgICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9zbmFwcHkiPlNuYXBweTwvYT4KKyAgICAgIGFsZ29yaXRobS48L3A+CisKKyAgICA8cD5UaGUgcmF3IFNuYXBweSBmb3JtYXQgd2hpY2ggb25seSBjb250YWlucyB0aGUgY29tcHJlc3NlZCBkYXRhCisgICAgICBpcyBzdXBwb3J0ZWQgYnkgdGhlIDxjb2RlPlNuYXBweUNvbXByZXNzb3IqcHV0U3RyZWFtPC9jb2RlPgorICAgICAgY2xhc3NlcyB3aGlsZSB0aGUgc28gY2FsbGVkICJmcmFtaW5nIGZvcm1hdCIgaXMgaW1wbGVtZW50ZWQKKyAgICAgIGJ5IDxjb2RlPkZyYW1lZFNuYXBweUNvbXByZXNzb3IqcHV0U3RyZWFtPC9jb2RlPi4gIE5vdGUgdGhlcmUKKyAgICAgIGhhdmUgYmVlbiBkaWZmZXJlbnQgdmVyc2lvbnMgb2YgdGhlIGZyYW1pbmcgZm9ybWF0IHNwZWNpZmljYXRpb24sCisgICAgICB0aGUgaW1wbGVtZW50YXRpb24gaW4gQ29tbW9ucyBDb21wcmVzcyBpcyBiYXNlZCBvbiB0aGUKKyAgICAgIHNwZWNpZmljYXRpb24gIkxhc3QgcmV2aXNlZDogMjAxMy0xMC0yNSIuPC9wPgorCisgICAgPHA+T25seSB0aGUgImZyYW1pbmcgZm9ybWF0IiBjYW4gYmUgYXV0by1kZXRlY3RlZCB0aGlzIG1lYW5zIHlvdQorICAgICAgaGF2ZSB0byBzcGVmaWN5IHRoZSBmb3JtYXQgZXhwbGljaXRseSBpZiB5b3Ugd2FudCB0byByZWFkIGEKKyAgICAgICJyYXciIFNuYXBweSBzdHJlYW0KKyAgICAgIHZpYSA8Y29kZT5Db21wcmVzc29yU3RyZWFtRmFjdG9yeTwvY29kZT4uPC9wPgorICA8L2JvZHk+Cis8L2h0bWw+CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy94ei9YWkNvbXByZXNzb3JJbnB1dFN0cmVhbS5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMveHovWFpDb21wcmVzc29ySW5wdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMGQ2N2ExCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMveHovWFpDb21wcmVzc29ySW5wdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDE4OSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy54ejsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKKworaW1wb3J0IG9yZy50dWthYW5pLnh6LlhaOworaW1wb3J0IG9yZy50dWthYW5pLnh6LlNpbmdsZVhaSW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLnR1a2FhbmkueHouWFpJbnB1dFN0cmVhbTsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5NZW1vcnlMaW1pdEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuQ29tcHJlc3NvcklucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5Db3VudGluZ0lucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5JT1V0aWxzOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5JbnB1dFN0cmVhbVN0YXRpc3RpY3M7CisKKy8qKgorICogWFogZGVjb21wcmVzc29yLgorICogQHNpbmNlIDEuNAorICovCitwdWJsaWMgY2xhc3MgWFpDb21wcmVzc29ySW5wdXRTdHJlYW0gZXh0ZW5kcyBDb21wcmVzc29ySW5wdXRTdHJlYW0KKyAgICBpbXBsZW1lbnRzIElucHV0U3RyZWFtU3RhdGlzdGljcyB7CisKKyAgICBwcml2YXRlIGZpbmFsIENvdW50aW5nSW5wdXRTdHJlYW0gY291bnRpbmdTdHJlYW07CisgICAgcHJpdmF0ZSBmaW5hbCBJbnB1dFN0cmVhbSBpbjsKKworICAgIC8qKgorICAgICAqIENoZWNrcyBpZiB0aGUgc2lnbmF0dXJlIG1hdGNoZXMgd2hhdCBpcyBleHBlY3RlZCBmb3IgYSAueHogZmlsZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSAgIHNpZ25hdHVyZSAgICAgdGhlIGJ5dGVzIHRvIGNoZWNrCisgICAgICogQHBhcmFtICAgbGVuZ3RoICAgICAgICB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRvIGNoZWNrCisgICAgICogQHJldHVybiAgdHJ1ZSBpZiBzaWduYXR1cmUgbWF0Y2hlcyB0aGUgLnh6IG1hZ2ljIGJ5dGVzLCBmYWxzZSBvdGhlcndpc2UKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gbWF0Y2hlcyhmaW5hbCBieXRlW10gc2lnbmF0dXJlLCBmaW5hbCBpbnQgbGVuZ3RoKSB7CisgICAgICAgIGlmIChsZW5ndGggPCBYWi5IRUFERVJfTUFHSUMubGVuZ3RoKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IFhaLkhFQURFUl9NQUdJQy5sZW5ndGg7ICsraSkgeworICAgICAgICAgICAgaWYgKHNpZ25hdHVyZVtpXSAhPSBYWi5IRUFERVJfTUFHSUNbaV0pIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IGlucHV0IHN0cmVhbSB0aGF0IGRlY29tcHJlc3NlcyBYWi1jb21wcmVzc2VkIGRhdGEKKyAgICAgKiBmcm9tIHRoZSBzcGVjaWZpZWQgaW5wdXQgc3RyZWFtLiBUaGlzIGRvZXNuJ3Qgc3VwcG9ydAorICAgICAqIGNvbmNhdGVuYXRlZCAueHogZmlsZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gICAgICAgaW5wdXRTdHJlYW0gd2hlcmUgdG8gcmVhZCB0aGUgY29tcHJlc3NlZCBkYXRhCisgICAgICoKKyAgICAgKiBAdGhyb3dzICAgICAgSU9FeGNlcHRpb24gaWYgdGhlIGlucHV0IGlzIG5vdCBpbiB0aGUgLnh6IGZvcm1hdCwKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIGlucHV0IGlzIGNvcnJ1cHQgb3IgdHJ1bmNhdGVkLCB0aGUgLnh6CisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIGhlYWRlcnMgc3BlY2lmeSBvcHRpb25zIHRoYXQgYXJlIG5vdCBzdXBwb3J0ZWQKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgYnkgdGhpcyBpbXBsZW1lbnRhdGlvbiwgb3IgdGhlIHVuZGVybHlpbmcKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgPGNvZGU+aW5wdXRTdHJlYW08L2NvZGU+IHRocm93cyBhbiBleGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgWFpDb21wcmVzc29ySW5wdXRTdHJlYW0oZmluYWwgSW5wdXRTdHJlYW0gaW5wdXRTdHJlYW0pCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzKGlucHV0U3RyZWFtLCBmYWxzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBpbnB1dCBzdHJlYW0gdGhhdCBkZWNvbXByZXNzZXMgWFotY29tcHJlc3NlZCBkYXRhCisgICAgICogZnJvbSB0aGUgc3BlY2lmaWVkIGlucHV0IHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSAgICAgICBpbnB1dFN0cmVhbSB3aGVyZSB0byByZWFkIHRoZSBjb21wcmVzc2VkIGRhdGEKKyAgICAgKiBAcGFyYW0gICAgICAgZGVjb21wcmVzc0NvbmNhdGVuYXRlZAorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICBpZiB0cnVlLCBkZWNvbXByZXNzIHVudGlsIHRoZSBlbmQgb2YgdGhlCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0OyBpZiBmYWxzZSwgc3RvcCBhZnRlciB0aGUgZmlyc3QgLnh6CisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbSBhbmQgbGVhdmUgdGhlIGlucHV0IHBvc2l0aW9uIHRvIHBvaW50CisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIHRvIHRoZSBuZXh0IGJ5dGUgYWZ0ZXIgdGhlIC54eiBzdHJlYW0KKyAgICAgKgorICAgICAqIEB0aHJvd3MgICAgICBJT0V4Y2VwdGlvbiBpZiB0aGUgaW5wdXQgaXMgbm90IGluIHRoZSAueHogZm9ybWF0LAorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICB0aGUgaW5wdXQgaXMgY29ycnVwdCBvciB0cnVuY2F0ZWQsIHRoZSAueHoKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgaGVhZGVycyBzcGVjaWZ5IG9wdGlvbnMgdGhhdCBhcmUgbm90IHN1cHBvcnRlZAorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICBieSB0aGlzIGltcGxlbWVudGF0aW9uLCBvciB0aGUgdW5kZXJseWluZworICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICA8Y29kZT5pbnB1dFN0cmVhbTwvY29kZT4gdGhyb3dzIGFuIGV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBYWkNvbXByZXNzb3JJbnB1dFN0cmVhbShmaW5hbCBJbnB1dFN0cmVhbSBpbnB1dFN0cmVhbSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgYm9vbGVhbiBkZWNvbXByZXNzQ29uY2F0ZW5hdGVkKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcyhpbnB1dFN0cmVhbSwgZGVjb21wcmVzc0NvbmNhdGVuYXRlZCwgLTEpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgaW5wdXQgc3RyZWFtIHRoYXQgZGVjb21wcmVzc2VzIFhaLWNvbXByZXNzZWQgZGF0YQorICAgICAqIGZyb20gdGhlIHNwZWNpZmllZCBpbnB1dCBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gICAgICAgaW5wdXRTdHJlYW0gd2hlcmUgdG8gcmVhZCB0aGUgY29tcHJlc3NlZCBkYXRhCisgICAgICogQHBhcmFtICAgICAgIGRlY29tcHJlc3NDb25jYXRlbmF0ZWQKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgdHJ1ZSwgZGVjb21wcmVzcyB1bnRpbCB0aGUgZW5kIG9mIHRoZQorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dDsgaWYgZmFsc2UsIHN0b3AgYWZ0ZXIgdGhlIGZpcnN0IC54egorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0gYW5kIGxlYXZlIHRoZSBpbnB1dCBwb3NpdGlvbiB0byBwb2ludAorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICB0byB0aGUgbmV4dCBieXRlIGFmdGVyIHRoZSAueHogc3RyZWFtCisgICAgICogQHBhcmFtICAgICAgIG1lbW9yeUxpbWl0SW5LYiBtZW1vcnkgbGltaXQgdXNlZCB3aGVuIHJlYWRpbmcgYmxvY2tzLiAgSWYKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIGVzdGltYXRlZCBtZW1vcnkgbGltaXQgaXMgZXhjZWVkZWQgb24ge0BsaW5rICNyZWFkKCl9LAorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICBhIHtAbGluayBNZW1vcnlMaW1pdEV4Y2VwdGlvbn0gaXMgdGhyb3duLgorICAgICAqCisgICAgICogQHRocm93cyAgICAgIElPRXhjZXB0aW9uIGlmIHRoZSBpbnB1dCBpcyBub3QgaW4gdGhlIC54eiBmb3JtYXQsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBpbnB1dCBpcyBjb3JydXB0IG9yIHRydW5jYXRlZCwgdGhlIC54egorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICBoZWFkZXJzIHNwZWNpZnkgb3B0aW9ucyB0aGF0IGFyZSBub3Qgc3VwcG9ydGVkCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIGJ5IHRoaXMgaW1wbGVtZW50YXRpb24sCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIG9yIHRoZSB1bmRlcmx5aW5nIDxjb2RlPmlucHV0U3RyZWFtPC9jb2RlPiB0aHJvd3MgYW4gZXhjZXB0aW9uCisgICAgICoKKyAgICAgKiBAc2luY2UgMS4xNAorICAgICAqLworICAgIHB1YmxpYyBYWkNvbXByZXNzb3JJbnB1dFN0cmVhbShJbnB1dFN0cmVhbSBpbnB1dFN0cmVhbSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBkZWNvbXByZXNzQ29uY2F0ZW5hdGVkLCBmaW5hbCBpbnQgbWVtb3J5TGltaXRJbktiKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY291bnRpbmdTdHJlYW0gPSBuZXcgQ291bnRpbmdJbnB1dFN0cmVhbShpbnB1dFN0cmVhbSk7CisgICAgICAgIGlmIChkZWNvbXByZXNzQ29uY2F0ZW5hdGVkKSB7CisgICAgICAgICAgICBpbiA9IG5ldyBYWklucHV0U3RyZWFtKGNvdW50aW5nU3RyZWFtLCBtZW1vcnlMaW1pdEluS2IpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaW4gPSBuZXcgU2luZ2xlWFpJbnB1dFN0cmVhbShjb3VudGluZ1N0cmVhbSwgbWVtb3J5TGltaXRJbktiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmaW5hbCBpbnQgcmV0ID0gaW4ucmVhZCgpOworICAgICAgICAgICAgY291bnQocmV0ID09IC0xID8gLTEgOiAxKTsKKyAgICAgICAgICAgIHJldHVybiByZXQ7CisgICAgICAgIH0gY2F0Y2ggKG9yZy50dWthYW5pLnh6Lk1lbW9yeUxpbWl0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBNZW1vcnlMaW1pdEV4Y2VwdGlvbihlLmdldE1lbW9yeU5lZWRlZCgpLCBlLmdldE1lbW9yeUxpbWl0KCksIGUpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCByZWFkKGZpbmFsIGJ5dGVbXSBidWYsIGZpbmFsIGludCBvZmYsIGZpbmFsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmaW5hbCBpbnQgcmV0ID0gaW4ucmVhZChidWYsIG9mZiwgbGVuKTsKKyAgICAgICAgICAgIGNvdW50KHJldCk7CisgICAgICAgICAgICByZXR1cm4gcmV0OworICAgICAgICB9IGNhdGNoIChvcmcudHVrYWFuaS54ei5NZW1vcnlMaW1pdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2NvbnZlcnQgdG8gY29tbW9ucy1jb21wcmVzcyBNZW1vcnlMaW10RXhjZXB0aW9uCisgICAgICAgICAgICB0aHJvdyBuZXcgTWVtb3J5TGltaXRFeGNlcHRpb24oZS5nZXRNZW1vcnlOZWVkZWQoKSwgZS5nZXRNZW1vcnlMaW1pdCgpLCBlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBsb25nIHNraXAoZmluYWwgbG9uZyBuKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIElPVXRpbHMuc2tpcChpbiwgbik7CisgICAgICAgIH0gY2F0Y2ggKG9yZy50dWthYW5pLnh6Lk1lbW9yeUxpbWl0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vY29udmVydCB0byBjb21tb25zLWNvbXByZXNzIE1lbW9yeUxpbXRFeGNlcHRpb24KKyAgICAgICAgICAgIHRocm93IG5ldyBNZW1vcnlMaW1pdEV4Y2VwdGlvbihlLmdldE1lbW9yeU5lZWRlZCgpLCBlLmdldE1lbW9yeUxpbWl0KCksIGUpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBhdmFpbGFibGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gaW4uYXZhaWxhYmxlKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbi5jbG9zZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzaW5jZSAxLjE3CisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGxvbmcgZ2V0Q29tcHJlc3NlZENvdW50KCkgeworICAgICAgICByZXR1cm4gY291bnRpbmdTdHJlYW0uZ2V0Qnl0ZXNSZWFkKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMveHovWFpDb21wcmVzc29yT3V0cHV0U3RyZWFtLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy94ei9YWkNvbXByZXNzb3JPdXRwdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42ZTliNzBlCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMveHovWFpDb21wcmVzc29yT3V0cHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwxMDEgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMueHo7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IG9yZy50dWthYW5pLnh6LkxaTUEyT3B0aW9uczsKK2ltcG9ydCBvcmcudHVrYWFuaS54ei5YWk91dHB1dFN0cmVhbTsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5Db21wcmVzc29yT3V0cHV0U3RyZWFtOworCisvKioKKyAqIFhaIGNvbXByZXNzb3IuCisgKiBAc2luY2UgMS40CisgKi8KK3B1YmxpYyBjbGFzcyBYWkNvbXByZXNzb3JPdXRwdXRTdHJlYW0gZXh0ZW5kcyBDb21wcmVzc29yT3V0cHV0U3RyZWFtIHsKKyAgICBwcml2YXRlIGZpbmFsIFhaT3V0cHV0U3RyZWFtIG91dDsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgWFogY29tcHJlc3NvciB1c2luZyB0aGUgZGVmYXVsdCBMWk1BMiBvcHRpb25zLgorICAgICAqIFRoaXMgaXMgZXF1aXZhbGVudCB0byA8Y29kZT5YWkNvbXByZXNzb3JPdXRwdXRTdHJlYW0ob3V0cHV0U3RyZWFtLCA2KTwvY29kZT4uCisgICAgICogQHBhcmFtIG91dHB1dFN0cmVhbSB0aGUgc3RyZWFtIHRvIHdyYXAKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIG9uIGVycm9yCisgICAgICovCisgICAgcHVibGljIFhaQ29tcHJlc3Nvck91dHB1dFN0cmVhbShmaW5hbCBPdXRwdXRTdHJlYW0gb3V0cHV0U3RyZWFtKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgb3V0ID0gbmV3IFhaT3V0cHV0U3RyZWFtKG91dHB1dFN0cmVhbSwgbmV3IExaTUEyT3B0aW9ucygpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IFhaIGNvbXByZXNzb3IgdXNpbmcgdGhlIHNwZWNpZmllZCBMWk1BMiBwcmVzZXQgbGV2ZWwuCisgICAgICogPHA+CisgICAgICogVGhlIHByZXNldHMgMC0zIGFyZSBmYXN0IHByZXNldHMgd2l0aCBtZWRpdW0gY29tcHJlc3Npb24uCisgICAgICogVGhlIHByZXNldHMgNC02IGFyZSBmYWlybHkgc2xvdyBwcmVzZXRzIHdpdGggaGlnaCBjb21wcmVzc2lvbi4KKyAgICAgKiBUaGUgZGVmYXVsdCBwcmVzZXQgaXMgNi4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgcHJlc2V0cyA3LTkgYXJlIGxpa2UgdGhlIHByZXNldCA2IGJ1dCB1c2UgYmlnZ2VyIGRpY3Rpb25hcmllcworICAgICAqIGFuZCBoYXZlIGhpZ2hlciBjb21wcmVzc29yIGFuZCBkZWNvbXByZXNzb3IgbWVtb3J5IHJlcXVpcmVtZW50cy4KKyAgICAgKiBVbmxlc3MgdGhlIHVuY29tcHJlc3NlZCBzaXplIG9mIHRoZSBmaWxlIGV4Y2VlZHMgOCZuYnNwO01pQiwKKyAgICAgKiAxNiZuYnNwO01pQiwgb3IgMzImbmJzcDtNaUIsIGl0IGlzIHdhc3RlIG9mIG1lbW9yeSB0byB1c2UgdGhlCisgICAgICogcHJlc2V0cyA3LCA4LCBvciA5LCByZXNwZWN0aXZlbHkuCisgICAgICogQHBhcmFtIG91dHB1dFN0cmVhbSB0aGUgc3RyZWFtIHRvIHdyYXAKKyAgICAgKiBAcGFyYW0gcHJlc2V0IHRoZSBwcmVzZXQKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIG9uIGVycm9yCisgICAgICovCisgICAgcHVibGljIFhaQ29tcHJlc3Nvck91dHB1dFN0cmVhbShmaW5hbCBPdXRwdXRTdHJlYW0gb3V0cHV0U3RyZWFtLCBmaW5hbCBpbnQgcHJlc2V0KQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgb3V0ID0gbmV3IFhaT3V0cHV0U3RyZWFtKG91dHB1dFN0cmVhbSwgbmV3IExaTUEyT3B0aW9ucyhwcmVzZXQpKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShmaW5hbCBpbnQgYikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgb3V0LndyaXRlKGIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGZpbmFsIGJ5dGVbXSBidWYsIGZpbmFsIGludCBvZmYsIGZpbmFsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG91dC53cml0ZShidWYsIG9mZiwgbGVuKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGbHVzaGVzIHRoZSBlbmNvZGVyIGFuZCBjYWxscyA8Y29kZT5vdXRwdXRTdHJlYW0uZmx1c2goKTwvY29kZT4uCisgICAgICogQWxsIGJ1ZmZlcmVkIHBlbmRpbmcgZGF0YSB3aWxsIHRoZW4gYmUgZGVjb21wcmVzc2libGUgZnJvbQorICAgICAqIHRoZSBvdXRwdXQgc3RyZWFtLiBDYWxsaW5nIHRoaXMgZnVuY3Rpb24gdmVyeSBvZnRlbiBtYXkgaW5jcmVhc2UKKyAgICAgKiB0aGUgY29tcHJlc3NlZCBmaWxlIHNpemUgYSBsb3QuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZmx1c2goKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvdXQuZmx1c2goKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaW5pc2hlcyBjb21wcmVzc2lvbiB3aXRob3V0IGNsb3NpbmcgdGhlIHVuZGVybHlpbmcgc3RyZWFtLgorICAgICAqIE5vIG1vcmUgZGF0YSBjYW4gYmUgd3JpdHRlbiB0byB0aGlzIHN0cmVhbSBhZnRlciBmaW5pc2hpbmcuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBvbiBlcnJvcgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGZpbmlzaCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG91dC5maW5pc2goKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG91dC5jbG9zZSgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL3h6L1haVXRpbHMuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL3h6L1haVXRpbHMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iZTQ2MjVlCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMveHovWFpVdGlscy5qYXZhCkBAIC0wLDAgKzEsMTgwIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLnh6OworCitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuRmlsZU5hbWVVdGlsOworCisvKioKKyAqIFV0aWxpdHkgY29kZSBmb3IgdGhlIHh6IGNvbXByZXNzaW9uIGZvcm1hdC4KKyAqIEBUaHJlYWRTYWZlCisgKiBAc2luY2UgMS40CisgKi8KK3B1YmxpYyBjbGFzcyBYWlV0aWxzIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEZpbGVOYW1lVXRpbCBmaWxlTmFtZVV0aWw7CisKKyAgICAvKioKKyAgICAgKiBYWiBIZWFkZXIgTWFnaWMgQnl0ZXMgYmVnaW4gYSBYWiBmaWxlLgorICAgICAqCisgICAgICogPHA+VGhpcyBpcyBhIGNvcHkgb2Yge0Bjb2RlIG9yZy50dWthYW5pLnh6LlhaLkhFQURFUl9NQUdJQ30gaW4KKyAgICAgKiBYWiBmb3IgSmF2YSB2ZXJzaW9uIDEuNS48L3A+CisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIEhFQURFUl9NQUdJQyA9IHsKKyAgICAgICAgKGJ5dGUpIDB4RkQsICc3JywgJ3onLCAnWCcsICdaJywgJ1wwJworICAgIH07CisKKyAgICBlbnVtIENhY2hlZEF2YWlsYWJpbGl0eSB7CisgICAgICAgIERPTlRfQ0FDSEUsIENBQ0hFRF9BVkFJTEFCTEUsIENBQ0hFRF9VTkFWQUlMQUJMRQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvbGF0aWxlIENhY2hlZEF2YWlsYWJpbGl0eSBjYWNoZWRYWkF2YWlsYWJpbGl0eTsKKworICAgIHN0YXRpYyB7CisgICAgICAgIGZpbmFsIE1hcDxTdHJpbmcsIFN0cmluZz4gdW5jb21wcmVzc1N1ZmZpeCA9IG5ldyBIYXNoTWFwPD4oKTsKKyAgICAgICAgdW5jb21wcmVzc1N1ZmZpeC5wdXQoIi50eHoiLCAiLnRhciIpOworICAgICAgICB1bmNvbXByZXNzU3VmZml4LnB1dCgiLnh6IiwgIiIpOworICAgICAgICB1bmNvbXByZXNzU3VmZml4LnB1dCgiLXh6IiwgIiIpOworICAgICAgICBmaWxlTmFtZVV0aWwgPSBuZXcgRmlsZU5hbWVVdGlsKHVuY29tcHJlc3NTdWZmaXgsICIueHoiKTsKKyAgICAgICAgY2FjaGVkWFpBdmFpbGFiaWxpdHkgPSBDYWNoZWRBdmFpbGFiaWxpdHkuRE9OVF9DQUNIRTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENsYXNzLmZvck5hbWUoIm9yZy5vc2dpLmZyYW1ld29yay5CdW5kbGVFdmVudCIpOworICAgICAgICB9IGNhdGNoIChmaW5hbCBFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHNldENhY2hlWFpBdmFpbGFibGl0eSh0cnVlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKiBQcml2YXRlIGNvbnN0cnVjdG9yIHRvIHByZXZlbnQgaW5zdGFudGlhdGlvbiBvZiB0aGlzIHV0aWxpdHkgY2xhc3MuICovCisgICAgcHJpdmF0ZSBYWlV0aWxzKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrcyBpZiB0aGUgc2lnbmF0dXJlIG1hdGNoZXMgd2hhdCBpcyBleHBlY3RlZCBmb3IgYSAueHogZmlsZS4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgaXMgbW9yZSBvciBsZXNzIGEgY29weSBvZiB0aGUgdmVyc2lvbiBmb3VuZCBpbiB7QGxpbmsKKyAgICAgKiBYWkNvbXByZXNzb3JJbnB1dFN0cmVhbX0gYnV0IGRvZXNuJ3QgZGVwZW5kIG9uIHRoZSBwcmVzZW5jZSBvZgorICAgICAqIFhaIGZvciBKYXZhLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSAgIHNpZ25hdHVyZSAgICAgdGhlIGJ5dGVzIHRvIGNoZWNrCisgICAgICogQHBhcmFtICAgbGVuZ3RoICAgICAgICB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRvIGNoZWNrCisgICAgICogQHJldHVybiAgdHJ1ZSBpZiBzaWduYXR1cmUgbWF0Y2hlcyB0aGUgLnh6IG1hZ2ljIGJ5dGVzLCBmYWxzZSBvdGhlcndpc2UKKyAgICAgKiBAc2luY2UgMS45CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIG1hdGNoZXMoZmluYWwgYnl0ZVtdIHNpZ25hdHVyZSwgZmluYWwgaW50IGxlbmd0aCkgeworICAgICAgICBpZiAobGVuZ3RoIDwgSEVBREVSX01BR0lDLmxlbmd0aCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBIRUFERVJfTUFHSUMubGVuZ3RoOyArK2kpIHsKKyAgICAgICAgICAgIGlmIChzaWduYXR1cmVbaV0gIT0gSEVBREVSX01BR0lDW2ldKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXJlIHRoZSBjbGFzc2VzIHJlcXVpcmVkIHRvIHN1cHBvcnQgWFogY29tcHJlc3Npb24gYXZhaWxhYmxlPworICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGNsYXNzZXMgcmVxdWlyZWQgdG8gc3VwcG9ydCBYWiBjb21wcmVzc2lvbiBhcmUgYXZhaWxhYmxlCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzWFpDb21wcmVzc2lvbkF2YWlsYWJsZSgpIHsKKyAgICAgICAgZmluYWwgQ2FjaGVkQXZhaWxhYmlsaXR5IGNhY2hlZFJlc3VsdCA9IGNhY2hlZFhaQXZhaWxhYmlsaXR5OworICAgICAgICBpZiAoY2FjaGVkUmVzdWx0ICE9IENhY2hlZEF2YWlsYWJpbGl0eS5ET05UX0NBQ0hFKSB7CisgICAgICAgICAgICByZXR1cm4gY2FjaGVkUmVzdWx0ID09IENhY2hlZEF2YWlsYWJpbGl0eS5DQUNIRURfQVZBSUxBQkxFOworICAgICAgICB9CisgICAgICAgIHJldHVybiBpbnRlcm5hbElzWFpDb21wcmVzc2lvbkF2YWlsYWJsZSgpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaW50ZXJuYWxJc1haQ29tcHJlc3Npb25BdmFpbGFibGUoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBYWkNvbXByZXNzb3JJbnB1dFN0cmVhbS5tYXRjaGVzKG51bGwsIDApOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIE5vQ2xhc3NEZWZGb3VuZEVycm9yIGVycm9yKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZXRlY3RzIGNvbW1vbiB4eiBzdWZmaXhlcyBpbiB0aGUgZ2l2ZW4gZmlsZW5hbWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmlsZW5hbWUgbmFtZSBvZiBhIGZpbGUKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgZmlsZW5hbWUgaGFzIGEgY29tbW9uIHh6IHN1ZmZpeCwKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzQ29tcHJlc3NlZEZpbGVuYW1lKGZpbmFsIFN0cmluZyBmaWxlbmFtZSkgeworICAgICAgICByZXR1cm4gZmlsZU5hbWVVdGlsLmlzQ29tcHJlc3NlZEZpbGVuYW1lKGZpbGVuYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBNYXBzIHRoZSBnaXZlbiBuYW1lIG9mIGEgeHotY29tcHJlc3NlZCBmaWxlIHRvIHRoZSBuYW1lIHRoYXQgdGhlCisgICAgICogZmlsZSBzaG91bGQgaGF2ZSBhZnRlciB1bmNvbXByZXNzaW9uLiBDb21tb25seSB1c2VkIGZpbGUgdHlwZSBzcGVjaWZpYworICAgICAqIHN1ZmZpeGVzIGxpa2UgIi50eHoiIGFyZSBhdXRvbWF0aWNhbGx5IGRldGVjdGVkIGFuZAorICAgICAqIGNvcnJlY3RseSBtYXBwZWQuIEZvciBleGFtcGxlIHRoZSBuYW1lICJwYWNrYWdlLnR4eiIgaXMgbWFwcGVkIHRvCisgICAgICogInBhY2thZ2UudGFyIi4gQW5kIGFueSBmaWxlbmFtZXMgd2l0aCB0aGUgZ2VuZXJpYyAiLnh6IiBzdWZmaXgKKyAgICAgKiAob3IgYW55IG90aGVyIGdlbmVyaWMgeHogc3VmZml4KSBpcyBtYXBwZWQgdG8gYSBuYW1lIHdpdGhvdXQgdGhhdAorICAgICAqIHN1ZmZpeC4gSWYgbm8geHogc3VmZml4IGlzIGRldGVjdGVkLCB0aGVuIHRoZSBmaWxlbmFtZSBpcyByZXR1cm5lZAorICAgICAqIHVubWFwcGVkLgorICAgICAqCisgICAgICogQHBhcmFtIGZpbGVuYW1lIG5hbWUgb2YgYSBmaWxlCisgICAgICogQHJldHVybiBuYW1lIG9mIHRoZSBjb3JyZXNwb25kaW5nIHVuY29tcHJlc3NlZCBmaWxlCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0VW5jb21wcmVzc2VkRmlsZW5hbWUoZmluYWwgU3RyaW5nIGZpbGVuYW1lKSB7CisgICAgICAgIHJldHVybiBmaWxlTmFtZVV0aWwuZ2V0VW5jb21wcmVzc2VkRmlsZW5hbWUoZmlsZW5hbWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIE1hcHMgdGhlIGdpdmVuIGZpbGVuYW1lIHRvIHRoZSBuYW1lIHRoYXQgdGhlIGZpbGUgc2hvdWxkIGhhdmUgYWZ0ZXIKKyAgICAgKiBjb21wcmVzc2lvbiB3aXRoIHh6LiBDb21tb24gZmlsZSB0eXBlcyB3aXRoIGN1c3RvbSBzdWZmaXhlcyBmb3IKKyAgICAgKiBjb21wcmVzc2VkIHZlcnNpb25zIGFyZSBhdXRvbWF0aWNhbGx5IGRldGVjdGVkIGFuZCBjb3JyZWN0bHkgbWFwcGVkLgorICAgICAqIEZvciBleGFtcGxlIHRoZSBuYW1lICJwYWNrYWdlLnRhciIgaXMgbWFwcGVkIHRvICJwYWNrYWdlLnR4eiIuIElmIG5vCisgICAgICogY3VzdG9tIG1hcHBpbmcgaXMgYXBwbGljYWJsZSwgdGhlbiB0aGUgZGVmYXVsdCAiLnh6IiBzdWZmaXggaXMgYXBwZW5kZWQKKyAgICAgKiB0byB0aGUgZmlsZW5hbWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmlsZW5hbWUgbmFtZSBvZiBhIGZpbGUKKyAgICAgKiBAcmV0dXJuIG5hbWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgY29tcHJlc3NlZCBmaWxlCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0Q29tcHJlc3NlZEZpbGVuYW1lKGZpbmFsIFN0cmluZyBmaWxlbmFtZSkgeworICAgICAgICByZXR1cm4gZmlsZU5hbWVVdGlsLmdldENvbXByZXNzZWRGaWxlbmFtZShmaWxlbmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogV2hldGhlciB0byBjYWNoZSB0aGUgcmVzdWx0IG9mIHRoZSBYWiBmb3IgSmF2YSBjaGVjay4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgZGVmYXVsdHMgdG8ge0Bjb2RlIGZhbHNlfSBpbiBhbiBPU0dpIGVudmlyb25tZW50IGFuZCB7QGNvZGUgdHJ1ZX0gb3RoZXJ3aXNlLjwvcD4KKyAgICAgKiBAcGFyYW0gZG9DYWNoZSB3aGV0aGVyIHRvIGNhY2hlIHRoZSByZXN1bHQKKyAgICAgKiBAc2luY2UgMS45CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHNldENhY2hlWFpBdmFpbGFibGl0eShmaW5hbCBib29sZWFuIGRvQ2FjaGUpIHsKKyAgICAgICAgaWYgKCFkb0NhY2hlKSB7CisgICAgICAgICAgICBjYWNoZWRYWkF2YWlsYWJpbGl0eSA9IENhY2hlZEF2YWlsYWJpbGl0eS5ET05UX0NBQ0hFOworICAgICAgICB9IGVsc2UgaWYgKGNhY2hlZFhaQXZhaWxhYmlsaXR5ID09IENhY2hlZEF2YWlsYWJpbGl0eS5ET05UX0NBQ0hFKSB7CisgICAgICAgICAgICBmaW5hbCBib29sZWFuIGhhc1h6ID0gaW50ZXJuYWxJc1haQ29tcHJlc3Npb25BdmFpbGFibGUoKTsKKyAgICAgICAgICAgIGNhY2hlZFhaQXZhaWxhYmlsaXR5ID0gaGFzWHogPyBDYWNoZWRBdmFpbGFiaWxpdHkuQ0FDSEVEX0FWQUlMQUJMRSAvLyBOT1NPTkFSCisgICAgICAgICAgICAgICAgOiBDYWNoZWRBdmFpbGFiaWxpdHkuQ0FDSEVEX1VOQVZBSUxBQkxFOworICAgICAgICB9CisgICAgfQorCisgICAgLy8gb25seSBleGlzdHMgdG8gc3VwcG9ydCB1bml0IHRlc3RzCisgICAgc3RhdGljIENhY2hlZEF2YWlsYWJpbGl0eSBnZXRDYWNoZWRYWkF2YWlsYWJpbGl0eSgpIHsKKyAgICAgICAgcmV0dXJuIGNhY2hlZFhaQXZhaWxhYmlsaXR5OworICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL3h6L3BhY2thZ2UuaHRtbCBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL3h6L3BhY2thZ2UuaHRtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40OGVjYTI1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMveHovcGFja2FnZS5odG1sCkBAIC0wLDAgKzEsMzEgQEAKKzxodG1sPgorPCEtLQorCisgICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAgIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAgICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorCisgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisKKyAgIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAgIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAgIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAgIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorCistLT4KKyAgPGJvZHk+CisgICAgPHA+UHJvdmlkZXMgc3RyZWFtIGNsYXNzZXMgZm9yIGNvbXByZXNzaW5nIGFuZCBkZWNvbXByZXNzaW5nCisgICAgICBzdHJlYW1zIHVzaW5nIHRoZSBYWiBhbGdvcml0aG0uPC9wPgorCisgICAgPHA+VGhlIGNsYXNzZXMgaW4gdGhpcyBwYWNrYWdlIGFyZSB3cmFwcGVycyBhcm91bmQge0BsaW5rCisgICAgICBvcmcudHVrYWFuaS54ei5YWklucHV0U3RyZWFtIG9yZy50dWthYW5pLnh6LlhaSW5wdXRTdHJlYW19IGFuZAorICAgICAge0BsaW5rIG9yZy50dWthYW5pLnh6LlhaT3V0cHV0U3RyZWFtCisgICAgICBvcmcudHVrYWFuaS54ei5YWk91dHB1dFN0cmVhbX0gcHJvdmlkZWQgYnkgdGhlIHB1YmxpYworICAgICAgZG9tYWluIDxhIGhyZWY9Imh0dHBzOi8vdHVrYWFuaS5vcmcveHovamF2YS5odG1sIj5YWiBmb3IgSmF2YTwvYT4KKyAgICAgIGxpYnJhcnkuPC9wPgorICA8L2JvZHk+Cis8L2h0bWw+CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy96L1pDb21wcmVzc29ySW5wdXRTdHJlYW0uamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL3ovWkNvbXByZXNzb3JJbnB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI3Y2UxNmYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy96L1pDb21wcmVzc29ySW5wdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDE3MSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy56OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEubmlvLkJ5dGVPcmRlcjsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5sencuTFpXSW5wdXRTdHJlYW07CisKKy8qKgorICogSW5wdXQgc3RyZWFtIHRoYXQgZGVjb21wcmVzc2VzIC5aIGZpbGVzLgorICogQE5vdFRocmVhZFNhZmUKKyAqIEBzaW5jZSAxLjcKKyAqLworcHVibGljIGNsYXNzIFpDb21wcmVzc29ySW5wdXRTdHJlYW0gZXh0ZW5kcyBMWldJbnB1dFN0cmVhbSB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE1BR0lDXzEgPSAweDFmOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNQUdJQ18yID0gMHg5ZDsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQkxPQ0tfTU9ERV9NQVNLID0gMHg4MDsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTUFYX0NPREVfU0laRV9NQVNLID0gMHgxZjsKKyAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gYmxvY2tNb2RlOworICAgIHByaXZhdGUgZmluYWwgaW50IG1heENvZGVTaXplOworICAgIHByaXZhdGUgbG9uZyB0b3RhbENvZGVzUmVhZCA9IDA7CisKKyAgICBwdWJsaWMgWkNvbXByZXNzb3JJbnB1dFN0cmVhbShmaW5hbCBJbnB1dFN0cmVhbSBpbnB1dFN0cmVhbSwgZmluYWwgaW50IG1lbW9yeUxpbWl0SW5LYikKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyKGlucHV0U3RyZWFtLCBCeXRlT3JkZXIuTElUVExFX0VORElBTik7CisgICAgICAgIGZpbmFsIGludCBmaXJzdEJ5dGUgPSAoaW50KSBpbi5yZWFkQml0cyg4KTsKKyAgICAgICAgZmluYWwgaW50IHNlY29uZEJ5dGUgPSAoaW50KSBpbi5yZWFkQml0cyg4KTsKKyAgICAgICAgZmluYWwgaW50IHRoaXJkQnl0ZSA9IChpbnQpIGluLnJlYWRCaXRzKDgpOworICAgICAgICBpZiAoZmlyc3RCeXRlICE9IE1BR0lDXzEgfHwgc2Vjb25kQnl0ZSAhPSBNQUdJQ18yIHx8IHRoaXJkQnl0ZSA8IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiSW5wdXQgaXMgbm90IGluIC5aIGZvcm1hdCIpOworICAgICAgICB9CisgICAgICAgIGJsb2NrTW9kZSA9ICh0aGlyZEJ5dGUgJiBCTE9DS19NT0RFX01BU0spICE9IDA7CisgICAgICAgIG1heENvZGVTaXplID0gdGhpcmRCeXRlICYgTUFYX0NPREVfU0laRV9NQVNLOworICAgICAgICBpZiAoYmxvY2tNb2RlKSB7CisgICAgICAgICAgICBzZXRDbGVhckNvZGUoREVGQVVMVF9DT0RFX1NJWkUpOworICAgICAgICB9CisgICAgICAgIGluaXRpYWxpemVUYWJsZXMobWF4Q29kZVNpemUsIG1lbW9yeUxpbWl0SW5LYik7CisgICAgICAgIGNsZWFyRW50cmllcygpOworICAgIH0KKworICAgIHB1YmxpYyBaQ29tcHJlc3NvcklucHV0U3RyZWFtKGZpbmFsIElucHV0U3RyZWFtIGlucHV0U3RyZWFtKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzKGlucHV0U3RyZWFtLCAtMSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNsZWFyRW50cmllcygpIHsKKyAgICAgICAgc2V0VGFibGVTaXplKCgxIDw8IDgpICsgKGJsb2NrTW9kZSA/IDEgOiAwKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICoge0Bpbmhlcml0RG9jfQorICAgICAqIDxwPjxzdHJvbmc+VGhpcyBtZXRob2QgaXMgb25seSBwcm90ZWN0ZWQgZm9yIHRlY2huaWNhbCByZWFzb25zCisgICAgICogYW5kIGlzIG5vdCBwYXJ0IG9mIENvbW1vbnMgQ29tcHJlc3MnIHB1Ymxpc2hlZCBBUEkuICBJdCBtYXkKKyAgICAgKiBjaGFuZ2Ugb3IgZGlzYXBwZWFyIHdpdGhvdXQgd2FybmluZy48L3N0cm9uZz48L3A+CisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIGludCByZWFkTmV4dENvZGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBpbnQgY29kZSA9IHN1cGVyLnJlYWROZXh0Q29kZSgpOworICAgICAgICBpZiAoY29kZSA+PSAwKSB7CisgICAgICAgICAgICArK3RvdGFsQ29kZXNSZWFkOworICAgICAgICB9CisgICAgICAgIHJldHVybiBjb2RlOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByZUFsaWduUmVhZGluZygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vICJjb21wcmVzcyIgd29ya3MgaW4gbXVsdGlwbGVzIG9mIDggc3ltYm9scywgZWFjaCBjb2RlQml0cyBiaXRzIGxvbmcuCisgICAgICAgIC8vIFdoZW4gY29kZUJpdHMgY2hhbmdlcywgdGhlIHJlbWFpbmluZyB1bnVzZWQgc3ltYm9scyBpbiB0aGUgY3VycmVudAorICAgICAgICAvLyBncm91cCBvZiA4IGFyZSBzdGlsbCB3cml0dGVuIG91dCwgaW4gdGhlIG9sZCBjb2RlU2l6ZSwKKyAgICAgICAgLy8gYXMgZ2FyYmFnZSB2YWx1ZXMgKHVzdWFsbHkgemVyb2VzKSB0aGF0IG5lZWQgdG8gYmUgc2tpcHBlZC4KKyAgICAgICAgbG9uZyBjb2RlUmVhZHNUb1Rocm93QXdheSA9IDggLSAodG90YWxDb2Rlc1JlYWQgJSA4KTsKKyAgICAgICAgaWYgKGNvZGVSZWFkc1RvVGhyb3dBd2F5ID09IDgpIHsKKyAgICAgICAgICAgIGNvZGVSZWFkc1RvVGhyb3dBd2F5ID0gMDsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGxvbmcgaSA9IDA7IGkgPCBjb2RlUmVhZHNUb1Rocm93QXdheTsgaSsrKSB7CisgICAgICAgICAgICByZWFkTmV4dENvZGUoKTsKKyAgICAgICAgfQorICAgICAgICBpbi5jbGVhckJpdENhY2hlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICoge0Bpbmhlcml0RG9jfQorICAgICAqIDxwPjxzdHJvbmc+VGhpcyBtZXRob2QgaXMgb25seSBwcm90ZWN0ZWQgZm9yIHRlY2huaWNhbCByZWFzb25zCisgICAgICogYW5kIGlzIG5vdCBwYXJ0IG9mIENvbW1vbnMgQ29tcHJlc3MnIHB1Ymxpc2hlZCBBUEkuICBJdCBtYXkKKyAgICAgKiBjaGFuZ2Ugb3IgZGlzYXBwZWFyIHdpdGhvdXQgd2FybmluZy48L3N0cm9uZz48L3A+CisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIGludCBhZGRFbnRyeShmaW5hbCBpbnQgcHJldmlvdXNDb2RlLCBmaW5hbCBieXRlIGNoYXJhY3RlcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgaW50IG1heFRhYmxlU2l6ZSA9IDEgPDwgZ2V0Q29kZVNpemUoKTsKKyAgICAgICAgZmluYWwgaW50IHIgPSBhZGRFbnRyeShwcmV2aW91c0NvZGUsIGNoYXJhY3RlciwgbWF4VGFibGVTaXplKTsKKyAgICAgICAgaWYgKGdldFRhYmxlU2l6ZSgpID09IG1heFRhYmxlU2l6ZSAmJiBnZXRDb2RlU2l6ZSgpIDwgbWF4Q29kZVNpemUpIHsKKyAgICAgICAgICAgIHJlQWxpZ25SZWFkaW5nKCk7CisgICAgICAgICAgICBpbmNyZW1lbnRDb2RlU2l6ZSgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByOworICAgIH0KKworICAgIC8qKgorICAgICAqIHtAaW5oZXJpdERvY30KKyAgICAgKiA8cD48c3Ryb25nPlRoaXMgbWV0aG9kIGlzIG9ubHkgcHJvdGVjdGVkIGZvciB0ZWNobmljYWwgcmVhc29ucworICAgICAqIGFuZCBpcyBub3QgcGFydCBvZiBDb21tb25zIENvbXByZXNzJyBwdWJsaXNoZWQgQVBJLiAgSXQgbWF5CisgICAgICogY2hhbmdlIG9yIGRpc2FwcGVhciB3aXRob3V0IHdhcm5pbmcuPC9zdHJvbmc+PC9wPgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBpbnQgZGVjb21wcmVzc05leHRTeW1ib2woKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLworICAgICAgICAvLyAgICAgICAgICAgICAgICAgICB0YWJsZSBlbnRyeSAgICB0YWJsZSBlbnRyeQorICAgICAgICAvLyAgICAgICAgICAgICAgICAgIF9fX19fX19fX19fX18gICBfX19fXworICAgICAgICAvLyAgICB0YWJsZSBlbnRyeSAgLyAgICAgICAgICAgICBcIC8gICAgIFwKKyAgICAgICAgLy8gICAgX19fX19fX19fX19fLyAgICAgICAgICAgICAgIFwgICAgICAgXAorICAgICAgICAvLyAgIC8gICAgICAgICAgIC8gXCAgICAgICAgICAgICAvIFwgICAgICAgXAorICAgICAgICAvLyAgKy0tLSstLS0rLS0tKy0tLSstLS0rLS0tKy0tLSstLS0rLS0tKy0tLSsKKyAgICAgICAgLy8gIHwgLiB8IC4gfCAuIHwgLiB8IC4gfCAuIHwgLiB8IC4gfCAuIHwgLiB8CisgICAgICAgIC8vICArLS0tKy0tLSstLS0rLS0tKy0tLSstLS0rLS0tKy0tLSstLS0rLS0tKworICAgICAgICAvLyAgfDwtLS0tLS0tLS0+fDwtLS0tLS0tLS0tLS0tPnw8LS0tLS0+fDwtPnwKKyAgICAgICAgLy8gICAgIHN5bWJvbCAgICAgICAgc3ltYm9sICAgICAgc3ltYm9sICBzeW1ib2wKKyAgICAgICAgLy8KKyAgICAgICAgZmluYWwgaW50IGNvZGUgPSByZWFkTmV4dENvZGUoKTsKKyAgICAgICAgaWYgKGNvZGUgPCAwKSB7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0gZWxzZSBpZiAoYmxvY2tNb2RlICYmIGNvZGUgPT0gZ2V0Q2xlYXJDb2RlKCkpIHsKKyAgICAgICAgICAgIGNsZWFyRW50cmllcygpOworICAgICAgICAgICAgcmVBbGlnblJlYWRpbmcoKTsKKyAgICAgICAgICAgIHJlc2V0Q29kZVNpemUoKTsKKyAgICAgICAgICAgIHJlc2V0UHJldmlvdXNDb2RlKCk7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGJvb2xlYW4gYWRkZWRVbmZpbmlzaGVkRW50cnkgPSBmYWxzZTsKKyAgICAgICAgICAgIGlmIChjb2RlID09IGdldFRhYmxlU2l6ZSgpKSB7CisgICAgICAgICAgICAgICAgYWRkUmVwZWF0T2ZQcmV2aW91c0NvZGUoKTsKKyAgICAgICAgICAgICAgICBhZGRlZFVuZmluaXNoZWRFbnRyeSA9IHRydWU7CisgICAgICAgICAgICB9IGVsc2UgaWYgKGNvZGUgPiBnZXRUYWJsZVNpemUoKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihTdHJpbmcuZm9ybWF0KCJJbnZhbGlkICVkIGJpdCBjb2RlIDB4JXgiLCBnZXRDb2RlU2l6ZSgpLCBjb2RlKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gZXhwYW5kQ29kZVRvT3V0cHV0U3RhY2soY29kZSwgYWRkZWRVbmZpbmlzaGVkRW50cnkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIHRoZSBzaWduYXR1cmUgbWF0Y2hlcyB3aGF0IGlzIGV4cGVjdGVkIGZvciBhIFVuaXggY29tcHJlc3MgZmlsZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzaWduYXR1cmUKKyAgICAgKiAgICAgICAgICAgIHRoZSBieXRlcyB0byBjaGVjaworICAgICAqIEBwYXJhbSBsZW5ndGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gY2hlY2sKKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIHRoaXMgc3RyZWFtIGlzIGEgVW5peCBjb21wcmVzcyBjb21wcmVzc2VkCisgICAgICogc3RyZWFtLCBmYWxzZSBvdGhlcndpc2UKKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjkKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gbWF0Y2hlcyhmaW5hbCBieXRlW10gc2lnbmF0dXJlLCBmaW5hbCBpbnQgbGVuZ3RoKSB7CisgICAgICAgIHJldHVybiBsZW5ndGggPiAzICYmIHNpZ25hdHVyZVswXSA9PSBNQUdJQ18xICYmIHNpZ25hdHVyZVsxXSA9PSAoYnl0ZSkgTUFHSUNfMjsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL3ovcGFja2FnZS5odG1sIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvei9wYWNrYWdlLmh0bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2E5OTI0YgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL3ovcGFja2FnZS5odG1sCkBAIC0wLDAgKzEsMjQgQEAKKzxodG1sPgorPCEtLQorCisgICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAgIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAgICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorCisgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisKKyAgIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAgIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAgIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAgIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorCistLT4KKyAgPGJvZHk+CisgICAgPHA+UHJvdmlkZXMgc3RyZWFtIGNsYXNzZXMgZm9yIGRlY29tcHJlc3NpbmcKKyAgICAgIHN0cmVhbXMgdXNpbmcgdGhlICJjb21wcmVzcyIgYWxnb3JpdGhtIHVzZWQgdG8gd3JpdGUgLlogZmlsZXMuPC9wPgorICA8L2JvZHk+Cis8L2h0bWw+CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy96c3RhbmRhcmQvWnN0ZENvbXByZXNzb3JJbnB1dFN0cmVhbS5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvenN0YW5kYXJkL1pzdGRDb21wcmVzc29ySW5wdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43YTQ3ZjEwCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvenN0YW5kYXJkL1pzdGRDb21wcmVzc29ySW5wdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDEwNyBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy56c3RhbmRhcmQ7CisKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKKworaW1wb3J0IGNvbS5naXRodWIubHViZW4uenN0ZC5ac3RkSW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLkNvbXByZXNzb3JJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuQ291bnRpbmdJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuSU9VdGlsczsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuSW5wdXRTdHJlYW1TdGF0aXN0aWNzOworCisvKioKKyAqIHtAbGluayBDb21wcmVzc29ySW5wdXRTdHJlYW19IGltcGxlbWVudGF0aW9uIHRvIGRlY29kZSBac3RhbmRhcmQgZW5jb2RlZCBzdHJlYW0uCisgKiBMaWJyYXJ5IHJlbGllcyBvbiA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vbHViZW4venN0ZC1qbmkvIj5ac3RhbmRhcmQgSk5JPC9hPgorICoKKyAqIEBzaW5jZSAxLjE2CisgKi8KK3B1YmxpYyBjbGFzcyBac3RkQ29tcHJlc3NvcklucHV0U3RyZWFtIGV4dGVuZHMgQ29tcHJlc3NvcklucHV0U3RyZWFtCisgICAgaW1wbGVtZW50cyBJbnB1dFN0cmVhbVN0YXRpc3RpY3MgeworCisgICAgcHJpdmF0ZSBmaW5hbCBDb3VudGluZ0lucHV0U3RyZWFtIGNvdW50aW5nU3RyZWFtOworICAgIHByaXZhdGUgZmluYWwgWnN0ZElucHV0U3RyZWFtIGRlY0lTOworCisgICAgcHVibGljIFpzdGRDb21wcmVzc29ySW5wdXRTdHJlYW0oZmluYWwgSW5wdXRTdHJlYW0gaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMuZGVjSVMgPSBuZXcgWnN0ZElucHV0U3RyZWFtKGNvdW50aW5nU3RyZWFtID0gbmV3IENvdW50aW5nSW5wdXRTdHJlYW0oaW4pKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGF2YWlsYWJsZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBkZWNJUy5hdmFpbGFibGUoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGRlY0lTLmNsb3NlKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCByZWFkKGZpbmFsIGJ5dGVbXSBiKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gZGVjSVMucmVhZChiKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgbG9uZyBza2lwKGZpbmFsIGxvbmcgbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIElPVXRpbHMuc2tpcChkZWNJUywgbik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgbWFyayhmaW5hbCBpbnQgcmVhZGxpbWl0KSB7CisgICAgICAgIGRlY0lTLm1hcmsocmVhZGxpbWl0KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBtYXJrU3VwcG9ydGVkKCkgeworICAgICAgICByZXR1cm4gZGVjSVMubWFya1N1cHBvcnRlZCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIGludCByZXQgPSBkZWNJUy5yZWFkKCk7CisgICAgICAgIGNvdW50KHJldCA9PSAtMSA/IDAgOiAxKTsKKyAgICAgICAgcmV0dXJuIHJldDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHJlYWQoZmluYWwgYnl0ZVtdIGJ1ZiwgZmluYWwgaW50IG9mZiwgZmluYWwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgaW50IHJldCA9IGRlY0lTLnJlYWQoYnVmLCBvZmYsIGxlbik7CisgICAgICAgIGNvdW50KHJldCk7CisgICAgICAgIHJldHVybiByZXQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuIGRlY0lTLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcmVzZXQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBkZWNJUy5yZXNldCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzaW5jZSAxLjE3CisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGxvbmcgZ2V0Q29tcHJlc3NlZENvdW50KCkgeworICAgICAgICByZXR1cm4gY291bnRpbmdTdHJlYW0uZ2V0Qnl0ZXNSZWFkKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvenN0YW5kYXJkL1pzdGRDb21wcmVzc29yT3V0cHV0U3RyZWFtLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy96c3RhbmRhcmQvWnN0ZENvbXByZXNzb3JPdXRwdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wZGVkYTdkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvenN0YW5kYXJkL1pzdGRDb21wcmVzc29yT3V0cHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwxMTAgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuenN0YW5kYXJkOworCisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworCitpbXBvcnQgY29tLmdpdGh1Yi5sdWJlbi56c3RkLlpzdGRPdXRwdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLkNvbXByZXNzb3JPdXRwdXRTdHJlYW07CisKKy8qKgorICoge0BsaW5rIENvbXByZXNzb3JPdXRwdXRTdHJlYW19IGltcGxlbWVudGF0aW9uIHRvIGNyZWF0ZSBac3RhbmRhcmQgZW5jb2RlZCBzdHJlYW0uCisgKiBMaWJyYXJ5IHJlbGllcyBvbiA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vbHViZW4venN0ZC1qbmkvIj5ac3RhbmRhcmQgSk5JPC9hPgorICoKKyAqIEBzaW5jZSAxLjE2CisgKi8KK3B1YmxpYyBjbGFzcyBac3RkQ29tcHJlc3Nvck91dHB1dFN0cmVhbSBleHRlbmRzIENvbXByZXNzb3JPdXRwdXRTdHJlYW0geworCisgICAgcHJpdmF0ZSBmaW5hbCBac3RkT3V0cHV0U3RyZWFtIGVuY09TOworCisgICAgLyoqCisgICAgICogV3JhcHMgdGhlIGdpdmVuIHN0cmVhbSBpbnRvIGEgenN0ZC1qbmkgWnN0ZE91dHB1dFN0cmVhbS4KKyAgICAgKiBAcGFyYW0gb3V0U3RyZWFtIHRoZSBzdHJlYW0gdG8gd3JpdGUgdG8KKyAgICAgKiBAcGFyYW0gbGV2ZWwgdmFsdWUgZm9yIHpzdGQtam5pJ3MgbGV2ZWwgYXJndW1lbnQKKyAgICAgKiBAcGFyYW0gY2xvc2VGcmFtZU9uRmx1c2ggdmFsdWUgZm9yIHpzdGQtam5pJ3MgY2xvc2VGcmFtZU9uRmx1c2ggYXJndW1lbnQKKyAgICAgKiBAcGFyYW0gdXNlQ2hlY2tzdW0gdmFsdWUgZm9yIHpzdGQtam5pJ3MgdXNlQ2hlY2tzdW0gYXJndW1lbnQKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHpzdGQtam5pIGRvZXMKKyAgICAgKiBAc2luY2UgMS4xOAorICAgICAqLworICAgIHB1YmxpYyBac3RkQ29tcHJlc3Nvck91dHB1dFN0cmVhbShmaW5hbCBPdXRwdXRTdHJlYW0gb3V0U3RyZWFtLCBpbnQgbGV2ZWwsIGJvb2xlYW4gY2xvc2VGcmFtZU9uRmx1c2gsCisgICAgICAgIGJvb2xlYW4gdXNlQ2hlY2tzdW0pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMuZW5jT1MgPSBuZXcgWnN0ZE91dHB1dFN0cmVhbShvdXRTdHJlYW0sIGxldmVsLCBjbG9zZUZyYW1lT25GbHVzaCwgdXNlQ2hlY2tzdW0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyYXBzIHRoZSBnaXZlbiBzdHJlYW0gaW50byBhIHpzdGQtam5pIFpzdGRPdXRwdXRTdHJlYW0gdXNpbmcgdGhlIGRlZmF1bHQgdmFsdWUgZm9yIHtAY29kZSB1c2VDaGVja3N1bX0uCisgICAgICogQHBhcmFtIG91dFN0cmVhbSB0aGUgc3RyZWFtIHRvIHdyaXRlIHRvCisgICAgICogQHBhcmFtIGxldmVsIHZhbHVlIGZvciB6c3RkLWpuaSdzIGxldmVsIGFyZ3VtZW50CisgICAgICogQHBhcmFtIGNsb3NlRnJhbWVPbkZsdXNoIHZhbHVlIGZvciB6c3RkLWpuaSdzIGNsb3NlRnJhbWVPbkZsdXNoIGFyZ3VtZW50CisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiB6c3RkLWpuaSBkb2VzCisgICAgICogQHNpbmNlIDEuMTgKKyAgICAgKi8KKyAgICBwdWJsaWMgWnN0ZENvbXByZXNzb3JPdXRwdXRTdHJlYW0oZmluYWwgT3V0cHV0U3RyZWFtIG91dFN0cmVhbSwgaW50IGxldmVsLCBib29sZWFuIGNsb3NlRnJhbWVPbkZsdXNoKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzLmVuY09TID0gbmV3IFpzdGRPdXRwdXRTdHJlYW0ob3V0U3RyZWFtLCBsZXZlbCwgY2xvc2VGcmFtZU9uRmx1c2gpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyYXBzIHRoZSBnaXZlbiBzdHJlYW0gaW50byBhIHpzdGQtam5pIFpzdGRPdXRwdXRTdHJlYW0gdXNpbmcgdGhlIGRlZmF1bHQgdmFsdWVzIGZvciB7QGNvZGUgY2xvc2VGcmFtZU9uRmx1c2h9CisgICAgICogYW5kIHtAY29kZSB1c2VDaGVja3N1bX0uCisgICAgICogQHBhcmFtIG91dFN0cmVhbSB0aGUgc3RyZWFtIHRvIHdyaXRlIHRvCisgICAgICogQHBhcmFtIGxldmVsIHZhbHVlIGZvciB6c3RkLWpuaSdzIGxldmVsIGFyZ3VtZW50CisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiB6c3RkLWpuaSBkb2VzCisgICAgICogQHNpbmNlIDEuMTgKKyAgICAgKi8KKyAgICBwdWJsaWMgWnN0ZENvbXByZXNzb3JPdXRwdXRTdHJlYW0oZmluYWwgT3V0cHV0U3RyZWFtIG91dFN0cmVhbSwgaW50IGxldmVsKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzLmVuY09TID0gbmV3IFpzdGRPdXRwdXRTdHJlYW0ob3V0U3RyZWFtLCBsZXZlbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JhcHMgdGhlIGdpdmVuIHN0cmVhbSBpbnRvIGEgenN0ZC1qbmkgWnN0ZE91dHB1dFN0cmVhbSB1c2luZyB0aGUgZGVmYXVsdCB2YWx1ZXMgZm9yIHtAY29kZSBsZXZlbH0sIHtAY29kZQorICAgICAqIGNsb3NlRnJhbWVPbkZsdXNofSBhbmQge0Bjb2RlIHVzZUNoZWNrc3VtfS4KKyAgICAgKiBAcGFyYW0gb3V0U3RyZWFtIHRoZSBzdHJlYW0gdG8gd3JpdGUgdG8KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHpzdGQtam5pIGRvZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgWnN0ZENvbXByZXNzb3JPdXRwdXRTdHJlYW0oZmluYWwgT3V0cHV0U3RyZWFtIG91dFN0cmVhbSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcy5lbmNPUyA9IG5ldyBac3RkT3V0cHV0U3RyZWFtKG91dFN0cmVhbSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBlbmNPUy5jbG9zZSgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGZpbmFsIGludCBiKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBlbmNPUy53cml0ZShiKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShmaW5hbCBieXRlW10gYnVmLCBmaW5hbCBpbnQgb2ZmLCBmaW5hbCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBlbmNPUy53cml0ZShidWYsIG9mZiwgbGVuKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICByZXR1cm4gZW5jT1MudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBmbHVzaCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGVuY09TLmZsdXNoKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvenN0YW5kYXJkL1pzdGRVdGlscy5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvenN0YW5kYXJkL1pzdGRVdGlscy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhiMmY4ZDMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy96c3RhbmRhcmQvWnN0ZFV0aWxzLmphdmEKQEAgLTAsMCArMSwxNDAgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuenN0YW5kYXJkOworCisvKioKKyAqIFV0aWxpdHkgY29kZSBmb3IgdGhlIFpzdGFuZGFyZCBjb21wcmVzc2lvbiBmb3JtYXQuCisgKiBAVGhyZWFkU2FmZQorICogQHNpbmNlIDEuMTYKKyAqLworcHVibGljIGNsYXNzIFpzdGRVdGlscyB7CisKKyAgICBlbnVtIENhY2hlZEF2YWlsYWJpbGl0eSB7CisgICAgICAgIERPTlRfQ0FDSEUsIENBQ0hFRF9BVkFJTEFCTEUsIENBQ0hFRF9VTkFWQUlMQUJMRQorICAgIH0KKworICAgIC8qKgorICAgICAqIFpzdGFuZGFyZCBGcmFtZSBNYWdpYyBCeXRlcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gWlNUQU5EQVJEX0ZSQU1FX01BR0lDID0geworICAgICAgICAoYnl0ZSkgMHgyOCwgKGJ5dGUpIDB4QjUsIChieXRlKSAweDJGLCAoYnl0ZSkgMHhGRAorICAgIH07CisKKyAgICAvKioKKyAgICAgKiBTa2lwcGFibGUgRnJhbWUgTWFnaWMgQnl0ZXMgLSB0aGUgdGhyZWUgY29tbW9uIGJ5dGVzLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBTS0lQUEFCTEVfRlJBTUVfTUFHSUMgPSB7CisgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgMHgyQSwgKGJ5dGUpIDB4NEQsIChieXRlKSAweDE4CisgICAgfTsKKworICAgIHByaXZhdGUgc3RhdGljIHZvbGF0aWxlIENhY2hlZEF2YWlsYWJpbGl0eSBjYWNoZWRac3RkQXZhaWxhYmlsaXR5OworCisgICAgc3RhdGljIHsKKyAgICAgICAgY2FjaGVkWnN0ZEF2YWlsYWJpbGl0eSA9IENhY2hlZEF2YWlsYWJpbGl0eS5ET05UX0NBQ0hFOworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ2xhc3MuZm9yTmFtZSgib3JnLm9zZ2kuZnJhbWV3b3JrLkJ1bmRsZUV2ZW50Iik7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIEV4Y2VwdGlvbiBleCkgeyAvLyBOT1NPTkFSCisgICAgICAgICAgICBzZXRDYWNoZVpzdGRBdmFpbGFibGl0eSh0cnVlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKiBQcml2YXRlIGNvbnN0cnVjdG9yIHRvIHByZXZlbnQgaW5zdGFudGlhdGlvbiBvZiB0aGlzIHV0aWxpdHkgY2xhc3MuICovCisgICAgcHJpdmF0ZSBac3RkVXRpbHMoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXJlIHRoZSBjbGFzc2VzIHJlcXVpcmVkIHRvIHN1cHBvcnQgWnN0YW5kYXJkIGNvbXByZXNzaW9uIGF2YWlsYWJsZT8KKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGNsYXNzZXMgcmVxdWlyZWQgdG8gc3VwcG9ydCBac3RhbmRhcmQgY29tcHJlc3Npb24gYXJlIGF2YWlsYWJsZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1pzdGRDb21wcmVzc2lvbkF2YWlsYWJsZSgpIHsKKyAgICAgICAgZmluYWwgQ2FjaGVkQXZhaWxhYmlsaXR5IGNhY2hlZFJlc3VsdCA9IGNhY2hlZFpzdGRBdmFpbGFiaWxpdHk7CisgICAgICAgIGlmIChjYWNoZWRSZXN1bHQgIT0gQ2FjaGVkQXZhaWxhYmlsaXR5LkRPTlRfQ0FDSEUpIHsKKyAgICAgICAgICAgIHJldHVybiBjYWNoZWRSZXN1bHQgPT0gQ2FjaGVkQXZhaWxhYmlsaXR5LkNBQ0hFRF9BVkFJTEFCTEU7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGludGVybmFsSXNac3RkQ29tcHJlc3Npb25BdmFpbGFibGUoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGludGVybmFsSXNac3RkQ29tcHJlc3Npb25BdmFpbGFibGUoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDbGFzcy5mb3JOYW1lKCJjb20uZ2l0aHViLmx1YmVuLnpzdGQuWnN0ZElucHV0U3RyZWFtIik7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfSBjYXRjaCAoTm9DbGFzc0RlZkZvdW5kRXJyb3IgfCBFeGNlcHRpb24gZXJyb3IpIHsgLy8gTk9TT05BUgorICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogV2hldGhlciB0byBjYWNoZSB0aGUgcmVzdWx0IG9mIHRoZSBac3RhbmRhcmQgZm9yIEphdmEgY2hlY2suCisgICAgICoKKyAgICAgKiA8cD5UaGlzIGRlZmF1bHRzIHRvIHtAY29kZSBmYWxzZX0gaW4gYW4gT1NHaSBlbnZpcm9ubWVudCBhbmQge0Bjb2RlIHRydWV9IG90aGVyd2lzZS48L3A+CisgICAgICogQHBhcmFtIGRvQ2FjaGUgd2hldGhlciB0byBjYWNoZSB0aGUgcmVzdWx0CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHNldENhY2hlWnN0ZEF2YWlsYWJsaXR5KGZpbmFsIGJvb2xlYW4gZG9DYWNoZSkgeworICAgICAgICBpZiAoIWRvQ2FjaGUpIHsKKyAgICAgICAgICAgIGNhY2hlZFpzdGRBdmFpbGFiaWxpdHkgPSBDYWNoZWRBdmFpbGFiaWxpdHkuRE9OVF9DQUNIRTsKKyAgICAgICAgfSBlbHNlIGlmIChjYWNoZWRac3RkQXZhaWxhYmlsaXR5ID09IENhY2hlZEF2YWlsYWJpbGl0eS5ET05UX0NBQ0hFKSB7CisgICAgICAgICAgICBmaW5hbCBib29sZWFuIGhhc1pzdGQgPSBpbnRlcm5hbElzWnN0ZENvbXByZXNzaW9uQXZhaWxhYmxlKCk7CisgICAgICAgICAgICBjYWNoZWRac3RkQXZhaWxhYmlsaXR5ID0gaGFzWnN0ZCA/IENhY2hlZEF2YWlsYWJpbGl0eS5DQUNIRURfQVZBSUxBQkxFCisgICAgICAgICAgICAgICAgOiBDYWNoZWRBdmFpbGFiaWxpdHkuQ0FDSEVEX1VOQVZBSUxBQkxFOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIHRoZSBzaWduYXR1cmUgbWF0Y2hlcyB3aGF0IGlzIGV4cGVjdGVkIGZvciBhIFpzdGFuZGFyZCBmaWxlLgorICAgICAqCisgICAgICogQHBhcmFtICAgc2lnbmF0dXJlICAgICB0aGUgYnl0ZXMgdG8gY2hlY2sKKyAgICAgKiBAcGFyYW0gICBsZW5ndGggICAgICAgIHRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gY2hlY2sKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgc2lnbmF0dXJlIG1hdGNoZXMgdGhlIFp0c3RhbmRhcmQgb3Igc2tpcHBhYmxlCisgICAgICogZnJhbWUgbWFnaWMgYnl0ZXMsIGZhbHNlIG90aGVyd2lzZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBtYXRjaGVzKGZpbmFsIGJ5dGVbXSBzaWduYXR1cmUsIGZpbmFsIGludCBsZW5ndGgpIHsKKyAgICAgICAgaWYgKGxlbmd0aCA8IFpTVEFOREFSRF9GUkFNRV9NQUdJQy5sZW5ndGgpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIGJvb2xlYW4gaXNac3RhbmRhcmQgPSB0cnVlOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IFpTVEFOREFSRF9GUkFNRV9NQUdJQy5sZW5ndGg7ICsraSkgeworICAgICAgICAgICAgaWYgKHNpZ25hdHVyZVtpXSAhPSBaU1RBTkRBUkRfRlJBTUVfTUFHSUNbaV0pIHsKKyAgICAgICAgICAgICAgICBpc1pzdGFuZGFyZCA9IGZhbHNlOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChpc1pzdGFuZGFyZCkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKworICAgICAgICBpZiAoMHg1MCA9PSAoc2lnbmF0dXJlWzBdICYgMHhGMCkpIHsKKyAgICAgICAgICAgIC8vIHNraXBwYWJsZSBmcmFtZQorICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBTS0lQUEFCTEVfRlJBTUVfTUFHSUMubGVuZ3RoOyArK2kpIHsKKyAgICAgICAgICAgICAgICBpZiAoc2lnbmF0dXJlW2kgKyAxXSAhPSBTS0lQUEFCTEVfRlJBTUVfTUFHSUNbaV0pIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLy8gb25seSBleGlzdHMgdG8gc3VwcG9ydCB1bml0IHRlc3RzCisgICAgc3RhdGljIENhY2hlZEF2YWlsYWJpbGl0eSBnZXRDYWNoZWRac3RkQXZhaWxhYmlsaXR5KCkgeworICAgICAgICByZXR1cm4gY2FjaGVkWnN0ZEF2YWlsYWJpbGl0eTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy96c3RhbmRhcmQvcGFja2FnZS5odG1sIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvenN0YW5kYXJkL3BhY2thZ2UuaHRtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42ZGViNzRmCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvenN0YW5kYXJkL3BhY2thZ2UuaHRtbApAQCAtMCwwICsxLDI2IEBACis8aHRtbD4KKzwhLS0KKworICAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAgIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAgIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKworICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorCisgICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKworLS0+CisgIDxib2R5PgorICAgIDxwPlByb3ZpZGVzIHN0cmVhbSBjbGFzcyBmb3IgKGRlKWNvbXByZXNzaW5nIHN0cmVhbXMgdXNpbmcgdGhlCisgICAgICBac3RhbmRhcmQgYWxnb3JpdGhtIGJhc2VkCisgICAgICBvbiA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vbHViZW4venN0ZC1qbmkiPlpzdGFuZGFyZAorICAgICAgSk5JPC9hPi48L3A+CisgIDwvYm9keT4KKzwvaHRtbD4KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL3BhcmFsbGVsL0ZpbGVCYXNlZFNjYXR0ZXJHYXRoZXJCYWNraW5nU3RvcmUuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL3BhcmFsbGVsL0ZpbGVCYXNlZFNjYXR0ZXJHYXRoZXJCYWNraW5nU3RvcmUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hOTEwNWYwCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvcGFyYWxsZWwvRmlsZUJhc2VkU2NhdHRlckdhdGhlckJhY2tpbmdTdG9yZS5qYXZhCkBAIC0wLDAgKzEsNzYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnBhcmFsbGVsOworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZU5vdEZvdW5kRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLm5pby5maWxlLkZpbGVzOworCisvKioKKyAqIFNjYXR0ZXJHYXRoZXJCYWNraW5nU3RvcmUgdGhhdCBpcyBiYWNrZWQgYnkgYSBmaWxlLgorICoKKyAqIEBzaW5jZSAxLjEwCisgKi8KK3B1YmxpYyBjbGFzcyBGaWxlQmFzZWRTY2F0dGVyR2F0aGVyQmFja2luZ1N0b3JlIGltcGxlbWVudHMgU2NhdHRlckdhdGhlckJhY2tpbmdTdG9yZSB7CisgICAgcHJpdmF0ZSBmaW5hbCBGaWxlIHRhcmdldDsKKyAgICBwcml2YXRlIGZpbmFsIE91dHB1dFN0cmVhbSBvczsKKyAgICBwcml2YXRlIGJvb2xlYW4gY2xvc2VkOworCisgICAgcHVibGljIEZpbGVCYXNlZFNjYXR0ZXJHYXRoZXJCYWNraW5nU3RvcmUoZmluYWwgRmlsZSB0YXJnZXQpIHRocm93cyBGaWxlTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICB0aGlzLnRhcmdldCA9IHRhcmdldDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9zID0gRmlsZXMubmV3T3V0cHV0U3RyZWFtKHRhcmdldC50b1BhdGgoKSk7CisgICAgICAgIH0gY2F0Y2ggKEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgdGhyb3cgZXg7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAvLyBtdXN0IGNvbnZlcnQgZXhjZXB0aW9uIHRvIHN0YXkgYmFja3dhcmRzIGNvbXBhdGlibGUgd2l0aCBDb21wcmVzcyAxLjEwIHRvIDEuMTMKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGV4KTsgLy8gTk9TT05BUgorICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIElucHV0U3RyZWFtIGdldElucHV0U3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIEZpbGVzLm5ld0lucHV0U3RyZWFtKHRhcmdldC50b1BhdGgoKSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgQFN1cHByZXNzV2FybmluZ3MoIlJlc3VsdE9mTWV0aG9kQ2FsbElnbm9yZWQiKQorICAgIHB1YmxpYyB2b2lkIGNsb3NlRm9yV3JpdGluZygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICghY2xvc2VkKSB7CisgICAgICAgICAgICBvcy5jbG9zZSgpOworICAgICAgICAgICAgY2xvc2VkID0gdHJ1ZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlT3V0KGZpbmFsIGJ5dGVbXSBkYXRhLCBmaW5hbCBpbnQgb2Zmc2V0LCBmaW5hbCBpbnQgbGVuZ3RoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvcy53cml0ZShkYXRhLCBvZmZzZXQsIGxlbmd0aCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgY2xvc2VGb3JXcml0aW5nKCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0YXJnZXQuZGVsZXRlKCk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9wYXJhbGxlbC9JbnB1dFN0cmVhbVN1cHBsaWVyLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9wYXJhbGxlbC9JbnB1dFN0cmVhbVN1cHBsaWVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjIyN2U2NAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL3BhcmFsbGVsL0lucHV0U3RyZWFtU3VwcGxpZXIuamF2YQpAQCAtMCwwICsxLDQwIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MucGFyYWxsZWw7CisKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworCisvKioKKyAqIFN1cHBsaWVzIGlucHV0IHN0cmVhbXMuCisgKgorICogSW1wbGVtZW50YXRpb25zIGFyZSByZXF1aXJlZCB0byBzdXBwb3J0IHRocmVhZC1oYW5kb3Zlci4gV2hpbGUgYW4gaW5zdGFuY2Ugd2lsbAorICogbm90IGJlIGFjY2Vzc2VkIGNvbmN1cnJlbnRseSBieSBtdWx0aXBsZSB0aHJlYWRzLCBpdCB3aWxsIGJlIGNhbGxlZCBieQorICogYSBkaWZmZXJlbnQgdGhyZWFkIHRoYW4gaXQgd2FzIGNyZWF0ZWQgb24uCisgKgorICogQHNpbmNlIDEuMTAKKyAqLworcHVibGljIGludGVyZmFjZSBJbnB1dFN0cmVhbVN1cHBsaWVyIHsKKworICAgIC8qKgorICAgICAqIFN1cHBseSBhbiBpbnB1dCBzdHJlYW0gZm9yIGEgcmVzb3VyY2UuCisgICAgICogQHJldHVybiB0aGUgaW5wdXQgc3RyZWFtLiBTaG91bGQgbmV2ZXIgbnVsbCwgYnV0IG1heSBiZSBhbiBlbXB0eSBzdHJlYW0uCisgICAgICovCisgICAgSW5wdXRTdHJlYW0gZ2V0KCk7Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9wYXJhbGxlbC9TY2F0dGVyR2F0aGVyQmFja2luZ1N0b3JlLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9wYXJhbGxlbC9TY2F0dGVyR2F0aGVyQmFja2luZ1N0b3JlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWE3MjZmZgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL3BhcmFsbGVsL1NjYXR0ZXJHYXRoZXJCYWNraW5nU3RvcmUuamF2YQpAQCAtMCwwICsxLDYxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5wYXJhbGxlbDsKKworaW1wb3J0IGphdmEuaW8uQ2xvc2VhYmxlOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKKworLyoqCisgKiA8cD5TdG9yZSBpbnRlcm1lZGlhdGUgcGF5bG9hZCBpbiBhIHNjYXR0ZXItZ2F0aGVyIHNjZW5hcmlvLgorICogTXVsdGlwbGUgdGhyZWFkcyB3cml0ZSB0aGVpciBwYXlsb2FkIHRvIGEgYmFja2luZyBzdG9yZSwgd2hpY2ggY2FuCisgKiBzdWJzZXF1ZW50bHkgYmUgcmV2ZXJzZWQgdG8gYW4ge0BsaW5rIElucHV0U3RyZWFtfSB0byBiZSB1c2VkIGFzIGlucHV0IGluIHRoZQorICogZ2F0aGVyIHBoYXNlLjwvcD4KKyAqCisgKiA8cD5JdCBpcyB0aGUgcmVzcG9uc2liaWxpdHkgb2YgdGhlIGFsbG9jYXRvciBvZiBhbiBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzCisgKiB0byBjbG9zZSB0aGlzLiBDbG9zaW5nIGl0IHNob3VsZCBjbGVhciBvZmYgYW55IGFsbG9jYXRlZCBzdHJ1Y3R1cmVzCisgKiBhbmQgcHJlZmVyYWJseSBkZWxldGUgZmlsZXMuPC9wPgorICoKKyAqIEBzaW5jZSAxLjEwCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgU2NhdHRlckdhdGhlckJhY2tpbmdTdG9yZSBleHRlbmRzIENsb3NlYWJsZSB7CisKKyAgICAvKioKKyAgICAgKiBBbiBpbnB1dCBzdHJlYW0gdGhhdCBjb250YWlucyB0aGUgc2NhdHRlcmVkIHBheWxvYWQKKyAgICAgKgorICAgICAqIEByZXR1cm4gQW4gSW5wdXRTdHJlYW0sIHNob3VsZCBiZSBjbG9zZWQgYnkgdGhlIGNhbGxlciBvZiB0aGlzIG1ldGhvZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIHdoZW4gc29tZXRoaW5nIGZhaWxzCisgICAgICovCisgICAgSW5wdXRTdHJlYW0gZ2V0SW5wdXRTdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgYSBwaWVjZSBvZiBwYXlsb2FkLgorICAgICAqCisgICAgICogQHBhcmFtIGRhdGEgdGhlIGRhdGEgdG8gd3JpdGUKKyAgICAgKiBAcGFyYW0gb2Zmc2V0IG9mZnNldCBpbnNpZGUgZGF0YSB0byBzdGFydCB3cml0aW5nIGZyb20KKyAgICAgKiBAcGFyYW0gbGVuZ3RoIHRoZSBhbW91bnQgb2YgZGF0YSB0byB3cml0ZQorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gd2hlbiBzb21ldGhpbmcgZmFpbHMKKyAgICAgKi8KKyAgICB2b2lkIHdyaXRlT3V0KGJ5dGVbXSBkYXRhLCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBDbG9zZXMgdGhpcyBiYWNraW5nIHN0b3JlIGZvciBmdXJ0aGVyIHdyaXRpbmcuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiB3aGVuIHNvbWV0aGluZyBmYWlscworICAgICAqLworICAgIHZvaWQgY2xvc2VGb3JXcml0aW5nKCkgdGhyb3dzIElPRXhjZXB0aW9uOworfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvcGFyYWxsZWwvU2NhdHRlckdhdGhlckJhY2tpbmdTdG9yZVN1cHBsaWVyLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9wYXJhbGxlbC9TY2F0dGVyR2F0aGVyQmFja2luZ1N0b3JlU3VwcGxpZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45YTIxNmE3Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvcGFyYWxsZWwvU2NhdHRlckdhdGhlckJhY2tpbmdTdG9yZVN1cHBsaWVyLmphdmEKQEAgLTAsMCArMSwzNiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5wYXJhbGxlbDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKKy8qKgorICogU3VwcGxpZXMge0BsaW5rIFNjYXR0ZXJHYXRoZXJCYWNraW5nU3RvcmV9IGluc3RhbmNlcy4KKyAqCisgKiBAc2luY2UgMS4xMAorICovCitwdWJsaWMgaW50ZXJmYWNlIFNjYXR0ZXJHYXRoZXJCYWNraW5nU3RvcmVTdXBwbGllciB7CisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgU2NhdHRlckdhdGhlckJhY2tpbmdTdG9yZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBTY2F0dGVyR2F0aGVyQmFja2luZ1N0b3JlLCBub3QgbnVsbAorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gd2hlbiBzb21ldGhpbmcgZmFpbHMKKyAgICAgKi8KKyAgICBTY2F0dGVyR2F0aGVyQmFja2luZ1N0b3JlIGdldCgpIHRocm93cyBJT0V4Y2VwdGlvbjsKK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL3BhcmFsbGVsL3BhY2thZ2UuaHRtbCBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL3BhcmFsbGVsL3BhY2thZ2UuaHRtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNTE3YmM1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvcGFyYWxsZWwvcGFja2FnZS5odG1sCkBAIC0wLDAgKzEsMjMgQEAKKzxodG1sPgorPCEtLQorCisgICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAgIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAgICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorCisgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisKKyAgIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAgIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAgIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAgIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorCistLT4KKyAgPGJvZHk+CisgICAgPHA+UHJvdmlkZXMgY29tbW9uIEFQSSBjbGFzc2VzIGZvciBwYXJhbGxlbCBjb21wcmVzc2lvbiBmZWF0dXJlcy48L3A+CisgIDwvYm9keT4KKzwvaHRtbD4KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL3V0aWxzL0FyY2hpdmVVdGlscy5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvdXRpbHMvQXJjaGl2ZVV0aWxzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2ZlM2ZiYQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL3V0aWxzL0FyY2hpdmVVdGlscy5qYXZhCkBAIC0wLDAgKzEsMjk5IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICoKKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlsczsKKworaW1wb3J0IGphdmEuaW8uVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5BcmNoaXZlRW50cnk7CisKKy8qKgorICogR2VuZXJpYyBBcmNoaXZlIHV0aWxpdGllcworICovCitwdWJsaWMgY2xhc3MgQXJjaGl2ZVV0aWxzIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNQVhfU0FOSVRJWkVEX05BTUVfTEVOR1RIID0gMjU1OworCisgICAgLyoqIFByaXZhdGUgY29uc3RydWN0b3IgdG8gcHJldmVudCBpbnN0YW50aWF0aW9uIG9mIHRoaXMgdXRpbGl0eSBjbGFzcy4gKi8KKyAgICBwcml2YXRlIEFyY2hpdmVVdGlscygpeworICAgIH0KKworICAgIC8qKgorICAgICAqIEdlbmVyYXRlcyBhIHN0cmluZyBjb250YWluaW5nIHRoZSBuYW1lLCBpc0RpcmVjdG9yeSBzZXR0aW5nIGFuZCBzaXplIG9mIGFuIGVudHJ5LgorICAgICAqIDxwPgorICAgICAqIEZvciBleGFtcGxlOgorICAgICAqIDxwcmU+CisgICAgICogLSAgICAyMDAwIG1haW4uYworICAgICAqIGQgICAgIDEwMCB0ZXN0ZmlsZXMKKyAgICAgKiA8L3ByZT4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlbnRyeSB0aGUgZW50cnkKKyAgICAgKiBAcmV0dXJuIHRoZSByZXByZXNlbnRhdGlvbiBvZiB0aGUgZW50cnkKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyB0b1N0cmluZyhmaW5hbCBBcmNoaXZlRW50cnkgZW50cnkpeworICAgICAgICBmaW5hbCBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgc2IuYXBwZW5kKGVudHJ5LmlzRGlyZWN0b3J5KCk/ICdkJyA6ICctJyk7Ly8gYy5mLiAibHMgLWwiIG91dHB1dAorICAgICAgICBmaW5hbCBTdHJpbmcgc2l6ZSA9IExvbmcudG9TdHJpbmcoZW50cnkuZ2V0U2l6ZSgpKTsKKyAgICAgICAgc2IuYXBwZW5kKCcgJyk7CisgICAgICAgIC8vIFBhZCBvdXRwdXQgdG8gNyBwbGFjZXMsIGxlYWRpbmcgc3BhY2VzCisgICAgICAgIGZvcihpbnQgaT03OyBpID4gc2l6ZS5sZW5ndGgoKTsgaS0tKXsKKyAgICAgICAgICAgIHNiLmFwcGVuZCgnICcpOworICAgICAgICB9CisgICAgICAgIHNiLmFwcGVuZChzaXplKTsKKyAgICAgICAgc2IuYXBwZW5kKCcgJykuYXBwZW5kKGVudHJ5LmdldE5hbWUoKSk7CisgICAgICAgIHJldHVybiBzYi50b1N0cmluZygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrIGlmIGJ1ZmZlciBjb250ZW50cyBtYXRjaGVzIEFzY2lpIFN0cmluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBleHBlY3RlZCBleHBlY3RlZCBzdHJpbmcKKyAgICAgKiBAcGFyYW0gYnVmZmVyIHRoZSBidWZmZXIKKyAgICAgKiBAcGFyYW0gb2Zmc2V0IG9mZnNldCB0byByZWFkIGZyb20KKyAgICAgKiBAcGFyYW0gbGVuZ3RoIGxlbmd0aCBvZiB0aGUgYnVmZmVyCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgYnVmZmVyIGlzIHRoZSBzYW1lIGFzIHRoZSBleHBlY3RlZCBzdHJpbmcKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gbWF0Y2hBc2NpaUJ1ZmZlcigKKyAgICAgICAgICAgIGZpbmFsIFN0cmluZyBleHBlY3RlZCwgZmluYWwgYnl0ZVtdIGJ1ZmZlciwgZmluYWwgaW50IG9mZnNldCwgZmluYWwgaW50IGxlbmd0aCl7CisgICAgICAgIGJ5dGVbXSBidWZmZXIxOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYnVmZmVyMSA9IGV4cGVjdGVkLmdldEJ5dGVzKENoYXJzZXROYW1lcy5VU19BU0NJSSk7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gU2hvdWxkIG5vdCBoYXBwZW4KKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOyAvL05PU09OQVIKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaXNFcXVhbChidWZmZXIxLCAwLCBidWZmZXIxLmxlbmd0aCwgYnVmZmVyLCBvZmZzZXQsIGxlbmd0aCwgZmFsc2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrIGlmIGJ1ZmZlciBjb250ZW50cyBtYXRjaGVzIEFzY2lpIFN0cmluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBleHBlY3RlZCB0aGUgZXhwZWN0ZWQgc3RyaW4KKyAgICAgKiBAcGFyYW0gYnVmZmVyIHRoZSBidWZmZXIKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBidWZmZXIgaXMgdGhlIHNhbWUgYXMgdGhlIGV4cGVjdGVkIHN0cmluZworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBtYXRjaEFzY2lpQnVmZmVyKGZpbmFsIFN0cmluZyBleHBlY3RlZCwgZmluYWwgYnl0ZVtdIGJ1ZmZlcil7CisgICAgICAgIHJldHVybiBtYXRjaEFzY2lpQnVmZmVyKGV4cGVjdGVkLCBidWZmZXIsIDAsIGJ1ZmZlci5sZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlcnQgYSBzdHJpbmcgdG8gQXNjaWkgYnl0ZXMuCisgICAgICogVXNlZCBmb3IgY29tcGFyaW5nICJtYWdpYyIgc3RyaW5ncyB3aGljaCBuZWVkIHRvIGJlIGluZGVwZW5kZW50IG9mIHRoZSBkZWZhdWx0IExvY2FsZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbnB1dFN0cmluZyBzdHJpbmcgdG8gY29udmVydAorICAgICAqIEByZXR1cm4gdGhlIGJ5dGVzCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBieXRlW10gdG9Bc2NpaUJ5dGVzKGZpbmFsIFN0cmluZyBpbnB1dFN0cmluZyl7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gaW5wdXRTdHJpbmcuZ2V0Qnl0ZXMoQ2hhcnNldE5hbWVzLlVTX0FTQ0lJKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBTaG91bGQgbmV2ZXIgaGFwcGVuCisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlKTsgLy9OT1NPTkFSCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZXJ0IGFuIGlucHV0IGJ5dGUgYXJyYXkgdG8gYSBTdHJpbmcgdXNpbmcgdGhlIEFTQ0lJIGNoYXJhY3RlciBzZXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5wdXRCeXRlcyBieXRlcyB0byBjb252ZXJ0CisgICAgICogQHJldHVybiB0aGUgYnl0ZXMsIGludGVycHJldGVkIGFzIGFuIEFzY2lpIHN0cmluZworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHRvQXNjaWlTdHJpbmcoZmluYWwgYnl0ZVtdIGlucHV0Qnl0ZXMpeworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmcoaW5wdXRCeXRlcywgQ2hhcnNldE5hbWVzLlVTX0FTQ0lJKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBTaG91bGQgbmV2ZXIgaGFwcGVuCisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlKTsgLy9OT1NPTkFSCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZXJ0IGFuIGlucHV0IGJ5dGUgYXJyYXkgdG8gYSBTdHJpbmcgdXNpbmcgdGhlIEFTQ0lJIGNoYXJhY3RlciBzZXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5wdXRCeXRlcyBpbnB1dCBieXRlIGFycmF5CisgICAgICogQHBhcmFtIG9mZnNldCBvZmZzZXQgd2l0aGluIGFycmF5CisgICAgICogQHBhcmFtIGxlbmd0aCBsZW5ndGggb2YgYXJyYXkKKyAgICAgKiBAcmV0dXJuIHRoZSBieXRlcywgaW50ZXJwcmV0ZWQgYXMgYW4gQXNjaWkgc3RyaW5nCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgdG9Bc2NpaVN0cmluZyhmaW5hbCBieXRlW10gaW5wdXRCeXRlcywgZmluYWwgaW50IG9mZnNldCwgZmluYWwgaW50IGxlbmd0aCl7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IFN0cmluZyhpbnB1dEJ5dGVzLCBvZmZzZXQsIGxlbmd0aCwgQ2hhcnNldE5hbWVzLlVTX0FTQ0lJKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBTaG91bGQgbmV2ZXIgaGFwcGVuCisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlKTsgLy9OT1NPTkFSCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlIGJ5dGUgYnVmZmVycywgb3B0aW9uYWxseSBpZ25vcmluZyB0cmFpbGluZyBudWxscworICAgICAqCisgICAgICogQHBhcmFtIGJ1ZmZlcjEgZmlyc3QgYnVmZmVyCisgICAgICogQHBhcmFtIG9mZnNldDEgZmlyc3Qgb2Zmc2V0CisgICAgICogQHBhcmFtIGxlbmd0aDEgZmlyc3QgbGVuZ3RoCisgICAgICogQHBhcmFtIGJ1ZmZlcjIgc2Vjb25kIGJ1ZmZlcgorICAgICAqIEBwYXJhbSBvZmZzZXQyIHNlY29uZCBvZmZzZXQKKyAgICAgKiBAcGFyYW0gbGVuZ3RoMiBzZWNvbmQgbGVuZ3RoCisgICAgICogQHBhcmFtIGlnbm9yZVRyYWlsaW5nTnVsbHMgd2hldGhlciB0byBpZ25vcmUgdHJhaWxpbmcgbnVsbHMKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBidWZmZXIxIGFuZCBidWZmZXIyIGhhdmUgc2FtZSBjb250ZW50cywgaGF2aW5nIHJlZ2FyZCB0byB0cmFpbGluZyBudWxscworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0VxdWFsKAorICAgICAgICAgICAgZmluYWwgYnl0ZVtdIGJ1ZmZlcjEsIGZpbmFsIGludCBvZmZzZXQxLCBmaW5hbCBpbnQgbGVuZ3RoMSwKKyAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBidWZmZXIyLCBmaW5hbCBpbnQgb2Zmc2V0MiwgZmluYWwgaW50IGxlbmd0aDIsCisgICAgICAgICAgICBmaW5hbCBib29sZWFuIGlnbm9yZVRyYWlsaW5nTnVsbHMpeworICAgICAgICBmaW5hbCBpbnQgbWluTGVuPWxlbmd0aDEgPCBsZW5ndGgyID8gbGVuZ3RoMSA6IGxlbmd0aDI7CisgICAgICAgIGZvciAoaW50IGk9MDsgaSA8IG1pbkxlbjsgaSsrKXsKKyAgICAgICAgICAgIGlmIChidWZmZXIxW29mZnNldDEraV0gIT0gYnVmZmVyMltvZmZzZXQyK2ldKXsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKGxlbmd0aDEgPT0gbGVuZ3RoMil7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoaWdub3JlVHJhaWxpbmdOdWxscyl7CisgICAgICAgICAgICBpZiAobGVuZ3RoMSA+IGxlbmd0aDIpeworICAgICAgICAgICAgICAgIGZvcihpbnQgaSA9IGxlbmd0aDI7IGkgPCBsZW5ndGgxOyBpKyspeworICAgICAgICAgICAgICAgICAgICBpZiAoYnVmZmVyMVtvZmZzZXQxK2ldICE9IDApeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBmb3IoaW50IGkgPSBsZW5ndGgxOyBpIDwgbGVuZ3RoMjsgaSsrKXsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGJ1ZmZlcjJbb2Zmc2V0MitpXSAhPSAwKXsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlIGJ5dGUgYnVmZmVycworICAgICAqCisgICAgICogQHBhcmFtIGJ1ZmZlcjEgdGhlIGZpcnN0IGJ1ZmZlcgorICAgICAqIEBwYXJhbSBvZmZzZXQxIHRoZSBmaXJzdCBvZmZzZXQKKyAgICAgKiBAcGFyYW0gbGVuZ3RoMSB0aGUgZmlyc3QgbGVuZ3RoCisgICAgICogQHBhcmFtIGJ1ZmZlcjIgdGhlIHNlY29uZCBidWZmZXIKKyAgICAgKiBAcGFyYW0gb2Zmc2V0MiB0aGUgc2Vjb25kIG9mZnNldAorICAgICAqIEBwYXJhbSBsZW5ndGgyIHRoZSBzZWNvbmQgbGVuZ3RoCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgYnVmZmVyMSBhbmQgYnVmZmVyMiBoYXZlIHNhbWUgY29udGVudHMKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNFcXVhbCgKKyAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBidWZmZXIxLCBmaW5hbCBpbnQgb2Zmc2V0MSwgZmluYWwgaW50IGxlbmd0aDEsCisgICAgICAgICAgICBmaW5hbCBieXRlW10gYnVmZmVyMiwgZmluYWwgaW50IG9mZnNldDIsIGZpbmFsIGludCBsZW5ndGgyKXsKKyAgICAgICAgcmV0dXJuIGlzRXF1YWwoYnVmZmVyMSwgb2Zmc2V0MSwgbGVuZ3RoMSwgYnVmZmVyMiwgb2Zmc2V0MiwgbGVuZ3RoMiwgZmFsc2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXBhcmUgYnl0ZSBidWZmZXJzCisgICAgICoKKyAgICAgKiBAcGFyYW0gYnVmZmVyMSB0aGUgZmlyc3QgYnVmZmVyCisgICAgICogQHBhcmFtIGJ1ZmZlcjIgdGhlIHNlY29uZCBidWZmZXIKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBidWZmZXIxIGFuZCBidWZmZXIyIGhhdmUgc2FtZSBjb250ZW50cworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0VxdWFsKGZpbmFsIGJ5dGVbXSBidWZmZXIxLCBmaW5hbCBieXRlW10gYnVmZmVyMiApeworICAgICAgICByZXR1cm4gaXNFcXVhbChidWZmZXIxLCAwLCBidWZmZXIxLmxlbmd0aCwgYnVmZmVyMiwgMCwgYnVmZmVyMi5sZW5ndGgsIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlIGJ5dGUgYnVmZmVycywgb3B0aW9uYWxseSBpZ25vcmluZyB0cmFpbGluZyBudWxscworICAgICAqCisgICAgICogQHBhcmFtIGJ1ZmZlcjEgdGhlIGZpcnN0IGJ1ZmZlcgorICAgICAqIEBwYXJhbSBidWZmZXIyIHRoZSBzZWNvbmQgYnVmZmVyCisgICAgICogQHBhcmFtIGlnbm9yZVRyYWlsaW5nTnVsbHMgd2hldGhlciB0byBpZ25vcmUgdGFyaWxpbmcgbnVsbHMKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBidWZmZXIxIGFuZCBidWZmZXIyIGhhdmUgc2FtZSBjb250ZW50cworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0VxdWFsKGZpbmFsIGJ5dGVbXSBidWZmZXIxLCBmaW5hbCBieXRlW10gYnVmZmVyMiwgZmluYWwgYm9vbGVhbiBpZ25vcmVUcmFpbGluZ051bGxzKXsKKyAgICAgICAgcmV0dXJuIGlzRXF1YWwoYnVmZmVyMSwgMCwgYnVmZmVyMS5sZW5ndGgsIGJ1ZmZlcjIsIDAsIGJ1ZmZlcjIubGVuZ3RoLCBpZ25vcmVUcmFpbGluZ051bGxzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlIGJ5dGUgYnVmZmVycywgaWdub3JpbmcgdHJhaWxpbmcgbnVsbHMKKyAgICAgKgorICAgICAqIEBwYXJhbSBidWZmZXIxIHRoZSBmaXJzdCBidWZmZXIKKyAgICAgKiBAcGFyYW0gb2Zmc2V0MSB0aGUgZmlyc3Qgb2Zmc2V0CisgICAgICogQHBhcmFtIGxlbmd0aDEgdGhlIGZpcnN0IGxlbmd0aAorICAgICAqIEBwYXJhbSBidWZmZXIyIHRoZSBzZWNvbmQgYnVmZmVyCisgICAgICogQHBhcmFtIG9mZnNldDIgdGhlIHNlY29uZCBvZmZzZXQKKyAgICAgKiBAcGFyYW0gbGVuZ3RoMiB0aGUgc2Vjb25kIGxlbmd0aAorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIGJ1ZmZlcjEgYW5kIGJ1ZmZlcjIgaGF2ZSBzYW1lIGNvbnRlbnRzLCBoYXZpbmcgcmVnYXJkIHRvIHRyYWlsaW5nIG51bGxzCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzRXF1YWxXaXRoTnVsbCgKKyAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBidWZmZXIxLCBmaW5hbCBpbnQgb2Zmc2V0MSwgZmluYWwgaW50IGxlbmd0aDEsCisgICAgICAgICAgICBmaW5hbCBieXRlW10gYnVmZmVyMiwgZmluYWwgaW50IG9mZnNldDIsIGZpbmFsIGludCBsZW5ndGgyKXsKKyAgICAgICAgcmV0dXJuIGlzRXF1YWwoYnVmZmVyMSwgb2Zmc2V0MSwgbGVuZ3RoMSwgYnVmZmVyMiwgb2Zmc2V0MiwgbGVuZ3RoMiwgdHJ1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBmaXJzdCBOIGJ5dGVzIG9mIGFuIGFycmF5IGFyZSBhbGwgemVybworICAgICAqCisgICAgICogQHBhcmFtIGEKKyAgICAgKiAgICAgICAgICAgIFRoZSBhcnJheSB0byBjaGVjaworICAgICAqIEBwYXJhbSBzaXplCisgICAgICogICAgICAgICAgICBUaGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gY2hlY2sgKG5vdCB0aGUgc2l6ZSBvZiB0aGUgYXJyYXkpCisgICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBmaXJzdCBOIGJ5dGVzIGFyZSB6ZXJvCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzQXJyYXlaZXJvKGZpbmFsIGJ5dGVbXSBhLCBmaW5hbCBpbnQgc2l6ZSkgeworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgeworICAgICAgICAgICAgaWYgKGFbaV0gIT0gMCkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgInNhbml0aXplZCIgdmVyc2lvbiBvZiB0aGUgc3RyaW5nIGdpdmVuIGFzIGFyZ3VtZW50cywKKyAgICAgKiB3aGVyZSBzYW5pdGl6ZWQgbWVhbnMgbm9uLXByaW50YWJsZSBjaGFyYWN0ZXJzIGhhdmUgYmVlbgorICAgICAqIHJlcGxhY2VkIHdpdGggYSBxdWVzdGlvbiBtYXJrIGFuZCB0aGUgb3V0Y29tZSBpcyBub3QgbG9uZ2VyCisgICAgICogdGhhbiAyNTUgY2hhcnMuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBpcyB1c2VkIHRvIGNsZWFuIHVwIGZpbGUgbmFtZXMgd2hlbiB0aGV5IGFyZQorICAgICAqIHVzZWQgaW4gZXhjZXB0aW9uIG1lc3NhZ2VzIGFzIHRoZXkgbWF5IGVuZCB1cCBpbiBsb2cgZmlsZXMgb3IKKyAgICAgKiBhcyBjb25zb2xlIG91dHB1dCBhbmQgbWF5IGhhdmUgYmVlbiByZWFkIGZyb20gYSBjb3JydXB0ZWQKKyAgICAgKiBpbnB1dC48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gcyB0aGUgc3RyaW5nIHRvIHNhbml0aXplCisgICAgICogQHJldHVybiBhIHNhbml0aXplZCB2ZXJzaW9uIG9mIHRoZSBhcmd1bWVudAorICAgICAqIEBzaW5jZSBDb21wcmVzcyAxLjEyCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgc2FuaXRpemUoZmluYWwgU3RyaW5nIHMpIHsKKyAgICAgICAgZmluYWwgY2hhcltdIGNzID0gcy50b0NoYXJBcnJheSgpOworICAgICAgICBmaW5hbCBjaGFyW10gY2hhcnMgPSBjcy5sZW5ndGggPD0gTUFYX1NBTklUSVpFRF9OQU1FX0xFTkdUSCA/IGNzIDogQXJyYXlzLmNvcHlPZihjcywgTUFYX1NBTklUSVpFRF9OQU1FX0xFTkdUSCk7CisgICAgICAgIGlmIChjcy5sZW5ndGggPiBNQVhfU0FOSVRJWkVEX05BTUVfTEVOR1RIKSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gTUFYX1NBTklUSVpFRF9OQU1FX0xFTkdUSCAtIDM7IGkgPCBNQVhfU0FOSVRJWkVEX05BTUVfTEVOR1RIOyBpKyspIHsKKyAgICAgICAgICAgICAgICBjaGFyc1tpXSA9ICcuJzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBmaW5hbCBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgZm9yIChmaW5hbCBjaGFyIGMgOiBjaGFycykgeworICAgICAgICAgICAgaWYgKCFDaGFyYWN0ZXIuaXNJU09Db250cm9sKGMpKSB7CisgICAgICAgICAgICAgICAgZmluYWwgQ2hhcmFjdGVyLlVuaWNvZGVCbG9jayBibG9jayA9IENoYXJhY3Rlci5Vbmljb2RlQmxvY2sub2YoYyk7CisgICAgICAgICAgICAgICAgaWYgKGJsb2NrICE9IG51bGwgJiYgYmxvY2sgIT0gQ2hhcmFjdGVyLlVuaWNvZGVCbG9jay5TUEVDSUFMUykgeworICAgICAgICAgICAgICAgICAgICBzYi5hcHBlbmQoYyk7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHNiLmFwcGVuZCgnPycpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBzYi50b1N0cmluZygpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvdXRpbHMvQml0SW5wdXRTdHJlYW0uamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL3V0aWxzL0JpdElucHV0U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGFiZmY1ZgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL3V0aWxzL0JpdElucHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwyMDMgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHM7CisKK2ltcG9ydCBqYXZhLmlvLkNsb3NlYWJsZTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5uaW8uQnl0ZU9yZGVyOworCisvKioKKyAqIFJlYWRzIGJpdHMgZnJvbSBhbiBJbnB1dFN0cmVhbS4KKyAqIEBzaW5jZSAxLjEwCisgKiBATm90VGhyZWFkU2FmZQorICovCitwdWJsaWMgY2xhc3MgQml0SW5wdXRTdHJlYW0gaW1wbGVtZW50cyBDbG9zZWFibGUgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNQVhJTVVNX0NBQ0hFX1NJWkUgPSA2MzsgLy8gYml0cyBpbiBsb25nIG1pbnVzIHNpZ24gYml0CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZ1tdIE1BU0tTID0gbmV3IGxvbmdbTUFYSU1VTV9DQUNIRV9TSVpFICsgMV07CisKKyAgICBzdGF0aWMgeworICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8PSBNQVhJTVVNX0NBQ0hFX1NJWkU7IGkrKykgeworICAgICAgICAgICAgTUFTS1NbaV0gPSAoTUFTS1NbaSAtIDFdIDw8IDEpICsgMTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgZmluYWwgQ291bnRpbmdJbnB1dFN0cmVhbSBpbjsKKyAgICBwcml2YXRlIGZpbmFsIEJ5dGVPcmRlciBieXRlT3JkZXI7CisgICAgcHJpdmF0ZSBsb25nIGJpdHNDYWNoZWQgPSAwOworICAgIHByaXZhdGUgaW50IGJpdHNDYWNoZWRTaXplID0gMDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yIHRha2luZyBhbiBJbnB1dFN0cmVhbSBhbmQgaXRzIGJpdCBhcnJhbmdlbWVudC4KKyAgICAgKiBAcGFyYW0gaW4gdGhlIElucHV0U3RyZWFtCisgICAgICogQHBhcmFtIGJ5dGVPcmRlciB0aGUgYml0IGFycmFuZ2VtZW50IGFjcm9zcyBieXRlIGJvdW5kYXJpZXMsCisgICAgICogICAgICBlaXRoZXIgQklHX0VORElBTiAoYWFhYWFiYmIgYmIwMDAwMDApIG9yIExJVFRMRV9FTkRJQU4gKGJiYmFhYWFhIDAwMDAwMGJiKQorICAgICAqLworICAgIHB1YmxpYyBCaXRJbnB1dFN0cmVhbShmaW5hbCBJbnB1dFN0cmVhbSBpbiwgZmluYWwgQnl0ZU9yZGVyIGJ5dGVPcmRlcikgeworICAgICAgICB0aGlzLmluID0gbmV3IENvdW50aW5nSW5wdXRTdHJlYW0oaW4pOworICAgICAgICB0aGlzLmJ5dGVPcmRlciA9IGJ5dGVPcmRlcjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGluLmNsb3NlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xlYXJzIHRoZSBjYWNoZSBvZiBiaXRzIHRoYXQgaGF2ZSBiZWVuIHJlYWQgZnJvbSB0aGUKKyAgICAgKiB1bmRlcmx5aW5nIHN0cmVhbSBidXQgbm90IHlldCBwcm92aWRlZCB2aWEge0BsaW5rICNyZWFkQml0c30uCisgICAgICovCisgICAgcHVibGljIHZvaWQgY2xlYXJCaXRDYWNoZSgpIHsKKyAgICAgICAgYml0c0NhY2hlZCA9IDA7CisgICAgICAgIGJpdHNDYWNoZWRTaXplID0gMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGF0IG1vc3QgNjMgYml0cyByZWFkIGZyb20gdGhlIHVuZGVybHlpbmcgc3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtIGNvdW50IHRoZSBudW1iZXIgb2YgYml0cyB0byByZWFkLCBtdXN0IGJlIGEgcG9zaXRpdmUKKyAgICAgKiBudW1iZXIgbm90IGJpZ2dlciB0aGFuIDYzLgorICAgICAqIEByZXR1cm4gdGhlIGJpdHMgY29uY2F0ZW5hdGVkIGFzIGEgbG9uZyB1c2luZyB0aGUgc3RyZWFtJ3MgYnl0ZSBvcmRlci4KKyAgICAgKiAgICAgICAgIC0xIGlmIHRoZSBlbmQgb2YgdGhlIHVuZGVybHlpbmcgc3RyZWFtIGhhcyBiZWVuIHJlYWNoZWQgYmVmb3JlIHJlYWRpbmcKKyAgICAgKiAgICAgICAgIHRoZSByZXF1ZXN0ZWQgbnVtYmVyIG9mIGJpdHMKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIG9uIGVycm9yCisgICAgICovCisgICAgcHVibGljIGxvbmcgcmVhZEJpdHMoZmluYWwgaW50IGNvdW50KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoY291bnQgPCAwIHx8IGNvdW50ID4gTUFYSU1VTV9DQUNIRV9TSVpFKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJjb3VudCBtdXN0IG5vdCBiZSBuZWdhdGl2ZSBvciBncmVhdGVyIHRoYW4gIiArIE1BWElNVU1fQ0FDSEVfU0laRSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGVuc3VyZUNhY2hlKGNvdW50KSkgeworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGJpdHNDYWNoZWRTaXplIDwgY291bnQpIHsKKyAgICAgICAgICAgIHJldHVybiBwcm9jZXNzQml0c0dyZWF0ZXI1Nyhjb3VudCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlYWRDYWNoZWRCaXRzKGNvdW50KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgYml0cyB0aGF0IGNhbiBiZSByZWFkIGZyb20gdGhpcyBpbnB1dAorICAgICAqIHN0cmVhbSB3aXRob3V0IHJlYWRpbmcgZnJvbSB0aGUgdW5kZXJseWluZyBpbnB1dCBzdHJlYW0gYXQgYWxsLgorICAgICAqIEByZXR1cm4gZXN0aW1hdGUgb2YgdGhlIG51bWJlciBvZiBiaXRzIHRoYXQgY2FuIGJlIHJlYWQgd2l0aG91dCByZWFkaW5nIGZyb20gdGhlIHVuZGVybHlpbmcgc3RyZWFtCisgICAgICogQHNpbmNlIDEuMTYKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGJpdHNDYWNoZWQoKSB7CisgICAgICAgIHJldHVybiBiaXRzQ2FjaGVkU2l6ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGVzdGltYXRlIG9mIHRoZSBudW1iZXIgb2YgYml0cyB0aGF0IGNhbiBiZSByZWFkIGZyb20KKyAgICAgKiB0aGlzIGlucHV0IHN0cmVhbSB3aXRob3V0IGJsb2NraW5nIGJ5IHRoZSBuZXh0IGludm9jYXRpb24gb2YgYQorICAgICAqIG1ldGhvZCBmb3IgdGhpcyBpbnB1dCBzdHJlYW0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiB0aGUgdW5kZXJseWluZyBzdHJlYW0gdGhyb3dzIG9uZSB3aGVuIGNhbGxpbmcgYXZhaWxhYmxlCisgICAgICogQHJldHVybiBlc3RpbWF0ZSBvZiB0aGUgbnVtYmVyIG9mIGJpdHMgdGhhdCBjYW4gYmUgcmVhZCB3aXRob3V0IGJsb2NraW5nCisgICAgICogQHNpbmNlIDEuMTYKKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBiaXRzQXZhaWxhYmxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGJpdHNDYWNoZWRTaXplICsgKChsb25nKSBCeXRlLlNJWkUpICogaW4uYXZhaWxhYmxlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRHJvcHMgYml0cyB1bnRpbCB0aGUgbmV4dCBiaXRzIHdpbGwgYmUgcmVhZCBmcm9tIGEgYnl0ZSBib3VuZGFyeS4KKyAgICAgKiBAc2luY2UgMS4xNgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFsaWduV2l0aEJ5dGVCb3VuZGFyeSgpIHsKKyAgICAgICAgaW50IHRvU2tpcCA9IGJpdHNDYWNoZWRTaXplICUgQnl0ZS5TSVpFOworICAgICAgICBpZiAodG9Ta2lwID4gMCkgeworICAgICAgICAgICAgcmVhZENhY2hlZEJpdHModG9Ta2lwKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBieXRlcyByZWFkIGZyb20gdGhlIHVuZGVybHlpbmcgc3RyZWFtLgorICAgICAqCisgICAgICogPHA+VGhpcyBpbmNsdWRlcyB0aGUgYnl0ZXMgcmVhZCB0byBmaWxsIHRoZSBjdXJyZW50IGNhY2hlIGFuZAorICAgICAqIG5vdCByZWFkIGFzIGJpdHMgc28gZmFyLjwvcD4KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgcmVhZCBmcm9tIHRoZSB1bmRlcmx5aW5nIHN0cmVhbQorICAgICAqIEBzaW5jZSAxLjE3CisgICAgICovCisgICAgcHVibGljIGxvbmcgZ2V0Qnl0ZXNSZWFkKCkgeworICAgICAgICByZXR1cm4gaW4uZ2V0Qnl0ZXNSZWFkKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBsb25nIHByb2Nlc3NCaXRzR3JlYXRlcjU3KGZpbmFsIGludCBjb3VudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgbG9uZyBiaXRzT3V0OworICAgICAgICBpbnQgb3ZlcmZsb3dCaXRzID0gMDsKKyAgICAgICAgbG9uZyBvdmVyZmxvdyA9IDBMOworCisgICAgICAgIC8vIGJpdHNDYWNoZWRTaXplID49IDU3IGFuZCBsZWZ0LXNoaWZ0aW5nIGl0IDggYml0cyB3b3VsZCBjYXVzZSBhbiBvdmVyZmxvdworICAgICAgICBpbnQgYml0c1RvQWRkQ291bnQgPSBjb3VudCAtIGJpdHNDYWNoZWRTaXplOworICAgICAgICBvdmVyZmxvd0JpdHMgPSBCeXRlLlNJWkUgLSBiaXRzVG9BZGRDb3VudDsKKyAgICAgICAgZmluYWwgbG9uZyBuZXh0Qnl0ZSA9IGluLnJlYWQoKTsKKyAgICAgICAgaWYgKG5leHRCeXRlIDwgMCkgeworICAgICAgICAgICAgcmV0dXJuIG5leHRCeXRlOworICAgICAgICB9CisgICAgICAgIGlmIChieXRlT3JkZXIgPT0gQnl0ZU9yZGVyLkxJVFRMRV9FTkRJQU4pIHsKKyAgICAgICAgICAgIGxvbmcgYml0c1RvQWRkID0gbmV4dEJ5dGUgJiBNQVNLU1tiaXRzVG9BZGRDb3VudF07CisgICAgICAgICAgICBiaXRzQ2FjaGVkIHw9IChiaXRzVG9BZGQgPDwgYml0c0NhY2hlZFNpemUpOworICAgICAgICAgICAgb3ZlcmZsb3cgPSAobmV4dEJ5dGUgPj4+IGJpdHNUb0FkZENvdW50KSAmIE1BU0tTW292ZXJmbG93Qml0c107CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBiaXRzQ2FjaGVkIDw8PSBiaXRzVG9BZGRDb3VudDsKKyAgICAgICAgICAgIGxvbmcgYml0c1RvQWRkID0gKG5leHRCeXRlID4+PiAob3ZlcmZsb3dCaXRzKSkgJiBNQVNLU1tiaXRzVG9BZGRDb3VudF07CisgICAgICAgICAgICBiaXRzQ2FjaGVkIHw9IGJpdHNUb0FkZDsKKyAgICAgICAgICAgIG92ZXJmbG93ID0gbmV4dEJ5dGUgJiBNQVNLU1tvdmVyZmxvd0JpdHNdOworICAgICAgICB9CisgICAgICAgIGJpdHNPdXQgPSBiaXRzQ2FjaGVkICYgTUFTS1NbY291bnRdOworICAgICAgICBiaXRzQ2FjaGVkID0gb3ZlcmZsb3c7CisgICAgICAgIGJpdHNDYWNoZWRTaXplID0gb3ZlcmZsb3dCaXRzOworICAgICAgICByZXR1cm4gYml0c091dDsKKyAgICB9CisKKyAgICBwcml2YXRlIGxvbmcgcmVhZENhY2hlZEJpdHMoaW50IGNvdW50KSB7CisgICAgICAgIGZpbmFsIGxvbmcgYml0c091dDsKKyAgICAgICAgaWYgKGJ5dGVPcmRlciA9PSBCeXRlT3JkZXIuTElUVExFX0VORElBTikgeworICAgICAgICAgICAgYml0c091dCA9IChiaXRzQ2FjaGVkICYgTUFTS1NbY291bnRdKTsKKyAgICAgICAgICAgIGJpdHNDYWNoZWQgPj4+PSBjb3VudDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGJpdHNPdXQgPSAoYml0c0NhY2hlZCA+PiAoYml0c0NhY2hlZFNpemUgLSBjb3VudCkpICYgTUFTS1NbY291bnRdOworICAgICAgICB9CisgICAgICAgIGJpdHNDYWNoZWRTaXplIC09IGNvdW50OworICAgICAgICByZXR1cm4gYml0c091dDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaWxscyB0aGUgY2FjaGUgdXAgdG8gNTYgYml0cworICAgICAqIEBwYXJhbSBjb3VudAorICAgICAqIEByZXR1cm4gcmV0dXJuIHRydWUsIHdoZW4gRU9GCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBlbnN1cmVDYWNoZShmaW5hbCBpbnQgY291bnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHdoaWxlIChiaXRzQ2FjaGVkU2l6ZSA8IGNvdW50ICYmIGJpdHNDYWNoZWRTaXplIDwgNTcpIHsKKyAgICAgICAgICAgIGZpbmFsIGxvbmcgbmV4dEJ5dGUgPSBpbi5yZWFkKCk7CisgICAgICAgICAgICBpZiAobmV4dEJ5dGUgPCAwKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoYnl0ZU9yZGVyID09IEJ5dGVPcmRlci5MSVRUTEVfRU5ESUFOKSB7CisgICAgICAgICAgICAgICAgYml0c0NhY2hlZCB8PSAobmV4dEJ5dGUgPDwgYml0c0NhY2hlZFNpemUpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBiaXRzQ2FjaGVkIDw8PSBCeXRlLlNJWkU7CisgICAgICAgICAgICAgICAgYml0c0NhY2hlZCB8PSBuZXh0Qnl0ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJpdHNDYWNoZWRTaXplICs9IEJ5dGUuU0laRTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy91dGlscy9Cb3VuZGVkSW5wdXRTdHJlYW0uamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL3V0aWxzL0JvdW5kZWRJbnB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhjMzQ2NWQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy91dGlscy9Cb3VuZGVkSW5wdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDczIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlsczsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKKworLyoqCisgKiBBIHN0cmVhbSB0aGF0IGxpbWl0cyByZWFkaW5nIGZyb20gYSB3cmFwcGVkIHN0cmVhbSB0byBhIGdpdmVuIG51bWJlciBvZiBieXRlcy4KKyAqIEBOb3RUaHJlYWRTYWZlCisgKiBAc2luY2UgMS42CisgKi8KK3B1YmxpYyBjbGFzcyBCb3VuZGVkSW5wdXRTdHJlYW0gZXh0ZW5kcyBJbnB1dFN0cmVhbSB7CisgICAgcHJpdmF0ZSBmaW5hbCBJbnB1dFN0cmVhbSBpbjsKKyAgICBwcml2YXRlIGxvbmcgYnl0ZXNSZW1haW5pbmc7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIHRoZSBzdHJlYW0gdGhhdCB3aWxsIGF0IG1vc3QgcmVhZCB0aGUgZ2l2ZW4gYW1vdW50IG9mCisgICAgICogYnl0ZXMgZnJvbSB0aGUgZ2l2ZW4gc3RyZWFtLgorICAgICAqIEBwYXJhbSBpbiB0aGUgc3RyZWFtIHRvIHJlYWQgZnJvbQorICAgICAqIEBwYXJhbSBzaXplIHRoZSBtYXhpbXVtIGFtb3VudCBvZiBieXRlcyB0byByZWFkCisgICAgICovCisgICAgcHVibGljIEJvdW5kZWRJbnB1dFN0cmVhbShmaW5hbCBJbnB1dFN0cmVhbSBpbiwgZmluYWwgbG9uZyBzaXplKSB7CisgICAgICAgIHRoaXMuaW4gPSBpbjsKKyAgICAgICAgYnl0ZXNSZW1haW5pbmcgPSBzaXplOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChieXRlc1JlbWFpbmluZyA+IDApIHsKKyAgICAgICAgICAgIC0tYnl0ZXNSZW1haW5pbmc7CisgICAgICAgICAgICByZXR1cm4gaW4ucmVhZCgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHJlYWQoZmluYWwgYnl0ZVtdIGIsIGZpbmFsIGludCBvZmYsIGZpbmFsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChieXRlc1JlbWFpbmluZyA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICAgICAgaW50IGJ5dGVzVG9SZWFkID0gbGVuOworICAgICAgICBpZiAoYnl0ZXNUb1JlYWQgPiBieXRlc1JlbWFpbmluZykgeworICAgICAgICAgICAgYnl0ZXNUb1JlYWQgPSAoaW50KSBieXRlc1JlbWFpbmluZzsKKyAgICAgICAgfQorICAgICAgICBmaW5hbCBpbnQgYnl0ZXNSZWFkID0gaW4ucmVhZChiLCBvZmYsIGJ5dGVzVG9SZWFkKTsKKyAgICAgICAgaWYgKGJ5dGVzUmVhZCA+PSAwKSB7CisgICAgICAgICAgICBieXRlc1JlbWFpbmluZyAtPSBieXRlc1JlYWQ7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGJ5dGVzUmVhZDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHsKKyAgICAgICAgLy8gdGhlcmUgaXNuJ3QgYW55dGhpbmcgdG8gY2xvc2UgaW4gdGhpcyBzdHJlYW0gYW5kIHRoZSBuZXN0ZWQKKyAgICAgICAgLy8gc3RyZWFtIGlzIGNvbnRyb2xsZWQgZXh0ZXJuYWxseQorICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL3V0aWxzL0J5dGVVdGlscy5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvdXRpbHMvQnl0ZVV0aWxzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODViNDExOAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL3V0aWxzL0J5dGVVdGlscy5qYXZhCkBAIC0wLDAgKzEsMjYxIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICoKKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlsczsKKworaW1wb3J0IGphdmEuaW8uRGF0YUlucHV0OworaW1wb3J0IGphdmEuaW8uRGF0YU91dHB1dDsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CisKKy8qKgorICogVXRpbGl0eSBtZXRob2RzIGZvciByZWFkaW5nIGFuZCB3cml0aW5nIGJ5dGVzLgorICogQHNpbmNlIDEuMTQKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIEJ5dGVVdGlscyB7CisgICAgcHJpdmF0ZSBCeXRlVXRpbHMoKSB7IC8qIG5vIGluc3RhbmNlcyAqLyB9CisKKyAgICAvKioKKyAgICAgKiBVc2VkIHRvIHN1cHBseSBieXRlcy4KKyAgICAgKiBAc2luY2UgMS4xNAorICAgICAqLworICAgIHB1YmxpYyBpbnRlcmZhY2UgQnl0ZVN1cHBsaWVyIHsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBjb250cmFjdCBpcyBzaW1pbGFyIHRvIHtAbGluayBJbnB1dFN0cmVhbSNyZWFkKCl9LCByZXR1cm4KKyAgICAgICAgICogdGhlIGJ5dGUgYXMgYW4gdW5zaWduZWQgaW50LCAtMSBpZiB0aGVyZSBhcmUgbm8gbW9yZSBieXRlcy4KKyAgICAgICAgICogQHJldHVybiB0aGUgc3VwcGxpZWQgYnl0ZSBvciAtMSBpZiB0aGVyZSBhcmUgbm8gbW9yZSBieXRlcworICAgICAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHN1cHBseWluZyBmYWlscworICAgICAgICAgKi8KKyAgICAgICAgaW50IGdldEFzQnl0ZSgpIHRocm93cyBJT0V4Y2VwdGlvbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVc2VkIHRvIGNvbnN1bWUgYnl0ZXMuCisgICAgICogQHNpbmNlIDEuMTQKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50ZXJmYWNlIEJ5dGVDb25zdW1lciB7CisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgY29udHJhY3QgaXMgc2ltaWxhciB0byB7QGxpbmsgT3V0cHV0U3RyZWFtI3dyaXRlKGludCl9LAorICAgICAgICAgKiBjb25zdW1lIHRoZSBsb3dlciBlaWdodCBieXRlcyBvZiB0aGUgaW50IGFzIGEgYnl0ZS4KKyAgICAgICAgICogQHBhcmFtIGIgdGhlIGJ5dGUgdG8gY29uc3VtZQorICAgICAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIGNvbnN1bWluZyBmYWlscworICAgICAgICAgKi8KKyAgICAgICAgdm9pZCBhY2NlcHQoaW50IGIpIHRocm93cyBJT0V4Y2VwdGlvbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyB0aGUgZ2l2ZW4gYnl0ZSBhcnJheSBhcyBhIGxpdHRsZSBlbmRpYW4gbG9uZy4KKyAgICAgKiBAcGFyYW0gYnl0ZXMgdGhlIGJ5dGUgYXJyYXkgdG8gY29udmVydAorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciByZWFkCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBsb25nIGZyb21MaXR0bGVFbmRpYW4oYnl0ZVtdIGJ5dGVzKSB7CisgICAgICAgIHJldHVybiBmcm9tTGl0dGxlRW5kaWFuKGJ5dGVzLCAwLCBieXRlcy5sZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIHRoZSBnaXZlbiBieXRlIGFycmF5IGFzIGEgbGl0dGxlIGVuZGlhbiBsb25nLgorICAgICAqIEBwYXJhbSBieXRlcyB0aGUgYnl0ZSBhcnJheSB0byBjb252ZXJ0CisgICAgICogQHBhcmFtIG9mZiB0aGUgb2Zmc2V0IGludG8gdGhlIGFycmF5IHRoYXQgc3RhcnRzIHRoZSB2YWx1ZQorICAgICAqIEBwYXJhbSBsZW5ndGggdGhlIG51bWJlciBvZiBieXRlcyByZXByZXNlbnRpbmcgdGhlIHZhbHVlCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIHJlYWQKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBsZW4gaXMgYmlnZ2VyIHRoYW4gZWlnaHQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGxvbmcgZnJvbUxpdHRsZUVuZGlhbihieXRlW10gYnl0ZXMsIGZpbmFsIGludCBvZmYsIGZpbmFsIGludCBsZW5ndGgpIHsKKyAgICAgICAgY2hlY2tSZWFkTGVuZ3RoKGxlbmd0aCk7CisgICAgICAgIGxvbmcgbCA9IDA7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGwgfD0gKGJ5dGVzW29mZiArIGldICYgMHhmZkwpIDw8ICg4ICogaSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgdGhlIGdpdmVuIG51bWJlciBvZiBieXRlcyBmcm9tIHRoZSBnaXZlbiBzdHJlYW0gYXMgYSBsaXR0bGUgZW5kaWFuIGxvbmcuCisgICAgICogQHBhcmFtIGluIHRoZSBzdHJlYW0gdG8gcmVhZCBmcm9tCisgICAgICogQHBhcmFtIGxlbmd0aCB0aGUgbnVtYmVyIG9mIGJ5dGVzIHJlcHJlc2VudGluZyB0aGUgdmFsdWUKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgcmVhZAorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIGxlbiBpcyBiaWdnZXIgdGhhbiBlaWdodAorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgcmVhZGluZyBmYWlscyBvciB0aGUgc3RyZWFtIGRvZXNuJ3QKKyAgICAgKiBjb250YWluIHRoZSBnaXZlbiBudW1iZXIgb2YgYnl0ZXMgYW55bW9yZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbG9uZyBmcm9tTGl0dGxlRW5kaWFuKElucHV0U3RyZWFtIGluLCBpbnQgbGVuZ3RoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBzb21ld2hhdCBkdXBsaWNhdGVzIHRoZSBCeXRlU3VwcGxpZXIgdmVyc2lvbiBpbiBvcmRlciB0byBzYXZlIHRoZSBjcmVhdGlvbiBvZiBhIHdyYXBwZXIgb2JqZWN0CisgICAgICAgIGNoZWNrUmVhZExlbmd0aChsZW5ndGgpOworICAgICAgICBsb25nIGwgPSAwOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBsb25nIGIgPSBpbi5yZWFkKCk7CisgICAgICAgICAgICBpZiAoYiA9PSAtMSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigicHJlbWF0dXJlIGVuZCBvZiBkYXRhIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBsIHw9IChiIDw8IChpICogOCkpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIHRoZSBnaXZlbiBudW1iZXIgb2YgYnl0ZXMgZnJvbSB0aGUgZ2l2ZW4gc3VwcGxpZXIgYXMgYSBsaXR0bGUgZW5kaWFuIGxvbmcuCisgICAgICoKKyAgICAgKiA8cD5UeXBpY2FsbHkgdXNlZCBieSBvdXIgSW5wdXRTdHJlYW1zIHRoYXQgbmVlZCB0byBjb3VudCB0aGUKKyAgICAgKiBieXRlcyByZWFkIGFzIHdlbGwuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIHN1cHBsaWVyIHRoZSBzdXBwbGllciBmb3IgYnl0ZXMKKyAgICAgKiBAcGFyYW0gbGVuZ3RoIHRoZSBudW1iZXIgb2YgYnl0ZXMgcmVwcmVzZW50aW5nIHRoZSB2YWx1ZQorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciByZWFkCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgbGVuIGlzIGJpZ2dlciB0aGFuIGVpZ2h0CisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiB0aGUgc3VwcGxpZXIgZmFpbHMgb3IgZG9lc24ndCBzdXBwbHkgdGhlCisgICAgICogZ2l2ZW4gbnVtYmVyIG9mIGJ5dGVzIGFueW1vcmUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGxvbmcgZnJvbUxpdHRsZUVuZGlhbihCeXRlU3VwcGxpZXIgc3VwcGxpZXIsIGZpbmFsIGludCBsZW5ndGgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrUmVhZExlbmd0aChsZW5ndGgpOworICAgICAgICBsb25nIGwgPSAwOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBsb25nIGIgPSBzdXBwbGllci5nZXRBc0J5dGUoKTsKKyAgICAgICAgICAgIGlmIChiID09IC0xKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJwcmVtYXR1cmUgZW5kIG9mIGRhdGEiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGwgfD0gKGIgPDwgKGkgKiA4KSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgdGhlIGdpdmVuIG51bWJlciBvZiBieXRlcyBmcm9tIHRoZSBnaXZlbiBpbnB1dCBhcyBsaXR0bGUgZW5kaWFuIGxvbmcuCisgICAgICogQHBhcmFtIGluIHRoZSBpbnB1dCB0byByZWFkIGZyb20KKyAgICAgKiBAcGFyYW0gbGVuZ3RoIHRoZSBudW1iZXIgb2YgYnl0ZXMgcmVwcmVzZW50aW5nIHRoZSB2YWx1ZQorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciByZWFkCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgbGVuIGlzIGJpZ2dlciB0aGFuIGVpZ2h0CisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiByZWFkaW5nIGZhaWxzIG9yIHRoZSBzdHJlYW0gZG9lc24ndAorICAgICAqIGNvbnRhaW4gdGhlIGdpdmVuIG51bWJlciBvZiBieXRlcyBhbnltb3JlCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBsb25nIGZyb21MaXR0bGVFbmRpYW4oRGF0YUlucHV0IGluLCBpbnQgbGVuZ3RoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBzb21ld2hhdCBkdXBsaWNhdGVzIHRoZSBCeXRlU3VwcGxpZXIgdmVyc2lvbiBpbiBvcmRlciB0byBzYXZlIHRoZSBjcmVhdGlvbiBvZiBhIHdyYXBwZXIgb2JqZWN0CisgICAgICAgIGNoZWNrUmVhZExlbmd0aChsZW5ndGgpOworICAgICAgICBsb25nIGwgPSAwOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBsb25nIGIgPSBpbi5yZWFkVW5zaWduZWRCeXRlKCk7CisgICAgICAgICAgICBsIHw9IChiIDw8IChpICogOCkpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBsOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc2VydHMgdGhlIGdpdmVuIHZhbHVlIGludG8gdGhlIGFycmF5IGFzIGEgbGl0dGxlIGVuZGlhbgorICAgICAqIHNlcXVlbmNlIG9mIHRoZSBnaXZlbiBsZW5ndGggc3RhcnRpbmcgYXQgdGhlIGdpdmVuIG9mZnNldC4KKyAgICAgKiBAcGFyYW0gYiB0aGUgYXJyYXkgdG8gd3JpdGUgaW50bworICAgICAqIEBwYXJhbSB2YWx1ZSB0aGUgdmFsdWUgdG8gaW5zZXJ0CisgICAgICogQHBhcmFtIG9mZiB0aGUgb2Zmc2V0IGludG8gdGhlIGFycmF5IHRoYXQgcmVjZWl2ZXMgdGhlIGZpcnN0IGJ5dGUKKyAgICAgKiBAcGFyYW0gbGVuZ3RoIHRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gdXNlIHRvIHJlcHJlc2VudCB0aGUgdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgdG9MaXR0bGVFbmRpYW4oZmluYWwgYnl0ZVtdIGIsIGZpbmFsIGxvbmcgdmFsdWUsIGZpbmFsIGludCBvZmYsIGZpbmFsIGludCBsZW5ndGgpIHsKKyAgICAgICAgbG9uZyBudW0gPSB2YWx1ZTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgeworICAgICAgICAgICAgYltvZmYgKyBpXSA9IChieXRlKSAobnVtICYgMHhmZik7CisgICAgICAgICAgICBudW0gPj49IDg7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgdGhlIGdpdmVuIHZhbHVlIHRvIHRoZSBnaXZlbiBzdHJlYW0gYXMgYSBsaXR0bGUgZW5kaWFuCisgICAgICogYXJyYXkgb2YgdGhlIGdpdmVuIGxlbmd0aC4KKyAgICAgKiBAcGFyYW0gb3V0IHRoZSBzdHJlYW0gdG8gd3JpdGUgdG8KKyAgICAgKiBAcGFyYW0gdmFsdWUgdGhlIHZhbHVlIHRvIHdyaXRlCisgICAgICogQHBhcmFtIGxlbmd0aCB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRvIHVzZSB0byByZXByZXNlbnQgdGhlIHZhbHVlCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiB3cml0aW5nIGZhaWxzCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHRvTGl0dGxlRW5kaWFuKE91dHB1dFN0cmVhbSBvdXQsIGZpbmFsIGxvbmcgdmFsdWUsIGZpbmFsIGludCBsZW5ndGgpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIHNvbWV3aGF0IGR1cGxpY2F0ZXMgdGhlIEJ5dGVDb25zdW1lciB2ZXJzaW9uIGluIG9yZGVyIHRvIHNhdmUgdGhlIGNyZWF0aW9uIG9mIGEgd3JhcHBlciBvYmplY3QKKyAgICAgICAgbG9uZyBudW0gPSB2YWx1ZTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgeworICAgICAgICAgICAgb3V0LndyaXRlKChpbnQpIChudW0gJiAweGZmKSk7CisgICAgICAgICAgICBudW0gPj49IDg7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcm92aWRlcyB0aGUgZ2l2ZW4gdmFsdWUgdG8gdGhlIGdpdmVuIGNvbnN1bWVyIGFzIGEgbGl0dGxlIGVuZGlhbgorICAgICAqIHNlcXVlbmNlIG9mIHRoZSBnaXZlbiBsZW5ndGguCisgICAgICogQHBhcmFtIGNvbnN1bWVyIHRoZSBjb25zdW1lciB0byBwcm92aWRlIHRoZSBieXRlcyB0bworICAgICAqIEBwYXJhbSB2YWx1ZSB0aGUgdmFsdWUgdG8gcHJvdmlkZQorICAgICAqIEBwYXJhbSBsZW5ndGggdGhlIG51bWJlciBvZiBieXRlcyB0byB1c2UgdG8gcmVwcmVzZW50IHRoZSB2YWx1ZQorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgd3JpdGluZyBmYWlscworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCB0b0xpdHRsZUVuZGlhbihCeXRlQ29uc3VtZXIgY29uc3VtZXIsIGZpbmFsIGxvbmcgdmFsdWUsIGZpbmFsIGludCBsZW5ndGgpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGxvbmcgbnVtID0gdmFsdWU7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGNvbnN1bWVyLmFjY2VwdCgoaW50KSAobnVtICYgMHhmZikpOworICAgICAgICAgICAgbnVtID4+PSA4OworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIHRoZSBnaXZlbiB2YWx1ZSB0byB0aGUgZ2l2ZW4gc3RyZWFtIGFzIGEgbGl0dGxlIGVuZGlhbgorICAgICAqIGFycmF5IG9mIHRoZSBnaXZlbiBsZW5ndGguCisgICAgICogQHBhcmFtIG91dCB0aGUgb3V0cHV0IHRvIHdyaXRlIHRvCisgICAgICogQHBhcmFtIHZhbHVlIHRoZSB2YWx1ZSB0byB3cml0ZQorICAgICAqIEBwYXJhbSBsZW5ndGggdGhlIG51bWJlciBvZiBieXRlcyB0byB1c2UgdG8gcmVwcmVzZW50IHRoZSB2YWx1ZQorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgd3JpdGluZyBmYWlscworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCB0b0xpdHRsZUVuZGlhbihEYXRhT3V0cHV0IG91dCwgZmluYWwgbG9uZyB2YWx1ZSwgZmluYWwgaW50IGxlbmd0aCkKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gc29tZXdoYXQgZHVwbGljYXRlcyB0aGUgQnl0ZUNvbnN1bWVyIHZlcnNpb24gaW4gb3JkZXIgdG8gc2F2ZSB0aGUgY3JlYXRpb24gb2YgYSB3cmFwcGVyIG9iamVjdAorICAgICAgICBsb25nIG51bSA9IHZhbHVlOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBvdXQud3JpdGUoKGludCkgKG51bSAmIDB4ZmYpKTsKKyAgICAgICAgICAgIG51bSA+Pj0gODsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIHtAbGluayBCeXRlU3VwcGxpZXJ9IGJhc2VkIG9uIHtAbGluayBJbnB1dFN0cmVhbX0uCisgICAgICogQHNpbmNlIDEuMTQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIElucHV0U3RyZWFtQnl0ZVN1cHBsaWVyIGltcGxlbWVudHMgQnl0ZVN1cHBsaWVyIHsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBJbnB1dFN0cmVhbSBpczsKKyAgICAgICAgcHVibGljIElucHV0U3RyZWFtQnl0ZVN1cHBsaWVyKElucHV0U3RyZWFtIGlzKSB7CisgICAgICAgICAgICB0aGlzLmlzID0gaXM7CisgICAgICAgIH0KKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBpbnQgZ2V0QXNCeXRlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBpcy5yZWFkKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB7QGxpbmsgQnl0ZUNvbnN1bWVyfSBiYXNlZCBvbiB7QGxpbmsgT3V0cHV0U3RyZWFtfS4KKyAgICAgKiBAc2luY2UgMS4xNAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgT3V0cHV0U3RyZWFtQnl0ZUNvbnN1bWVyIGltcGxlbWVudHMgQnl0ZUNvbnN1bWVyIHsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBPdXRwdXRTdHJlYW0gb3M7CisgICAgICAgIHB1YmxpYyBPdXRwdXRTdHJlYW1CeXRlQ29uc3VtZXIoT3V0cHV0U3RyZWFtIG9zKSB7CisgICAgICAgICAgICB0aGlzLm9zID0gb3M7CisgICAgICAgIH0KKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIGFjY2VwdChpbnQgYikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIG9zLndyaXRlKGIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgdm9pZCBjaGVja1JlYWRMZW5ndGgoaW50IGxlbmd0aCkgeworICAgICAgICBpZiAobGVuZ3RoID4gOCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiY2FuJ3QgcmVhZCBtb3JlIHRoYW4gZWlnaHQgYnl0ZXMgaW50byBhIGxvbmcgdmFsdWUiKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL3V0aWxzL0NSQzMyVmVyaWZ5aW5nSW5wdXRTdHJlYW0uamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL3V0aWxzL0NSQzMyVmVyaWZ5aW5nSW5wdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xYjUwZThjCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvdXRpbHMvQ1JDMzJWZXJpZnlpbmdJbnB1dFN0cmVhbS5qYXZhCkBAIC0wLDAgKzEsNTAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzOworCitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLkNSQzMyOworCisvKioKKyAqIEEgc3RyZWFtIHRoYXQgdmVyaWZpZXMgdGhlIENSQyBvZiB0aGUgZGF0YSByZWFkIG9uY2UgdGhlIHN0cmVhbSBpcworICogZXhoYXVzdGVkLgorICogQE5vdFRocmVhZFNhZmUKKyAqIEBzaW5jZSAxLjYKKyAqLworcHVibGljIGNsYXNzIENSQzMyVmVyaWZ5aW5nSW5wdXRTdHJlYW0gZXh0ZW5kcyBDaGVja3N1bVZlcmlmeWluZ0lucHV0U3RyZWFtIHsKKworICAgIC8qKgorICAgICAqIEBwYXJhbSBpbiB0aGUgc3RyZWFtIHRvIHdyYXAKKyAgICAgKiBAcGFyYW0gc2l6ZSB0aGUgb2YgdGhlIHN0cmVhbSdzIGNvbnRlbnQKKyAgICAgKiBAcGFyYW0gZXhwZWN0ZWRDcmMzMiB0aGUgZXhwZWN0ZWQgY2hlY2tzdW0KKyAgICAgKi8KKyAgICBwdWJsaWMgQ1JDMzJWZXJpZnlpbmdJbnB1dFN0cmVhbShmaW5hbCBJbnB1dFN0cmVhbSBpbiwgZmluYWwgbG9uZyBzaXplLCBmaW5hbCBpbnQgZXhwZWN0ZWRDcmMzMikgeworICAgICAgICB0aGlzKGluLCBzaXplLCBleHBlY3RlZENyYzMyICYgMHhGRkZGZmZmZkwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzaW5jZSAxLjcKKyAgICAgKiBAcGFyYW0gaW4gdGhlIHN0cmVhbSB0byB3cmFwCisgICAgICogQHBhcmFtIHNpemUgdGhlIG9mIHRoZSBzdHJlYW0ncyBjb250ZW50CisgICAgICogQHBhcmFtIGV4cGVjdGVkQ3JjMzIgdGhlIGV4cGVjdGVkIGNoZWNrc3VtCisgICAgICovCisgICAgcHVibGljIENSQzMyVmVyaWZ5aW5nSW5wdXRTdHJlYW0oZmluYWwgSW5wdXRTdHJlYW0gaW4sIGZpbmFsIGxvbmcgc2l6ZSwgZmluYWwgbG9uZyBleHBlY3RlZENyYzMyKSB7CisgICAgICAgIHN1cGVyKG5ldyBDUkMzMigpLCBpbiwgc2l6ZSwgZXhwZWN0ZWRDcmMzMik7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy91dGlscy9DaGFyc2V0TmFtZXMuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL3V0aWxzL0NoYXJzZXROYW1lcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY2YjljYzgKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy91dGlscy9DaGFyc2V0TmFtZXMuamF2YQpAQCAtMCwwICsxLDEyNSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHM7CisKKy8qKgorICogQ2hhcmFjdGVyIGVuY29kaW5nIG5hbWVzIHJlcXVpcmVkIG9mIGV2ZXJ5IGltcGxlbWVudGF0aW9uIG9mIHRoZSBKYXZhIHBsYXRmb3JtLgorICoKKyAqIEZyb20gdGhlIEphdmEgZG9jdW1lbnRhdGlvbiA8YSBocmVmPSJodHRwczovL2Rvd25sb2FkLm9yYWNsZS5jb20vamF2YXNlLzYvZG9jcy9hcGkvamF2YS9uaW8vY2hhcnNldC9DaGFyc2V0Lmh0bWwiPlN0YW5kYXJkCisgKiBjaGFyc2V0czwvYT46CisgKiA8cD4KKyAqIDxjaXRlPkV2ZXJ5IGltcGxlbWVudGF0aW9uIG9mIHRoZSBKYXZhIHBsYXRmb3JtIGlzIHJlcXVpcmVkIHRvIHN1cHBvcnQgdGhlIGZvbGxvd2luZyBjaGFyYWN0ZXIgZW5jb2RpbmdzLiBDb25zdWx0IHRoZQorICogcmVsZWFzZSBkb2N1bWVudGF0aW9uIGZvciB5b3VyIGltcGxlbWVudGF0aW9uIHRvIHNlZSBpZiBhbnkgb3RoZXIgZW5jb2RpbmdzIGFyZSBzdXBwb3J0ZWQuIENvbnN1bHQgdGhlIHJlbGVhc2UKKyAqIGRvY3VtZW50YXRpb24gZm9yIHlvdXIgaW1wbGVtZW50YXRpb24gdG8gc2VlIGlmIGFueSBvdGhlciBlbmNvZGluZ3MgYXJlIHN1cHBvcnRlZC4gPC9jaXRlPgorICogPC9wPgorICoKKyAqIDxkbD4KKyAqIDxkdD48Y29kZT5VUy1BU0NJSTwvY29kZT48L2R0PgorICogPGRkPlNldmVuLWJpdCBBU0NJSSwgYS5rLmEuIElTTzY0Ni1VUywgYS5rLmEuIHRoZSBCYXNpYyBMYXRpbiBibG9jayBvZiB0aGUgVW5pY29kZSBjaGFyYWN0ZXIgc2V0LjwvZGQ+CisgKiA8ZHQ+PGNvZGU+SVNPLTg4NTktMTwvY29kZT48L2R0PgorICogPGRkPklTTyBMYXRpbiBBbHBoYWJldCBOby4gMSwgYS5rLmEuIElTTy1MQVRJTi0xLjwvZGQ+CisgKiA8ZHQ+PGNvZGU+VVRGLTg8L2NvZGU+PC9kdD4KKyAqIDxkZD5FaWdodC1iaXQgVW5pY29kZSBUcmFuc2Zvcm1hdGlvbiBGb3JtYXQuPC9kZD4KKyAqIDxkdD48Y29kZT5VVEYtMTZCRTwvY29kZT48L2R0PgorICogPGRkPlNpeHRlZW4tYml0IFVuaWNvZGUgVHJhbnNmb3JtYXRpb24gRm9ybWF0LCBiaWctZW5kaWFuIGJ5dGUgb3JkZXIuPC9kZD4KKyAqIDxkdD48Y29kZT5VVEYtMTZMRTwvY29kZT48L2R0PgorICogPGRkPlNpeHRlZW4tYml0IFVuaWNvZGUgVHJhbnNmb3JtYXRpb24gRm9ybWF0LCBsaXR0bGUtZW5kaWFuIGJ5dGUgb3JkZXIuPC9kZD4KKyAqIDxkdD48Y29kZT5VVEYtMTY8L2NvZGU+PC9kdD4KKyAqIDxkZD5TaXh0ZWVuLWJpdCBVbmljb2RlIFRyYW5zZm9ybWF0aW9uIEZvcm1hdCwgYnl0ZSBvcmRlciBzcGVjaWZpZWQgYnkgYSBtYW5kYXRvcnkgaW5pdGlhbCBieXRlLW9yZGVyIG1hcmsgKGVpdGhlciBvcmRlcgorICogYWNjZXB0ZWQgb24gaW5wdXQsIGJpZy1lbmRpYW4gdXNlZCBvbiBvdXRwdXQuKTwvZGQ+CisgKiA8L2RsPgorICoKKyAqIDxwPlRoaXMgcGVyaGFwcyB3b3VsZCBiZXN0IGJlbG9uZyBpbiB0aGUgW2xhbmddIHByb2plY3QuIEV2ZW4gaWYgYSBzaW1pbGFyIGludGVyZmFjZSBpcyBkZWZpbmVkIGluIFtsYW5nXSwgaXQgaXMgbm90CisgKiBmb3Jlc2VlbiB0aGF0IFtjb21wcmVzc10gd291bGQgYmUgbWFkZSB0byBkZXBlbmQgb24gW2xhbmddLjwvcD4KKyAqCisgKiBAc2VlIDxhIGhyZWY9Imh0dHBzOi8vZG93bmxvYWQub3JhY2xlLmNvbS9qYXZhc2UvNi9kb2NzL2FwaS9qYXZhL25pby9jaGFyc2V0L0NoYXJzZXQuaHRtbCI+U3RhbmRhcmQgY2hhcnNldHM8L2E+CisgKiBAc2luY2UgMS40CisgKi8KK3B1YmxpYyBjbGFzcyBDaGFyc2V0TmFtZXMgeworICAgIC8qKgorICAgICAqIENoYXJFbmNvZGluZ0lTTyBMYXRpbiBBbHBoYWJldCBOby4gMSwgYS5rLmEuIElTTy1MQVRJTi0xLgorICAgICAqIDxwPgorICAgICAqIEV2ZXJ5IGltcGxlbWVudGF0aW9uIG9mIHRoZSBKYXZhIHBsYXRmb3JtIGlzIHJlcXVpcmVkIHRvIHN1cHBvcnQgdGhpcyBjaGFyYWN0ZXIgZW5jb2RpbmcuCisgICAgICogPC9wPgorICAgICAqCisgICAgICogQHNlZSA8YSBocmVmPSJodHRwczovL2Rvd25sb2FkLm9yYWNsZS5jb20vamF2YXNlLzYvZG9jcy9hcGkvamF2YS9uaW8vY2hhcnNldC9DaGFyc2V0Lmh0bWwiPlN0YW5kYXJkIGNoYXJzZXRzPC9hPgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElTT184ODU5XzEgPSAiSVNPLTg4NTktMSI7CisKKyAgICAvKioKKyAgICAgKiA8cD4KKyAgICAgKiBTZXZlbi1iaXQgQVNDSUksIGFsc28ga25vd24gYXMgSVNPNjQ2LVVTLCBhbHNvIGtub3duIGFzIHRoZSBCYXNpYyBMYXRpbiBibG9jayBvZiB0aGUgVW5pY29kZSBjaGFyYWN0ZXIgc2V0LgorICAgICAqIDwvcD4KKyAgICAgKiA8cD4KKyAgICAgKiBFdmVyeSBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgSmF2YSBwbGF0Zm9ybSBpcyByZXF1aXJlZCB0byBzdXBwb3J0IHRoaXMgY2hhcmFjdGVyIGVuY29kaW5nLgorICAgICAqIDwvcD4KKyAgICAgKgorICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cHM6Ly9kb3dubG9hZC5vcmFjbGUuY29tL2phdmFzZS82L2RvY3MvYXBpL2phdmEvbmlvL2NoYXJzZXQvQ2hhcnNldC5odG1sIj5TdGFuZGFyZCBjaGFyc2V0czwvYT4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBVU19BU0NJSSA9ICJVUy1BU0NJSSI7CisKKyAgICAvKioKKyAgICAgKiA8cD4KKyAgICAgKiBTaXh0ZWVuLWJpdCBVbmljb2RlIFRyYW5zZm9ybWF0aW9uIEZvcm1hdCwgVGhlIGJ5dGUgb3JkZXIgc3BlY2lmaWVkIGJ5IGEgbWFuZGF0b3J5IGluaXRpYWwgYnl0ZS1vcmRlciBtYXJrCisgICAgICogKGVpdGhlciBvcmRlciBhY2NlcHRlZCBvbiBpbnB1dCwgYmlnLWVuZGlhbiB1c2VkIG9uIG91dHB1dCkKKyAgICAgKiA8L3A+CisgICAgICogPHA+CisgICAgICogRXZlcnkgaW1wbGVtZW50YXRpb24gb2YgdGhlIEphdmEgcGxhdGZvcm0gaXMgcmVxdWlyZWQgdG8gc3VwcG9ydCB0aGlzIGNoYXJhY3RlciBlbmNvZGluZy4KKyAgICAgKiA8L3A+CisgICAgICoKKyAgICAgKiBAc2VlIDxhIGhyZWY9Imh0dHBzOi8vZG93bmxvYWQub3JhY2xlLmNvbS9qYXZhc2UvNi9kb2NzL2FwaS9qYXZhL25pby9jaGFyc2V0L0NoYXJzZXQuaHRtbCI+U3RhbmRhcmQgY2hhcnNldHM8L2E+CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVVRGXzE2ID0gIlVURi0xNiI7CisKKyAgICAvKioKKyAgICAgKiA8cD4KKyAgICAgKiBTaXh0ZWVuLWJpdCBVbmljb2RlIFRyYW5zZm9ybWF0aW9uIEZvcm1hdCwgYmlnLWVuZGlhbiBieXRlIG9yZGVyLgorICAgICAqIDwvcD4KKyAgICAgKiA8cD4KKyAgICAgKiBFdmVyeSBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgSmF2YSBwbGF0Zm9ybSBpcyByZXF1aXJlZCB0byBzdXBwb3J0IHRoaXMgY2hhcmFjdGVyIGVuY29kaW5nLgorICAgICAqIDwvcD4KKyAgICAgKgorICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cHM6Ly9kb3dubG9hZC5vcmFjbGUuY29tL2phdmFzZS82L2RvY3MvYXBpL2phdmEvbmlvL2NoYXJzZXQvQ2hhcnNldC5odG1sIj5TdGFuZGFyZCBjaGFyc2V0czwvYT4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBVVEZfMTZCRSA9ICJVVEYtMTZCRSI7CisKKyAgICAvKioKKyAgICAgKiA8cD4KKyAgICAgKiBTaXh0ZWVuLWJpdCBVbmljb2RlIFRyYW5zZm9ybWF0aW9uIEZvcm1hdCwgbGl0dGxlLWVuZGlhbiBieXRlIG9yZGVyLgorICAgICAqIDwvcD4KKyAgICAgKiA8cD4KKyAgICAgKiBFdmVyeSBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgSmF2YSBwbGF0Zm9ybSBpcyByZXF1aXJlZCB0byBzdXBwb3J0IHRoaXMgY2hhcmFjdGVyIGVuY29kaW5nLgorICAgICAqIDwvcD4KKyAgICAgKgorICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cHM6Ly9kb3dubG9hZC5vcmFjbGUuY29tL2phdmFzZS82L2RvY3MvYXBpL2phdmEvbmlvL2NoYXJzZXQvQ2hhcnNldC5odG1sIj5TdGFuZGFyZCBjaGFyc2V0czwvYT4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBVVEZfMTZMRSA9ICJVVEYtMTZMRSI7CisKKyAgICAvKioKKyAgICAgKiA8cD4KKyAgICAgKiBFaWdodC1iaXQgVW5pY29kZSBUcmFuc2Zvcm1hdGlvbiBGb3JtYXQuCisgICAgICogPC9wPgorICAgICAqIDxwPgorICAgICAqIEV2ZXJ5IGltcGxlbWVudGF0aW9uIG9mIHRoZSBKYXZhIHBsYXRmb3JtIGlzIHJlcXVpcmVkIHRvIHN1cHBvcnQgdGhpcyBjaGFyYWN0ZXIgZW5jb2RpbmcuCisgICAgICogPC9wPgorICAgICAqCisgICAgICogQHNlZSA8YSBocmVmPSJodHRwczovL2Rvd25sb2FkLm9yYWNsZS5jb20vamF2YXNlLzYvZG9jcy9hcGkvamF2YS9uaW8vY2hhcnNldC9DaGFyc2V0Lmh0bWwiPlN0YW5kYXJkIGNoYXJzZXRzPC9hPgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFVURl84ID0gIlVURi04IjsKK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL3V0aWxzL0NoYXJzZXRzLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy91dGlscy9DaGFyc2V0cy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjlmNTI0MGEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy91dGlscy9DaGFyc2V0cy5qYXZhCkBAIC0wLDAgKzEsMTY3IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICoKKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlsczsKKworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldDsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LlN0YW5kYXJkQ2hhcnNldHM7CisKKy8qKgorICogQ2hhcnNldHMgcmVxdWlyZWQgb2YgZXZlcnkgaW1wbGVtZW50YXRpb24gb2YgdGhlIEphdmEgcGxhdGZvcm0uCisgKgorICogRnJvbSB0aGUgSmF2YSBkb2N1bWVudGF0aW9uIDxhIGhyZWY9Imh0dHBzOi8vZG9jcy5vcmFjbGUuY29tL2phdmFzZS82L2RvY3MvYXBpL2phdmEvbmlvL2NoYXJzZXQvQ2hhcnNldC5odG1sIj5TdGFuZGFyZAorICogY2hhcnNldHM8L2E+OgorICogPHA+CisgKiA8Y2l0ZT5FdmVyeSBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgSmF2YSBwbGF0Zm9ybSBpcyByZXF1aXJlZCB0byBzdXBwb3J0IHRoZSBmb2xsb3dpbmcgY2hhcmFjdGVyIGVuY29kaW5ncy4gQ29uc3VsdCB0aGUKKyAqIHJlbGVhc2UgZG9jdW1lbnRhdGlvbiBmb3IgeW91ciBpbXBsZW1lbnRhdGlvbiB0byBzZWUgaWYgYW55IG90aGVyIGVuY29kaW5ncyBhcmUgc3VwcG9ydGVkLiBDb25zdWx0IHRoZSByZWxlYXNlCisgKiBkb2N1bWVudGF0aW9uIGZvciB5b3VyIGltcGxlbWVudGF0aW9uIHRvIHNlZSBpZiBhbnkgb3RoZXIgZW5jb2RpbmdzIGFyZSBzdXBwb3J0ZWQuIDwvY2l0ZT4KKyAqIDwvcD4KKyAqCisgKiA8ZGw+CisgKiA8ZHQ+PGNvZGU+VVMtQVNDSUk8L2NvZGU+PC9kdD4KKyAqIDxkZD5TZXZlbi1iaXQgQVNDSUksIGEuay5hLiBJU082NDYtVVMsIGEuay5hLiB0aGUgQmFzaWMgTGF0aW4gYmxvY2sgb2YgdGhlIFVuaWNvZGUgY2hhcmFjdGVyIHNldC48L2RkPgorICogPGR0Pjxjb2RlPklTTy04ODU5LTE8L2NvZGU+PC9kdD4KKyAqIDxkZD5JU08gTGF0aW4gQWxwaGFiZXQgTm8uIDEsIGEuay5hLiBJU08tTEFUSU4tMS48L2RkPgorICogPGR0Pjxjb2RlPlVURi04PC9jb2RlPjwvZHQ+CisgKiA8ZGQ+RWlnaHQtYml0IFVuaWNvZGUgVHJhbnNmb3JtYXRpb24gRm9ybWF0LjwvZGQ+CisgKiA8ZHQ+PGNvZGU+VVRGLTE2QkU8L2NvZGU+PC9kdD4KKyAqIDxkZD5TaXh0ZWVuLWJpdCBVbmljb2RlIFRyYW5zZm9ybWF0aW9uIEZvcm1hdCwgYmlnLWVuZGlhbiBieXRlIG9yZGVyLjwvZGQ+CisgKiA8ZHQ+PGNvZGU+VVRGLTE2TEU8L2NvZGU+PC9kdD4KKyAqIDxkZD5TaXh0ZWVuLWJpdCBVbmljb2RlIFRyYW5zZm9ybWF0aW9uIEZvcm1hdCwgbGl0dGxlLWVuZGlhbiBieXRlIG9yZGVyLjwvZGQ+CisgKiA8ZHQ+PGNvZGU+VVRGLTE2PC9jb2RlPjwvZHQ+CisgKiA8ZGQ+U2l4dGVlbi1iaXQgVW5pY29kZSBUcmFuc2Zvcm1hdGlvbiBGb3JtYXQsIGJ5dGUgb3JkZXIgc3BlY2lmaWVkIGJ5IGEgbWFuZGF0b3J5IGluaXRpYWwgYnl0ZS1vcmRlciBtYXJrIChlaXRoZXIgb3JkZXIKKyAqIGFjY2VwdGVkIG9uIGlucHV0LCBiaWctZW5kaWFuIHVzZWQgb24gb3V0cHV0Lik8L2RkPgorICogPC9kbD4KKyAqCisgKiA8cD5UaGlzIGNsYXNzIGJlc3QgYmVsb25ncyBpbiB0aGUgQ29tbW9ucyBMYW5nIG9yIElPIHByb2plY3QuIEV2ZW4gaWYgYSBzaW1pbGFyIGNsYXNzIGlzIGRlZmluZWQgaW4gYW5vdGhlciBDb21tb25zCisgKiBjb21wb25lbnQsIGl0IGlzIG5vdCBmb3Jlc2VlbiB0aGF0IENvbW1vbnMgQ29tcHJlc3Mgd291bGQgYmUgbWFkZSB0byBkZXBlbmQgb24gYW5vdGhlciBDb21tb25zIGNvbXBvbmVudC48L3A+CisgKgorICogQHNlZSA8YSBocmVmPSJodHRwczovL2RvY3Mub3JhY2xlLmNvbS9qYXZhc2UvNi9kb2NzL2FwaS9qYXZhL25pby9jaGFyc2V0L0NoYXJzZXQuaHRtbCI+U3RhbmRhcmQgY2hhcnNldHM8L2E+CisgKiBAc2VlIFN0YW5kYXJkQ2hhcnNldHMKKyAqIEBzaW5jZSAxLjQKKyAqLworcHVibGljIGNsYXNzIENoYXJzZXRzIHsKKworICAgIC8vCisgICAgLy8gVGhpcyBjbGFzcyBzaG91bGQgb25seSBjb250YWluIENoYXJzZXQgaW5zdGFuY2VzIGZvciByZXF1aXJlZCBlbmNvZGluZ3MuIFRoaXMgZ3VhcmFudGVlcyB0aGF0IGl0IHdpbGwgbG9hZCBjb3JyZWN0bHkgYW5kCisgICAgLy8gd2l0aG91dCBkZWxheSBvbiBhbGwgSmF2YSBwbGF0Zm9ybXMuCisgICAgLy8KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGdpdmVuIENoYXJzZXQgb3IgdGhlIGRlZmF1bHQgQ2hhcnNldCBpZiB0aGUgZ2l2ZW4gQ2hhcnNldCBpcyBudWxsLgorICAgICAqCisgICAgICogQHBhcmFtIGNoYXJzZXQKKyAgICAgKiAgICAgICAgICAgIEEgY2hhcnNldCBvciBudWxsLgorICAgICAqIEByZXR1cm4gdGhlIGdpdmVuIENoYXJzZXQgb3IgdGhlIGRlZmF1bHQgQ2hhcnNldCBpZiB0aGUgZ2l2ZW4gQ2hhcnNldCBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBDaGFyc2V0IHRvQ2hhcnNldChmaW5hbCBDaGFyc2V0IGNoYXJzZXQpIHsKKyAgICAgICAgcmV0dXJuIGNoYXJzZXQgPT0gbnVsbCA/IENoYXJzZXQuZGVmYXVsdENoYXJzZXQoKSA6IGNoYXJzZXQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIENoYXJzZXQgZm9yIHRoZSBuYW1lZCBjaGFyc2V0LiBJZiB0aGUgbmFtZSBpcyBudWxsLCByZXR1cm4gdGhlIGRlZmF1bHQgQ2hhcnNldC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjaGFyc2V0CisgICAgICogICAgICAgICAgICBUaGUgbmFtZSBvZiB0aGUgcmVxdWVzdGVkIGNoYXJzZXQsIG1heSBiZSBudWxsLgorICAgICAqIEByZXR1cm4gYSBDaGFyc2V0IGZvciB0aGUgbmFtZWQgY2hhcnNldAorICAgICAqIEB0aHJvd3MgamF2YS5uaW8uY2hhcnNldC5VbnN1cHBvcnRlZENoYXJzZXRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiB0aGUgbmFtZWQgY2hhcnNldCBpcyB1bmF2YWlsYWJsZQorICAgICAqIEB0aHJvd3MgamF2YS5uaW8uY2hhcnNldC5JbGxlZ2FsQ2hhcnNldE5hbWVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiB0aGUgZ2l2ZW4gY2hhcnNldCBuYW1lIGlzIGlsbGVnYWwKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIENoYXJzZXQgdG9DaGFyc2V0KGZpbmFsIFN0cmluZyBjaGFyc2V0KSB7CisgICAgICAgIHJldHVybiBjaGFyc2V0ID09IG51bGwgPyBDaGFyc2V0LmRlZmF1bHRDaGFyc2V0KCkgOiBDaGFyc2V0LmZvck5hbWUoY2hhcnNldCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hhcnNldE5hbWVzSVNPIExhdGluIEFscGhhYmV0IE5vLiAxLCBhLmsuYS4gSVNPLUxBVElOLTEuCisgICAgICogPHA+CisgICAgICogRXZlcnkgaW1wbGVtZW50YXRpb24gb2YgdGhlIEphdmEgcGxhdGZvcm0gaXMgcmVxdWlyZWQgdG8gc3VwcG9ydCB0aGlzIGNoYXJhY3RlciBlbmNvZGluZy4KKyAgICAgKiA8L3A+CisgICAgICoKKyAgICAgKiBAc2VlIDxhIGhyZWY9Imh0dHBzOi8vZG9jcy5vcmFjbGUuY29tL2phdmFzZS82L2RvY3MvYXBpL2phdmEvbmlvL2NoYXJzZXQvQ2hhcnNldC5odG1sIj5TdGFuZGFyZCBjaGFyc2V0czwvYT4KKyAgICAgKiBAZGVwcmVjYXRlZCByZXBsYWNlZCBieSB7QGxpbmsgU3RhbmRhcmRDaGFyc2V0c30gaW4gSmF2YSA3CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBDaGFyc2V0IElTT184ODU5XzEgPSBTdGFuZGFyZENoYXJzZXRzLklTT184ODU5XzE7CisKKyAgICAvKioKKyAgICAgKiA8cD4KKyAgICAgKiBTZXZlbi1iaXQgQVNDSUksIGFsc28ga25vd24gYXMgSVNPNjQ2LVVTLCBhbHNvIGtub3duIGFzIHRoZSBCYXNpYyBMYXRpbiBibG9jayBvZiB0aGUgVW5pY29kZSBjaGFyYWN0ZXIgc2V0LgorICAgICAqIDwvcD4KKyAgICAgKiA8cD4KKyAgICAgKiBFdmVyeSBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgSmF2YSBwbGF0Zm9ybSBpcyByZXF1aXJlZCB0byBzdXBwb3J0IHRoaXMgY2hhcmFjdGVyIGVuY29kaW5nLgorICAgICAqIDwvcD4KKyAgICAgKgorICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cHM6Ly9kb2NzLm9yYWNsZS5jb20vamF2YXNlLzYvZG9jcy9hcGkvamF2YS9uaW8vY2hhcnNldC9DaGFyc2V0Lmh0bWwiPlN0YW5kYXJkIGNoYXJzZXRzPC9hPgorICAgICAqIEBkZXByZWNhdGVkIHJlcGxhY2VkIGJ5IHtAbGluayBTdGFuZGFyZENoYXJzZXRzfSBpbiBKYXZhIDcKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIENoYXJzZXQgVVNfQVNDSUkgPSBTdGFuZGFyZENoYXJzZXRzLlVTX0FTQ0lJOworCisgICAgLyoqCisgICAgICogPHA+CisgICAgICogU2l4dGVlbi1iaXQgVW5pY29kZSBUcmFuc2Zvcm1hdGlvbiBGb3JtYXQsIFRoZSBieXRlIG9yZGVyIHNwZWNpZmllZCBieSBhIG1hbmRhdG9yeSBpbml0aWFsIGJ5dGUtb3JkZXIgbWFyaworICAgICAqIChlaXRoZXIgb3JkZXIgYWNjZXB0ZWQgb24gaW5wdXQsIGJpZy1lbmRpYW4gdXNlZCBvbiBvdXRwdXQpCisgICAgICogPC9wPgorICAgICAqIDxwPgorICAgICAqIEV2ZXJ5IGltcGxlbWVudGF0aW9uIG9mIHRoZSBKYXZhIHBsYXRmb3JtIGlzIHJlcXVpcmVkIHRvIHN1cHBvcnQgdGhpcyBjaGFyYWN0ZXIgZW5jb2RpbmcuCisgICAgICogPC9wPgorICAgICAqCisgICAgICogQHNlZSA8YSBocmVmPSJodHRwczovL2RvY3Mub3JhY2xlLmNvbS9qYXZhc2UvNi9kb2NzL2FwaS9qYXZhL25pby9jaGFyc2V0L0NoYXJzZXQuaHRtbCI+U3RhbmRhcmQgY2hhcnNldHM8L2E+CisgICAgICogQGRlcHJlY2F0ZWQgcmVwbGFjZWQgYnkge0BsaW5rIFN0YW5kYXJkQ2hhcnNldHN9IGluIEphdmEgNworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQ2hhcnNldCBVVEZfMTYgPSBTdGFuZGFyZENoYXJzZXRzLlVURl8xNjsKKworICAgIC8qKgorICAgICAqIDxwPgorICAgICAqIFNpeHRlZW4tYml0IFVuaWNvZGUgVHJhbnNmb3JtYXRpb24gRm9ybWF0LCBiaWctZW5kaWFuIGJ5dGUgb3JkZXIuCisgICAgICogPC9wPgorICAgICAqIDxwPgorICAgICAqIEV2ZXJ5IGltcGxlbWVudGF0aW9uIG9mIHRoZSBKYXZhIHBsYXRmb3JtIGlzIHJlcXVpcmVkIHRvIHN1cHBvcnQgdGhpcyBjaGFyYWN0ZXIgZW5jb2RpbmcuCisgICAgICogPC9wPgorICAgICAqCisgICAgICogQHNlZSA8YSBocmVmPSJodHRwczovL2RvY3Mub3JhY2xlLmNvbS9qYXZhc2UvNi9kb2NzL2FwaS9qYXZhL25pby9jaGFyc2V0L0NoYXJzZXQuaHRtbCI+U3RhbmRhcmQgY2hhcnNldHM8L2E+CisgICAgICogQGRlcHJlY2F0ZWQgcmVwbGFjZWQgYnkge0BsaW5rIFN0YW5kYXJkQ2hhcnNldHN9IGluIEphdmEgNworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQ2hhcnNldCBVVEZfMTZCRSA9IFN0YW5kYXJkQ2hhcnNldHMuVVRGXzE2QkU7CisKKyAgICAvKioKKyAgICAgKiA8cD4KKyAgICAgKiBTaXh0ZWVuLWJpdCBVbmljb2RlIFRyYW5zZm9ybWF0aW9uIEZvcm1hdCwgbGl0dGxlLWVuZGlhbiBieXRlIG9yZGVyLgorICAgICAqIDwvcD4KKyAgICAgKiA8cD4KKyAgICAgKiBFdmVyeSBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgSmF2YSBwbGF0Zm9ybSBpcyByZXF1aXJlZCB0byBzdXBwb3J0IHRoaXMgY2hhcmFjdGVyIGVuY29kaW5nLgorICAgICAqIDwvcD4KKyAgICAgKgorICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cHM6Ly9kb2NzLm9yYWNsZS5jb20vamF2YXNlLzYvZG9jcy9hcGkvamF2YS9uaW8vY2hhcnNldC9DaGFyc2V0Lmh0bWwiPlN0YW5kYXJkIGNoYXJzZXRzPC9hPgorICAgICAqIEBkZXByZWNhdGVkIHJlcGxhY2VkIGJ5IHtAbGluayBTdGFuZGFyZENoYXJzZXRzfSBpbiBKYXZhIDcKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIENoYXJzZXQgVVRGXzE2TEUgPSBTdGFuZGFyZENoYXJzZXRzLlVURl8xNkxFOworCisgICAgLyoqCisgICAgICogPHA+CisgICAgICogRWlnaHQtYml0IFVuaWNvZGUgVHJhbnNmb3JtYXRpb24gRm9ybWF0LgorICAgICAqIDwvcD4KKyAgICAgKiA8cD4KKyAgICAgKiBFdmVyeSBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgSmF2YSBwbGF0Zm9ybSBpcyByZXF1aXJlZCB0byBzdXBwb3J0IHRoaXMgY2hhcmFjdGVyIGVuY29kaW5nLgorICAgICAqIDwvcD4KKyAgICAgKgorICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cHM6Ly9kb2NzLm9yYWNsZS5jb20vamF2YXNlLzYvZG9jcy9hcGkvamF2YS9uaW8vY2hhcnNldC9DaGFyc2V0Lmh0bWwiPlN0YW5kYXJkIGNoYXJzZXRzPC9hPgorICAgICAqIEBkZXByZWNhdGVkIHJlcGxhY2VkIGJ5IHtAbGluayBTdGFuZGFyZENoYXJzZXRzfSBpbiBKYXZhIDcKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIENoYXJzZXQgVVRGXzggPSBTdGFuZGFyZENoYXJzZXRzLlVURl84OworfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvdXRpbHMvQ2hlY2tzdW1DYWxjdWxhdGluZ0lucHV0U3RyZWFtLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy91dGlscy9DaGVja3N1bUNhbGN1bGF0aW5nSW5wdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40YTQwOGE1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvdXRpbHMvQ2hlY2tzdW1DYWxjdWxhdGluZ0lucHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwxMDUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC56aXAuQ2hlY2tzdW07CisKKy8qKgorICogQSBzdHJlYW0gdGhhdCBjYWxjdWxhdGVzIHRoZSBjaGVja3N1bSBvZiB0aGUgZGF0YSByZWFkLgorICogQE5vdFRocmVhZFNhZmUKKyAqIEBzaW5jZSAxLjE0CisgKi8KK3B1YmxpYyBjbGFzcyBDaGVja3N1bUNhbGN1bGF0aW5nSW5wdXRTdHJlYW0gZXh0ZW5kcyBJbnB1dFN0cmVhbSB7CisgICAgcHJpdmF0ZSBmaW5hbCBJbnB1dFN0cmVhbSBpbjsKKyAgICBwcml2YXRlIGZpbmFsIENoZWNrc3VtIGNoZWNrc3VtOworCisgICAgcHVibGljIENoZWNrc3VtQ2FsY3VsYXRpbmdJbnB1dFN0cmVhbShmaW5hbCBDaGVja3N1bSBjaGVja3N1bSwgZmluYWwgSW5wdXRTdHJlYW0gaW4pIHsKKworICAgICAgICBpZiAoIGNoZWNrc3VtID09IG51bGwgKXsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiUGFyYW1ldGVyIGNoZWNrc3VtIG11c3Qgbm90IGJlIG51bGwiKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICggaW4gPT0gbnVsbCApeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJQYXJhbWV0ZXIgaW4gbXVzdCBub3QgYmUgbnVsbCIpOworICAgICAgICB9CisKKyAgICAgICAgdGhpcy5jaGVja3N1bSA9IGNoZWNrc3VtOworICAgICAgICB0aGlzLmluID0gaW47CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgYSBzaW5nbGUgYnl0ZSBmcm9tIHRoZSBzdHJlYW0KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHRoZSB1bmRlcmx5aW5nIHN0cmVhbSB0aHJvd3Mgb3IgdGhlCisgICAgICogc3RyZWFtIGlzIGV4aGF1c3RlZCBhbmQgdGhlIENoZWNrc3VtIGRvZXNuJ3QgbWF0Y2ggdGhlIGV4cGVjdGVkCisgICAgICogdmFsdWUKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHJlYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBpbnQgcmV0ID0gaW4ucmVhZCgpOworICAgICAgICBpZiAocmV0ID49IDApIHsKKyAgICAgICAgICAgIGNoZWNrc3VtLnVwZGF0ZShyZXQpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgYSBieXRlIGFycmF5IGZyb20gdGhlIHN0cmVhbQorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgdGhlIHVuZGVybHlpbmcgc3RyZWFtIHRocm93cyBvciB0aGUKKyAgICAgKiBzdHJlYW0gaXMgZXhoYXVzdGVkIGFuZCB0aGUgQ2hlY2tzdW0gZG9lc24ndCBtYXRjaCB0aGUgZXhwZWN0ZWQKKyAgICAgKiB2YWx1ZQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZChmaW5hbCBieXRlW10gYikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHJlYWQoYiwgMCwgYi5sZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGZyb20gdGhlIHN0cmVhbSBpbnRvIGEgYnl0ZSBhcnJheS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHRoZSB1bmRlcmx5aW5nIHN0cmVhbSB0aHJvd3Mgb3IgdGhlCisgICAgICogc3RyZWFtIGlzIGV4aGF1c3RlZCBhbmQgdGhlIENoZWNrc3VtIGRvZXNuJ3QgbWF0Y2ggdGhlIGV4cGVjdGVkCisgICAgICogdmFsdWUKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHJlYWQoZmluYWwgYnl0ZVtdIGIsIGZpbmFsIGludCBvZmYsIGZpbmFsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIGludCByZXQgPSBpbi5yZWFkKGIsIG9mZiwgbGVuKTsKKyAgICAgICAgaWYgKHJldCA+PSAwKSB7CisgICAgICAgICAgICBjaGVja3N1bS51cGRhdGUoYiwgb2ZmLCByZXQpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGxvbmcgc2tpcChmaW5hbCBsb25nIG4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIENhbid0IHJlYWxseSBza2lwLCB3ZSBoYXZlIHRvIGhhc2ggZXZlcnl0aGluZyB0byB2ZXJpZnkgdGhlIGNoZWNrc3VtCisgICAgICAgIGlmIChyZWFkKCkgPj0gMCkgeworICAgICAgICAgICAgcmV0dXJuIDE7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY2FsY3VsYXRlZCBjaGVja3N1bS4KKyAgICAgKiBAcmV0dXJuIHRoZSBjYWxjdWxhdGVkIGNoZWNrc3VtLgorICAgICAqLworICAgIHB1YmxpYyBsb25nIGdldFZhbHVlKCkgeworICAgICAgICByZXR1cm4gY2hlY2tzdW0uZ2V0VmFsdWUoKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL3V0aWxzL0NoZWNrc3VtVmVyaWZ5aW5nSW5wdXRTdHJlYW0uamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL3V0aWxzL0NoZWNrc3VtVmVyaWZ5aW5nSW5wdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hN2Q4ZDZjCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvdXRpbHMvQ2hlY2tzdW1WZXJpZnlpbmdJbnB1dFN0cmVhbS5qYXZhCkBAIC0wLDAgKzEsMTA5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlsczsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLkNoZWNrc3VtOworCisvKioKKyAqIEEgc3RyZWFtIHRoYXQgdmVyaWZpZXMgdGhlIGNoZWNrc3VtIG9mIHRoZSBkYXRhIHJlYWQgb25jZSB0aGUgc3RyZWFtIGlzCisgKiBleGhhdXN0ZWQuCisgKiBATm90VGhyZWFkU2FmZQorICogQHNpbmNlIDEuNworICovCitwdWJsaWMgY2xhc3MgQ2hlY2tzdW1WZXJpZnlpbmdJbnB1dFN0cmVhbSBleHRlbmRzIElucHV0U3RyZWFtIHsKKyAgICBwcml2YXRlIGZpbmFsIElucHV0U3RyZWFtIGluOworICAgIHByaXZhdGUgbG9uZyBieXRlc1JlbWFpbmluZzsKKyAgICBwcml2YXRlIGZpbmFsIGxvbmcgZXhwZWN0ZWRDaGVja3N1bTsKKyAgICBwcml2YXRlIGZpbmFsIENoZWNrc3VtIGNoZWNrc3VtOworCisgICAgcHVibGljIENoZWNrc3VtVmVyaWZ5aW5nSW5wdXRTdHJlYW0oZmluYWwgQ2hlY2tzdW0gY2hlY2tzdW0sIGZpbmFsIElucHV0U3RyZWFtIGluLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGxvbmcgc2l6ZSwgZmluYWwgbG9uZyBleHBlY3RlZENoZWNrc3VtKSB7CisgICAgICAgIHRoaXMuY2hlY2tzdW0gPSBjaGVja3N1bTsKKyAgICAgICAgdGhpcy5pbiA9IGluOworICAgICAgICB0aGlzLmV4cGVjdGVkQ2hlY2tzdW0gPSBleHBlY3RlZENoZWNrc3VtOworICAgICAgICB0aGlzLmJ5dGVzUmVtYWluaW5nID0gc2l6ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhIHNpbmdsZSBieXRlIGZyb20gdGhlIHN0cmVhbQorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgdGhlIHVuZGVybHlpbmcgc3RyZWFtIHRocm93cyBvciB0aGUKKyAgICAgKiBzdHJlYW0gaXMgZXhoYXVzdGVkIGFuZCB0aGUgQ2hlY2tzdW0gZG9lc24ndCBtYXRjaCB0aGUgZXhwZWN0ZWQKKyAgICAgKiB2YWx1ZQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChieXRlc1JlbWFpbmluZyA8PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICAgICAgZmluYWwgaW50IHJldCA9IGluLnJlYWQoKTsKKyAgICAgICAgaWYgKHJldCA+PSAwKSB7CisgICAgICAgICAgICBjaGVja3N1bS51cGRhdGUocmV0KTsKKyAgICAgICAgICAgIC0tYnl0ZXNSZW1haW5pbmc7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGJ5dGVzUmVtYWluaW5nID09IDAgJiYgZXhwZWN0ZWRDaGVja3N1bSAhPSBjaGVja3N1bS5nZXRWYWx1ZSgpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkNoZWNrc3VtIHZlcmlmaWNhdGlvbiBmYWlsZWQiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmV0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGEgYnl0ZSBhcnJheSBmcm9tIHRoZSBzdHJlYW0KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHRoZSB1bmRlcmx5aW5nIHN0cmVhbSB0aHJvd3Mgb3IgdGhlCisgICAgICogc3RyZWFtIGlzIGV4aGF1c3RlZCBhbmQgdGhlIENoZWNrc3VtIGRvZXNuJ3QgbWF0Y2ggdGhlIGV4cGVjdGVkCisgICAgICogdmFsdWUKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHJlYWQoZmluYWwgYnl0ZVtdIGIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiByZWFkKGIsIDAsIGIubGVuZ3RoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBmcm9tIHRoZSBzdHJlYW0gaW50byBhIGJ5dGUgYXJyYXkuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiB0aGUgdW5kZXJseWluZyBzdHJlYW0gdGhyb3dzIG9yIHRoZQorICAgICAqIHN0cmVhbSBpcyBleGhhdXN0ZWQgYW5kIHRoZSBDaGVja3N1bSBkb2Vzbid0IG1hdGNoIHRoZSBleHBlY3RlZAorICAgICAqIHZhbHVlCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCByZWFkKGZpbmFsIGJ5dGVbXSBiLCBmaW5hbCBpbnQgb2ZmLCBmaW5hbCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBpbnQgcmV0ID0gaW4ucmVhZChiLCBvZmYsIGxlbik7CisgICAgICAgIGlmIChyZXQgPj0gMCkgeworICAgICAgICAgICAgY2hlY2tzdW0udXBkYXRlKGIsIG9mZiwgcmV0KTsKKyAgICAgICAgICAgIGJ5dGVzUmVtYWluaW5nIC09IHJldDsKKyAgICAgICAgfQorICAgICAgICBpZiAoYnl0ZXNSZW1haW5pbmcgPD0gMCAmJiBleHBlY3RlZENoZWNrc3VtICE9IGNoZWNrc3VtLmdldFZhbHVlKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiQ2hlY2tzdW0gdmVyaWZpY2F0aW9uIGZhaWxlZCIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGxvbmcgc2tpcChmaW5hbCBsb25nIG4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIENhbid0IHJlYWxseSBza2lwLCB3ZSBoYXZlIHRvIGhhc2ggZXZlcnl0aGluZyB0byB2ZXJpZnkgdGhlIGNoZWNrc3VtCisgICAgICAgIGlmIChyZWFkKCkgPj0gMCkgeworICAgICAgICAgICAgcmV0dXJuIDE7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbi5jbG9zZSgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL3V0aWxzL0Nsb3NlU2hpZWxkRmlsdGVySW5wdXRTdHJlYW0uamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL3V0aWxzL0Nsb3NlU2hpZWxkRmlsdGVySW5wdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hMGVjOGZmCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvdXRpbHMvQ2xvc2VTaGllbGRGaWx0ZXJJbnB1dFN0cmVhbS5qYXZhCkBAIC0wLDAgKzEsNDEgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlsczsKKworaW1wb3J0IGphdmEuaW8uRmlsdGVySW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworCisvKioKKyAqIFJlLWltcGxlbWVudHMge0BsaW5rIEZpbHRlcklucHV0U3RyZWFtI2Nsb3NlKCl9IHRvIGRvIG5vdGhpbmcuCisgKiBAc2luY2UgMS4xNAorICovCitwdWJsaWMgY2xhc3MgQ2xvc2VTaGllbGRGaWx0ZXJJbnB1dFN0cmVhbSBleHRlbmRzIEZpbHRlcklucHV0U3RyZWFtIHsKKworICAgIHB1YmxpYyBDbG9zZVNoaWVsZEZpbHRlcklucHV0U3RyZWFtKElucHV0U3RyZWFtIGluKSB7CisgICAgICAgIHN1cGVyKGluKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIE5PIElNUExFTUVOVEFUSU9OLgorICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvdXRpbHMvQ291bnRpbmdJbnB1dFN0cmVhbS5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvdXRpbHMvQ291bnRpbmdJbnB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ2MTA3MWUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy91dGlscy9Db3VudGluZ0lucHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSw3NiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlsczsKKworaW1wb3J0IGphdmEuaW8uRmlsdGVySW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworCisvKioKKyAqIFN0cmVhbSB0aGF0IHRyYWNrcyB0aGUgbnVtYmVyIG9mIGJ5dGVzIHJlYWQuCisgKiBAc2luY2UgMS4zCisgKiBATm90VGhyZWFkU2FmZQorICovCitwdWJsaWMgY2xhc3MgQ291bnRpbmdJbnB1dFN0cmVhbSBleHRlbmRzIEZpbHRlcklucHV0U3RyZWFtIHsKKyAgICBwcml2YXRlIGxvbmcgYnl0ZXNSZWFkOworCisgICAgcHVibGljIENvdW50aW5nSW5wdXRTdHJlYW0oZmluYWwgSW5wdXRTdHJlYW0gaW4pIHsKKyAgICAgICAgc3VwZXIoaW4pOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIGludCByID0gaW4ucmVhZCgpOworICAgICAgICBpZiAociA+PSAwKSB7CisgICAgICAgICAgICBjb3VudCgxKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcjsKKyAgICB9CisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCByZWFkKGZpbmFsIGJ5dGVbXSBiKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gcmVhZChiLCAwLCBiLmxlbmd0aCk7CisgICAgfQorICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZChmaW5hbCBieXRlW10gYiwgZmluYWwgaW50IG9mZiwgZmluYWwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgaW50IHIgPSBpbi5yZWFkKGIsIG9mZiwgbGVuKTsKKyAgICAgICAgaWYgKHIgPj0gMCkgeworICAgICAgICAgICAgY291bnQocik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHI7CisgICAgfQorICAgIC8qKgorICAgICAqIEluY3JlbWVudHMgdGhlIGNvdW50ZXIgb2YgYWxyZWFkeSByZWFkIGJ5dGVzLgorICAgICAqIERvZXNuJ3QgaW5jcmVtZW50IGlmIHRoZSBFT0YgaGFzIGJlZW4gaGl0IChyZWFkID09IC0xKQorICAgICAqCisgICAgICogQHBhcmFtIHJlYWQgdGhlIG51bWJlciBvZiBieXRlcyByZWFkCisgICAgICovCisgICAgcHJvdGVjdGVkIGZpbmFsIHZvaWQgY291bnQoZmluYWwgbG9uZyByZWFkKSB7CisgICAgICAgIGlmIChyZWFkICE9IC0xKSB7CisgICAgICAgICAgICBieXRlc1JlYWQgKz0gcmVhZDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGN1cnJlbnQgbnVtYmVyIG9mIGJ5dGVzIHJlYWQgZnJvbSB0aGlzIHN0cmVhbS4KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgcmVhZCBieXRlcworICAgICAqLworICAgIHB1YmxpYyBsb25nIGdldEJ5dGVzUmVhZCgpIHsKKyAgICAgICAgcmV0dXJuIGJ5dGVzUmVhZDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy91dGlscy9Db3VudGluZ091dHB1dFN0cmVhbS5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvdXRpbHMvQ291bnRpbmdPdXRwdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hYzg4NmJjCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvdXRpbHMvQ291bnRpbmdPdXRwdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDcxIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzOworCitpbXBvcnQgamF2YS5pby5GaWx0ZXJPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKKworLyoqCisgKiBTdHJlYW0gdGhhdCB0cmFja3MgdGhlIG51bWJlciBvZiBieXRlcyByZWFkLgorICogQHNpbmNlIDEuMworICogQE5vdFRocmVhZFNhZmUKKyAqLworcHVibGljIGNsYXNzIENvdW50aW5nT3V0cHV0U3RyZWFtIGV4dGVuZHMgRmlsdGVyT3V0cHV0U3RyZWFtIHsKKyAgICBwcml2YXRlIGxvbmcgYnl0ZXNXcml0dGVuID0gMDsKKworICAgIHB1YmxpYyBDb3VudGluZ091dHB1dFN0cmVhbShmaW5hbCBPdXRwdXRTdHJlYW0gb3V0KSB7CisgICAgICAgIHN1cGVyKG91dCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGUoZmluYWwgaW50IGIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG91dC53cml0ZShiKTsKKyAgICAgICAgY291bnQoMSk7CisgICAgfQorICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGZpbmFsIGJ5dGVbXSBiKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB3cml0ZShiLCAwLCBiLmxlbmd0aCk7CisgICAgfQorICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGZpbmFsIGJ5dGVbXSBiLCBmaW5hbCBpbnQgb2ZmLCBmaW5hbCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvdXQud3JpdGUoYiwgb2ZmLCBsZW4pOworICAgICAgICBjb3VudChsZW4pOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluY3JlbWVudHMgdGhlIGNvdW50ZXIgb2YgYWxyZWFkeSB3cml0dGVuIGJ5dGVzLgorICAgICAqIERvZXNuJ3QgaW5jcmVtZW50IGlmIHRoZSBFT0YgaGFzIGJlZW4gaGl0ICh3cml0dGVuID09IC0xKQorICAgICAqCisgICAgICogQHBhcmFtIHdyaXR0ZW4gdGhlIG51bWJlciBvZiBieXRlcyB3cml0dGVuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgY291bnQoZmluYWwgbG9uZyB3cml0dGVuKSB7CisgICAgICAgIGlmICh3cml0dGVuICE9IC0xKSB7CisgICAgICAgICAgICBieXRlc1dyaXR0ZW4gKz0gd3JpdHRlbjsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGN1cnJlbnQgbnVtYmVyIG9mIGJ5dGVzIHdyaXR0ZW4gdG8gdGhpcyBzdHJlYW0uCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIHdyaXR0ZW4gYnl0ZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBnZXRCeXRlc1dyaXR0ZW4oKSB7CisgICAgICAgIHJldHVybiBieXRlc1dyaXR0ZW47CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvdXRpbHMvRml4ZWRMZW5ndGhCbG9ja091dHB1dFN0cmVhbS5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvdXRpbHMvRml4ZWRMZW5ndGhCbG9ja091dHB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM2MGYzODAKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy91dGlscy9GaXhlZExlbmd0aEJsb2NrT3V0cHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwyNzEgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHM7CisKK2ltcG9ydCBqYXZhLmlvLkZpbGVPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworaW1wb3J0IGphdmEubmlvLkJ5dGVPcmRlcjsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5DbG9zZWRDaGFubmVsRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLldyaXRhYmxlQnl0ZUNoYW5uZWw7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljLkF0b21pY0Jvb2xlYW47CisKKy8qKgorICogVGhpcyBjbGFzcyBzdXBwb3J0cyB3cml0aW5nIHRvIGFuIE91dHB1dHN0cmVhbSBvciBXcml0YWJsZUJ5dGVDaGFubmVsIGluIGZpeGVkIGxlbmd0aCBibG9ja3MuCisgKiA8cD5JdCBjYW4gYmUgYmUgdXNlZCB0byBzdXBwb3J0IG91dHB1dCB0byBkZXZpY2VzIHN1Y2ggYXMgdGFwZSBkcml2ZXMgdGhhdCByZXF1aXJlIG91dHB1dCBpbiB0aGlzCisgKiBmb3JtYXQuIElmIHRoZSBmaW5hbCBibG9jayBkb2VzIG5vdCBoYXZlIGVub3VnaCBjb250ZW50IHRvIGZpbGwgYW4gZW50aXJlIGJsb2NrLCB0aGUgb3V0cHV0IHdpbGwKKyAqIGJlIHBhZGRlZCB0byBhIGZ1bGwgYmxvY2sgc2l6ZS48L3A+CisgKgorICogPHA+VGhpcyBjbGFzcyBjYW4gYmUgdXNlZCB0byBzdXBwb3J0IFRBUixQQVgsIGFuZCBDUElPIGJsb2NrZWQgb3V0cHV0IHRvIGNoYXJhY3RlciBzcGVjaWFsIGRldmljZXMuCisgKiBJdCBpcyBub3QgcmVjb21tZW5kZWQgdGhhdCB0aGlzIGNsYXNzIGJlIHVzZWQgdW5sZXNzIHdyaXRpbmcgdG8gc3VjaCBkZXZpY2VzLCBhcyB0aGUgcGFkZGluZworICogc2VydmVzIG5vIHVzZWZ1bCBwdXJwb3NlIGluIHN1Y2ggY2FzZXMuPC9wPgorICoKKyAqIDxwPlRoaXMgY2xhc3Mgc2hvdWxkIG5vcm1hbGx5IHdyYXAgYSBGaWxlT3V0cHV0U3RyZWFtIG9yIGFzc29jaWF0ZWQgV3JpdGFibGVCeXRlQ2hhbm5lbCBkaXJlY3RseS4KKyAqIElmIHRoZXJlIGlzIGFuIGludGVydmVuaW5nIGZpbHRlciB0aGF0IG1vZGlmaWVkIHRoZSBvdXRwdXQsIHN1Y2ggYXMgYSBDb21wcmVzc29yT3V0cHV0U3RyZWFtLCBvcgorICogcGVyZm9ybXMgaXRzIG93biBidWZmZXJpbmcsIHN1Y2ggYXMgQnVmZmVyZWRPdXRwdXRTdHJlYW0sICBvdXRwdXQgdG8gdGhlIGRldmljZSBtYXkKKyAqIG5vIGxvbmdlciBiZSBvZiB0aGUgc3BlY2lmaWVkIHNpemUuPC9wPgorICoKKyAqIDxwPkFueSBjb250ZW50IHdyaXR0ZW4gdG8gdGhpcyBzdHJlYW0gc2hvdWxkIGJlIHNlbGYtZGVsaW1pdGluZyBhbmQgc2hvdWxkIHRvbGVyYXRlIGFueSBwYWRkaW5nCisgKiBhZGRlZCB0byBmaWxsIHRoZSBsYXN0IGJsb2NrLjwvcD4KKyAqCisgKiBAc2luY2UgMS4xNQorICovCitwdWJsaWMgY2xhc3MgRml4ZWRMZW5ndGhCbG9ja091dHB1dFN0cmVhbSBleHRlbmRzIE91dHB1dFN0cmVhbSBpbXBsZW1lbnRzIFdyaXRhYmxlQnl0ZUNoYW5uZWwgeworCisgICAgcHJpdmF0ZSBmaW5hbCBXcml0YWJsZUJ5dGVDaGFubmVsIG91dDsKKyAgICBwcml2YXRlIGZpbmFsIGludCBibG9ja1NpemU7CisgICAgcHJpdmF0ZSBmaW5hbCBCeXRlQnVmZmVyIGJ1ZmZlcjsKKyAgICBwcml2YXRlIGZpbmFsIEF0b21pY0Jvb2xlYW4gY2xvc2VkID0gbmV3IEF0b21pY0Jvb2xlYW4oZmFsc2UpOworCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgZml4ZWQgbGVuZ3RoIGJsb2NrIG91dHB1dCBzdHJlYW0gd2l0aCBnaXZlbiBkZXN0aW5hdGlvbiBzdHJlYW0gYW5kIGJsb2NrIHNpemUKKyAgICAgKiBAcGFyYW0gb3MgICBUaGUgc3RyZWFtIHRvIHdyYXAuCisgICAgICogQHBhcmFtIGJsb2NrU2l6ZSBUaGUgYmxvY2sgc2l6ZSB0byB1c2UuCisgICAgICovCisgICAgcHVibGljIEZpeGVkTGVuZ3RoQmxvY2tPdXRwdXRTdHJlYW0oT3V0cHV0U3RyZWFtIG9zLCBpbnQgYmxvY2tTaXplKSB7CisgICAgICAgIGlmIChvcyBpbnN0YW5jZW9mIEZpbGVPdXRwdXRTdHJlYW0pIHsKKyAgICAgICAgICAgIEZpbGVPdXRwdXRTdHJlYW0gZmlsZU91dHB1dFN0cmVhbSA9IChGaWxlT3V0cHV0U3RyZWFtKSBvczsKKyAgICAgICAgICAgIG91dCA9IGZpbGVPdXRwdXRTdHJlYW0uZ2V0Q2hhbm5lbCgpOworICAgICAgICAgICAgYnVmZmVyID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZURpcmVjdChibG9ja1NpemUpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgb3V0ID0gbmV3IEJ1ZmZlckF0QVRpbWVPdXRwdXRDaGFubmVsKG9zKTsKKyAgICAgICAgICAgIGJ1ZmZlciA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUoYmxvY2tTaXplKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmJsb2NrU2l6ZSA9IGJsb2NrU2l6ZTsKKyAgICB9CisgICAgIC8qKgorICAgICAgKiBDcmVhdGUgYSBmaXhlZCBsZW5ndGggYmxvY2sgb3V0cHV0IHN0cmVhbSB3aXRoIGdpdmVuIGRlc3RpbmF0aW9uIHdyaXRhYmxlIGJ5dGUgY2hhbm5lbCBhbmQgYmxvY2sgc2l6ZQorICAgICAqIEBwYXJhbSBvdXQgICBUaGUgd3JpdGFibGUgYnl0ZSBjaGFubmVsIHRvIHdyYXAuCisgICAgICogQHBhcmFtIGJsb2NrU2l6ZSBUaGUgYmxvY2sgc2l6ZSB0byB1c2UuCisgICAgICovCisgICAgcHVibGljIEZpeGVkTGVuZ3RoQmxvY2tPdXRwdXRTdHJlYW0oV3JpdGFibGVCeXRlQ2hhbm5lbCBvdXQsIGludCBibG9ja1NpemUpIHsKKyAgICAgICAgdGhpcy5vdXQgPSBvdXQ7CisgICAgICAgIHRoaXMuYmxvY2tTaXplID0gYmxvY2tTaXplOworICAgICAgICB0aGlzLmJ1ZmZlciA9IEJ5dGVCdWZmZXIuYWxsb2NhdGVEaXJlY3QoYmxvY2tTaXplKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgbWF5YmVGbHVzaCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICghYnVmZmVyLmhhc1JlbWFpbmluZygpKSB7CisgICAgICAgICAgICB3cml0ZUJsb2NrKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgd3JpdGVCbG9jaygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJ1ZmZlci5mbGlwKCk7CisgICAgICAgIGludCBpID0gb3V0LndyaXRlKGJ1ZmZlcik7CisgICAgICAgIGJvb2xlYW4gaGFzUmVtYWluaW5nID0gYnVmZmVyLmhhc1JlbWFpbmluZygpOworICAgICAgICBpZiAoaSAhPSBibG9ja1NpemUgfHwgaGFzUmVtYWluaW5nKSB7CisgICAgICAgICAgICBTdHJpbmcgbXNnID0gU3RyaW5nCisgICAgICAgICAgICAgICAgLmZvcm1hdCgiRmFpbGVkIHRvIHdyaXRlICUsZCBieXRlcyBhdG9taWNhbGx5LiBPbmx5IHdyb3RlICAlLGQiLAorICAgICAgICAgICAgICAgICAgICBibG9ja1NpemUsIGkpOworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKG1zZyk7CisgICAgICAgIH0KKyAgICAgICAgYnVmZmVyLmNsZWFyKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGUoaW50IGIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICghaXNPcGVuKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBDbG9zZWRDaGFubmVsRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgYnVmZmVyLnB1dCgoYnl0ZSkgYik7CisgICAgICAgIG1heWJlRmx1c2goKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShieXRlW10gYiwgZmluYWwgaW50IG9mZnNldCwgZmluYWwgaW50IGxlbmd0aCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFpc09wZW4oKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IENsb3NlZENoYW5uZWxFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpbnQgb2ZmID0gb2Zmc2V0OworICAgICAgICBpbnQgbGVuID0gbGVuZ3RoOworICAgICAgICB3aGlsZSAobGVuID4gMCkgeworICAgICAgICAgICAgaW50IG4gPSBNYXRoLm1pbihsZW4sIGJ1ZmZlci5yZW1haW5pbmcoKSk7CisgICAgICAgICAgICBidWZmZXIucHV0KGIsIG9mZiwgbik7CisgICAgICAgICAgICBtYXliZUZsdXNoKCk7CisgICAgICAgICAgICBsZW4gLT0gbjsKKyAgICAgICAgICAgIG9mZiArPSBuOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCB3cml0ZShCeXRlQnVmZmVyIHNyYykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFpc09wZW4oKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IENsb3NlZENoYW5uZWxFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpbnQgc3JjUmVtYWluaW5nID0gc3JjLnJlbWFpbmluZygpOworCisgICAgICAgIGlmIChzcmNSZW1haW5pbmcgPCBidWZmZXIucmVtYWluaW5nKCkpIHsKKyAgICAgICAgICAgIC8vIGlmIGRvbid0IGhhdmUgZW5vdWdoIGJ5dGVzIGluIHNyYyB0byBmaWxsIHVwIGEgYmxvY2sgd2UgbXVzdCBidWZmZXIKKyAgICAgICAgICAgIGJ1ZmZlci5wdXQoc3JjKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGludCBzcmNMZWZ0ID0gc3JjUmVtYWluaW5nOworICAgICAgICAgICAgaW50IHNhdmVkTGltaXQgPSBzcmMubGltaXQoKTsKKyAgICAgICAgICAgIC8vIElmIHdlJ3JlIG5vdCBhdCB0aGUgc3RhcnQgb2YgYnVmZmVyLCB3ZSBoYXZlIHNvbWUgYnl0ZXMgYWxyZWFkeSAgYnVmZmVyZWQKKyAgICAgICAgICAgIC8vIGZpbGwgdXAgdGhlIHJlc2V0IG9mIGJ1ZmZlciBhbmQgd3JpdGUgdGhlIGJsb2NrLgorICAgICAgICAgICAgaWYgKGJ1ZmZlci5wb3NpdGlvbigpICE9IDApIHsKKyAgICAgICAgICAgICAgICBpbnQgbiA9IGJ1ZmZlci5yZW1haW5pbmcoKTsKKyAgICAgICAgICAgICAgICBzcmMubGltaXQoc3JjLnBvc2l0aW9uKCkgKyBuKTsKKyAgICAgICAgICAgICAgICBidWZmZXIucHV0KHNyYyk7CisgICAgICAgICAgICAgICAgd3JpdGVCbG9jaygpOworICAgICAgICAgICAgICAgIHNyY0xlZnQgLT0gbjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIHdoaWxzdCB3ZSBoYXZlIGVub3VnaCBieXRlcyBpbiBzcmMgZm9yIGNvbXBsZXRlIGJsb2NrcywKKyAgICAgICAgICAgIC8vIHdyaXRlIHRoZW0gZGlyZWN0bHkgZnJvbSBzcmMgd2l0aG91dCBjb3B5aW5nIHRoZW0gdG8gYnVmZmVyCisgICAgICAgICAgICB3aGlsZSAoc3JjTGVmdCA+PSBibG9ja1NpemUpIHsKKyAgICAgICAgICAgICAgICBzcmMubGltaXQoc3JjLnBvc2l0aW9uKCkgKyBibG9ja1NpemUpOworICAgICAgICAgICAgICAgIG91dC53cml0ZShzcmMpOworICAgICAgICAgICAgICAgIHNyY0xlZnQgLT0gYmxvY2tTaXplOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gY29weSBhbnkgcmVtYWluaW5nIGJ5dGVzIGludG8gYnVmZmVyCisgICAgICAgICAgICBzcmMubGltaXQoc2F2ZWRMaW1pdCk7CisgICAgICAgICAgICBidWZmZXIucHV0KHNyYyk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHNyY1JlbWFpbmluZzsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc09wZW4oKSB7CisgICAgICAgIGlmICghb3V0LmlzT3BlbigpKSB7CisgICAgICAgICAgICBjbG9zZWQuc2V0KHRydWUpOworICAgICAgICB9CisgICAgICAgIHJldHVybiAhY2xvc2VkLmdldCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBvdGVudGlhbGx5IHBhZHMgYW5kIHRoZW4gd3JpdGVzIHRoZSBjdXJyZW50IGJsb2NrIHRvIHRoZSB1bmRlcmx5aW5nIHN0cmVhbS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHdyaXRpbmcgZmFpbHMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBmbHVzaEJsb2NrKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGJ1ZmZlci5wb3NpdGlvbigpICE9IDApIHsKKyAgICAgICAgICAgIHBhZEJsb2NrKCk7CisgICAgICAgICAgICB3cml0ZUJsb2NrKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChjbG9zZWQuY29tcGFyZUFuZFNldChmYWxzZSwgdHJ1ZSkpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZmx1c2hCbG9jaygpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBwYWRCbG9jaygpIHsKKyAgICAgICAgYnVmZmVyLm9yZGVyKEJ5dGVPcmRlci5uYXRpdmVPcmRlcigpKTsKKyAgICAgICAgaW50IGJ5dGVzVG9Xcml0ZSA9IGJ1ZmZlci5yZW1haW5pbmcoKTsKKyAgICAgICAgaWYgKGJ5dGVzVG9Xcml0ZSA+IDgpIHsKKyAgICAgICAgICAgIGludCBhbGlnbiA9IGJ1ZmZlci5wb3NpdGlvbigpICYgNzsKKyAgICAgICAgICAgIGlmIChhbGlnbiAhPSAwKSB7CisgICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gOCAtIGFsaWduOworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGltaXQ7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBidWZmZXIucHV0KChieXRlKSAwKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYnl0ZXNUb1dyaXRlIC09IGxpbWl0OworICAgICAgICAgICAgfQorCisgICAgICAgICAgICB3aGlsZSAoYnl0ZXNUb1dyaXRlID49IDgpIHsKKyAgICAgICAgICAgICAgICBidWZmZXIucHV0TG9uZygwTCk7CisgICAgICAgICAgICAgICAgYnl0ZXNUb1dyaXRlIC09IDg7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgd2hpbGUgKGJ1ZmZlci5oYXNSZW1haW5pbmcoKSkgeworICAgICAgICAgICAgYnVmZmVyLnB1dCgoYnl0ZSkgMCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBIZWxwZXIgY2xhc3MgdG8gcHJvdmlkZSBjaGFubmVsIHdyYXBwZXIgZm9yIGFyYml0cmFyeSBvdXRwdXQgc3RyZWFtIHRoYXQgZG9lc24ndCBhbHRlciB0aGUKKyAgICAgKiBzaXplIG9mIHdyaXRlcy4gIFdlIGNhbid0IHVzZSBDaGFubmVscy5uZXdDaGFubmVsLCBiZWNhdXNlIGZvciBub24gRmlsZU91dHB1dFN0cmVhbXMsIGl0CisgICAgICogYnJlYWtzIHVwIHdyaXRlcyBpbnRvIDhLQiBtYXggY2h1bmtzLiBTaW5jZSB0aGUgcHVycG9zZSBvZiB0aGlzIGNsYXNzIGlzIHRvIGFsd2F5cyB3cml0ZQorICAgICAqIGNvbXBsZXRlIGJsb2Nrcywgd2UgbmVlZCB0byB3cml0ZSBhIHNpbXBsZSBjbGFzcyB0byB0YWtlIGNhcmUgb2YgaXQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgQnVmZmVyQXRBVGltZU91dHB1dENoYW5uZWwgaW1wbGVtZW50cyBXcml0YWJsZUJ5dGVDaGFubmVsIHsKKworICAgICAgICBwcml2YXRlIGZpbmFsIE91dHB1dFN0cmVhbSBvdXQ7CisgICAgICAgIHByaXZhdGUgZmluYWwgQXRvbWljQm9vbGVhbiBjbG9zZWQgPSBuZXcgQXRvbWljQm9vbGVhbihmYWxzZSk7CisKKyAgICAgICAgcHJpdmF0ZSBCdWZmZXJBdEFUaW1lT3V0cHV0Q2hhbm5lbChPdXRwdXRTdHJlYW0gb3V0KSB7CisgICAgICAgICAgICB0aGlzLm91dCA9IG91dDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgaW50IHdyaXRlKEJ5dGVCdWZmZXIgYnVmZmVyKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgaWYgKCFpc09wZW4oKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbG9zZWRDaGFubmVsRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoIWJ1ZmZlci5oYXNBcnJheSgpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiZGlyZWN0IGJ1ZmZlciBzb21laG93IHdyaXR0ZW4gdG8gQnVmZmVyQXRBVGltZU91dHB1dENoYW5uZWwiKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBpbnQgcG9zID0gYnVmZmVyLnBvc2l0aW9uKCk7CisgICAgICAgICAgICAgICAgaW50IGxlbiA9IGJ1ZmZlci5saW1pdCgpIC0gcG9zOworICAgICAgICAgICAgICAgIG91dC53cml0ZShidWZmZXIuYXJyYXkoKSwgYnVmZmVyLmFycmF5T2Zmc2V0KCkgKyBwb3MsIGxlbik7CisgICAgICAgICAgICAgICAgYnVmZmVyLnBvc2l0aW9uKGJ1ZmZlci5saW1pdCgpKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gbGVuOworICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGNsb3NlKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaWdub3JlZCkgeyAvL05PU09OQVIKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgdGhyb3cgZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc09wZW4oKSB7CisgICAgICAgICAgICByZXR1cm4gIWNsb3NlZC5nZXQoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBpZiAoY2xvc2VkLmNvbXBhcmVBbmRTZXQoZmFsc2UsIHRydWUpKSB7CisgICAgICAgICAgICAgICAgb3V0LmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgIH0KKworCit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy91dGlscy9GbHVzaFNoaWVsZEZpbHRlck91dHB1dFN0cmVhbS5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvdXRpbHMvRmx1c2hTaGllbGRGaWx0ZXJPdXRwdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMzllODIzCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvdXRpbHMvRmx1c2hTaGllbGRGaWx0ZXJPdXRwdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDQwIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHM7CisKK2ltcG9ydCBqYXZhLmlvLkZpbHRlck91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworCisvKioKKyAqIFJlLWltcGxlbWVudHMge0BsaW5rIEZpbHRlck91dHB1dFN0cmVhbSNmbHVzaCgpfSB0byBkbyBub3RoaW5nLgorICovCitwdWJsaWMgY2xhc3MgRmx1c2hTaGllbGRGaWx0ZXJPdXRwdXRTdHJlYW0gZXh0ZW5kcyBGaWx0ZXJPdXRwdXRTdHJlYW0geworCisgICAgcHVibGljIEZsdXNoU2hpZWxkRmlsdGVyT3V0cHV0U3RyZWFtKE91dHB1dFN0cmVhbSBvdXQpIHsKKyAgICAgICAgc3VwZXIob3V0KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBmbHVzaCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIE5PIElNUExFTUVOVEFUSU9OLgorICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvdXRpbHMvSU9VdGlscy5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvdXRpbHMvSU9VdGlscy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjUwNTc3YzkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy91dGlscy9JT1V0aWxzLmphdmEKQEAgLTAsMCArMSwyNDMgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHM7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkNsb3NlYWJsZTsKK2ltcG9ydCBqYXZhLmlvLkVPRkV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5SZWFkYWJsZUJ5dGVDaGFubmVsOworCisvKioKKyAqIFV0aWxpdHkgZnVuY3Rpb25zCisgKiBASW1tdXRhYmxlIChoYXMgbXV0YWJsZSBkYXRhIGJ1dCBpdCBpcyB3cml0ZS1vbmx5KQorICovCitwdWJsaWMgZmluYWwgY2xhc3MgSU9VdGlscyB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQ09QWV9CVUZfU0laRSA9IDgwMjQ7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFNLSVBfQlVGX1NJWkUgPSA0MDk2OworCisgICAgLy8gVGhpcyBidWZmZXIgZG9lcyBub3QgbmVlZCB0byBiZSBzeW5jaHJvbmlzZWQgYmVjYXVzZSBpdCBpcyB3cml0ZSBvbmx5OyB0aGUgY29udGVudHMgYXJlIGlnbm9yZWQKKyAgICAvLyBEb2VzIG5vdCBhZmZlY3QgSW1tdXRhYmlsaXR5CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIFNLSVBfQlVGID0gbmV3IGJ5dGVbU0tJUF9CVUZfU0laRV07CisKKyAgICAvKiogUHJpdmF0ZSBjb25zdHJ1Y3RvciB0byBwcmV2ZW50IGluc3RhbnRpYXRpb24gb2YgdGhpcyB1dGlsaXR5IGNsYXNzLiAqLworICAgIHByaXZhdGUgSU9VdGlscygpeworICAgIH0KKworICAgIC8qKgorICAgICAqIENvcGllcyB0aGUgY29udGVudCBvZiBhIElucHV0U3RyZWFtIGludG8gYW4gT3V0cHV0U3RyZWFtLgorICAgICAqIFVzZXMgYSBkZWZhdWx0IGJ1ZmZlciBzaXplIG9mIDgwMjQgYnl0ZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5wdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBJbnB1dFN0cmVhbSB0byBjb3B5CisgICAgICogQHBhcmFtIG91dHB1dAorICAgICAqICAgICAgICAgICAgdGhlIHRhcmdldCBTdHJlYW0KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgY29waWVkCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbG9uZyBjb3B5KGZpbmFsIElucHV0U3RyZWFtIGlucHV0LCBmaW5hbCBPdXRwdXRTdHJlYW0gb3V0cHV0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gY29weShpbnB1dCwgb3V0cHV0LCBDT1BZX0JVRl9TSVpFKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb3BpZXMgdGhlIGNvbnRlbnQgb2YgYSBJbnB1dFN0cmVhbSBpbnRvIGFuIE91dHB1dFN0cmVhbQorICAgICAqCisgICAgICogQHBhcmFtIGlucHV0CisgICAgICogICAgICAgICAgICB0aGUgSW5wdXRTdHJlYW0gdG8gY29weQorICAgICAqIEBwYXJhbSBvdXRwdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSB0YXJnZXQgU3RyZWFtCisgICAgICogQHBhcmFtIGJ1ZmZlcnNpemUKKyAgICAgKiAgICAgICAgICAgIHRoZSBidWZmZXIgc2l6ZSB0byB1c2UsIG11c3QgYmUgYmlnZ2VyIHRoYW4gMAorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyBjb3BpZWQKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBidWZmZXJzaXplIGlzIHNtYWxsZXIgdGhhbiBvciBlcXVhbCB0byAwCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBsb25nIGNvcHkoZmluYWwgSW5wdXRTdHJlYW0gaW5wdXQsIGZpbmFsIE91dHB1dFN0cmVhbSBvdXRwdXQsIGZpbmFsIGludCBidWZmZXJzaXplKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoYnVmZmVyc2l6ZSA8IDEpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImJ1ZmZlcnNpemUgbXVzdCBiZSBiaWdnZXIgdGhhbiAwIik7CisgICAgICAgIH0KKyAgICAgICAgZmluYWwgYnl0ZVtdIGJ1ZmZlciA9IG5ldyBieXRlW2J1ZmZlcnNpemVdOworICAgICAgICBpbnQgbiA9IDA7CisgICAgICAgIGxvbmcgY291bnQ9MDsKKyAgICAgICAgd2hpbGUgKC0xICE9IChuID0gaW5wdXQucmVhZChidWZmZXIpKSkgeworICAgICAgICAgICAgb3V0cHV0LndyaXRlKGJ1ZmZlciwgMCwgbik7CisgICAgICAgICAgICBjb3VudCArPSBuOworICAgICAgICB9CisgICAgICAgIHJldHVybiBjb3VudDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTa2lwcyB0aGUgZ2l2ZW4gbnVtYmVyIG9mIGJ5dGVzIGJ5IHJlcGVhdGVkbHkgaW52b2tpbmcgc2tpcCBvbgorICAgICAqIHRoZSBnaXZlbiBpbnB1dCBzdHJlYW0gaWYgbmVjZXNzYXJ5LgorICAgICAqCisgICAgICogPHA+SW4gYSBjYXNlIHdoZXJlIHRoZSBzdHJlYW0ncyBza2lwKCkgbWV0aG9kIHJldHVybnMgMCBiZWZvcmUKKyAgICAgKiB0aGUgcmVxdWVzdGVkIG51bWJlciBvZiBieXRlcyBoYXMgYmVlbiBza2lwIHRoaXMgaW1wbGVtZW50YXRpb24KKyAgICAgKiB3aWxsIGZhbGwgYmFjayB0byB1c2luZyB0aGUgcmVhZCgpIG1ldGhvZC48L3A+CisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCB3aWxsIG9ubHkgc2tpcCBsZXNzIHRoYW4gdGhlIHJlcXVlc3RlZCBudW1iZXIgb2YKKyAgICAgKiBieXRlcyBpZiB0aGUgZW5kIG9mIHRoZSBpbnB1dCBzdHJlYW0gaGFzIGJlZW4gcmVhY2hlZC48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5wdXQgc3RyZWFtIHRvIHNraXAgYnl0ZXMgaW4KKyAgICAgKiBAcGFyYW0gbnVtVG9Ta2lwIHRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gc2tpcAorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyBhY3R1YWxseSBza2lwcGVkCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBvbiBlcnJvcgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbG9uZyBza2lwKGZpbmFsIElucHV0U3RyZWFtIGlucHV0LCBsb25nIG51bVRvU2tpcCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgbG9uZyBhdmFpbGFibGUgPSBudW1Ub1NraXA7CisgICAgICAgIHdoaWxlIChudW1Ub1NraXAgPiAwKSB7CisgICAgICAgICAgICBmaW5hbCBsb25nIHNraXBwZWQgPSBpbnB1dC5za2lwKG51bVRvU2tpcCk7CisgICAgICAgICAgICBpZiAoc2tpcHBlZCA9PSAwKSB7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBudW1Ub1NraXAgLT0gc2tpcHBlZDsKKyAgICAgICAgfQorCisgICAgICAgIHdoaWxlIChudW1Ub1NraXAgPiAwKSB7CisgICAgICAgICAgICBmaW5hbCBpbnQgcmVhZCA9IHJlYWRGdWxseShpbnB1dCwgU0tJUF9CVUYsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaW50KSBNYXRoLm1pbihudW1Ub1NraXAsIFNLSVBfQlVGX1NJWkUpKTsKKyAgICAgICAgICAgIGlmIChyZWFkIDwgMSkgeworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgbnVtVG9Ta2lwIC09IHJlYWQ7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGF2YWlsYWJsZSAtIG51bVRvU2tpcDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhcyBtdWNoIGZyb20gaW5wdXQgYXMgcG9zc2libGUgdG8gZmlsbCB0aGUgZ2l2ZW4gYXJyYXkuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBtYXkgaW52b2tlIHJlYWQgcmVwZWF0ZWRseSB0byBmaWxsIHRoZSBhcnJheSBhbmQKKyAgICAgKiBvbmx5IHJlYWQgbGVzcyBieXRlcyB0aGFuIHRoZSBsZW5ndGggb2YgdGhlIGFycmF5IGlmIHRoZSBlbmQgb2YKKyAgICAgKiB0aGUgc3RyZWFtIGhhcyBiZWVuIHJlYWNoZWQuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGlucHV0IHN0cmVhbSB0byByZWFkIGZyb20KKyAgICAgKiBAcGFyYW0gYiBidWZmZXIgdG8gZmlsbAorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyBhY3R1YWxseSByZWFkCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBvbiBlcnJvcgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IHJlYWRGdWxseShmaW5hbCBJbnB1dFN0cmVhbSBpbnB1dCwgZmluYWwgYnl0ZVtdIGIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiByZWFkRnVsbHkoaW5wdXQsIGIsIDAsIGIubGVuZ3RoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhcyBtdWNoIGZyb20gaW5wdXQgYXMgcG9zc2libGUgdG8gZmlsbCB0aGUgZ2l2ZW4gYXJyYXkKKyAgICAgKiB3aXRoIHRoZSBnaXZlbiBhbW91bnQgb2YgYnl0ZXMuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBtYXkgaW52b2tlIHJlYWQgcmVwZWF0ZWRseSB0byByZWFkIHRoZSBieXRlcyBhbmQKKyAgICAgKiBvbmx5IHJlYWQgbGVzcyBieXRlcyB0aGFuIHRoZSByZXF1ZXN0ZWQgbGVuZ3RoIGlmIHRoZSBlbmQgb2YKKyAgICAgKiB0aGUgc3RyZWFtIGhhcyBiZWVuIHJlYWNoZWQuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGlucHV0IHN0cmVhbSB0byByZWFkIGZyb20KKyAgICAgKiBAcGFyYW0gYiBidWZmZXIgdG8gZmlsbAorICAgICAqIEBwYXJhbSBvZmZzZXQgb2Zmc2V0IGludG8gdGhlIGJ1ZmZlciB0byBzdGFydCBmaWxsaW5nIGF0CisgICAgICogQHBhcmFtIGxlbiBvZiBieXRlcyB0byByZWFkCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGJ5dGVzIGFjdHVhbGx5IHJlYWQKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIGhhcyBvY2N1cnJlZAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IHJlYWRGdWxseShmaW5hbCBJbnB1dFN0cmVhbSBpbnB1dCwgZmluYWwgYnl0ZVtdIGIsIGZpbmFsIGludCBvZmZzZXQsIGZpbmFsIGludCBsZW4pCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChsZW4gPCAwIHx8IG9mZnNldCA8IDAgfHwgbGVuICsgb2Zmc2V0ID4gYi5sZW5ndGgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaW50IGNvdW50ID0gMCwgeCA9IDA7CisgICAgICAgIHdoaWxlIChjb3VudCAhPSBsZW4pIHsKKyAgICAgICAgICAgIHggPSBpbnB1dC5yZWFkKGIsIG9mZnNldCArIGNvdW50LCBsZW4gLSBjb3VudCk7CisgICAgICAgICAgICBpZiAoeCA9PSAtMSkgeworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgY291bnQgKz0geDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY291bnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMge0Bjb2RlIGIucmVtYWluaW5nKCl9IGJ5dGVzIGZyb20gdGhlIGdpdmVuIGNoYW5uZWwKKyAgICAgKiBzdGFydGluZyBhdCB0aGUgY3VycmVudCBjaGFubmVsJ3MgcG9zaXRpb24uCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCByZWFkcyByZXBlYXRlZGx5IGZyb20gdGhlIGNoYW5uZWwgdW50aWwgdGhlCisgICAgICogcmVxdWVzdGVkIG51bWJlciBvZiBieXRlcyBhcmUgcmVhZC4gVGhpcyBtZXRob2QgYmxvY2tzIHVudGlsCisgICAgICogdGhlIHJlcXVlc3RlZCBudW1iZXIgb2YgYnl0ZXMgYXJlIHJlYWQsIHRoZSBlbmQgb2YgdGhlIGNoYW5uZWwKKyAgICAgKiBpcyBkZXRlY3RlZCwgb3IgYW4gZXhjZXB0aW9uIGlzIHRocm93bi48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gY2hhbm5lbCB0aGUgY2hhbm5lbCB0byByZWFkIGZyb20KKyAgICAgKiBAcGFyYW0gYiB0aGUgYnVmZmVyIGludG8gd2hpY2ggdGhlIGRhdGEgaXMgcmVhZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIC0gaWYgYW4gSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKiBAdGhyb3dzIEVPRkV4Y2VwdGlvbiAtIGlmIHRoZSBjaGFubmVsIHJlYWNoZXMgdGhlIGVuZCBiZWZvcmUgcmVhZGluZyBhbGwgdGhlIGJ5dGVzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCByZWFkRnVsbHkoUmVhZGFibGVCeXRlQ2hhbm5lbCBjaGFubmVsLCBCeXRlQnVmZmVyIGIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIGludCBleHBlY3RlZExlbmd0aCA9IGIucmVtYWluaW5nKCk7CisgICAgICAgIGludCByZWFkID0gMDsKKyAgICAgICAgd2hpbGUgKHJlYWQgPCBleHBlY3RlZExlbmd0aCkgeworICAgICAgICAgICAgaW50IHJlYWROb3cgPSBjaGFubmVsLnJlYWQoYik7CisgICAgICAgICAgICBpZiAocmVhZE5vdyA8PSAwKSB7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZWFkICs9IHJlYWROb3c7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHJlYWQgPCBleHBlY3RlZExlbmd0aCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEVPRkV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgfQorCisgICAgLy8gdG9CeXRlQXJyYXkoSW5wdXRTdHJlYW0pIGNvcGllZCBmcm9tOgorICAgIC8vIGNvbW1vbnMvcHJvcGVyL2lvL3RydW5rL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2lvL0lPVXRpbHMuamF2YT9yZXZpc2lvbj0xNDI4OTQxCisgICAgLy8gSmFudWFyeSA4dGgsIDIwMTMKKyAgICAvLworICAgIC8vIEFzc3VtaW5nIG91ciBjb3B5KCkgd29ya3MganVzdCBhcyB3ZWxsIGFzIHRoZWlycyEgIDotKQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgY29udGVudHMgb2YgYW4gPGNvZGU+SW5wdXRTdHJlYW08L2NvZGU+IGFzIGEgPGNvZGU+Ynl0ZVtdPC9jb2RlPi4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIG1ldGhvZCBidWZmZXJzIHRoZSBpbnB1dCBpbnRlcm5hbGx5LCBzbyB0aGVyZSBpcyBubyBuZWVkIHRvIHVzZSBhCisgICAgICogPGNvZGU+QnVmZmVyZWRJbnB1dFN0cmVhbTwvY29kZT4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5wdXQgIHRoZSA8Y29kZT5JbnB1dFN0cmVhbTwvY29kZT4gdG8gcmVhZCBmcm9tCisgICAgICogQHJldHVybiB0aGUgcmVxdWVzdGVkIGJ5dGUgYXJyYXkKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBpbnB1dCBpcyBudWxsCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiBhbiBJL08gZXJyb3Igb2NjdXJzCisgICAgICogQHNpbmNlIDEuNQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYnl0ZVtdIHRvQnl0ZUFycmF5KGZpbmFsIElucHV0U3RyZWFtIGlucHV0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gb3V0cHV0ID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICBjb3B5KGlucHV0LCBvdXRwdXQpOworICAgICAgICByZXR1cm4gb3V0cHV0LnRvQnl0ZUFycmF5KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvc2VzIHRoZSBnaXZlbiBDbG9zZWFibGUgYW5kIHN3YWxsb3dzIGFueSBJT0V4Y2VwdGlvbiB0aGF0IG1heSBvY2N1ci4KKyAgICAgKiBAcGFyYW0gYyBDbG9zZWFibGUgdG8gY2xvc2UsIGNhbiBiZSBudWxsCisgICAgICogQHNpbmNlIDEuNworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBjbG9zZVF1aWV0bHkoZmluYWwgQ2xvc2VhYmxlIGMpIHsKKyAgICAgICAgaWYgKGMgIT0gbnVsbCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBjLmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChmaW5hbCBJT0V4Y2VwdGlvbiBpZ25vcmVkKSB7IC8vIE5PUE1ECisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy91dGlscy9JbnB1dFN0cmVhbVN0YXRpc3RpY3MuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL3V0aWxzL0lucHV0U3RyZWFtU3RhdGlzdGljcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU2OWFiMzYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy91dGlscy9JbnB1dFN0cmVhbVN0YXRpc3RpY3MuamF2YQpAQCAtMCwwICsxLDM4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzOworCisvKioKKyAqIFRoaXMgaW50ZXJmYWNlIHByb3ZpZGVzIHN0YXRpc3RpY3Mgb24gdGhlIGN1cnJlbnQgZGVjb21wcmVzc2lvbiBzdHJlYW0uCisgKiBUaGUgc3RyZWFtIGNvbnN1bWVyIGNhbiB1c2UgdGhhdCBzdGF0aXN0aWNzIHRvIGhhbmRsZSBhYm5vcm1hbAorICogY29tcHJlc3Npb24gcmF0aW9zLCBpLmUuIHRvIHByZXZlbnQgemlwIGJvbWJzLgorICoKKyAqIEBzaW5jZSAxLjE3CisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgSW5wdXRTdHJlYW1TdGF0aXN0aWNzIHsKKyAgICAvKioKKyAgICAgKiBAcmV0dXJuIHRoZSBhbW91bnQgb2YgcmF3IG9yIGNvbXByZXNzZWQgYnl0ZXMgcmVhZCBieSB0aGUgc3RyZWFtCisgICAgICovCisgICAgbG9uZyBnZXRDb21wcmVzc2VkQ291bnQoKTsKKworICAgIC8qKgorICAgICAqIEByZXR1cm4gdGhlIGFtb3VudCBvZiBkZWNvbXByZXNzZWQgYnl0ZXMgcmV0dXJuZWQgYnkgdGhlIHN0cmVhbQorICAgICAqLworICAgIGxvbmcgZ2V0VW5jb21wcmVzc2VkQ291bnQoKTsKK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL3V0aWxzL0l0ZXJhdG9ycy5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvdXRpbHMvSXRlcmF0b3JzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGRiMGMzNgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL3V0aWxzL0l0ZXJhdG9ycy5qYXZhCkBAIC0wLDAgKzEsNjIgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlsczsKKworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuT2JqZWN0czsKKworLyoqCisgKiBJdGVyYXRvciB1dGlsaXRpZXMuCisgKgorICogQHNpbmNlIDEuMTMuCisgKi8KK3B1YmxpYyBjbGFzcyBJdGVyYXRvcnMgeworCisgICAgLyoqCisgICAgICogQWRkcyBhbGwgdGhlIGVsZW1lbnRzIGluIHRoZSBzb3VyY2Uge0Bjb2RlIGl0ZXJhdG9yfSB0byB0aGUgdGFyZ2V0CisgICAgICoge0Bjb2RlIGNvbGxlY3Rpb259LgorICAgICAqCisgICAgICogPHA+CisgICAgICogV2hlbiB0aGlzIG1ldGhvZCByZXR1cm5zLCB0aGUge0Bjb2RlIGl0ZXJhdG9yfSB3aWxsIGJlICJlbXB0eSI6IGl0cworICAgICAqIHtAY29kZSBoYXNOZXh0KCl9IG1ldGhvZCByZXR1cm5zIHtAY29kZSBmYWxzZX0uCisgICAgICogPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIDxUPiB0eXBlIG9mIHRoZSBlbGVtZW50cyBjb250YWluZWQgaW5zaWRlIHRoZSBjb2xsZWN0aW9uCisgICAgICogQHBhcmFtIGNvbGxlY3Rpb24gdGFyZ2V0IGNvbGxlY3Rpb24KKyAgICAgKiBAcGFyYW0gaXRlcmF0b3Igc291cmNlCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHRhcmdldCB7QGNvZGUgY29sbGVjdGlvbn0gd2FzIG1vZGlmaWVkIGFzIGEKKyAgICAgKiAgICAgICAgIHJlc3VsdCBvZiB0aGlzIG9wZXJhdGlvbgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgPFQ+IGJvb2xlYW4gYWRkQWxsKGZpbmFsIENvbGxlY3Rpb248VD4gY29sbGVjdGlvbiwgZmluYWwgSXRlcmF0b3I8PyBleHRlbmRzIFQ+IGl0ZXJhdG9yKSB7CisgICAgICAgIE9iamVjdHMucmVxdWlyZU5vbk51bGwoY29sbGVjdGlvbik7CisgICAgICAgIE9iamVjdHMucmVxdWlyZU5vbk51bGwoaXRlcmF0b3IpOworICAgICAgICBib29sZWFuIHdhc01vZGlmaWVkID0gZmFsc2U7CisgICAgICAgIHdoaWxlIChpdGVyYXRvci5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgIHdhc01vZGlmaWVkIHw9IGNvbGxlY3Rpb24uYWRkKGl0ZXJhdG9yLm5leHQoKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHdhc01vZGlmaWVkOworICAgIH0KKworICAgIHByaXZhdGUgSXRlcmF0b3JzKCkgeworICAgICAgICAvLyBkbyBub3QgaW5zdGFudGlhdGUKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL3V0aWxzL0xpc3RzLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy91dGlscy9MaXN0cy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU3YTgyZGMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy91dGlscy9MaXN0cy5qYXZhCkBAIC0wLDAgKzEsNjEgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlsczsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworCisvKioKKyAqIExpc3QgdXRpbGl0aWVzCisgKgorICogQHNpbmNlIDEuMTMKKyAqLworcHVibGljIGNsYXNzIExpc3RzIHsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0BsaW5rIEFycmF5TGlzdH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gPEU+IHR5cGUgb2YgZWxlbWVudHMgY29udGFpbmVkIGluIG5ldyBsaXN0CisgICAgICogQHJldHVybiBhIG5ldyB7QGxpbmsgQXJyYXlMaXN0fQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgPEU+IEFycmF5TGlzdDxFPiBuZXdBcnJheUxpc3QoKSB7CisgICAgICAgIHJldHVybiBuZXcgQXJyYXlMaXN0PD4oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAbGluayBBcnJheUxpc3R9IGZpbGxlZCB3aXRoIHRoZSBjb250ZW50cyBvZiB0aGUgZ2l2ZW4KKyAgICAgKiB7QGNvZGUgaXRlcmF0b3J9LgorICAgICAqCisgICAgICogQHBhcmFtIGl0ZXJhdG9yCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIGl0ZXJhdG9yCisgICAgICogQHBhcmFtIDxFPiB0eXBlIG9mIGVsZW1lbnRzIGNvbnRhaW5lZCBpbiBuZXcgbGlzdAorICAgICAqIEByZXR1cm4gYSBuZXcge0BsaW5rIEFycmF5TGlzdH0KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIDxFPiBBcnJheUxpc3Q8RT4gbmV3QXJyYXlMaXN0KGZpbmFsIEl0ZXJhdG9yPD8gZXh0ZW5kcyBFPiBpdGVyYXRvcikgeworICAgICAgICBmaW5hbCBBcnJheUxpc3Q8RT4gbGlzdCA9IG5ld0FycmF5TGlzdCgpOworICAgICAgICBJdGVyYXRvcnMuYWRkQWxsKGxpc3QsIGl0ZXJhdG9yKTsKKyAgICAgICAgcmV0dXJuIGxpc3Q7CisgICAgfQorCisgICAgcHJpdmF0ZSBMaXN0cygpIHsKKyAgICAgICAgLy8gZG8gbm90IGluc3RhbnRpYXRlCisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy91dGlscy9TZWVrYWJsZUluTWVtb3J5Qnl0ZUNoYW5uZWwuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL3V0aWxzL1NlZWthYmxlSW5NZW1vcnlCeXRlQ2hhbm5lbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVlY2U3ZjUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy91dGlscy9TZWVrYWJsZUluTWVtb3J5Qnl0ZUNoYW5uZWwuamF2YQpAQCAtMCwwICsxLDE5NSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHM7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLkJ5dGVCdWZmZXI7CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5TZWVrYWJsZUJ5dGVDaGFubmVsOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljLkF0b21pY0Jvb2xlYW47CisKKy8qKgorICogQSB7QGxpbmsgU2Vla2FibGVCeXRlQ2hhbm5lbH0gaW1wbGVtZW50YXRpb24gdGhhdCB3cmFwcyBhIGJ5dGVbXS4KKyAqCisgKiA8cD5XaGVuIHRoaXMgY2hhbm5lbCBpcyB1c2VkIGZvciB3cml0aW5nIGFuIGludGVybmFsIGJ1ZmZlciBncm93cyB0byBhY2NvbW1vZGF0ZQorICogaW5jb21pbmcgZGF0YS4gQSBuYXR1cmFsIHNpemUgbGltaXQgaXMgdGhlIHZhbHVlIG9mIHtAbGluayBJbnRlZ2VyI01BWF9WQUxVRX0uCisgKiBJbnRlcm5hbCBidWZmZXIgY2FuIGJlIGFjY2Vzc2VkIHZpYSB7QGxpbmsgU2Vla2FibGVJbk1lbW9yeUJ5dGVDaGFubmVsI2FycmF5KCl9LjwvcD4KKyAqCisgKiBAc2luY2UgMS4xMworICogQE5vdFRocmVhZFNhZmUKKyAqLworcHVibGljIGNsYXNzIFNlZWthYmxlSW5NZW1vcnlCeXRlQ2hhbm5lbCBpbXBsZW1lbnRzIFNlZWthYmxlQnl0ZUNoYW5uZWwgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE5BSVZFX1JFU0laRV9MSU1JVCA9IEludGVnZXIuTUFYX1ZBTFVFID4+IDE7CisKKyAgICBwcml2YXRlIGJ5dGVbXSBkYXRhOworICAgIHByaXZhdGUgZmluYWwgQXRvbWljQm9vbGVhbiBjbG9zZWQgPSBuZXcgQXRvbWljQm9vbGVhbigpOworICAgIHByaXZhdGUgaW50IHBvc2l0aW9uLCBzaXplOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IgdGFraW5nIGEgYnl0ZSBhcnJheS4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgY29uc3RydWN0b3IgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCB3aXRoIHByZS1hbGxvY2F0ZWQgYnVmZmVyIG9yIHdoZW4KKyAgICAgKiByZWFkaW5nIGZyb20gYSBnaXZlbiBieXRlIGFycmF5LjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkYXRhIGlucHV0IGRhdGEgb3IgcHJlLWFsbG9jYXRlZCBhcnJheS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU2Vla2FibGVJbk1lbW9yeUJ5dGVDaGFubmVsKGJ5dGVbXSBkYXRhKSB7CisgICAgICAgIHRoaXMuZGF0YSA9IGRhdGE7CisgICAgICAgIHNpemUgPSBkYXRhLmxlbmd0aDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJhbWV0ZXJsZXNzIGNvbnN0cnVjdG9yIC0gYWxsb2NhdGVzIGludGVybmFsIGJ1ZmZlciBieSBpdHNlbGYuCisgICAgICovCisgICAgcHVibGljIFNlZWthYmxlSW5NZW1vcnlCeXRlQ2hhbm5lbCgpIHsKKyAgICAgICAgdGhpcyhuZXcgYnl0ZVswXSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IgdGFraW5nIGEgc2l6ZSBvZiBzdG9yYWdlIHRvIGJlIGFsbG9jYXRlZC4KKyAgICAgKgorICAgICAqIDxwPkNyZWF0ZXMgYSBjaGFubmVsIGFuZCBhbGxvY2F0ZXMgaW50ZXJuYWwgc3RvcmFnZSBvZiBhIGdpdmVuIHNpemUuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIHNpemUgc2l6ZSBvZiBpbnRlcm5hbCBidWZmZXIgdG8gYWxsb2NhdGUsIGluIGJ5dGVzLgorICAgICAqLworICAgIHB1YmxpYyBTZWVrYWJsZUluTWVtb3J5Qnl0ZUNoYW5uZWwoaW50IHNpemUpIHsKKyAgICAgICAgdGhpcyhuZXcgYnl0ZVtzaXplXSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGxvbmcgcG9zaXRpb24oKSB7CisgICAgICAgIHJldHVybiBwb3NpdGlvbjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU2Vla2FibGVCeXRlQ2hhbm5lbCBwb3NpdGlvbihsb25nIG5ld1Bvc2l0aW9uKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBlbnN1cmVPcGVuKCk7CisgICAgICAgIGlmIChuZXdQb3NpdGlvbiA8IDBMIHx8IG5ld1Bvc2l0aW9uID4gSW50ZWdlci5NQVhfVkFMVUUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlBvc2l0aW9uIGhhcyB0byBiZSBpbiByYW5nZSAwLi4gIiArIEludGVnZXIuTUFYX1ZBTFVFKTsKKyAgICAgICAgfQorICAgICAgICBwb3NpdGlvbiA9IChpbnQpIG5ld1Bvc2l0aW9uOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgbG9uZyBzaXplKCkgeworICAgICAgICByZXR1cm4gc2l6ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU2Vla2FibGVCeXRlQ2hhbm5lbCB0cnVuY2F0ZShsb25nIG5ld1NpemUpIHsKKyAgICAgICAgaWYgKHNpemUgPiBuZXdTaXplKSB7CisgICAgICAgICAgICBzaXplID0gKGludCkgbmV3U2l6ZTsKKyAgICAgICAgfQorICAgICAgICByZXBvc2l0aW9uSWZOZWNlc3NhcnkoKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCByZWFkKEJ5dGVCdWZmZXIgYnVmKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBlbnN1cmVPcGVuKCk7CisgICAgICAgIHJlcG9zaXRpb25JZk5lY2Vzc2FyeSgpOworICAgICAgICBpbnQgd2FudGVkID0gYnVmLnJlbWFpbmluZygpOworICAgICAgICBpbnQgcG9zc2libGUgPSBzaXplIC0gcG9zaXRpb247CisgICAgICAgIGlmIChwb3NzaWJsZSA8PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHdhbnRlZCA+IHBvc3NpYmxlKSB7CisgICAgICAgICAgICB3YW50ZWQgPSBwb3NzaWJsZTsKKyAgICAgICAgfQorICAgICAgICBidWYucHV0KGRhdGEsIHBvc2l0aW9uLCB3YW50ZWQpOworICAgICAgICBwb3NpdGlvbiArPSB3YW50ZWQ7CisgICAgICAgIHJldHVybiB3YW50ZWQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB7CisgICAgICAgIGNsb3NlZC5zZXQodHJ1ZSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gaXNPcGVuKCkgeworICAgICAgICByZXR1cm4gIWNsb3NlZC5nZXQoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHdyaXRlKEJ5dGVCdWZmZXIgYikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZW5zdXJlT3BlbigpOworICAgICAgICBpbnQgd2FudGVkID0gYi5yZW1haW5pbmcoKTsKKyAgICAgICAgaW50IHBvc3NpYmxlV2l0aG91dFJlc2l6ZSA9IHNpemUgLSBwb3NpdGlvbjsKKyAgICAgICAgaWYgKHdhbnRlZCA+IHBvc3NpYmxlV2l0aG91dFJlc2l6ZSkgeworICAgICAgICAgICAgaW50IG5ld1NpemUgPSBwb3NpdGlvbiArIHdhbnRlZDsKKyAgICAgICAgICAgIGlmIChuZXdTaXplIDwgMCkgeyAvLyBvdmVyZmxvdworICAgICAgICAgICAgICAgIHJlc2l6ZShJbnRlZ2VyLk1BWF9WQUxVRSk7CisgICAgICAgICAgICAgICAgd2FudGVkID0gSW50ZWdlci5NQVhfVkFMVUUgLSBwb3NpdGlvbjsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcmVzaXplKG5ld1NpemUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGIuZ2V0KGRhdGEsIHBvc2l0aW9uLCB3YW50ZWQpOworICAgICAgICBwb3NpdGlvbiArPSB3YW50ZWQ7CisgICAgICAgIGlmIChzaXplIDwgcG9zaXRpb24pIHsKKyAgICAgICAgICAgIHNpemUgPSBwb3NpdGlvbjsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gd2FudGVkOworICAgIH0KKworICAgIC8qKgorICAgICAqIE9idGFpbnMgdGhlIGFycmF5IGJhY2tpbmcgdGhpcyBjaGFubmVsLgorICAgICAqCisgICAgICogPHA+Tk9URToKKyAgICAgKiBUaGUgcmV0dXJuZWQgYnVmZmVyIGlzIG5vdCBhbGlnbmVkIHdpdGggY29udGFpbmluZyBkYXRhLCB1c2UKKyAgICAgKiB7QGxpbmsgI3NpemUoKX0gdG8gb2J0YWluIHRoZSBzaXplIG9mIGRhdGEgc3RvcmVkIGluIHRoZSBidWZmZXIuPC9wPgorICAgICAqCisgICAgICogQHJldHVybiBpbnRlcm5hbCBieXRlIGFycmF5LgorICAgICAqLworICAgIHB1YmxpYyBieXRlW10gYXJyYXkoKSB7CisgICAgICAgIHJldHVybiBkYXRhOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByZXNpemUoaW50IG5ld0xlbmd0aCkgeworICAgICAgICBpbnQgbGVuID0gZGF0YS5sZW5ndGg7CisgICAgICAgIGlmIChsZW4gPD0gMCkgeworICAgICAgICAgICAgbGVuID0gMTsKKyAgICAgICAgfQorICAgICAgICBpZiAobmV3TGVuZ3RoIDwgTkFJVkVfUkVTSVpFX0xJTUlUKSB7CisgICAgICAgICAgICB3aGlsZSAobGVuIDwgbmV3TGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgbGVuIDw8PSAxOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeyAvLyBhdm9pZCBvdmVyZmxvdworICAgICAgICAgICAgbGVuID0gbmV3TGVuZ3RoOworICAgICAgICB9CisgICAgICAgIGRhdGEgPSBBcnJheXMuY29weU9mKGRhdGEsIGxlbik7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZU9wZW4oKSB0aHJvd3MgQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghaXNPcGVuKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBDbG9zZWRDaGFubmVsRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcmVwb3NpdGlvbklmTmVjZXNzYXJ5KCkgeworICAgICAgICBpZiAocG9zaXRpb24gPiBzaXplKSB7CisgICAgICAgICAgICBwb3NpdGlvbiA9IHNpemU7CisgICAgICAgIH0KKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL3V0aWxzL1NlcnZpY2VMb2FkZXJJdGVyYXRvci5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvdXRpbHMvU2VydmljZUxvYWRlckl0ZXJhdG9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWVkYTg1NwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL3V0aWxzL1NlcnZpY2VMb2FkZXJJdGVyYXRvci5qYXZhCkBAIC0wLDAgKzEsOTEgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlsczsKKworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTm9TdWNoRWxlbWVudEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuU2VydmljZUNvbmZpZ3VyYXRpb25FcnJvcjsKK2ltcG9ydCBqYXZhLnV0aWwuU2VydmljZUxvYWRlcjsKKworLyoqCisgKiBJdGVyYXRlcyBhbGwgc2VydmljZXMgZm9yIGEgZ2l2ZW4gY2xhc3MgdGhyb3VnaCB0aGUgc3RhbmRhcmQKKyAqIHtAbGluayBTZXJ2aWNlTG9hZGVyfSBtZWNoYW5pc20uCisgKgorICogQHBhcmFtIDxFPgorICogICAgICAgICAgICBUaGUgc2VydmljZSB0byBsb2FkCisgKiBAc2luY2UgMS4xMworICovCitwdWJsaWMgY2xhc3MgU2VydmljZUxvYWRlckl0ZXJhdG9yPEU+IGltcGxlbWVudHMgSXRlcmF0b3I8RT4geworCisgICAgcHJpdmF0ZSBFIG5leHRTZXJ2aWNlTG9hZGVyOworICAgIHByaXZhdGUgZmluYWwgQ2xhc3M8RT4gc2VydmljZTsKKyAgICBwcml2YXRlIGZpbmFsIEl0ZXJhdG9yPEU+IHNlcnZpY2VMb2FkZXJJdGVyYXRvcjsKKworICAgIHB1YmxpYyBTZXJ2aWNlTG9hZGVySXRlcmF0b3IoZmluYWwgQ2xhc3M8RT4gc2VydmljZSkgeworICAgICAgICB0aGlzKHNlcnZpY2UsIENsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCkpOworICAgIH0KKworICAgIHB1YmxpYyBTZXJ2aWNlTG9hZGVySXRlcmF0b3IoZmluYWwgQ2xhc3M8RT4gc2VydmljZSwgZmluYWwgQ2xhc3NMb2FkZXIgY2xhc3NMb2FkZXIpIHsKKyAgICAgICAgdGhpcy5zZXJ2aWNlID0gc2VydmljZTsKKyAgICAgICAgZmluYWwgU2VydmljZUxvYWRlcjxFPiBzZXJ2aWNlTG9hZGVyID0gU2VydmljZUxvYWRlci5sb2FkKHNlcnZpY2UsIGNsYXNzTG9hZGVyKTsKKyAgICAgICAgc2VydmljZUxvYWRlckl0ZXJhdG9yID0gc2VydmljZUxvYWRlci5pdGVyYXRvcigpOworICAgICAgICBuZXh0U2VydmljZUxvYWRlciA9IG51bGw7CisgICAgfQorCisgICAgcHJpdmF0ZSBib29sZWFuIGdldE5leHRTZXJ2aWNlTG9hZGVyKCkgeworICAgICAgICB3aGlsZSAobmV4dFNlcnZpY2VMb2FkZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBpZiAoIXNlcnZpY2VMb2FkZXJJdGVyYXRvci5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBuZXh0U2VydmljZUxvYWRlciA9IHNlcnZpY2VMb2FkZXJJdGVyYXRvci5uZXh0KCk7CisgICAgICAgICAgICB9IGNhdGNoIChmaW5hbCBTZXJ2aWNlQ29uZmlndXJhdGlvbkVycm9yIGUpIHsKKyAgICAgICAgICAgICAgICBpZiAoZS5nZXRDYXVzZSgpIGluc3RhbmNlb2YgU2VjdXJpdHlFeGNlcHRpb24pIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gSWdub3JlIHNlY3VyaXR5IGV4Y2VwdGlvbnMKKyAgICAgICAgICAgICAgICAgICAgLy8gVE9ETyBMb2c/CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB0aHJvdyBlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGhhc05leHQoKSB7CisgICAgICAgIHJldHVybiBnZXROZXh0U2VydmljZUxvYWRlcigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBFIG5leHQoKSB7CisgICAgICAgIGlmICghZ2V0TmV4dFNlcnZpY2VMb2FkZXIoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oIk5vIG1vcmUgZWxlbWVudHMgZm9yIHNlcnZpY2UgIiArIHNlcnZpY2UuZ2V0TmFtZSgpKTsKKyAgICAgICAgfQorICAgICAgICBmaW5hbCBFIHRlbXBOZXh0ID0gbmV4dFNlcnZpY2VMb2FkZXI7CisgICAgICAgIG5leHRTZXJ2aWNlTG9hZGVyID0gbnVsbDsKKyAgICAgICAgcmV0dXJuIHRlbXBOZXh0OworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHJlbW92ZSgpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJzZXJ2aWNlPSIgKyBzZXJ2aWNlLmdldE5hbWUoKSk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy91dGlscy9TZXRzLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy91dGlscy9TZXRzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGE3OTIxYgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL3V0aWxzL1NldHMuamF2YQpAQCAtMCwwICsxLDUwIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHM7CisKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CitpbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CisKKy8qKgorICogU2V0IHV0aWxpdGllcworICoKKyAqIEBzaW5jZSAxLjEzCisgKi8KK3B1YmxpYyBjbGFzcyBTZXRzIHsKKworICAgIHByaXZhdGUgU2V0cygpIHsKKyAgICAgICAgLy8gRG8gbm90IGluc3RhbnRpYXRlCisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBIYXNoU2V0IGZpbGxlZCB3aXRoIHRoZSBnaXZlbiBlbGVtZW50cworICAgICAqCisgICAgICogQHBhcmFtIGVsZW1lbnRzCisgICAgICogICAgICAgICAgICB0aGUgZWxlbWVudHMgdG8gZmlsbCB0aGUgbmV3IHNldAorICAgICAqIEBwYXJhbSA8RT4gdHlwZSBvZiBlbGVtZW50cyBjb250YWluZWQgaW4gbmV3IHNldAorICAgICAqIEByZXR1cm4gQSBuZXcgSGFzU2V0CisgICAgICovCisgICAgQFNhZmVWYXJhcmdzCisgICAgcHVibGljIHN0YXRpYyA8RT4gSGFzaFNldDxFPiBuZXdIYXNoU2V0KEUuLi4gZWxlbWVudHMpIHsKKyAgICAgICAgZmluYWwgSGFzaFNldDxFPiBzZXQgPSBuZXcgSGFzaFNldDw+KGVsZW1lbnRzLmxlbmd0aCk7CisgICAgICAgIENvbGxlY3Rpb25zLmFkZEFsbChzZXQsIGVsZW1lbnRzKTsKKyAgICAgICAgcmV0dXJuIHNldDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy91dGlscy9Ta2lwU2hpZWxkaW5nSW5wdXRTdHJlYW0uamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL3V0aWxzL1NraXBTaGllbGRpbmdJbnB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUxY2JjYmMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy91dGlscy9Ta2lwU2hpZWxkaW5nSW5wdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDUxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlsczsKKworaW1wb3J0IGphdmEuaW8uRmlsdGVySW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworCisvKioKKyAqIEEgd3JhcHBlciB0aGF0IG92ZXJ3cml0ZXMge0BsaW5rICNza2lwfSBhbmQgZGVsZWdhdGVzIHRvIHtAbGluayAjcmVhZH0gaW5zdGVhZC4KKyAqCisgKiA8cD5Tb21lIGltcGxlbWVudGF0aW9ucyBvZiB7QGxpbmsgSW5wdXRTdHJlYW19IGltcGxlbWVudCB7QGxpbmsKKyAqIElucHV0U3RyZWFtI3NraXB9IGluIGEgd2F5IHRoYXQgdGhyb3dzIGFuIGV4Y2VwdGlvbiBpZiB0aGUgc3RyZWFtCisgKiBpcyBub3Qgc2Vla2FibGUgLSB7QGxpbmsgU3lzdGVtI2luIFN5c3RlbS5pbn0gaXMga25vd24gdG8gYmVoYXZlCisgKiB0aGF0IHdheS4gRm9yIHN1Y2ggYSBzdHJlYW0gaXQgaXMgaW1wb3NzaWJsZSB0byBpbnZva2Ugc2tpcCBhdCBhbGwKKyAqIGFuZCB5b3UgaGF2ZSB0byByZWFkIGZyb20gdGhlIHN0cmVhbSAoYW5kIGRpc2NhcmQgdGhlIGRhdGEgcmVhZCkKKyAqIGluc3RlYWQuIFNraXBwaW5nIGlzIHBvdGVudGlhbGx5IG11Y2ggZmFzdGVyIHRoYW4gcmVhZGluZyBzbyB3ZSBkbworICogd2FudCB0byBpbnZva2Uge0Bjb2RlIHNraXB9IHdoZW4gcG9zc2libGUuIFdlIHByb3ZpZGUgdGhpcyBjbGFzcyBzbworICogeW91IGNhbiB3cmFwIHlvdXIgb3duIHtAbGluayBJbnB1dFN0cmVhbX0gaW4gaXQgaWYgeW91IGVuY291bnRlcgorICogcHJvYmxlbXMgd2l0aCB7QGNvZGUgc2tpcH0gdGhyb3dpbmcgYW4gZXhjcGV0aW9uLjwvcD4KKyAqCisgKiBAc2luY2UgMS4xNworICovCitwdWJsaWMgY2xhc3MgU2tpcFNoaWVsZGluZ0lucHV0U3RyZWFtIGV4dGVuZHMgRmlsdGVySW5wdXRTdHJlYW0geworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBTS0lQX0JVRkZFUl9TSVpFID0gODE5MjsKKyAgICAvLyB3ZSBjYW4gdXNlIGEgc2hhcmVkIGJ1ZmZlciBhcyB0aGUgY29udGVudCBpcyBkaXNjYXJkZWQgYW55d2F5CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIFNLSVBfQlVGRkVSID0gbmV3IGJ5dGVbU0tJUF9CVUZGRVJfU0laRV07CisgICAgcHVibGljIFNraXBTaGllbGRpbmdJbnB1dFN0cmVhbShJbnB1dFN0cmVhbSBpbikgeworICAgICAgICBzdXBlcihpbik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGxvbmcgc2tpcChsb25nIG4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBuIDwgMCA/IDAgOiByZWFkKFNLSVBfQlVGRkVSLCAwLCAoaW50KSBNYXRoLm1pbihuLCBTS0lQX0JVRkZFUl9TSVpFKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvdXRpbHMvcGFja2FnZS5odG1sIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvdXRpbHMvcGFja2FnZS5odG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA0MDlkMTIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy91dGlscy9wYWNrYWdlLmh0bWwKQEAgLTAsMCArMSwyMyBAQAorPGh0bWw+Cis8IS0tCisKKyAgIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAgIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisKKyAgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKworICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAgIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisKKy0tPgorICA8Ym9keT4KKyAgICA8cD5Db250YWlucyB1dGlsaXRpZXMgdXNlZCBpbnRlcm5hbGx5IGJ5IHRoZSBjb21wcmVzcyBsaWJyYXJ5LjwvcD4KKyAgPC9ib2R5PgorPC9odG1sPgpkaWZmIC0tZ2l0IGEvc3JjL3NpdGUvcmVzb3VyY2VzL2Rvd25sb2FkX2NvbXByZXNzLmNnaSBiL3NyYy9zaXRlL3Jlc291cmNlcy9kb3dubG9hZF9jb21wcmVzcy5jZ2kKbmV3IGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggMDAwMDAwMC4uOGNhMzc1MgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9zaXRlL3Jlc291cmNlcy9kb3dubG9hZF9jb21wcmVzcy5jZ2kKQEAgLTAsMCArMSwyMCBAQAorIyEvYmluL3NoCisKKyMgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisjIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorIyB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisjIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisjICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisjIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisjCisjICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyMKKyMgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorIyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorIyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyMgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorIyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKworIyBKdXN0IGNhbGwgdGhlIHN0YW5kYXJkIG1pcnJvcnMuY2dpIHNjcmlwdC4gSXQgd2lsbCB1c2UgZG93bmxvYWQuaHRtbAorIyBhcyB0aGUgaW5wdXQgdGVtcGxhdGUuCitleGVjIC93d3cvd3d3LmFwYWNoZS5vcmcvZHluL21pcnJvcnMvbWlycm9ycy5jZ2kgJCoKZGlmZiAtLWdpdCBhL3NyYy9zaXRlL3Jlc291cmNlcy9pbWFnZXMvY29tcHJlc3MtbG9nby13aGl0ZS5wbmcgYi9zcmMvc2l0ZS9yZXNvdXJjZXMvaW1hZ2VzL2NvbXByZXNzLWxvZ28td2hpdGUucG5nCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU3NDlmYzQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvc2l0ZS9yZXNvdXJjZXMvaW1hZ2VzL2NvbXByZXNzLWxvZ28td2hpdGUucG5nCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy9zaXRlL3Jlc291cmNlcy9pbWFnZXMvY29tcHJlc3MtbG9nby13aGl0ZS54Y2YgYi9zcmMvc2l0ZS9yZXNvdXJjZXMvaW1hZ2VzL2NvbXByZXNzLWxvZ28td2hpdGUueGNmCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM4OGE1YTEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvc2l0ZS9yZXNvdXJjZXMvaW1hZ2VzL2NvbXByZXNzLWxvZ28td2hpdGUueGNmCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy9zaXRlL3Jlc291cmNlcy9wcm9maWxlLmphY29jbyBiL3NyYy9zaXRlL3Jlc291cmNlcy9wcm9maWxlLmphY29jbwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNjlkZTI5Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3NpdGUvcmVzb3VyY2VzL3Byb2ZpbGUuamFjb2NvCmRpZmYgLS1naXQgYS9zcmMvc2l0ZS9yZXNvdXJjZXMvcHJvZmlsZS5qYXBpY21wIGIvc3JjL3NpdGUvcmVzb3VyY2VzL3Byb2ZpbGUuamFwaWNtcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNjlkZTI5Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3NpdGUvcmVzb3VyY2VzL3Byb2ZpbGUuamFwaWNtcApkaWZmIC0tZ2l0IGEvc3JjL3NpdGUvc2l0ZS54bWwgYi9zcmMvc2l0ZS9zaXRlLnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lODE2MjUwCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3NpdGUvc2l0ZS54bWwKQEAgLTAsMCArMSw2MCBAQAorPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iSVNPLTg4NTktMSI/PgorPCEtLQorCisgICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAgIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAgICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorCisgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisKKyAgIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAgIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAgIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAgIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorCistLT4KKzxwcm9qZWN0IG5hbWU9IkNvbW1vbnMgQ29tcHJlc3MiPgorCisgIDxiYW5uZXJSaWdodD4KKyAgICA8bmFtZT5Db21tb25zIENvbXByZXNzPC9uYW1lPgorICAgIDxzcmM+L2ltYWdlcy9jb21wcmVzcy1sb2dvLXdoaXRlLnBuZzwvc3JjPgorICAgIDxocmVmPi9pbmRleC5odG1sPC9ocmVmPgorICA8L2Jhbm5lclJpZ2h0PgorCisgIDxib2R5PgorICAgIDxtZW51IG5hbWU9IkNvbXByZXNzIj4KKyAgICAgIDxpdGVtIG5hbWU9Ik92ZXJ2aWV3IiAgICBocmVmPSIvaW5kZXguaHRtbCIvPgorICAgICAgPGl0ZW0gbmFtZT0iVXNlciBHdWlkZSIgIGhyZWY9Ii9leGFtcGxlcy5odG1sIi8+CisgICAgICA8aXRlbSBuYW1lPSJLbm93biBMaW1pdGF0aW9ucyIgaHJlZj0iL2xpbWl0YXRpb25zLmh0bWwiLz4KKyAgICAgIDxpdGVtIG5hbWU9IkNvbnZlbnRpb25zIiAgICBocmVmPSIvY29udmVudGlvbnMuaHRtbCIvPgorICAgICAgPGl0ZW0gbmFtZT0iSXNzdWUgVHJhY2tpbmciIGhyZWY9Ii9pc3N1ZS10cmFja2luZy5odG1sIi8+CisgICAgICA8aXRlbSBuYW1lPSJEb3dubG9hZCIgICAgaHJlZj0iL2Rvd25sb2FkX2NvbXByZXNzLmNnaSIvPgorICAgICAgPGl0ZW0gbmFtZT0iU2VjdXJpdHkgUmVwb3J0cyIgICAgaHJlZj0iL3NlY3VyaXR5LXJlcG9ydHMuaHRtbCIvPgorICAgICAgPGl0ZW0gbmFtZT0iV2lraSIgaHJlZj0iaHR0cHM6Ly93aWtpLmFwYWNoZS5vcmcvY29tbW9ucy9Db21wcmVzcyIvPgorICAgIDwvbWVudT4KKyAgICA8bWVudSBuYW1lPSJBUEkgRG9jcyI+CisgICAgICA8aXRlbSBuYW1lPSJMYXRlc3QgcmVsZWFzZSIgaHJlZj0iamF2YWRvY3MvYXBpLXJlbGVhc2UvaW5kZXguaHRtbCIvPgorICAgICAgPGl0ZW0gbmFtZT0iMS4xOCIgaHJlZj0iamF2YWRvY3MvYXBpLTEuMTgvaW5kZXguaHRtbCIvPgorICAgICAgPGl0ZW0gbmFtZT0iMS4xNyIgaHJlZj0iamF2YWRvY3MvYXBpLTEuMTcvaW5kZXguaHRtbCIvPgorICAgICAgPGl0ZW0gbmFtZT0iMS4xNi4xIiBocmVmPSJqYXZhZG9jcy9hcGktMS4xNi4xL2luZGV4Lmh0bWwiLz4KKyAgICAgIDxpdGVtIG5hbWU9IjEuMTYiIGhyZWY9ImphdmFkb2NzL2FwaS0xLjE2L2luZGV4Lmh0bWwiLz4KKyAgICAgIDxpdGVtIG5hbWU9IjEuMTUiIGhyZWY9ImphdmFkb2NzL2FwaS0xLjE1L2luZGV4Lmh0bWwiLz4KKyAgICAgIDxpdGVtIG5hbWU9IjEuMTQiIGhyZWY9ImphdmFkb2NzL2FwaS0xLjE0L2luZGV4Lmh0bWwiLz4KKyAgICAgIDxpdGVtIG5hbWU9IjEuMTMiIGhyZWY9ImphdmFkb2NzL2FwaS0xLjEzL2luZGV4Lmh0bWwiLz4KKyAgICAgIDxpdGVtIG5hbWU9IjEuMTIiIGhyZWY9ImphdmFkb2NzL2FwaS0xLjEyL2luZGV4Lmh0bWwiLz4KKyAgICAgIDxpdGVtIG5hbWU9IjEuMTEiIGhyZWY9ImphdmFkb2NzL2FwaS0xLjExL2luZGV4Lmh0bWwiLz4KKyAgICAgIDxpdGVtIG5hbWU9IjEuMTAiIGhyZWY9ImphdmFkb2NzL2FwaS0xLjEwL2luZGV4Lmh0bWwiLz4KKyAgICAgIDxpdGVtIG5hbWU9IjEuOSIgaHJlZj0iamF2YWRvY3MvYXBpLTEuOS9pbmRleC5odG1sIi8+CisgICAgICA8aXRlbSBuYW1lPSIxLjguMSIgaHJlZj0iamF2YWRvY3MvYXBpLTEuOC4xL2luZGV4Lmh0bWwiLz4KKyAgICAgIDxpdGVtIG5hbWU9IjEuOCIgaHJlZj0iamF2YWRvY3MvYXBpLTEuOC9pbmRleC5odG1sIi8+CisgICAgICA8aXRlbSBuYW1lPSIxLjciIGhyZWY9ImphdmFkb2NzL2FwaS0xLjcvaW5kZXguaHRtbCIvPgorICAgICAgPGl0ZW0gbmFtZT0iMS42IiBocmVmPSJqYXZhZG9jcy9hcGktMS42L2luZGV4Lmh0bWwiLz4KKyAgICAgIDxpdGVtIG5hbWU9IkdJVCBsYXRlc3QiIGhyZWY9ImFwaWRvY3MvaW5kZXguaHRtbCIvPgorICAgIDwvbWVudT4KKyAgPC9ib2R5PgorICAKKzwvcHJvamVjdD4KZGlmZiAtLWdpdCBhL3NyYy9zaXRlL3hkb2MvY29udmVudGlvbnMueG1sIGIvc3JjL3NpdGUveGRvYy9jb252ZW50aW9ucy54bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjFhOTNiNwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9zaXRlL3hkb2MvY29udmVudGlvbnMueG1sCkBAIC0wLDAgKzEsNjkgQEAKKzw/eG1sIHZlcnNpb249IjEuMCI/PgorPCEtLQorICAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAgIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAgIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKworICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorCisgICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKy0tPgorPGRvY3VtZW50PgorICAgPHByb3BlcnRpZXM+CisgICAgICA8dGl0bGU+Q29udmVudGlvbnM8L3RpdGxlPgorICAgPC9wcm9wZXJ0aWVzPgorCisgICA8Ym9keT4KKyAgICAgIDxzZWN0aW9uIG5hbWU9IkNvZGUgU3R5bGUiPgorICAgICAgICAgICAgPHA+CisgICAgICAgICAgICBUaGUgZGV2ZWxvcGVycyBvZiB0aGlzIGNvbXBvbmVudCBkZWNpZGVkIHRvIGZvbGxvdyB0aGUgcmVjb21tZW5kZWQgc3RhbmRhcmRzCisgICAgICAgICAgICBidXQgbm90IHRvIGluY2x1ZGUgQ2hlY2tzdHlsZSAob3Igc2ltaWxhciB0b29scykgaW50byBDb21tb25zIENvbXByZXNzLgorICAgICAgICAgICAgPC9wPgorICAgICAgPC9zZWN0aW9uPgorICAgICAgPHNlY3Rpb24gbmFtZT0iTXVsdGl0aHJlYWRpbmciPgorICAgICAgICAgICAgPHA+CisgICAgICAgICAgICBDb21tb25zIENvbXByZXNzIGRvZXMgbm90IGFpbSB0byBiZSB0aHJlYWRzYWZlIGF0IHRoZSBtb21lbnQuIEJ1dCB0aGUgZGV2ZWxvcGVycworICAgICAgICAgICAgYWdyZWVkIHRvIGRvY3VtZW50IG11bHRpdGhyZWFkaW5nIGJlaGF2aW91ciBpbiB0aGUgamF2YWRvY3MuCisgICAgICAgICAgICA8L3A+CisgICAgICAgICAgICA8cD4KKyAgICAgICAgICAgIFdlIHVzZSBzb21lIG9mIHRoZSBhbm5vdGF0aW9ucyBmcm9tIAorICAgICAgICAgICAgPGEgaHJlZj0iaHR0cDovL2pjaXAubmV0L2Fubm90YXRpb25zL2RvYy9uZXQvamNpcC9hbm5vdGF0aW9ucy9wYWNrYWdlLXN1bW1hcnkuaHRtbCI+SkNJUDwvYT4KKyAgICAgICAgICAgIGFzIEphdmFkb2MgdGFncy4gVGhlIHVzZWQgdGFncyBhcmU6IAorICAgIAorICAgICAgICAgICAgPHVsPgorICAgICAgICAgICAgICAgIDxsaT5AR3VhcmRlZEJ5IChmaWVsZCBvciBtZXRob2QpPC9saT4KKyAgICAgICAgICAgICAgICA8bGk+QEltbXV0YWJsZSAoY2xhc3MpPC9saT4KKyAgICAgICAgICAgICAgICA8bGk+QE5vdFRocmVhZFNhZmUgKGNsYXNzKTwvbGk+CisgICAgICAgICAgICAgICAgPGxpPkBUaHJlYWRTYWZlIChjbGFzcyk8L2xpPgorICAgICAgICAgICAgPC91bD4KKworICAgICAgICAgICAgRm9yIGV4YW1wbGU6CisgICAgICAgICAgICA8c291cmNlPgorLyoqCisgKiBVdGlsaXR5IGNsYXNzIHRoYXQgcmVwcmVzZW50cyBhIGZvdXIgYnl0ZSBpbnRlZ2VyIHdpdGggY29udmVyc2lvbgorICogcnVsZXMgZm9yIHRoZSBiaWcgZW5kaWFuIGJ5dGUgb3JkZXIgb2YgWklQIGZpbGVzLgorICoKKyAqIEBJbW11dGFibGUKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFppcExvbmcgaW1wbGVtZW50cyBDbG9uZWFibGUgeworICAgICAgICAgICAgPC9zb3VyY2U+IAorICAgICAgICAgICAgCisgICAgICAgICAgICBhbmQ6CisgICAgICAgICAgICAKKyAgICAgICAgICAgIDxzb3VyY2U+IAorcHJpdmF0ZSBmaW5hbCBjaGFyIFtdIGhpZ2hDaGFyczsKKy8vQEd1YXJkZWRCeSgidGhpcyIpCitwcml2YXRlIFNpbXBsZThCaXRaaXBFbmNvZGluZyBlbmNvZGluZzsKKyAgICAgICAgICAgIDwvc291cmNlPgorICAgICAgICAgICAgPC9wPgorICAgICAgPC9zZWN0aW9uPgorCisgICA8L2JvZHk+Cis8L2RvY3VtZW50PgpkaWZmIC0tZ2l0IGEvc3JjL3NpdGUveGRvYy9kb3dubG9hZF9jb21wcmVzcy54bWwgYi9zcmMvc2l0ZS94ZG9jL2Rvd25sb2FkX2NvbXByZXNzLnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iZWQxY2U3Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3NpdGUveGRvYy9kb3dubG9hZF9jb21wcmVzcy54bWwKQEAgLTAsMCArMSwxNTQgQEAKKzw/eG1sIHZlcnNpb249IjEuMCI/PgorPCEtLQorTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCitjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKK3RoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KK1RoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAordGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKworICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKworVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKK1dJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCistLT4KKzwhLS0KKyArPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSsKKyB8KioqKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKioqKnwKKyB8KioqKiAgICAgIFRISVMgRklMRSBJUyBHRU5FUkFURUQgQlkgVEhFIENPTU1PTlMgQlVJTEQgUExVR0lOICAgICAgKioqKnwKKyB8KioqKiAgICAgICAgICAgICAgICAgICAgRE8gTk9UIEVESVQgRElSRUNUTFkgICAgICAgICAgICAgICAgICAgICAgKioqKnwKKyB8KioqKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKioqKnwKKyArPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSsKKyB8IFRFTVBMQVRFIEZJTEU6IGRvd25sb2FkLXBhZ2UtdGVtcGxhdGUueG1sICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKyB8IGNvbW1vbnMtYnVpbGQtcGx1Z2luL3RydW5rL3NyYy9tYWluL3Jlc291cmNlcy9jb21tb25zLXhkb2MtdGVtcGxhdGVzIHwKKyArPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSsKKyB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKyB8IDEpIFJlLWdlbmVyYXRlIHVzaW5nOiBtdm4gY29tbW9uczpkb3dubG9hZC1wYWdlICAgICAgICAgICAgICAgICAgICAgIHwKKyB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKyB8IDIpIFNldCB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXMgaW4gdGhlIGNvbXBvbmVudCdzIHBvbTogICAgICAgICAgICAgIHwKKyB8ICAgIC0gY29tbW9ucy5jb21wb25lbnRpZCAocmVxdWlyZWQsIGFscGhhYmV0aWMsIGxvd2VyIGNhc2UpICAgICAgICAgIHwKKyB8ICAgIC0gY29tbW9ucy5yZWxlYXNlLnZlcnNpb24gKHJlcXVpcmVkKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKyB8ICAgIC0gY29tbW9ucy5yZWxlYXNlLm5hbWUgICAgKHJlcXVpcmVkKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKyB8ICAgIC0gY29tbW9ucy5iaW5hcnkuc3VmZml4ICAgKG9wdGlvbmFsKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKyB8ICAgICAgKGRlZmF1bHRzIHRvICItYmluIiwgc2V0IHRvICIiIGZvciBwcmUtbWF2ZW4yIHJlbGVhc2VzKSAgICAgICAgIHwKKyB8ICAgIC0gY29tbW9ucy5yZWxlYXNlLmRlc2MgICAgKG9wdGlvbmFsKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKyB8ICAgIC0gY29tbW9ucy5yZWxlYXNlLnN1YmRpciAgKG9wdGlvbmFsKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKyB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKyB8ICAgIC0gY29tbW9ucy5yZWxlYXNlLjIvMy52ZXJzaW9uICAgICAgIChjb25kaXRpb25hbCkgICAgICAgICAgICAgICAgIHwKKyB8ICAgIC0gY29tbW9ucy5yZWxlYXNlLjIvMy5uYW1lICAgICAgICAgIChjb25kaXRpb25hbCkgICAgICAgICAgICAgICAgIHwKKyB8ICAgIC0gY29tbW9ucy5yZWxlYXNlLjIvMy5iaW5hcnkuc3VmZml4IChvcHRpb25hbCkgICAgICAgICAgICAgICAgICAgIHwKKyB8ICAgIC0gY29tbW9ucy5yZWxlYXNlLjIvMy5kZXNjICAgICAgICAgIChvcHRpb25hbCkgICAgICAgICAgICAgICAgICAgIHwKKyB8ICAgIC0gY29tbW9ucy5yZWxlYXNlLjIvMy5zdWJkaXIgICAgICAgIChvcHRpb25hbCkgICAgICAgICAgICAgICAgICAgIHwKKyB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKyB8IDMpIEV4YW1wbGUgUHJvcGVydGllcyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKyB8ICAgIChjb21tb25zLnJlbGVhc2UubmFtZSBpbmhlcml0ZWQgYnkgcGFyZW50OiAgICAgICAgICAgICAgICAgICAgICAgIHwKKyB8ICAgICAke3Byb2plY3QuYXJ0aWZhY3RJZH0tJHtjb21tb25zLnJlbGVhc2UudmVyc2lvbn0gICAgICAgICAgICAgICAgIHwKKyB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKyB8ICA8cHJvcGVydGllcz4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKyB8ICAgIDxjb21tb25zLmNvbXBvbmVudGlkPm1hdGg8L2NvbW1vbnMuY29tcG9uZW50aWQ+ICAgICAgICAgICAgICAgICAgIHwKKyB8ICAgIDxjb21tb25zLnJlbGVhc2UudmVyc2lvbj4xLjI8L2NvbW1vbnMucmVsZWFzZS52ZXJzaW9uPiAgICAgICAgICAgIHwKKyB8ICA8L3Byb3BlcnRpZXM+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKyB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKyArPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSsKKy0tPgorPGRvY3VtZW50PgorICA8cHJvcGVydGllcz4KKyAgICA8dGl0bGU+RG93bmxvYWQgQXBhY2hlIENvbW1vbnMgQ29tcHJlc3M8L3RpdGxlPgorICAgIDxhdXRob3IgZW1haWw9ImRldkBjb21tb25zLmFwYWNoZS5vcmciPkFwYWNoZSBDb21tb25zIERvY3VtZW50YXRpb24gVGVhbTwvYXV0aG9yPgorICA8L3Byb3BlcnRpZXM+CisgIDxib2R5PgorICAgIDxzZWN0aW9uIG5hbWU9IkRvd25sb2FkIEFwYWNoZSBDb21tb25zIENvbXByZXNzIj4KKyAgICA8c3Vic2VjdGlvbiBuYW1lPSJVc2luZyBhIE1pcnJvciI+CisgICAgICA8cD4KKyAgICAgICAgV2UgcmVjb21tZW5kIHlvdSB1c2UgYSBtaXJyb3IgdG8gZG93bmxvYWQgb3VyIHJlbGVhc2UKKyAgICAgICAgYnVpbGRzLCBidXQgeW91IDxzdHJvbmc+bXVzdDwvc3Ryb25nPiA8YSBocmVmPSJodHRwczovL3d3dy5hcGFjaGUub3JnL2luZm8vdmVyaWZpY2F0aW9uLmh0bWwiPnZlcmlmeSB0aGUgaW50ZWdyaXR5PC9hPiBvZgorICAgICAgICB0aGUgZG93bmxvYWRlZCBmaWxlcyB1c2luZyBzaWduYXR1cmVzIGRvd25sb2FkZWQgZnJvbSBvdXIgbWFpbgorICAgICAgICBkaXN0cmlidXRpb24gZGlyZWN0b3JpZXMuIFJlY2VudCByZWxlYXNlcyAoNDggaG91cnMpIG1heSBub3QgeWV0CisgICAgICAgIGJlIGF2YWlsYWJsZSBmcm9tIGFsbCB0aGUgbWlycm9ycy4KKyAgICAgIDwvcD4KKworICAgICAgPHA+CisgICAgICAgIFlvdSBhcmUgY3VycmVudGx5IHVzaW5nIDxiPltwcmVmZXJyZWRdPC9iPi4gIElmIHlvdQorICAgICAgICBlbmNvdW50ZXIgYSBwcm9ibGVtIHdpdGggdGhpcyBtaXJyb3IsIHBsZWFzZSBzZWxlY3QgYW5vdGhlcgorICAgICAgICBtaXJyb3IuICBJZiBhbGwgbWlycm9ycyBhcmUgZmFpbGluZywgdGhlcmUgYXJlIDxpPmJhY2t1cDwvaT4KKyAgICAgICAgbWlycm9ycyAoYXQgdGhlIGVuZCBvZiB0aGUgbWlycm9ycyBsaXN0KSB0aGF0IHNob3VsZCBiZQorICAgICAgICBhdmFpbGFibGUuCisgICAgICAgIDxicj48L2JyPgorICAgICAgICBbaWYtYW55IGxvZ29dPGEgaHJlZj0iW2xpbmtdIj48aW1nIGFsaWduPSJyaWdodCIgc3JjPSJbbG9nb10iIGJvcmRlcj0iMCI+PC9pbWc+PC9hPltlbmRdCisgICAgICA8L3A+CisKKyAgICAgIDxmb3JtIGFjdGlvbj0iW2xvY2F0aW9uXSIgbWV0aG9kPSJnZXQiIGlkPSJTZWxlY3RNaXJyb3IiPgorICAgICAgICA8cD4KKyAgICAgICAgICBPdGhlciBtaXJyb3JzOgorICAgICAgICAgIDxzZWxlY3QgbmFtZT0iUHJlZmVycmVkIj4KKyAgICAgICAgICBbaWYtYW55IGh0dHBdCisgICAgICAgICAgICBbZm9yIGh0dHBdPG9wdGlvbiB2YWx1ZT0iW2h0dHBdIj5baHR0cF08L29wdGlvbj5bZW5kXQorICAgICAgICAgIFtlbmRdCisgICAgICAgICAgW2lmLWFueSBmdHBdCisgICAgICAgICAgICBbZm9yIGZ0cF08b3B0aW9uIHZhbHVlPSJbZnRwXSI+W2Z0cF08L29wdGlvbj5bZW5kXQorICAgICAgICAgIFtlbmRdCisgICAgICAgICAgW2lmLWFueSBiYWNrdXBdCisgICAgICAgICAgICBbZm9yIGJhY2t1cF08b3B0aW9uIHZhbHVlPSJbYmFja3VwXSI+W2JhY2t1cF0gKGJhY2t1cCk8L29wdGlvbj5bZW5kXQorICAgICAgICAgIFtlbmRdCisgICAgICAgICAgPC9zZWxlY3Q+CisgICAgICAgICAgPGlucHV0IHR5cGU9InN1Ym1pdCIgdmFsdWU9IkNoYW5nZSI+PC9pbnB1dD4KKyAgICAgICAgPC9wPgorICAgICAgPC9mb3JtPgorCisgICAgICA8cD4KKyAgICAgICAgSXQgaXMgZXNzZW50aWFsIHRoYXQgeW91CisgICAgICAgIDxhIGhyZWY9Imh0dHBzOi8vd3d3LmFwYWNoZS5vcmcvaW5mby92ZXJpZmljYXRpb24uaHRtbCI+dmVyaWZ5IHRoZSBpbnRlZ3JpdHk8L2E+CisgICAgICAgIG9mIGRvd25sb2FkZWQgZmlsZXMsIHByZWZlcmFibHkgdXNpbmcgdGhlIDxjb2RlPlBHUDwvY29kZT4gc2lnbmF0dXJlICg8Y29kZT4qLmFzYzwvY29kZT4gZmlsZXMpOworICAgICAgICBmYWlsaW5nIHRoYXQgdXNpbmcgdGhlIDxjb2RlPlNIQTI1NjwvY29kZT4gaGFzaCAoPGNvZGU+Ki5zaGEyNTY8L2NvZGU+IGNoZWNrc3VtIGZpbGVzKS4KKyAgICAgIDwvcD4KKyAgICAgIDxwPgorICAgICAgICBUaGUgPGEgaHJlZj0iaHR0cHM6Ly93d3cuYXBhY2hlLm9yZy9kaXN0L2NvbW1vbnMvS0VZUyI+S0VZUzwvYT4KKyAgICAgICAgZmlsZSBjb250YWlucyB0aGUgcHVibGljIFBHUCBrZXlzIHVzZWQgYnkgQXBhY2hlIENvbW1vbnMgZGV2ZWxvcGVycworICAgICAgICB0byBzaWduIHJlbGVhc2VzLgorICAgICAgPC9wPgorICAgIDwvc3Vic2VjdGlvbj4KKyAgICA8L3NlY3Rpb24+CisgICAgPHNlY3Rpb24gbmFtZT0iQXBhY2hlIENvbW1vbnMgQ29tcHJlc3MgMS4xOCAiPgorICAgICAgPHN1YnNlY3Rpb24gbmFtZT0iQmluYXJpZXMiPgorICAgICAgICA8dGFibGU+CisgICAgICAgICAgPHRyPgorICAgICAgICAgICAgICA8dGQ+PGEgaHJlZj0iW3ByZWZlcnJlZF0vY29tbW9ucy9jb21wcmVzcy9iaW5hcmllcy9jb21tb25zLWNvbXByZXNzLTEuMTgtYmluLnRhci5neiI+Y29tbW9ucy1jb21wcmVzcy0xLjE4LWJpbi50YXIuZ3o8L2E+PC90ZD4KKyAgICAgICAgICAgICAgPHRkPjxhIGhyZWY9Imh0dHBzOi8vd3d3LmFwYWNoZS5vcmcvZGlzdC9jb21tb25zL2NvbXByZXNzL2JpbmFyaWVzL2NvbW1vbnMtY29tcHJlc3MtMS4xOC1iaW4udGFyLmd6LnNoYTI1NiI+c2hhMjU2PC9hPjwvdGQ+CisgICAgICAgICAgICAgIDx0ZD48YSBocmVmPSJodHRwczovL3d3dy5hcGFjaGUub3JnL2Rpc3QvY29tbW9ucy9jb21wcmVzcy9iaW5hcmllcy9jb21tb25zLWNvbXByZXNzLTEuMTgtYmluLnRhci5nei5hc2MiPnBncDwvYT48L3RkPgorICAgICAgICAgIDwvdHI+CisgICAgICAgICAgPHRyPgorICAgICAgICAgICAgICA8dGQ+PGEgaHJlZj0iW3ByZWZlcnJlZF0vY29tbW9ucy9jb21wcmVzcy9iaW5hcmllcy9jb21tb25zLWNvbXByZXNzLTEuMTgtYmluLnppcCI+Y29tbW9ucy1jb21wcmVzcy0xLjE4LWJpbi56aXA8L2E+PC90ZD4KKyAgICAgICAgICAgICAgPHRkPjxhIGhyZWY9Imh0dHBzOi8vd3d3LmFwYWNoZS5vcmcvZGlzdC9jb21tb25zL2NvbXByZXNzL2JpbmFyaWVzL2NvbW1vbnMtY29tcHJlc3MtMS4xOC1iaW4uemlwLnNoYTI1NiI+c2hhMjU2PC9hPjwvdGQ+CisgICAgICAgICAgICAgIDx0ZD48YSBocmVmPSJodHRwczovL3d3dy5hcGFjaGUub3JnL2Rpc3QvY29tbW9ucy9jb21wcmVzcy9iaW5hcmllcy9jb21tb25zLWNvbXByZXNzLTEuMTgtYmluLnppcC5hc2MiPnBncDwvYT48L3RkPgorICAgICAgICAgIDwvdHI+CisgICAgICAgIDwvdGFibGU+CisgICAgICA8L3N1YnNlY3Rpb24+CisgICAgICA8c3Vic2VjdGlvbiBuYW1lPSJTb3VyY2UiPgorICAgICAgICA8dGFibGU+CisgICAgICAgICAgPHRyPgorICAgICAgICAgICAgICA8dGQ+PGEgaHJlZj0iW3ByZWZlcnJlZF0vY29tbW9ucy9jb21wcmVzcy9zb3VyY2UvY29tbW9ucy1jb21wcmVzcy0xLjE4LXNyYy50YXIuZ3oiPmNvbW1vbnMtY29tcHJlc3MtMS4xOC1zcmMudGFyLmd6PC9hPjwvdGQ+CisgICAgICAgICAgICAgIDx0ZD48YSBocmVmPSJodHRwczovL3d3dy5hcGFjaGUub3JnL2Rpc3QvY29tbW9ucy9jb21wcmVzcy9zb3VyY2UvY29tbW9ucy1jb21wcmVzcy0xLjE4LXNyYy50YXIuZ3ouc2hhMjU2Ij5zaGEyNTY8L2E+PC90ZD4KKyAgICAgICAgICAgICAgPHRkPjxhIGhyZWY9Imh0dHBzOi8vd3d3LmFwYWNoZS5vcmcvZGlzdC9jb21tb25zL2NvbXByZXNzL3NvdXJjZS9jb21tb25zLWNvbXByZXNzLTEuMTgtc3JjLnRhci5nei5hc2MiPnBncDwvYT48L3RkPgorICAgICAgICAgIDwvdHI+CisgICAgICAgICAgPHRyPgorICAgICAgICAgICAgICA8dGQ+PGEgaHJlZj0iW3ByZWZlcnJlZF0vY29tbW9ucy9jb21wcmVzcy9zb3VyY2UvY29tbW9ucy1jb21wcmVzcy0xLjE4LXNyYy56aXAiPmNvbW1vbnMtY29tcHJlc3MtMS4xOC1zcmMuemlwPC9hPjwvdGQ+CisgICAgICAgICAgICAgIDx0ZD48YSBocmVmPSJodHRwczovL3d3dy5hcGFjaGUub3JnL2Rpc3QvY29tbW9ucy9jb21wcmVzcy9zb3VyY2UvY29tbW9ucy1jb21wcmVzcy0xLjE4LXNyYy56aXAuc2hhMjU2Ij5zaGEyNTY8L2E+PC90ZD4KKyAgICAgICAgICAgICAgPHRkPjxhIGhyZWY9Imh0dHBzOi8vd3d3LmFwYWNoZS5vcmcvZGlzdC9jb21tb25zL2NvbXByZXNzL3NvdXJjZS9jb21tb25zLWNvbXByZXNzLTEuMTgtc3JjLnppcC5hc2MiPnBncDwvYT48L3RkPgorICAgICAgICAgIDwvdHI+CisgICAgICAgIDwvdGFibGU+CisgICAgICA8L3N1YnNlY3Rpb24+CisgICAgPC9zZWN0aW9uPgorICAgIDxzZWN0aW9uIG5hbWU9IkFyY2hpdmVzIj4KKyAgICAgICAgPHA+CisgICAgICAgICAgT2xkZXIgcmVsZWFzZXMgY2FuIGJlIG9idGFpbmVkIGZyb20gdGhlIGFyY2hpdmVzLgorICAgICAgICA8L3A+CisgICAgICAgIDx1bD4KKyAgICAgICAgICA8bGkgY2xhc3M9ImRvd25sb2FkIj48YSBocmVmPSJbcHJlZmVycmVkXS9jb21tb25zL2NvbXByZXNzLyI+YnJvd3NlIGRvd25sb2FkIGFyZWE8L2E+PC9saT4KKyAgICAgICAgICA8bGk+PGEgaHJlZj0iaHR0cHM6Ly9hcmNoaXZlLmFwYWNoZS5vcmcvZGlzdC9jb21tb25zL2NvbXByZXNzLyI+YXJjaGl2ZXMuLi48L2E+PC9saT4KKyAgICAgICAgPC91bD4KKyAgICA8L3NlY3Rpb24+CisgIDwvYm9keT4KKzwvZG9jdW1lbnQ+CmRpZmYgLS1naXQgYS9zcmMvc2l0ZS94ZG9jL2V4YW1wbGVzLnhtbCBiL3NyYy9zaXRlL3hkb2MvZXhhbXBsZXMueG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgxYWY0NGIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvc2l0ZS94ZG9jL2V4YW1wbGVzLnhtbApAQCAtMCwwICsxLDEyNDggQEAKKzw/eG1sIHZlcnNpb249IjEuMCI/PgorPCEtLQorCisgICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAgIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAgICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorCisgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisKKyAgIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAgIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAgIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAgIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorCistLT4KKzxkb2N1bWVudD4KKyAgPHByb3BlcnRpZXM+CisgICAgPHRpdGxlPkNvbW1vbnMgQ29tcHJlc3MgVXNlciBHdWlkZTwvdGl0bGU+CisgICAgPGF1dGhvciBlbWFpbD0iZGV2QGNvbW1vbnMuYXBhY2hlLm9yZyI+Q29tbW9ucyBEb2N1bWVudGF0aW9uIFRlYW08L2F1dGhvcj4KKyAgPC9wcm9wZXJ0aWVzPgorICA8Ym9keT4KKyAgICA8c2VjdGlvbiBuYW1lPSJHZW5lcmFsIE5vdGVzIj4KKworICAgICAgPHN1YnNlY3Rpb24gbmFtZT0iQXJjaGl2ZXJzIGFuZCBDb21wcmVzc29ycyI+CisgICAgICAgIDxwPkNvbW1vbnMgQ29tcHJlc3MgY2FsbHMgYWxsIGZvcm1hdHMgdGhhdCBjb21wcmVzcyBhIHNpbmdsZQorICAgICAgICBzdHJlYW0gb2YgZGF0YSBjb21wcmVzc29yIGZvcm1hdHMgd2hpbGUgYWxsIGZvcm1hdHMgdGhhdAorICAgICAgICBjb2xsZWN0IG11bHRpcGxlIGVudHJpZXMgaW5zaWRlIGEgc2luZ2xlIChwb3RlbnRpYWxseQorICAgICAgICBjb21wcmVzc2VkKSBhcmNoaXZlIGFyZSBhcmNoaXZlciBmb3JtYXRzLjwvcD4KKworICAgICAgICA8cD5UaGUgY29tcHJlc3NvciBmb3JtYXRzIHN1cHBvcnRlZCBhcmUgZ3ppcCwgYnppcDIsIHh6LCBsem1hLAorICAgICAgICBQYWNrMjAwLCBERUZMQVRFLCBCcm90bGksIERFRkxBVEU2NCwgWlN0YW5kYXJkIGFuZCBaLCB0aGUgYXJjaGl2ZXIgZm9ybWF0cyBhcmUgN3osIGFyLCBhcmosCisgICAgICAgIGNwaW8sIGR1bXAsIHRhciBhbmQgemlwLiAgUGFjazIwMCBpcyBhIHNwZWNpYWwgY2FzZSBhcyBpdCBjYW4KKyAgICAgICAgb25seSBjb21wcmVzcyBKQVIgZmlsZXMuPC9wPgorCisgICAgICAgIDxwPldlIGN1cnJlbnRseSBvbmx5IHByb3ZpZGUgcmVhZCBzdXBwb3J0IGZvciBhcmosCisgICAgICAgIGR1bXAsIEJyb3RsaSwgREVGTEFURTY0IGFuZCBaLiAgYXJqIGNhbiBvbmx5IHJlYWQgdW5jb21wcmVzc2VkIGFyY2hpdmVzLCA3eiBjYW4gcmVhZAorICAgICAgICBhcmNoaXZlcyB3aXRoIG1hbnkgY29tcHJlc3Npb24gYW5kIGVuY3J5cHRpb24gYWxnb3JpdGhtcworICAgICAgICBzdXBwb3J0ZWQgYnkgN3ogYnV0IGRvZXNuJ3Qgc3VwcG9ydCBlbmNyeXB0aW9uIHdoZW4gd3JpdGluZworICAgICAgICBhcmNoaXZlcy48L3A+CisgICAgICA8L3N1YnNlY3Rpb24+CisKKyAgICAgIDxzdWJzZWN0aW9uIG5hbWU9IkJ1ZmZlcmluZyI+CisgICAgICAgIDxwPlRoZSBzdHJlYW0gY2xhc3NlcyBhbGwgd3JhcCBhcm91bmQgc3RyZWFtcyBwcm92aWRlZCBieSB0aGUKKyAgICAgICAgICBjYWxsaW5nIGNvZGUgYW5kIHRoZXkgd29yayBvbiB0aGVtIGRpcmVjdGx5IHdpdGhvdXQgYW55CisgICAgICAgICAgYWRkaXRpb25hbCBidWZmZXJpbmcuICBPbiB0aGUgb3RoZXIgaGFuZCBtb3N0IG9mIHRoZW0gd2lsbAorICAgICAgICAgIGJlbmVmaXQgZnJvbSBidWZmZXJpbmcgc28gaXQgaXMgaGlnaGx5IHJlY29tbWVuZGVkIHRoYXQKKyAgICAgICAgICB1c2VycyB3cmFwIHRoZWlyIHN0cmVhbQorICAgICAgICAgIGluIDxjb2RlPkJ1ZmZlcmVkPGVtPihJbnxPdXQpPC9lbT5wdXRTdHJlYW08L2NvZGU+cyBiZWZvcmUKKyAgICAgICAgICB1c2luZyB0aGUgQ29tbW9ucyBDb21wcmVzcyBBUEkuPC9wPgorCisgICAgICA8L3N1YnNlY3Rpb24+CisKKyAgICAgIDxzdWJzZWN0aW9uIG5hbWU9IkZhY3RvcmllcyI+CisKKyAgICAgICAgPHA+Q29tcHJlc3MgcHJvdmlkZXMgZmFjdG9yeSBtZXRob2RzIHRvIGNyZWF0ZSBpbnB1dC9vdXRwdXQKKyAgICAgICAgICBzdHJlYW1zIGJhc2VkIG9uIHRoZSBuYW1lcyBvZiB0aGUgY29tcHJlc3NvciBvciBhcmNoaXZlcgorICAgICAgICAgIGZvcm1hdCBhcyB3ZWxsIGFzIGZhY3RvcnkgbWV0aG9kcyB0aGF0IHRyeSB0byBndWVzcyB0aGUKKyAgICAgICAgICBmb3JtYXQgb2YgYW4gaW5wdXQgc3RyZWFtLjwvcD4KKworICAgICAgICA8cD5UbyBjcmVhdGUgYSBjb21wcmVzc29yIHdyaXRpbmcgdG8gYSBnaXZlbiBvdXRwdXQgYnkgdXNpbmcKKyAgICAgICAgICB0aGUgYWxnb3JpdGhtIG5hbWU6PC9wPgorICAgICAgICA8c291cmNlPjwhW0NEQVRBWworQ29tcHJlc3Nvck91dHB1dFN0cmVhbSBnemlwcGVkT3V0ID0gbmV3IENvbXByZXNzb3JTdHJlYW1GYWN0b3J5KCkKKyAgICAuY3JlYXRlQ29tcHJlc3Nvck91dHB1dFN0cmVhbShDb21wcmVzc29yU3RyZWFtRmFjdG9yeS5HWklQLCBteU91dHB1dFN0cmVhbSk7CitdXT48L3NvdXJjZT4KKworICAgICAgICA8cD5NYWtlIHRoZSBmYWN0b3J5IGd1ZXNzIHRoZSBpbnB1dCBmb3JtYXQgZm9yIGEgZ2l2ZW4KKyAgICAgICAgYXJjaGl2ZXIgc3RyZWFtOjwvcD4KKyAgICAgICAgPHNvdXJjZT48IVtDREFUQVsKK0FyY2hpdmVJbnB1dFN0cmVhbSBpbnB1dCA9IG5ldyBBcmNoaXZlU3RyZWFtRmFjdG9yeSgpCisgICAgLmNyZWF0ZUFyY2hpdmVJbnB1dFN0cmVhbShvcmlnaW5hbElucHV0KTsKK11dPjwvc291cmNlPgorCisgICAgICAgIDxwPk1ha2UgdGhlIGZhY3RvcnkgZ3Vlc3MgdGhlIGlucHV0IGZvcm1hdCBmb3IgYSBnaXZlbgorICAgICAgICBjb21wcmVzc29yIHN0cmVhbTo8L3A+CisgICAgICAgIDxzb3VyY2U+PCFbQ0RBVEFbCitDb21wcmVzc29ySW5wdXRTdHJlYW0gaW5wdXQgPSBuZXcgQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkoKQorICAgIC5jcmVhdGVDb21wcmVzc29ySW5wdXRTdHJlYW0ob3JpZ2luYWxJbnB1dCk7CitdXT48L3NvdXJjZT4KKworICAgICAgICA8cD5Ob3RlIHRoYXQgdGhlcmUgaXMgbm8gd2F5IHRvIGRldGVjdCB0aGUgbHptYSBvciBCcm90bGkgZm9ybWF0cyBzbyBvbmx5CisgICAgICAgIHRoZSB0d28tYXJnIHZlcnNpb24gb2YKKyAgICAgICAgPGNvZGU+Y3JlYXRlQ29tcHJlc3NvcklucHV0U3RyZWFtPC9jb2RlPiBjYW4gYmUgdXNlZC4gIFByaW9yCisgICAgICAgIHRvIENvbXByZXNzIDEuOSB0aGUgLlogZm9ybWF0IGhhc24ndCBiZWVuIGF1dG8tZGV0ZWN0ZWQKKyAgICAgICAgZWl0aGVyLjwvcD4KKworICAgICAgPC9zdWJzZWN0aW9uPgorCisgICAgICA8c3Vic2VjdGlvbiBuYW1lPSJSZXN0cmljdGluZyBNZW1vcnkgVXNhZ2UiPgorICAgICAgICA8cD5TdGFydGluZyB3aXRoIENvbXByZXNzIDEuMTQKKyAgICAgICAgPGNvZGU+Q29tcHJlc3NvclN0cmVhbUZhY3Rvcnk8L2NvZGU+IGhhcyBhbiBvcHRpb25hbAorICAgICAgICBjb25zdHJ1Y3RvciBhcmd1bWVudCB0aGF0IGNhbiBiZSB1c2VkIHRvIHNldCBhbiB1cHBlciBsaW1pdCBvZgorICAgICAgICBtZW1vcnkgdGhhdCBtYXkgYmUgdXNlZCB3aGlsZSBkZWNvbXByZXNzaW5nIG9yIGNvbXByZXNzaW5nIGEKKyAgICAgICAgc3RyZWFtLiBBcyBvZiAxLjE0IHRoaXMgc2V0dGluZyBvbmx5IGFmZmVjdHMgZGVjb21wcmVzc2luZyBaLAorICAgICAgICBYWiBhbmQgTFpNQSBjb21wcmVzc2VkIHN0cmVhbXMuPC9wPgorICAgICAgICA8cD5Gb3IgdGhlIFNuYXBweSBhbmQgTFo0IGZvcm1hdHMgdGhlIGFtb3VudCBvZiBtZW1vcnkgdXNlZAorICAgICAgICBkdXJpbmcgY29tcHJlc3Npb24gaXMgZGlyZWN0bHkgcHJvcG9ydGlvbmFsIHRvIHRoZSB3aW5kb3cKKyAgICAgICAgc2l6ZS48L3A+CisgICAgICA8L3N1YnNlY3Rpb24+CisKKyAgICAgIDxzdWJzZWN0aW9uIG5hbWU9IlN0YXRpc3RpY3MiPgorICAgICAgICA8cD5TdGFydGluZyB3aXRoIENvbXByZXNzIDEuMTcgbW9zdCBvZiB0aGUKKyAgICAgICAgPGNvZGU+Q29tcHJlc3NvcklucHV0U3RyZWFtPC9jb2RlPiBpbXBsZW1lbnRhdGlvbnMgYXMgd2VsbCBhcworICAgICAgICA8Y29kZT5aaXBBcmNoaXZlSW5wdXRTdHJlYW08L2NvZGU+IGFuZCBhbGwgc3RyZWFtcyByZXR1cm5lZCBieQorICAgICAgICA8Y29kZT5aaXBGaWxlLmdldElucHV0U3RyZWFtPC9jb2RlPiBpbXBsZW1lbnQgdGhlCisgICAgICAgIDxjb2RlPklucHV0U3RyZWFtU3RhdGlzdGljczwvY29kZT4KKyAgICAgICAgaW50ZXJmYWNlLiA8Y29kZT5TZXZlblpGaWxlPC9jb2RlPiBwcm92aWRlcyBzdGF0aXN0aWNzIGZvciB0aGUKKyAgICAgICAgY3VycmVudCBlbnRyeSB2aWEgdGhlCisgICAgICAgIDxjb2RlPmdldFN0YXRpc3RpY3NGb3JDdXJyZW50RW50cnk8L2NvZGU+IG1ldGhvZC4gVGhpcworICAgICAgICBpbnRlcmZhY2UgY2FuIGJlIHVzZWQgdG8gdHJhY2sgcHJvZ3Jlc3Mgd2hpbGUgZXh0cmFjdGluZyBhCisgICAgICAgIHN0cmVhbSBvciB0byBkZXRlY3QgcG90ZW50aWFsIDxhCisgICAgICAgIGhyZWY9Imh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1ppcF9ib21iIj56aXAgYm9tYnM8L2E+CisgICAgICAgIHdoZW4gdGhlIGNvbXByZXNzaW9uIHJhdGlvbiBiZWNvbWVzIHN1c3BpY2lvdXNseSBsYXJnZS48L3A+CisgICAgICA8L3N1YnNlY3Rpb24+CisKKyAgICA8L3NlY3Rpb24+CisgICAgPHNlY3Rpb24gbmFtZT0iQXJjaGl2ZXJzIj4KKworICAgICAgPHN1YnNlY3Rpb24gbmFtZT0iVW5zdXBwb3J0ZWQgRmVhdHVyZXMiPgorICAgICAgICA8cD5NYW55IG9mIHRoZSBzdXBwb3J0ZWQgZm9ybWF0cyBoYXZlIGRldmVsb3BlZCBkaWZmZXJlbnQKKyAgICAgICAgZGlhbGVjdHMgYW5kIGV4dGVuc2lvbnMgYW5kIHNvbWUgZm9ybWF0cyBhbGxvdyBmb3IgZmVhdHVyZXMKKyAgICAgICAgKG5vdCB5ZXQpIHN1cHBvcnRlZCBieSBDb21tb25zIENvbXByZXNzLjwvcD4KKworICAgICAgICA8cD5UaGUgPGNvZGU+QXJjaGl2ZUlucHV0U3RyZWFtPC9jb2RlPiBjbGFzcyBwcm92aWRlcyBhIG1ldGhvZAorICAgICAgICA8Y29kZT5jYW5SZWFkRW50cnlEYXRhPC9jb2RlPiB0aGF0IHdpbGwgcmV0dXJuIGZhbHNlIGlmCisgICAgICAgIENvbW1vbnMgQ29tcHJlc3MgY2FuIGRldGVjdCB0aGF0IGFuIGFyY2hpdmUgdXNlcyBhIGZlYXR1cmUKKyAgICAgICAgdGhhdCBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoZSBjdXJyZW50IGltcGxlbWVudGF0aW9uLiAgSWYgaXQKKyAgICAgICAgcmV0dXJucyBmYWxzZSB5b3Ugc2hvdWxkIG5vdCB0cnkgdG8gcmVhZCB0aGUgZW50cnkgYnV0IHNraXAKKyAgICAgICAgb3ZlciBpdC48L3A+CisKKyAgICAgIDwvc3Vic2VjdGlvbj4KKworICAgICAgPHN1YnNlY3Rpb24gbmFtZT0iRW50cnkgTmFtZXMiPgorICAgICAgICA8cD5BbGwgYXJjaGl2ZSBmb3JtYXRzIHByb3ZpZGUgbWV0YSBkYXRhIGFib3V0IHRoZSBpbmRpdmlkdWFsCisgICAgICAgIGFyY2hpdmUgZW50cmllcyB2aWEgaW5zdGFuY2VzIG9mIDxjb2RlPkFyY2hpdmVFbnRyeTwvY29kZT4gKG9yCisgICAgICAgIHJhdGhlciBzdWJjbGFzc2VzIG9mIGl0KS4gV2hlbiByZWFkaW5nIGZyb20gYW4gYXJjaGl2ZSB0aGUKKyAgICAgICAgaW5mb3JtYXRpb24gcHJvdmlkZWQgdGhlIDxjb2RlPmdldE5hbWU8L2NvZGU+IG1ldGhvZCBpcyB0aGUKKyAgICAgICAgcmF3IG5hbWUgYXMgc3RvcmVkIGluc2lkZSBvZiB0aGUgYXJjaGl2ZS4gVGhlcmUgaXMgbm8KKyAgICAgICAgZ3VhcmFudGVlIHRoZSBuYW1lIHJlcHJlc2VudHMgYSByZWxhdGl2ZSBmaWxlIG5hbWUgb3IgZXZlbiBhCisgICAgICAgIHZhbGlkIGZpbGUgbmFtZSBvbiB5b3VyIHRhcmdldCBvcGVyYXRpbmcgc3lzdGVtIGF0IGFsbC4gWW91CisgICAgICAgIHNob3VsZCBkb3VibGUgY2hlY2sgdGhlIG91dGNvbWUgd2hlbiB5b3UgdHJ5IHRvIGNyZWF0ZSBmaWxlCisgICAgICAgIG5hbWVzIGZyb20gZW50cnkgbmFtZXMuPC9wPgorICAgICAgPC9zdWJzZWN0aW9uPgorCisgICAgICA8c3Vic2VjdGlvbiBuYW1lPSJDb21tb24gRXh0cmFjdGlvbiBMb2dpYyI+CisgICAgICAgIDxwPkFwYXJ0IGZyb20gN3ogYWxsIGZvcm1hdHMgcHJvdmlkZSBhIHN1YmNsYXNzIG9mCisgICAgICAgIDxjb2RlPkFyY2hpdmVJbnB1dFN0cmVhbTwvY29kZT4gdGhhdCBjYW4gYmUgdXNlZCB0byBjcmVhdGUgYW4KKyAgICAgICAgYXJjaGl2ZS4gRm9yIDd6IDxjb2RlPlNldmVuWkZpbGU8L2NvZGU+IHByb3ZpZGVzIGEgc2ltaWxhciBBUEkKKyAgICAgICAgdGhhdCBkb2VzIG5vdCByZXByZXNlbnQgYSBzdHJlYW0gYXMgb3VyIGltcGxlbWVudGF0aW9uCisgICAgICAgIHJlcXVpcmVzIHJhbmRvbSBhY2Nlc3MgdG8gdGhlIGlucHV0IGFuZCBjYW5ub3QgYmUgdXNlZCBmb3IKKyAgICAgICAgZ2VuZXJhbCBzdHJlYW1zLiBUaGUgWklQIGltcGxlbWVudGF0aW9uIGNhbiBiZW5lZml0IGEgbG90IGZyb20KKyAgICAgICAgcmFuZG9tIGFjY2VzcyBhcyB3ZWxsLCBzZWUgdGhlIDxhCisgICAgICAgIGhyZWY9InppcC5odG1sI1ppcEFyY2hpdmVJbnB1dFN0cmVhbV92c19aaXBGaWxlIj56aXAKKyAgICAgICAgcGFnZTwvYT4gZm9yIGRldGFpbHMuPC9wPgorCisgICAgICAgIDxwPkFzc3VtaW5nIHlvdSB3YW50IHRvIGV4dHJhY3QgYW4gYXJjaGl2ZSB0byBhIHRhcmdldAorICAgICAgICBkaXJlY3RvcnkgeW91J2QgY2FsbCA8Y29kZT5nZXROZXh0RW50cnk8L2NvZGU+LCB2ZXJpZnkgdGhlCisgICAgICAgIGVudHJ5IGNhbiBiZSByZWFkLCBjb25zdHJ1Y3QgYSBzYW5lIGZpbGUgbmFtZSBmcm9tIHRoZSBlbnRyeSdzCisgICAgICAgIG5hbWUsIGNyZWF0ZSBhIDxjb2RlZT5GaWxlPC9jb2RlZT4gYW5kIHdyaXRlIGFsbCBjb250ZW50cyB0bworICAgICAgICBpdCAtIGhlcmUgPGNvZGU+SU9VdGlscy5jb3B5PC9jb2RlPiBtYXkgY29tZSBoYW5keS4gWW91IGRvIHNvCisgICAgICAgIGZvciBldmVyeSBlbnRyeSB1bnRpbCA8Y29kZT5nZXROZXh0RW50cnk8L2NvZGU+IHJldHVybnMKKyAgICAgICAgPGNvZGU+bnVsbDwvY29kZT4uPC9wPgorCisgICAgICAgIDxwPkEgc2tlbGV0b24gbWlnaHQgbG9vayBsaWtlOjwvcD4KKworICAgICAgICA8c291cmNlPjwhW0NEQVRBWworRmlsZSB0YXJnZXREaXIgPSAuLi4KK3RyeSAoQXJjaGl2ZUlucHV0U3RyZWFtIGkgPSAuLi4gY3JlYXRlIHRoZSBzdHJlYW0gZm9yIHlvdXIgZm9ybWF0LCB1c2UgYnVmZmVyaW5nLi4uKSB7CisgICAgQXJjaGl2ZUVudHJ5IGVudHJ5ID0gbnVsbDsKKyAgICB3aGlsZSAoKGVudHJ5ID0gaS5nZXROZXh0RW50cnkoKSkgIT0gbnVsbCkgeworICAgICAgICBpZiAoIWkuY2FuUmVhZEVudHJ5RGF0YShlbnRyeSkpIHsKKyAgICAgICAgICAgIC8vIGxvZyBzb21ldGhpbmc/CisgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgfQorICAgICAgICBTdHJpbmcgbmFtZSA9IGZpbGVOYW1lKHRhcmdldERpciwgZW50cnkpOworICAgICAgICBGaWxlIGYgPSBuZXcgRmlsZShuYW1lKTsKKyAgICAgICAgaWYgKGVudHJ5LmlzRGlyZWN0b3J5KCkpIHsKKyAgICAgICAgICAgIGlmICghZi5pc0RpcmVjdG9yeSgpICYmICFmLm1rZGlycygpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJmYWlsZWQgdG8gY3JlYXRlIGRpcmVjdG9yeSAiICsgZik7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBGaWxlIHBhcmVudCA9IGYuZ2V0UGFyZW50RmlsZSgpOworICAgICAgICAgICAgaWYgKCFwYXJlbnQuaXNEaXJlY3RvcnkoKSAmJiAhcGFyZW50Lm1rZGlycygpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJmYWlsZWQgdG8gY3JlYXRlIGRpcmVjdG9yeSAiICsgcGFyZW50KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRyeSAoT3V0cHV0U3RyZWFtIG8gPSBGaWxlcy5uZXdPdXRwdXRTdHJlYW0oZi50b1BhdGgoKSkpIHsKKyAgICAgICAgICAgICAgICBJT1V0aWxzLmNvcHkoaSwgbyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9Cit9CitdXT48L3NvdXJjZT4KKworICAgICAgICA8cD53aGVyZSB0aGUgaHlwb3RoZXRpY2FsIDxjb2RlPmZpbGVOYW1lPC9jb2RlPiBtZXRob2QgaXMKKyAgICAgICAgd3JpdHRlbiBieSB5b3UgYW5kIHByb3ZpZGVzIHRoZSBhYnNvbHV0ZSBuYW1lIGZvciB0aGUgZmlsZQorICAgICAgICB0aGF0IGlzIGdvaW5nIHRvIGJlIHdyaXR0ZW4gb24gZGlzay4gSGVyZSB5b3Ugc2hvdWxkIHBlcmZvcm0KKyAgICAgICAgY2hlY2tzIHRoYXQgZW5zdXJlIHRoZSByZXN1bHRpbmcgZmlsZSBuYW1lIGFjdHVhbGx5IGlzIGEgdmFsaWQKKyAgICAgICAgZmlsZSBuYW1lIG9uIHlvdXIgb3BlcmF0aW5nIHN5c3RlbSBvciBiZWxvbmdzIHRvIGEgZmlsZSBpbnNpZGUKKyAgICAgICAgb2YgPGNvZGU+dGFyZ2V0RGlyPC9jb2RlPiB3aGVuIHVzaW5nIHRoZSBlbnRyeSdzIG5hbWUgYXMKKyAgICAgICAgaW5wdXQuPC9wPgorCisgICAgICAgIDxwPklmIHlvdSB3YW50IHRvIGNvbWJpbmUgYW4gYXJjaGl2ZSBmb3JtYXQgd2l0aCBhIGNvbXByZXNzaW9uCisgICAgICAgIGZvcm1hdCAtIGxpa2Ugd2hlbiByZWFkaW5nIGEgInRhci5neiIgZmlsZSAtIHlvdSB3cmFwIHRoZQorICAgICAgICA8Y29kZT5BcmNoaXZlSW5wdXRTdHJlYW08L2NvZGU+IGFyb3VuZAorICAgICAgICA8Y29kZT5Db21wcmVzc29ySW5wdXRTdHJlYW08L2NvZGU+IGZvciBleGFtcGxlOjwvcD4KKworICAgICAgICA8c291cmNlPjwhW0NEQVRBWwordHJ5IChJbnB1dFN0cmVhbSBmaSA9IEZpbGVzLm5ld0lucHV0U3RyZWFtKFBhdGhzLmdldCgibXkudGFyLmd6IikpOworICAgICBJbnB1dFN0cmVhbSBiaSA9IG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKGZpKTsKKyAgICAgSW5wdXRTdHJlYW0gZ3ppID0gbmV3IEd6aXBDb21wcmVzc29ySW5wdXRTdHJlYW0oYmkpOworICAgICBBcmNoaXZlSW5wdXRTdHJlYW0gbyA9IG5ldyBUYXJBcmNoaXZlSW5wdXRTdHJlYW0oZ3ppKSkgeworfQorXV0+PC9zb3VyY2U+CisKKyAgICAgIDwvc3Vic2VjdGlvbj4KKworICAgICAgPHN1YnNlY3Rpb24gbmFtZT0iQ29tbW9uIEFyY2hpdmFsIExvZ2ljIj4KKyAgICAgICAgPHA+QXBhcnQgZnJvbSA3eiBhbGwgZm9ybWF0cyB0aGF0IHN1cHBvcnQgd3JpdGluZyBwcm92aWRlIGEKKyAgICAgICAgc3ViY2xhc3Mgb2YgPGNvZGU+QXJjaGl2ZU91dHB1dFN0cmVhbTwvY29kZT4gdGhhdCBjYW4gYmUgdXNlZAorICAgICAgICB0byBjcmVhdGUgYW4gYXJjaGl2ZS4gRm9yIDd6IDxjb2RlPlNldmVuWk91dHB1dEZpbGU8L2NvZGU+CisgICAgICAgIHByb3ZpZGVzIGEgc2ltaWxhciBBUEkgdGhhdCBkb2VzIG5vdCByZXByZXNlbnQgYSBzdHJlYW0gYXMgb3VyCisgICAgICAgIGltcGxlbWVudGF0aW9uIHJlcXVpcmVzIHJhbmRvbSBhY2Nlc3MgdG8gdGhlIG91dHB1dCBhbmQgY2Fubm90CisgICAgICAgIGJlIHVzZWQgZm9yIGdlbmVyYWwgc3RyZWFtcy4gVGhlCisgICAgICAgIDxjb2RlPlppcEFyY2hpdmVPdXRwdXRTdHJlYW08L2NvZGU+IGNsYXNzIHdpbGwgYmVuZWZpdCBmcm9tCisgICAgICAgIHJhbmRvbSBhY2Nlc3MgYXMgd2VsbCBidXQgY2FuIGJlIHVzZWQgZm9yIG5vbi1zZWVrYWJsZSBzdHJlYW1zCisgICAgICAgIC0gYnV0IG5vdCBhbGwgZmVhdHVyZXMgd2lsbCBiZSBhdmFpbGFibGUgYW5kIHRoZSBhcmNoaXZlIHNpemUKKyAgICAgICAgbWlnaHQgYmUgc2xpZ2h0bHkgYmlnZ2VyLCBzZWUgPGEKKyAgICAgICAgaHJlZj0iemlwLmh0bWwjWmlwQXJjaGl2ZU91dHB1dFN0cmVhbSI+dGhlIHppcCBwYWdlPC9hPiBmb3IKKyAgICAgICAgZGV0YWlscy48L3A+CisKKyAgICAgICAgPHA+QXNzdW1pbmcgeW91IHdhbnQgdG8gYWRkIGEgY29sbGVjdGlvbiBvZiBmaWxlcyB0byBhbgorICAgICAgICBhcmNoaXZlLCB5b3UgY2FuIGZpcnN0IHVzZSA8Y29kZT5jcmVhdGVBcmNoaXZlRW50cnk8L2NvZGU+IGZvcgorICAgICAgICBlYWNoIGZpbGUuIEluIGdlbmVyYWwgdGhpcyB3aWxsIHNldCBhIGZldyBmbGFncyAodXN1YWxseSB0aGUKKyAgICAgICAgbGFzdCBtb2RpZmllZCB0aW1lLCB0aGUgc2l6ZSBhbmQgdGhlIGluZm9ybWF0aW9uIHdoZXRoZXIgdGhpcworICAgICAgICBpcyBhIGZpbGUgb3IgZGlyZWN0b3J5KSBiYXNlZCBvbiB0aGUgPGNvZGU+RmlsZTwvY29kZT4KKyAgICAgICAgaW5zdGFuY2UuIEFsdGVybmF0aXZlbHkgeW91IGNhbiBjcmVhdGUgdGhlCisgICAgICAgIDxjb2RlPkFyY2hpdmVFbnRyeTwvY29kZT4gc3ViY2xhc3MgY29ycmVzcG9uZGluZyB0byB5b3VyCisgICAgICAgIGZvcm1hdCBkaXJlY3RseS4gT2Z0ZW4geW91IG1heSB3YW50IHRvIHNldCBhZGRpdGlvbmFsIGZsYWdzCisgICAgICAgIGxpa2UgZmlsZSBwZXJtaXNzaW9ucyBvciBvd25lciBpbmZvcm1hdGlvbiBiZWZvcmUgYWRkaW5nIHRoZQorICAgICAgICBlbnRyeSB0byB0aGUgYXJjaGl2ZS48L3A+CisKKyAgICAgICAgPHA+TmV4dCB5b3UgdXNlIDxjb2RlPnB1dEFyY2hpdmVFbnRyeTwvY29kZT4gaW4gb3JkZXIgdG8gYWRkCisgICAgICAgIHRoZSBlbnRyeSBhbmQgdGhlbiBzdGFydCB1c2luZyA8Y29kZT53cml0ZTwvY29kZT4gdG8gYWRkIHRoZQorICAgICAgICBjb250ZW50IG9mIHRoZSBlbnRyeSAtIGhlcmUgPGNvZGU+SU9VdGlscy5jb3B5PC9jb2RlPiBtYXkKKyAgICAgICAgY29tZSBoYW5keS4gRmluYWxseSB5b3UgaW52b2tlCisgICAgICAgIDxjb2RlPmNsb3NlQXJjaGl2ZUVudHJ5PC9jb2RlPiBvbmNlIHlvdSd2ZSB3cml0dGVuIGFsbCBjb250ZW50CisgICAgICAgIGFuZCBiZWZvcmUgeW91IGFkZCB0aGUgbmV4dCBlbnRyeS48L3A+CisKKyAgICAgICAgPHA+T25jZSBhbGwgZW50cmllcyBoYXZlIGJlZW4gYWRkZWQgeW91J2QgaW52b2tlCisgICAgICAgIDxjb2RlPmZpbmlzaDwvY29kZT4gYW5kIGZpbmFsbHkgPGNvZGU+Y2xvc2U8L2NvZGU+IHRoZQorICAgICAgICBzdHJlYW0uPC9wPgorCisgICAgICAgIDxwPkEgc2tlbGV0b24gbWlnaHQgbG9vayBsaWtlOjwvcD4KKworICAgICAgICA8c291cmNlPjwhW0NEQVRBWworQ29sbGVjdGlvbjxGaWxlPiBmaWxlc1RvQXJjaGl2ZSA9IC4uLgordHJ5IChBcmNoaXZlT3V0cHV0U3RyZWFtIG8gPSAuLi4gY3JlYXRlIHRoZSBzdHJlYW0gZm9yIHlvdXIgZm9ybWF0IC4uLikgeworICAgIGZvciAoRmlsZSBmIDogZmlsZXNUb0FyY2hpdmUpIHsKKyAgICAgICAgLy8gbWF5YmUgc2tpcCBkaXJlY3RvcmllcyBmb3IgZm9ybWF0cyBsaWtlIEFSIHRoYXQgZG9uJ3Qgc3RvcmUgZGlyZWN0b3JpZXMKKyAgICAgICAgQXJjaGl2ZUVudHJ5IGVudHJ5ID0gby5jcmVhdGVBcmNoaXZlRW50cnkoZiwgZW50cnlOYW1lKGYpKTsKKyAgICAgICAgLy8gcG90ZW50aWFsbHkgYWRkIG1vcmUgZmxhZ3MgdG8gZW50cnkKKyAgICAgICAgby5wdXRBcmNoaXZlRW50cnkoZW50cnkpOworICAgICAgICBpZiAoZi5pc0ZpbGUoKSkgeworICAgICAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBpID0gRmlsZXMubmV3SW5wdXRTdHJlYW0oZi50b1BhdGgoKSkpIHsKKyAgICAgICAgICAgICAgICBJT1V0aWxzLmNvcHkoaSwgbyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgby5jbG9zZUFyY2hpdmVFbnRyeSgpOworICAgIH0KKyAgICBvdXQuZmluaXNoKCk7Cit9CitdXT48L3NvdXJjZT4KKworICAgICAgICA8cD53aGVyZSB0aGUgaHlwb3RoZXRpY2FsIDxjb2RlPmVudHJ5TmFtZTwvY29kZT4gbWV0aG9kIGlzCisgICAgICAgIHdyaXR0ZW4gYnkgeW91IGFuZCBwcm92aWRlcyB0aGUgbmFtZSBmb3IgdGhlIGVudHJ5IGFzIGl0IGlzCisgICAgICAgIGdvaW5nIHRvIGJlIHdyaXR0ZW4gdG8gdGhlIGFyY2hpdmUuPC9wPgorCisgICAgICAgIDxwPklmIHlvdSB3YW50IHRvIGNvbWJpbmUgYW4gYXJjaGl2ZSBmb3JtYXQgd2l0aCBhIGNvbXByZXNzaW9uCisgICAgICAgIGZvcm1hdCAtIGxpa2Ugd2hlbiBjcmVhdGluZyBhICJ0YXIuZ3oiIGZpbGUgLSB5b3Ugd3JhcCB0aGUKKyAgICAgICAgPGNvZGU+QXJjaGl2ZU91dHB1dFN0cmVhbTwvY29kZT4gYXJvdW5kIGEKKyAgICAgICAgPGNvZGU+Q29tcHJlc3Nvck91dHB1dFN0cmVhbTwvY29kZT4gZm9yIGV4YW1wbGU6PC9wPgorCisgICAgICAgIDxzb3VyY2U+PCFbQ0RBVEFbCit0cnkgKE91dHB1dFN0cmVhbSBmbyA9IEZpbGVzLm5ld091dHB1dFN0cmVhbShQYXRocy5nZXQoIm15LnRhci5neiIpKTsKKyAgICAgT3V0cHV0U3RyZWFtIGd6byA9IG5ldyBHemlwQ29tcHJlc3Nvck91dHB1dFN0cmVhbShmbyk7CisgICAgIEFyY2hpdmVPdXRwdXRTdHJlYW0gbyA9IG5ldyBUYXJBcmNoaXZlT3V0cHV0U3RyZWFtKGd6bykpIHsKK30KK11dPjwvc291cmNlPgorCisgICAgICA8L3N1YnNlY3Rpb24+CisKKyAgICAgIDxzdWJzZWN0aW9uIG5hbWU9Ijd6Ij4KKworICAgICAgICA8cD5Ob3RlIHRoYXQgQ29tbW9ucyBDb21wcmVzcyBjdXJyZW50bHkgb25seSBzdXBwb3J0cyBhIHN1YnNldAorICAgICAgICBvZiBjb21wcmVzc2lvbiBhbmQgZW5jcnlwdGlvbiBhbGdvcml0aG1zIHVzZWQgZm9yIDd6IGFyY2hpdmVzLgorICAgICAgICBGb3Igd3JpdGluZyBvbmx5IHVuY29tcHJlc3NlZCBlbnRyaWVzLCBMWk1BLCBMWk1BMiwgQlpJUDIgYW5kCisgICAgICAgIERlZmxhdGUgYXJlIHN1cHBvcnRlZCAtIGluIGFkZGl0aW9uIHRvIHRob3NlIHJlYWRpbmcgc3VwcG9ydHMKKyAgICAgICAgQUVTLTI1Ni9TSEEtMjU2IGFuZCBERUZMQVRFNjQuPC9wPgorCisgICAgICAgIDxwPk11bHRpcGFydCBhcmNoaXZlcyBhcmUgbm90IHN1cHBvcnRlZCBhdCBhbGwuPC9wPgorCisgICAgICAgIDxwPjd6IGFyY2hpdmVzIGNhbiB1c2UgbXVsdGlwbGUgY29tcHJlc3Npb24gYW5kIGVuY3J5cHRpb24KKyAgICAgICAgbWV0aG9kcyBhcyB3ZWxsIGFzIGZpbHRlcnMgY29tYmluZWQgYXMgYSBwaXBlbGluZSBvZiBtZXRob2RzCisgICAgICAgIGZvciBpdHMgZW50cmllcy4gIFByaW9yIHRvIENvbXByZXNzIDEuOCB5b3UgY291bGQgb25seSBzcGVjaWZ5CisgICAgICAgIGEgc2luZ2xlIG1ldGhvZCB3aGVuIGNyZWF0aW5nIGFyY2hpdmVzIC0gcmVhZGluZyBhcmNoaXZlcworICAgICAgICB1c2luZyBtb3JlIHRoYW4gb25lIG1ldGhvZCBoYXMgYmVlbiBwb3NzaWJsZSBiZWZvcmUuICBTdGFydGluZworICAgICAgICB3aXRoIENvbXByZXNzIDEuOCBpdCBpcyBwb3NzaWJsZSB0byBjb25maWd1cmUgdGhlIGZ1bGwKKyAgICAgICAgcGlwZWxpbmUgdXNpbmcgdGhlIDxjb2RlPnNldENvbnRlbnRNZXRob2RzPC9jb2RlPiBtZXRob2Qgb2YKKyAgICAgICAgPGNvZGU+U2V2ZW5aT3V0cHV0RmlsZTwvY29kZT4uICBNZXRob2RzIGFyZSBzcGVjaWZpZWQgaW4gdGhlCisgICAgICAgIG9yZGVyIHRoZXkgYXBwZWFyIGluc2lkZSB0aGUgcGlwZWxpbmUgd2hlbiBjcmVhdGluZyB0aGUKKyAgICAgICAgYXJjaGl2ZSwgeW91IGNhbiBhbHNvIHNwZWNpZnkgY2VydGFpbiBwYXJhbWV0ZXJzIGZvciBzb21lIG9mCisgICAgICAgIHRoZSBtZXRob2RzIC0gc2VlIHRoZSBKYXZhZG9jcyBvZgorICAgICAgICA8Y29kZT5TZXZlblpNZXRob2RDb25maWd1cmF0aW9uPC9jb2RlPiBmb3IgZGV0YWlscy48L3A+CisKKyAgICAgICAgPHA+V2hlbiByZWFkaW5nIGVudHJpZXMgZnJvbSBhbiBhcmNoaXZlIHRoZQorICAgICAgICA8Y29kZT5nZXRDb250ZW50TWV0aG9kczwvY29kZT4gbWV0aG9kIG9mCisgICAgICAgIDxjb2RlPlNldmVuWkFyY2hpdmVFbnRyeTwvY29kZT4gd2lsbCBwcm9wZXJseSByZXByZXNlbnQgdGhlCisgICAgICAgIGNvbXByZXNzaW9uL2VuY3J5cHRpb24vZmlsdGVyIG1ldGhvZHMgYnV0IG1heSBmYWlsIHRvCisgICAgICAgIGRldGVybWluZSB0aGUgY29uZmlndXJhdGlvbiBvcHRpb25zIHVzZWQuICBBcyBvZiBDb21wcmVzcyAxLjgKKyAgICAgICAgb25seSB0aGUgZGljdGlvbmFyeSBzaXplIHVzZWQgZm9yIExaTUEyIGNhbiBiZSByZWFkLjwvcD4KKworICAgICAgICA8cD5DdXJyZW50bHkgc29saWQgY29tcHJlc3Npb24gLSBjb21wcmVzc2luZyBtdWx0aXBsZSBmaWxlcworICAgICAgICBhcyBhIHNpbmdsZSBibG9jayB0byBiZW5lZml0IGZyb20gcGF0dGVybnMgcmVwZWF0aW5nIGFjY3Jvc3MKKyAgICAgICAgZmlsZXMgLSBpcyBvbmx5IHN1cHBvcnRlZCB3aGVuIHJlYWRpbmcgYXJjaGl2ZXMuICBUaGlzIGFsc28KKyAgICAgICAgbWVhbnMgY29tcHJlc3Npb24gcmF0aW8gd2lsbCBsaWtlbHkgYmUgd29yc2Ugd2hlbiB1c2luZworICAgICAgICBDb21tb25zIENvbXByZXNzIGNvbXBhcmVkIHRvIHRoZSBuYXRpdmUgN3ogZXhlY3V0YWJsZS48L3A+CisKKyAgICAgICAgPHA+UmVhZGluZyBvciB3cml0aW5nIHJlcXVpcmVzIGEKKyAgICAgICAgPGNvZGU+U2Vla2FibGVCeXRlQ2hhbm5lbDwvY29kZT4gdGhhdCB3aWxsIGJlIG9idGFpbmVkCisgICAgICAgIHRyYW5zcGFyZW50bHkgd2hlbiByZWFkaW5nIGZyb20gb3Igd3JpdGluZyB0byBhIGZpbGUuIFRoZQorICAgICAgICBjbGFzcworICAgICAgICA8Y29kZT5vcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuU2Vla2FibGVJbk1lbW9yeUJ5dGVDaGFubmVsPC9jb2RlPgorICAgICAgICBhbGxvd3MgeW91IHRvIHJlYWQgZnJvbSBvciB3cml0ZSB0byBhbiBpbi1tZW1vcnkgYXJjaGl2ZS48L3A+CisKKyAgICAgICAgPHA+QWRkaW5nIGFuIGVudHJ5IHRvIGEgN3ogYXJjaGl2ZTo8L3A+Cis8c291cmNlPjwhW0NEQVRBWworU2V2ZW5aT3V0cHV0RmlsZSBzZXZlblpPdXRwdXQgPSBuZXcgU2V2ZW5aT3V0cHV0RmlsZShmaWxlKTsKK1NldmVuWkFyY2hpdmVFbnRyeSBlbnRyeSA9IHNldmVuWk91dHB1dC5jcmVhdGVBcmNoaXZlRW50cnkoZmlsZVRvQXJjaGl2ZSwgbmFtZSk7CitzZXZlblpPdXRwdXQucHV0QXJjaGl2ZUVudHJ5KGVudHJ5KTsKK3NldmVuWk91dHB1dC53cml0ZShjb250ZW50T2ZFbnRyeSk7CitzZXZlblpPdXRwdXQuY2xvc2VBcmNoaXZlRW50cnkoKTsKK11dPjwvc291cmNlPgorCisgICAgICAgIDxwPlVuY29tcHJlc3NpbmcgYSBnaXZlbiA3eiBhcmNoaXZlICh5b3Ugd291bGQKKyAgICAgICAgICBjZXJ0YWlubHkgYWRkIGV4Y2VwdGlvbiBoYW5kbGluZyBhbmQgbWFrZSBzdXJlIGFsbCBzdHJlYW1zCisgICAgICAgICAgZ2V0IGNsb3NlZCBwcm9wZXJseSk6PC9wPgorPHNvdXJjZT48IVtDREFUQVsKK1NldmVuWkZpbGUgc2V2ZW5aRmlsZSA9IG5ldyBTZXZlblpGaWxlKG5ldyBGaWxlKCJhcmNoaXZlLjd6IikpOworU2V2ZW5aQXJjaGl2ZUVudHJ5IGVudHJ5ID0gc2V2ZW5aRmlsZS5nZXROZXh0RW50cnkoKTsKK2J5dGVbXSBjb250ZW50ID0gbmV3IGJ5dGVbZW50cnkuZ2V0U2l6ZSgpXTsKK0xPT1AgVU5USUwgZW50cnkuZ2V0U2l6ZSgpIEhBUyBCRUVOIFJFQUQgeworICAgIHNldmVuWkZpbGUucmVhZChjb250ZW50LCBvZmZzZXQsIGNvbnRlbnQubGVuZ3RoIC0gb2Zmc2V0KTsKK30KK11dPjwvc291cmNlPgorCisgICAgICAgICAgPHA+VW5jb21wcmVzc2luZyBhIGdpdmVuIGluLW1lbW9yeSA3eiBhcmNoaXZlOjwvcD4KKyAgICAgICAgICA8c291cmNlPjwhW0NEQVRBWworYnl0ZVtdIGlucHV0RGF0YTsgLy8gN3ogYXJjaGl2ZSBjb250ZW50cworU2Vla2FibGVJbk1lbW9yeUJ5dGVDaGFubmVsIGluTWVtb3J5Qnl0ZUNoYW5uZWwgPSBuZXcgU2Vla2FibGVJbk1lbW9yeUJ5dGVDaGFubmVsKGlucHV0RGF0YSk7CitTZXZlblpGaWxlIHNldmVuWkZpbGUgPSBuZXcgU2V2ZW5aRmlsZShpbk1lbW9yeUJ5dGVDaGFubmVsKTsKK1NldmVuWkFyY2hpdmVFbnRyeSBlbnRyeSA9IHNldmVuWkZpbGUuZ2V0TmV4dEVudHJ5KCk7CitzZXZlblpGaWxlLnJlYWQoKTsgIC8vIHJlYWQgY3VycmVudCBlbnRyeSdzIGRhdGEKK11dPjwvc291cmNlPgorCisgICAgICAgICAgPGg0PjxhIG5hbWU9IkVuY3J5cHRlZCA3eiBBcmNoaXZlcyI+PC9hPkVuY3J5cHRlZCA3eiBBcmNoaXZlczwvaDQ+CisKKyAgICAgICAgICA8cD5DdXJyZW50bHkgQ29tcHJlc3Mgc3VwcG9ydHMgcmVhZGluZyBidXQgbm90IHdyaXRpbmcgb2YKKyAgICAgICAgICBlbmNyeXB0ZWQgYXJjaGl2ZXMuIFdoZW4gcmVhZGluZyBhbiBlbmNyeXB0ZWQgYXJjaGl2ZSBhCisgICAgICAgICAgcGFzc3dvcmQgaGFzIHRvIGJlIHByb3ZpZGVkIHRvIG9uZSBvZgorICAgICAgICAgIDxjb2RlPlNldmVuWkZpbGU8L2NvZGU+J3MgY29uc3RydWN0b3JzLiBJZiB5b3UgdHJ5IHRvIHJlYWQKKyAgICAgICAgICBhbiBlbmNyeXB0ZWQgYXJjaGl2ZSB3aXRob3V0IHNwZWNpZnlpbmcgYSBwYXNzd29yZCBhCisgICAgICAgICAgPGNvZGU+UGFzc3dvcmRSZXF1aXJlZEV4Y2VwdGlvbjwvY29kZT4gKGEgc3ViY2xhc3Mgb2YKKyAgICAgICAgICA8Y29kZT5JT0V4Y2VwdGlvbjwvY29kZT4pIHdpbGwgYmUgdGhyb3duLjwvcD4KKworICAgICAgICAgIDxwPldoZW4gc3BlY2lmeWluZyB0aGUgcGFzc3dvcmQgYXMgYSA8Y29kZT5ieXRlW108L2NvZGU+IG9uZQorICAgICAgICAgIGNvbW1vbiBtaXN0YWtlIGlzIHRvIHVzZSB0aGUgd3JvbmcgZW5jb2Rpbmcgd2hlbiBjcmVhdGluZworICAgICAgICAgIHRoZSA8Y29kZT5ieXRlW108L2NvZGU+IGZyb20gYSA8Y29kZT5TdHJpbmc8L2NvZGU+LiBUaGUKKyAgICAgICAgICA8Y29kZT5TZXZlblpGaWxlPC9jb2RlPiBjbGFzcyBleHBlY3RzIHRoZSBieXRlcyB0bworICAgICAgICAgIGNvcnJlc3BvbmQgdG8gdGhlIFVURjE2LUxFIGVuY29kaW5nIG9mIHRoZSBwYXNzd29yZC4gQW4KKyAgICAgICAgICBleGFtcGxlIG9mIHJlYWRpbmcgYW4gZW5jcnlwdGVkIGFyY2hpdmUgaXM8L3A+CisKKzxzb3VyY2U+PCFbQ0RBVEFbCitTZXZlblpGaWxlIHNldmVuWkZpbGUgPSBuZXcgU2V2ZW5aRmlsZShuZXcgRmlsZSgiYXJjaGl2ZS43eiIpLCAic2VjcmV0Ii5nZXRCeXRlcyhTdGFuZGFyZENoYXJzZXRzLlVURl8xNkxFKSk7CitTZXZlblpBcmNoaXZlRW50cnkgZW50cnkgPSBzZXZlblpGaWxlLmdldE5leHRFbnRyeSgpOworYnl0ZVtdIGNvbnRlbnQgPSBuZXcgYnl0ZVtlbnRyeS5nZXRTaXplKCldOworTE9PUCBVTlRJTCBlbnRyeS5nZXRTaXplKCkgSEFTIEJFRU4gUkVBRCB7CisgICAgc2V2ZW5aRmlsZS5yZWFkKGNvbnRlbnQsIG9mZnNldCwgY29udGVudC5sZW5ndGggLSBvZmZzZXQpOworfQorXV0+PC9zb3VyY2U+CisKKyAgICAgICAgPHA+U3RhcnRpbmcgd2l0aCBDb21wcmVzcyAxLjE3IG5ldyBjb25zdHJ1Y3RvcnMgaGF2ZSBiZWVuCisgICAgICAgIGFkZGVkIHRoYXQgYWNjZXB0IHRoZSBwYXNzd29yZCBhcyA8Y29kZT5jaGFyW108L2NvZGU+IHJhdGhlcgorICAgICAgICB0aGFuIGEgPGNvZGU+Ynl0ZVtdPC9jb2RlPi4gV2UgcmVjb21tZW5kIHlvdSB1c2UgdGhlc2UgaW4KKyAgICAgICAgb3JkZXIgdG8gYXZvaWQgdGhlIHByb2JsZW0gYWJvdmUuPC9wPgorCis8c291cmNlPjwhW0NEQVRBWworU2V2ZW5aRmlsZSBzZXZlblpGaWxlID0gbmV3IFNldmVuWkZpbGUobmV3IEZpbGUoImFyY2hpdmUuN3oiKSwgInNlY3JldCIudG9DaGFyQXJyYXkoKSk7CitTZXZlblpBcmNoaXZlRW50cnkgZW50cnkgPSBzZXZlblpGaWxlLmdldE5leHRFbnRyeSgpOworYnl0ZVtdIGNvbnRlbnQgPSBuZXcgYnl0ZVtlbnRyeS5nZXRTaXplKCldOworTE9PUCBVTlRJTCBlbnRyeS5nZXRTaXplKCkgSEFTIEJFRU4gUkVBRCB7CisgICAgc2V2ZW5aRmlsZS5yZWFkKGNvbnRlbnQsIG9mZnNldCwgY29udGVudC5sZW5ndGggLSBvZmZzZXQpOworfQorXV0+PC9zb3VyY2U+CisKKyAgICAgIDwvc3Vic2VjdGlvbj4KKworICAgICAgPHN1YnNlY3Rpb24gbmFtZT0iYXIiPgorCisgICAgICAgIDxwPkluIGFkZGl0aW9uIHRvIHRoZSBpbmZvcm1hdGlvbiBzdG9yZWQKKyAgICAgICAgICBpbiA8Y29kZT5BcmNoaXZlRW50cnk8L2NvZGU+IGEgPGNvZGU+QXJBcmNoaXZlRW50cnk8L2NvZGU+CisgICAgICAgICAgc3RvcmVzIGluZm9ybWF0aW9uIGFib3V0IHRoZSBvd25lciB1c2VyIGFuZCBncm91cCBhcyB3ZWxsIGFzCisgICAgICAgICAgVW5peCBwZXJtaXNzaW9ucy48L3A+CisKKyAgICAgICAgPHA+QWRkaW5nIGFuIGVudHJ5IHRvIGFuIGFyIGFyY2hpdmU6PC9wPgorPHNvdXJjZT48IVtDREFUQVsKK0FyQXJjaGl2ZUVudHJ5IGVudHJ5ID0gbmV3IEFyQXJjaGl2ZUVudHJ5KG5hbWUsIHNpemUpOworYXJPdXRwdXQucHV0QXJjaGl2ZUVudHJ5KGVudHJ5KTsKK2FyT3V0cHV0LndyaXRlKGNvbnRlbnRPZkVudHJ5KTsKK2FyT3V0cHV0LmNsb3NlQXJjaGl2ZUVudHJ5KCk7CitdXT48L3NvdXJjZT4KKworICAgICAgICA8cD5SZWFkaW5nIGVudHJpZXMgZnJvbSBhbiBhciBhcmNoaXZlOjwvcD4KKzxzb3VyY2U+PCFbQ0RBVEFbCitBckFyY2hpdmVFbnRyeSBlbnRyeSA9IChBckFyY2hpdmVFbnRyeSkgYXJJbnB1dC5nZXROZXh0RW50cnkoKTsKK2J5dGVbXSBjb250ZW50ID0gbmV3IGJ5dGVbZW50cnkuZ2V0U2l6ZSgpXTsKK0xPT1AgVU5USUwgZW50cnkuZ2V0U2l6ZSgpIEhBUyBCRUVOIFJFQUQgeworICAgIGFySW5wdXQucmVhZChjb250ZW50LCBvZmZzZXQsIGNvbnRlbnQubGVuZ3RoIC0gb2Zmc2V0KTsKK30KK11dPjwvc291cmNlPgorCisgICAgICAgIDxwPlRyYWRpdGlvbmFsbHkgdGhlIEFSIGZvcm1hdCBkb2Vzbid0IGFsbG93IGZpbGUgbmFtZXMgbG9uZ2VyCisgICAgICAgICAgdGhhbiAxNiBjaGFyYWN0ZXJzLiAgVGhlcmUgYXJlIHR3byB2YXJpYW50cyB0aGF0IGNpcmN1bXZlbnQKKyAgICAgICAgICB0aGlzIGxpbWl0YXRpb24gaW4gZGlmZmVyZW50IHdheXMsIHRoZSBHTlUvU1JWNCBhbmQgdGhlIEJTRAorICAgICAgICAgIHZhcmlhbnQuICBDb21tb25zIENvbXByZXNzIDEuMCB0byAxLjIgY2FuIG9ubHkgcmVhZCBhcmNoaXZlcworICAgICAgICAgIHVzaW5nIHRoZSBHTlUvU1JWNCB2YXJpYW50LCBzdXBwb3J0IGZvciB0aGUgQlNEIHZhcmlhbnQgaGFzCisgICAgICAgICAgYmVlbiBhZGRlZCBpbiBDb21tb25zIENvbXByZXNzIDEuMy4gIENvbW1vbnMgQ29tcHJlc3MgMS4zCisgICAgICAgICAgYWxzbyBvcHRpb25hbGx5IHN1cHBvcnRzIHdyaXRpbmcgYXJjaGl2ZXMgd2l0aCBmaWxlIG5hbWVzCisgICAgICAgICAgbG9uZ2VyIHRoYW4gMTYgY2hhcmFjdGVycyB1c2luZyB0aGUgQlNEIGRpYWxlY3QsIHdyaXRpbmcKKyAgICAgICAgICB0aGUgU1ZSNC9HTlUgZGlhbGVjdCBpcyBub3Qgc3VwcG9ydGVkLjwvcD4KKworICAgICAgICA8dGFibGU+CisgICAgICAgICAgPHRoZWFkPgorICAgICAgICAgICAgPHRyPgorICAgICAgICAgICAgICA8dGg+VmVyc2lvbiBvZiBBcGFjaGUgQ29tbW9ucyBDb21wcmVzczwvdGg+CisgICAgICAgICAgICAgIDx0aD5TdXBwb3J0IGZvciBUcmFkaXRpb25hbCBBUiBGb3JtYXQ8L3RoPgorICAgICAgICAgICAgICA8dGg+U3VwcG9ydCBmb3IgR05VL1NSVjQgRGlhbGVjdDwvdGg+CisgICAgICAgICAgICAgIDx0aD5TdXBwb3J0IGZvciBCU0QgRGlhbGVjdDwvdGg+CisgICAgICAgICAgICA8L3RyPgorICAgICAgICAgIDwvdGhlYWQ+CisgICAgICAgICAgPHRib2R5PgorICAgICAgICAgICAgPHRyPgorICAgICAgICAgICAgICA8dGQ+MS4wIHRvIDEuMjwvdGQ+CisgICAgICAgICAgICAgIDx0ZD5yZWFkL3dyaXRlPC90ZD4KKyAgICAgICAgICAgICAgPHRkPnJlYWQ8L3RkPgorICAgICAgICAgICAgICA8dGQ+LTwvdGQ+CisgICAgICAgICAgICA8L3RyPgorICAgICAgICAgICAgPHRyPgorICAgICAgICAgICAgICA8dGQ+MS4zIGFuZCBsYXRlcjwvdGQ+CisgICAgICAgICAgICAgIDx0ZD5yZWFkL3dyaXRlPC90ZD4KKyAgICAgICAgICAgICAgPHRkPnJlYWQ8L3RkPgorICAgICAgICAgICAgICA8dGQ+cmVhZC93cml0ZTwvdGQ+CisgICAgICAgICAgICA8L3RyPgorICAgICAgICAgIDwvdGJvZHk+CisgICAgICAgIDwvdGFibGU+CisKKyAgICAgICAgPHA+SXQgaXMgbm90IHBvc3NpYmxlIHRvIGRldGVjdCB0aGUgZW5kIG9mIGFuIEFSIGFyY2hpdmUgaW4gYQorICAgICAgICByZWxpYWJsZSB3YXkgc28gPGNvZGU+QXJBcmNoaXZlSW5wdXRTdHJlYW08L2NvZGU+IHdpbGwgcmVhZAorICAgICAgICB1bnRpbCBpdCByZWFjaGVzIHRoZSBlbmQgb2YgdGhlIHN0cmVhbSBvciBmYWlscyB0byBwYXJzZSB0aGUKKyAgICAgICAgc3RyZWFtJ3MgY29udGVudCBhcyBBUiBlbnRyaWVzLjwvcD4KKworICAgICAgPC9zdWJzZWN0aW9uPgorCisgICAgICA8c3Vic2VjdGlvbiBuYW1lPSJhcmoiPgorCisgICAgICAgIDxwPk5vdGUgdGhhdCBDb21tb25zIENvbXByZXNzIGRvZXNuJ3Qgc3VwcG9ydCBjb21wcmVzc2VkLAorICAgICAgICBlbmNyeXB0ZWQgb3IgbXVsdGktdm9sdW1lIEFSSiBhcmNoaXZlcywgeWV0LjwvcD4KKworICAgICAgICA8cD5VbmNvbXByZXNzaW5nIGEgZ2l2ZW4gYXJqIGFyY2hpdmUgKHlvdSB3b3VsZAorICAgICAgICAgIGNlcnRhaW5seSBhZGQgZXhjZXB0aW9uIGhhbmRsaW5nIGFuZCBtYWtlIHN1cmUgYWxsIHN0cmVhbXMKKyAgICAgICAgICBnZXQgY2xvc2VkIHByb3Blcmx5KTo8L3A+Cis8c291cmNlPjwhW0NEQVRBWworQXJqQXJjaGl2ZUVudHJ5IGVudHJ5ID0gYXJqSW5wdXQuZ2V0TmV4dEVudHJ5KCk7CitieXRlW10gY29udGVudCA9IG5ldyBieXRlW2VudHJ5LmdldFNpemUoKV07CitMT09QIFVOVElMIGVudHJ5LmdldFNpemUoKSBIQVMgQkVFTiBSRUFEIHsKKyAgICBhcmpJbnB1dC5yZWFkKGNvbnRlbnQsIG9mZnNldCwgY29udGVudC5sZW5ndGggLSBvZmZzZXQpOworfQorXV0+PC9zb3VyY2U+CisgICAgICA8L3N1YnNlY3Rpb24+CisKKyAgICAgIDxzdWJzZWN0aW9uIG5hbWU9ImNwaW8iPgorCisgICAgICAgIDxwPkluIGFkZGl0aW9uIHRvIHRoZSBpbmZvcm1hdGlvbiBzdG9yZWQKKyAgICAgICAgICBpbiA8Y29kZT5BcmNoaXZlRW50cnk8L2NvZGU+IGEgPGNvZGU+Q3Bpb0FyY2hpdmVFbnRyeTwvY29kZT4KKyAgICAgICAgICBzdG9yZXMgdmFyaW91cyBhdHRyaWJ1dGVzIGluY2x1ZGluZyBpbmZvcm1hdGlvbiBhYm91dCB0aGUKKyAgICAgICAgICBvcmlnaW5hbCBvd25lciBhbmQgcGVybWlzc2lvbnMuPC9wPgorCisgICAgICAgIDxwPlRoZSBjcGlvIHBhY2thZ2Ugc3VwcG9ydHMgdGhlICJuZXcgcG9ydGFibGUiIGFzIHdlbGwgYXMgdGhlCisgICAgICAgICAgIm9sZCIgZm9ybWF0IG9mIENQSU8gYXJjaGl2ZXMgaW4gdGhlaXIgYmluYXJ5LCBBU0NJSSBhbmQKKyAgICAgICAgICAid2l0aCBDUkMiIHZhcmlhbnRzLjwvcD4KKworICAgICAgICA8cD5BZGRpbmcgYW4gZW50cnkgdG8gYSBjcGlvIGFyY2hpdmU6PC9wPgorPHNvdXJjZT48IVtDREFUQVsKK0NwaW9BcmNoaXZlRW50cnkgZW50cnkgPSBuZXcgQ3Bpb0FyY2hpdmVFbnRyeShuYW1lLCBzaXplKTsKK2NwaW9PdXRwdXQucHV0QXJjaGl2ZUVudHJ5KGVudHJ5KTsKK2NwaW9PdXRwdXQud3JpdGUoY29udGVudE9mRW50cnkpOworY3Bpb091dHB1dC5jbG9zZUFyY2hpdmVFbnRyeSgpOworXV0+PC9zb3VyY2U+CisKKyAgICAgICAgPHA+UmVhZGluZyBlbnRyaWVzIGZyb20gYW4gY3BpbyBhcmNoaXZlOjwvcD4KKzxzb3VyY2U+PCFbQ0RBVEFbCitDcGlvQXJjaGl2ZUVudHJ5IGVudHJ5ID0gY3Bpb0lucHV0LmdldE5leHRDUElPRW50cnkoKTsKK2J5dGVbXSBjb250ZW50ID0gbmV3IGJ5dGVbZW50cnkuZ2V0U2l6ZSgpXTsKK0xPT1AgVU5USUwgZW50cnkuZ2V0U2l6ZSgpIEhBUyBCRUVOIFJFQUQgeworICAgIGNwaW9JbnB1dC5yZWFkKGNvbnRlbnQsIG9mZnNldCwgY29udGVudC5sZW5ndGggLSBvZmZzZXQpOworfQorXV0+PC9zb3VyY2U+CisKKyAgICAgICAgPHA+VHJhZGl0aW9uYWxseSBDUElPIGFyY2hpdmVzIGFyZSB3cml0dGVuIGluIGJsb2NrcyBvZiA1MTIKKyAgICAgICAgYnl0ZXMgLSB0aGUgYmxvY2sgc2l6ZSBpcyBhIGNvbmZpZ3VyYXRpb24gcGFyYW1ldGVyIG9mIHRoZQorICAgICAgICA8Y29kZT5DcGlvKlN0cmVhbTwvY29kZT4ncyBjb25zdHVjdG9ycy4gIFN0YXJ0aW5nIHdpdGggdmVyc2lvbgorICAgICAgICAxLjUgPGNvZGU+Q3Bpb0FyY2hpdmVJbnB1dFN0cmVhbTwvY29kZT4gd2lsbCBjb25zdW1lIHRoZQorICAgICAgICBwYWRkaW5nIHdyaXR0ZW4gdG8gZmlsbCB0aGUgY3VycmVudCBibG9jayB3aGVuIHRoZSBlbmQgb2YgdGhlCisgICAgICAgIGFyY2hpdmUgaXMgcmVhY2hlZC4gIFVuZm9ydHVuYXRlbHkgbWFueSBDUElPIGltcGxlbWVudGF0aW9ucworICAgICAgICB1c2UgbGFyZ2VyIGJsb2NrIHNpemVzIHNvIHRoZXJlIG1heSBiZSBtb3JlIHplcm8tYnl0ZSBwYWRkaW5nCisgICAgICAgIGxlZnQgaW5zaWRlIHRoZSBvcmlnaW5hbCBpbnB1dCBzdHJlYW0gYWZ0ZXIgdGhlIGFyY2hpdmUgaGFzCisgICAgICAgIGJlZW4gY29uc3VtZWQgY29tcGxldGVseS48L3A+CisKKyAgICAgIDwvc3Vic2VjdGlvbj4KKworICAgICAgPHN1YnNlY3Rpb24gbmFtZT0iamFyIj4KKyAgICAgICAgPHA+SW4gZ2VuZXJhbCwgSkFSIGFyY2hpdmVzIGFyZSBaSVAgZmlsZXMsIHNvIHRoZSBKQVIgcGFja2FnZQorICAgICAgICAgIHN1cHBvcnRzIGFsbCBvcHRpb25zIHByb3ZpZGVkIGJ5IHRoZSA8YSBocmVmPSIjemlwIj5aSVA8L2E+IHBhY2thZ2UuPC9wPgorCisgICAgICAgIDxwPlRvIGJlIGludGVyb3BlcmFibGUgSkFSIGFyY2hpdmVzIHNob3VsZCBhbHdheXMgYmUgY3JlYXRlZAorICAgICAgICAgIHVzaW5nIHRoZSBVVEYtOCBlbmNvZGluZyBmb3IgZmlsZSBuYW1lcyAod2hpY2ggaXMgdGhlCisgICAgICAgICAgZGVmYXVsdCkuPC9wPgorCisgICAgICAgIDxwPkFyY2hpdmVzIGNyZWF0ZWQgdXNpbmcgPGNvZGU+SmFyQXJjaGl2ZU91dHB1dFN0cmVhbTwvY29kZT4KKyAgICAgICAgICB3aWxsIGltcGxpY2l0bHkgYWRkIGEgPGNvZGU+SmFyTWFya2VyPC9jb2RlPiBleHRyYSBmaWVsZCB0bworICAgICAgICAgIHRoZSB2ZXJ5IGZpcnN0IGFyY2hpdmUgZW50cnkgb2YgdGhlIGFyY2hpdmUgd2hpY2ggd2lsbCBtYWtlCisgICAgICAgICAgU29sYXJpcyByZWNvZ25pemUgdGhlbSBhcyBKYXZhIGFyY2hpdmVzIGFuZCBhbGxvd3MgdGhlbSB0bworICAgICAgICAgIGJlIHVzZWQgYXMgZXhlY3V0YWJsZXMuPC9wPgorCisgICAgICAgIDxwPk5vdGUgdGhhdCA8Y29kZT5BcmNoaXZlU3RyZWFtRmFjdG9yeTwvY29kZT4gZG9lc24ndAorICAgICAgICAgIGRpc3Rpbmd1aXNoIFpJUCBhcmNoaXZlcyBmcm9tIEpBUiBhcmNoaXZlcywgc28gaWYgeW91IHVzZQorICAgICAgICAgIHRoZSBvbmUtYXJndW1lbnQgPGNvZGU+Y3JlYXRlQXJjaGl2ZUlucHV0U3RyZWFtPC9jb2RlPgorICAgICAgICAgIG1ldGhvZCBvbiBhIEpBUiBhcmNoaXZlLCBpdCB3aWxsIHN0aWxsIHJldHVybiB0aGUgbW9yZQorICAgICAgICAgIGdlbmVyaWMgPGNvZGU+WmlwQXJjaGl2ZUlucHV0U3RyZWFtPC9jb2RlPi48L3A+CisKKyAgICAgICAgPHA+VGhlIDxjb2RlPkphckFyY2hpdmVFbnRyeTwvY29kZT4gY2xhc3MgY29udGFpbnMgZmllbGRzIGZvcgorICAgICAgICAgIGNlcnRpZmljYXRlcyBhbmQgYXR0cmlidXRlcyB0aGF0IGFyZSBwbGFubmVkIHRvIGJlIHN1cHBvcnRlZAorICAgICAgICAgIGluIHRoZSBmdXR1cmUgYnV0IGFyZSBub3Qgc3VwcG9ydGVkIGFzIG9mIENvbXByZXNzIDEuMC48L3A+CisKKyAgICAgICAgPHA+QWRkaW5nIGFuIGVudHJ5IHRvIGEgamFyIGFyY2hpdmU6PC9wPgorPHNvdXJjZT48IVtDREFUQVsKK0phckFyY2hpdmVFbnRyeSBlbnRyeSA9IG5ldyBKYXJBcmNoaXZlRW50cnkobmFtZSwgc2l6ZSk7CitlbnRyeS5zZXRTaXplKHNpemUpOworamFyT3V0cHV0LnB1dEFyY2hpdmVFbnRyeShlbnRyeSk7CitqYXJPdXRwdXQud3JpdGUoY29udGVudE9mRW50cnkpOworamFyT3V0cHV0LmNsb3NlQXJjaGl2ZUVudHJ5KCk7CitdXT48L3NvdXJjZT4KKworICAgICAgICA8cD5SZWFkaW5nIGVudHJpZXMgZnJvbSBhbiBqYXIgYXJjaGl2ZTo8L3A+Cis8c291cmNlPjwhW0NEQVRBWworSmFyQXJjaGl2ZUVudHJ5IGVudHJ5ID0gamFySW5wdXQuZ2V0TmV4dEphckVudHJ5KCk7CitieXRlW10gY29udGVudCA9IG5ldyBieXRlW2VudHJ5LmdldFNpemUoKV07CitMT09QIFVOVElMIGVudHJ5LmdldFNpemUoKSBIQVMgQkVFTiBSRUFEIHsKKyAgICBqYXJJbnB1dC5yZWFkKGNvbnRlbnQsIG9mZnNldCwgY29udGVudC5sZW5ndGggLSBvZmZzZXQpOworfQorXV0+PC9zb3VyY2U+CisgICAgICA8L3N1YnNlY3Rpb24+CisKKyAgICAgIDxzdWJzZWN0aW9uIG5hbWU9ImR1bXAiPgorCisgICAgICAgIDxwPkluIGFkZGl0aW9uIHRvIHRoZSBpbmZvcm1hdGlvbiBzdG9yZWQKKyAgICAgICAgICBpbiA8Y29kZT5BcmNoaXZlRW50cnk8L2NvZGU+IGEgPGNvZGU+RHVtcEFyY2hpdmVFbnRyeTwvY29kZT4KKyAgICAgICAgICBzdG9yZXMgdmFyaW91cyBhdHRyaWJ1dGVzIGluY2x1ZGluZyBpbmZvcm1hdGlvbiBhYm91dCB0aGUKKyAgICAgICAgICBvcmlnaW5hbCBvd25lciBhbmQgcGVybWlzc2lvbnMuPC9wPgorCisgICAgICAgIDxwPkFzIG9mIENvbW1vbnMgQ29tcHJlc3MgMS4zIG9ubHkgZHVtcCBhcmNoaXZlcyB1c2luZyB0aGUKKyAgICAgICAgICBuZXctZnMgZm9ybWF0IC0gdGhpcyBpcyB0aGUgbW9zdCBjb21tb24gdmFyaWFudCAtIGFyZQorICAgICAgICAgIHN1cHBvcnRlZC4gIFJpZ2h0IG5vdyB0aGlzIGxpYnJhcnkgc3VwcG9ydHMgdW5jb21wcmVzc2VkIGFuZAorICAgICAgICAgIFpMSUIgY29tcHJlc3NlZCBhcmNoaXZlcyBhbmQgY2FuIG5vdCB3cml0ZSBhcmNoaXZlcyBhdAorICAgICAgICAgIGFsbC48L3A+CisKKyAgICAgICAgPHA+UmVhZGluZyBlbnRyaWVzIGZyb20gYW4gZHVtcCBhcmNoaXZlOjwvcD4KKzxzb3VyY2U+PCFbQ0RBVEFbCitEdW1wQXJjaGl2ZUVudHJ5IGVudHJ5ID0gZHVtcElucHV0LmdldE5leHREdW1wRW50cnkoKTsKK2J5dGVbXSBjb250ZW50ID0gbmV3IGJ5dGVbZW50cnkuZ2V0U2l6ZSgpXTsKK0xPT1AgVU5USUwgZW50cnkuZ2V0U2l6ZSgpIEhBUyBCRUVOIFJFQUQgeworICAgIGR1bXBJbnB1dC5yZWFkKGNvbnRlbnQsIG9mZnNldCwgY29udGVudC5sZW5ndGggLSBvZmZzZXQpOworfQorXV0+PC9zb3VyY2U+CisKKyAgICAgICAgPHA+UHJpb3IgdG8gdmVyc2lvbiAxLjUgPGNvZGU+RHVtcEFyY2hpdmVJbnB1dFN0cmVhbTwvY29kZT4KKyAgICAgICAgd291bGQgY2xvc2UgdGhlIG9yaWdpbmFsIGlucHV0IG9uY2UgaXQgaGFkIHJlYWQgdGhlIGxhc3QKKyAgICAgICAgcmVjb3JkLiAgU3RhcnRpbmcgd2l0aCB2ZXJzaW9uIDEuNSBpdCB3aWxsIG5vdCBjbG9zZSB0aGUKKyAgICAgICAgc3RyZWFtIGltcGxpY2l0bHkuPC9wPgorCisgICAgICA8L3N1YnNlY3Rpb24+CisKKyAgICAgIDxzdWJzZWN0aW9uIG5hbWU9InRhciI+CisKKyAgICAgICAgPHA+VGhlIFRBUiBwYWNrYWdlIGhhcyBhIDxhIGhyZWY9InRhci5odG1sIj5kZWRpY2F0ZWQKKyAgICAgICAgICAgIGRvY3VtZW50YXRpb24gcGFnZTwvYT4uPC9wPgorCisgICAgICAgIDxwPkFkZGluZyBhbiBlbnRyeSB0byBhIHRhciBhcmNoaXZlOjwvcD4KKzxzb3VyY2U+PCFbQ0RBVEFbCitUYXJBcmNoaXZlRW50cnkgZW50cnkgPSBuZXcgVGFyQXJjaGl2ZUVudHJ5KG5hbWUpOworZW50cnkuc2V0U2l6ZShzaXplKTsKK3Rhck91dHB1dC5wdXRBcmNoaXZlRW50cnkoZW50cnkpOwordGFyT3V0cHV0LndyaXRlKGNvbnRlbnRPZkVudHJ5KTsKK3Rhck91dHB1dC5jbG9zZUFyY2hpdmVFbnRyeSgpOworXV0+PC9zb3VyY2U+CisKKyAgICAgICAgPHA+UmVhZGluZyBlbnRyaWVzIGZyb20gYW4gdGFyIGFyY2hpdmU6PC9wPgorPHNvdXJjZT48IVtDREFUQVsKK1RhckFyY2hpdmVFbnRyeSBlbnRyeSA9IHRhcklucHV0LmdldE5leHRUYXJFbnRyeSgpOworYnl0ZVtdIGNvbnRlbnQgPSBuZXcgYnl0ZVtlbnRyeS5nZXRTaXplKCldOworTE9PUCBVTlRJTCBlbnRyeS5nZXRTaXplKCkgSEFTIEJFRU4gUkVBRCB7CisgICAgdGFySW5wdXQucmVhZChjb250ZW50LCBvZmZzZXQsIGNvbnRlbnQubGVuZ3RoIC0gb2Zmc2V0KTsKK30KK11dPjwvc291cmNlPgorICAgICAgPC9zdWJzZWN0aW9uPgorCisgICAgICA8c3Vic2VjdGlvbiBuYW1lPSJ6aXAiPgorICAgICAgICA8cD5UaGUgWklQIHBhY2thZ2UgaGFzIGEgPGEgaHJlZj0iemlwLmh0bWwiPmRlZGljYXRlZAorICAgICAgICAgICAgZG9jdW1lbnRhdGlvbiBwYWdlPC9hPi48L3A+CisKKyAgICAgICAgPHA+QWRkaW5nIGFuIGVudHJ5IHRvIGEgemlwIGFyY2hpdmU6PC9wPgorPHNvdXJjZT48IVtDREFUQVsKK1ppcEFyY2hpdmVFbnRyeSBlbnRyeSA9IG5ldyBaaXBBcmNoaXZlRW50cnkobmFtZSk7CitlbnRyeS5zZXRTaXplKHNpemUpOworemlwT3V0cHV0LnB1dEFyY2hpdmVFbnRyeShlbnRyeSk7Cit6aXBPdXRwdXQud3JpdGUoY29udGVudE9mRW50cnkpOworemlwT3V0cHV0LmNsb3NlQXJjaGl2ZUVudHJ5KCk7CitdXT48L3NvdXJjZT4KKworICAgICAgICA8cD48Y29kZT5aaXBBcmNoaXZlT3V0cHV0U3RyZWFtPC9jb2RlPiBjYW4gdXNlIHNvbWUgaW50ZXJuYWwKKyAgICAgICAgICBvcHRpbWl6YXRpb25zIGV4cGxvaXRpbmcgPGNvZGU+U2Vla2FibGVCeXRlQ2hhbm5lbDwvY29kZT4gaWYgaXQKKyAgICAgICAgICBrbm93cyBpdCBpcyB3cml0aW5nIHRvIGEgc2Vla2FibGUgb3V0cHV0IHJhdGhlciB0aGFuIGEgbm9uLXNlZWthYmxlCisgICAgICAgICAgc3RyZWFtLiAgSWYgeW91IGFyZSB3cml0aW5nIHRvIGEgZmlsZSwgeW91IHNob3VsZCB1c2UgdGhlCisgICAgICAgICAgY29uc3RydWN0b3IgdGhhdCBhY2NlcHRzIGEgPGNvZGU+RmlsZTwvY29kZT4gb3IKKyAgICAgICAgICA8Y29kZT5TZWVrYWJsZUJ5dGVDaGFubmVsPC9jb2RlPiBhcmd1bWVudCByYXRoZXIKKyAgICAgICAgICB0aGFuIHRoZSBvbmUgdXNpbmcgYW4gPGNvZGU+T3V0cHV0U3RyZWFtPC9jb2RlPiBvciB0aGUKKyAgICAgICAgICBmYWN0b3J5IG1ldGhvZCBpbiA8Y29kZT5BcmNoaXZlU3RyZWFtRmFjdG9yeTwvY29kZT4uPC9wPgorCisgICAgICAgIDxwPlJlYWRpbmcgZW50cmllcyBmcm9tIGFuIHppcCBhcmNoaXZlOjwvcD4KKzxzb3VyY2U+PCFbQ0RBVEFbCitaaXBBcmNoaXZlRW50cnkgZW50cnkgPSB6aXBJbnB1dC5nZXROZXh0WmlwRW50cnkoKTsKK2J5dGVbXSBjb250ZW50ID0gbmV3IGJ5dGVbZW50cnkuZ2V0U2l6ZSgpXTsKK0xPT1AgVU5USUwgZW50cnkuZ2V0U2l6ZSgpIEhBUyBCRUVOIFJFQUQgeworICAgIHppcElucHV0LnJlYWQoY29udGVudCwgb2Zmc2V0LCBjb250ZW50Lmxlbmd0aCAtIG9mZnNldCk7Cit9CitdXT48L3NvdXJjZT4KKworICAgICAgICA8cD5SZWFkaW5nIGVudHJpZXMgZnJvbSBhbiB6aXAgYXJjaGl2ZSB1c2luZyB0aGUKKyAgICAgICAgICByZWNvbW1lbmRlZCA8Y29kZT5aaXBGaWxlPC9jb2RlPiBjbGFzczo8L3A+Cis8c291cmNlPjwhW0NEQVRBWworWmlwQXJjaGl2ZUVudHJ5IGVudHJ5ID0gemlwRmlsZS5nZXRFbnRyeShuYW1lKTsKK0lucHV0U3RyZWFtIGNvbnRlbnQgPSB6aXBGaWxlLmdldElucHV0U3RyZWFtKGVudHJ5KTsKK3RyeSB7CisgICAgUkVBRCBVTlRJTCBjb250ZW50IElTIEVYSEFVU1RFRAorfSBmaW5hbGx5IHsKKyAgICBjb250ZW50LmNsb3NlKCk7Cit9CitdXT48L3NvdXJjZT4KKworICAgICAgICAgIDxwPlJlYWRpbmcgZW50cmllcyBmcm9tIGFuIGluLW1lbW9yeSB6aXAgYXJjaGl2ZSB1c2luZworICAgICAgICAgICAgICA8Y29kZT5TZWVrYWJsZUluTWVtb3J5Qnl0ZUNoYW5uZWw8L2NvZGU+IGFuZCA8Y29kZT5aaXBGaWxlPC9jb2RlPiBjbGFzczo8L3A+Cis8c291cmNlPjwhW0NEQVRBWworYnl0ZVtdIGlucHV0RGF0YTsgLy8gemlwIGFyY2hpdmUgY29udGVudHMKK1NlZWthYmxlSW5NZW1vcnlCeXRlQ2hhbm5lbCBpbk1lbW9yeUJ5dGVDaGFubmVsID0gbmV3IFNlZWthYmxlSW5NZW1vcnlCeXRlQ2hhbm5lbChpbnB1dERhdGEpOworWmlwRmlsZSB6aXBGaWxlID0gbmV3IFppcEZpbGUoaW5NZW1vcnlCeXRlQ2hhbm5lbCk7CitaaXBBcmNoaXZlRW50cnkgYXJjaGl2ZUVudHJ5ID0gemlwRmlsZS5nZXRFbnRyeSgiZW50cnlOYW1lIik7CitJbnB1dFN0cmVhbSBpbnB1dFN0cmVhbSA9IHppcEZpbGUuZ2V0SW5wdXRTdHJlYW0oYXJjaGl2ZUVudHJ5KTsKK2lucHV0U3RyZWFtLnJlYWQoKSAvLyByZWFkIGRhdGEgZnJvbSB0aGUgaW5wdXQgc3RyZWFtCitdXT48L3NvdXJjZT4KKworICAgICAgICAgIDxwPkNyZWF0aW5nIGEgemlwIGZpbGUgd2l0aCBtdWx0aXBsZSB0aHJlYWRzOjwvcD4KKworICAgICAgICAgIEEgc2ltcGxlIGltcGxlbWVudGF0aW9uIHRvIGNyZWF0ZSBhIHppcCBmaWxlIG1pZ2h0IGxvb2sgbGlrZSB0aGlzOgorCis8c291cmNlPgorcHVibGljIGNsYXNzIFNjYXR0ZXJTYW1wbGUgeworCisgIFBhcmFsbGVsU2NhdHRlclppcENyZWF0b3Igc2NhdHRlclppcENyZWF0b3IgPSBuZXcgUGFyYWxsZWxTY2F0dGVyWmlwQ3JlYXRvcigpOworICBTY2F0dGVyWmlwT3V0cHV0U3RyZWFtIGRpcnMgPSBTY2F0dGVyWmlwT3V0cHV0U3RyZWFtLmZpbGVCYXNlZChGaWxlLmNyZWF0ZVRlbXBGaWxlKCJzY2F0dGVyLWRpcnMiLCAidG1wIikpOworCisgIHB1YmxpYyBTY2F0dGVyU2FtcGxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgfQorCisgIHB1YmxpYyB2b2lkIGFkZEVudHJ5KFppcEFyY2hpdmVFbnRyeSB6aXBBcmNoaXZlRW50cnksIElucHV0U3RyZWFtU3VwcGxpZXIgc3RyZWFtU3VwcGxpZXIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgIGlmICh6aXBBcmNoaXZlRW50cnkuaXNEaXJlY3RvcnkoKSAmYW1wOyZhbXA7ICF6aXBBcmNoaXZlRW50cnkuaXNVbml4U3ltbGluaygpKQorICAgICAgICBkaXJzLmFkZEFyY2hpdmVFbnRyeShaaXBBcmNoaXZlRW50cnlSZXF1ZXN0LmNyZWF0ZVppcEFyY2hpdmVFbnRyeVJlcXVlc3QoemlwQXJjaGl2ZUVudHJ5LCBzdHJlYW1TdXBwbGllcikpOworICAgICBlbHNlCisgICAgICAgIHNjYXR0ZXJaaXBDcmVhdG9yLmFkZEFyY2hpdmVFbnRyeSggemlwQXJjaGl2ZUVudHJ5LCBzdHJlYW1TdXBwbGllcik7CisgIH0KKworICBwdWJsaWMgdm9pZCB3cml0ZVRvKFppcEFyY2hpdmVPdXRwdXRTdHJlYW0gemlwQXJjaGl2ZU91dHB1dFN0cmVhbSkKKyAgdGhyb3dzIElPRXhjZXB0aW9uLCBFeGVjdXRpb25FeGNlcHRpb24sIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgZGlycy53cml0ZVRvKHppcEFyY2hpdmVPdXRwdXRTdHJlYW0pOworICAgICBkaXJzLmNsb3NlKCk7CisgICAgIHNjYXR0ZXJaaXBDcmVhdG9yLndyaXRlVG8oemlwQXJjaGl2ZU91dHB1dFN0cmVhbSk7CisgIH0KK30KKzwvc291cmNlPgorICAgICAgPC9zdWJzZWN0aW9uPgorCisgICAgPC9zZWN0aW9uPgorICAgIDxzZWN0aW9uIG5hbWU9IkNvbXByZXNzb3JzIj4KKworICAgICAgPHN1YnNlY3Rpb24gbmFtZT0iQ29uY2F0ZW5hdGVkIFN0cmVhbXMiPgorICAgICAgICA8cD5Gb3IgdGhlIGJ6aXAyLCBnemlwIGFuZCB4eiBmb3JtYXRzIGFzIHdlbGwgYXMgdGhlIGZyYW1lZAorICAgICAgICBsejQgZm9ybWF0IGEgc2luZ2xlIGNvbXByZXNzZWQgZmlsZQorICAgICAgICBtYXkgYWN0dWFsbHkgY29uc2lzdCBvZiBzZXZlcmFsIHN0cmVhbXMgdGhhdCB3aWxsIGJlCisgICAgICAgIGNvbmNhdGVuYXRlZCBieSB0aGUgY29tbWFuZCBsaW5lIHV0aWxpdGllcyB3aGVuIGRlY29tcHJlc3NpbmcKKyAgICAgICAgdGhlbS4gIFN0YXJ0aW5nIHdpdGggQ29tbW9ucyBDb21wcmVzcyAxLjQgdGhlCisgICAgICAgIDxjb2RlPipDb21wcmVzc29ySW5wdXRTdHJlYW08L2NvZGU+cyBmb3IgdGhlc2UgZm9ybWF0cyBzdXBwb3J0CisgICAgICAgIGNvbmNhdGVuYXRpbmcgc3RyZWFtcyBhcyB3ZWxsLCBidXQgdGhleSB3b24ndCBkbyBzbyBieQorICAgICAgICBkZWZhdWx0LiAgWW91IG11c3QgdXNlIHRoZSB0d28tYXJnIGNvbnN0cnVjdG9yIGFuZCBleHBsaWNpdGx5CisgICAgICAgIGVuYWJsZSB0aGUgc3VwcG9ydC48L3A+CisgICAgICA8L3N1YnNlY3Rpb24+CisKKyAgICAgIDxzdWJzZWN0aW9uIG5hbWU9IkJyb3RsaSI+CisKKyAgICAgICAgPHA+VGhlIGltcGxlbWVudGF0aW9uIG9mIHRoaXMgcGFja2FnZSBpcyBwcm92aWRlZCBieSB0aGUKKyAgICAgICAgICA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2Jyb3RsaSI+R29vZ2xlIEJyb3RsaSBkZWM8L2E+IGxpYnJhcnkuPC9wPgorCisgICAgICAgIDxwPlVuY29tcHJlc3NpbmcgYSBnaXZlbiBCcm90bGkgY29tcHJlc3NlZCBmaWxlICh5b3Ugd291bGQKKyAgICAgICAgICBjZXJ0YWlubHkgYWRkIGV4Y2VwdGlvbiBoYW5kbGluZyBhbmQgbWFrZSBzdXJlIGFsbCBzdHJlYW1zCisgICAgICAgICAgZ2V0IGNsb3NlZCBwcm9wZXJseSk6PC9wPgorPHNvdXJjZT48IVtDREFUQVsKK0lucHV0U3RyZWFtIGZpbiA9IEZpbGVzLm5ld0lucHV0U3RyZWFtKFBhdGhzLmdldCgiYXJjaGl2ZS50YXIuYnIiKSk7CitCdWZmZXJlZElucHV0U3RyZWFtIGluID0gbmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0oZmluKTsKK091dHB1dFN0cmVhbSBvdXQgPSBGaWxlcy5uZXdPdXRwdXRTdHJlYW0oUGF0aHMuZ2V0KCJhcmNoaXZlLnRhciIpKTsKK0Jyb3RsaUNvbXByZXNzb3JJbnB1dFN0cmVhbSBickluID0gbmV3IEJyb3RsaUNvbXByZXNzb3JJbnB1dFN0cmVhbShpbik7CitmaW5hbCBieXRlW10gYnVmZmVyID0gbmV3IGJ5dGVbYnVmZmVyc2l6ZV07CitpbnQgbiA9IDA7Cit3aGlsZSAoLTEgIT0gKG4gPSBickluLnJlYWQoYnVmZmVyKSkpIHsKKyAgICBvdXQud3JpdGUoYnVmZmVyLCAwLCBuKTsKK30KK291dC5jbG9zZSgpOworYnJJbi5jbG9zZSgpOworXV0+PC9zb3VyY2U+CisgICAgICA8L3N1YnNlY3Rpb24+CisKKyAgICAgIDxzdWJzZWN0aW9uIG5hbWU9ImJ6aXAyIj4KKworICAgICAgICA8cD5Ob3RlIHRoYXQgPGNvZGU+QlppcENvbXByZXNzb3JPdXRwdXRTdHJlYW08L2NvZGU+IGtlZXBzCisgICAgICAgICAgaG9sZCBvZiBzb21lIGJpZyBkYXRhIHN0cnVjdHVyZXMgaW4gbWVtb3J5LiAgV2hpbGUgaXQgaXMKKyAgICAgICAgICByZWNvbW1lbmRlZCBmb3IgPGVtPmFueTwvZW0+IHN0cmVhbSB0aGF0IHlvdSBjbG9zZSBpdCBhcyBzb29uIGFzCisgICAgICAgICAgeW91IG5vIGxvbmdlciBuZWVkIGl0LCB0aGlzIGlzIGV2ZW4gbW9yZSBpbXBvcnRhbnQKKyAgICAgICAgICBmb3IgPGNvZGU+QlppcENvbXByZXNzb3JPdXRwdXRTdHJlYW08L2NvZGU+LjwvcD4KKworICAgICAgICA8cD5VbmNvbXByZXNzaW5nIGEgZ2l2ZW4gYnppcDIgY29tcHJlc3NlZCBmaWxlICh5b3Ugd291bGQKKyAgICAgICAgICBjZXJ0YWlubHkgYWRkIGV4Y2VwdGlvbiBoYW5kbGluZyBhbmQgbWFrZSBzdXJlIGFsbCBzdHJlYW1zCisgICAgICAgICAgZ2V0IGNsb3NlZCBwcm9wZXJseSk6PC9wPgorPHNvdXJjZT48IVtDREFUQVsKK0lucHV0U3RyZWFtIGZpbiA9IEZpbGVzLm5ld0lucHV0U3RyZWFtKFBhdGhzLmdldCgiYXJjaGl2ZS50YXIuYnoyIikpOworQnVmZmVyZWRJbnB1dFN0cmVhbSBpbiA9IG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKGZpbik7CitPdXRwdXRTdHJlYW0gb3V0ID0gRmlsZXMubmV3T3V0cHV0U3RyZWFtKFBhdGhzLmdldCgiYXJjaGl2ZS50YXIiKSk7CitCWmlwMkNvbXByZXNzb3JJbnB1dFN0cmVhbSBiekluID0gbmV3IEJaaXAyQ29tcHJlc3NvcklucHV0U3RyZWFtKGluKTsKK2ZpbmFsIGJ5dGVbXSBidWZmZXIgPSBuZXcgYnl0ZVtidWZmZXJzaXplXTsKK2ludCBuID0gMDsKK3doaWxlICgtMSAhPSAobiA9IGJ6SW4ucmVhZChidWZmZXIpKSkgeworICAgIG91dC53cml0ZShidWZmZXIsIDAsIG4pOworfQorb3V0LmNsb3NlKCk7CitiekluLmNsb3NlKCk7CitdXT48L3NvdXJjZT4KKworICAgICAgICA8cD5Db21wcmVzc2luZyBhIGdpdmVuIGZpbGUgdXNpbmcgYnppcDIgKHlvdSB3b3VsZAorICAgICAgICAgIGNlcnRhaW5seSBhZGQgZXhjZXB0aW9uIGhhbmRsaW5nIGFuZCBtYWtlIHN1cmUgYWxsIHN0cmVhbXMKKyAgICAgICAgICBnZXQgY2xvc2VkIHByb3Blcmx5KTo8L3A+Cis8c291cmNlPjwhW0NEQVRBWworSW5wdXRTdHJlYW0gaW4gPSBGaWxlcy5uZXdJbnB1dFN0cmVhbShQYXRocy5nZXQoImFyY2hpdmUudGFyIikpOworT3V0cHV0U3RyZWFtIGZvdXQgPSBGaWxlcy5uZXdPdXRwdXRTdHJlYW0oUGF0aHMuZ2V0KCJhcmNoaXZlLnRhci5neiIpKTsKK0J1ZmZlcmVkT3V0cHV0U3RyZWFtIG91dCA9IG5ldyBCdWZmZXJlZE91dHB1dFN0cmVhbShmb3V0KTsKK0JaaXAyQ29tcHJlc3Nvck91dHB1dFN0cmVhbSBiek91dCA9IG5ldyBCWmlwMkNvbXByZXNzb3JPdXRwdXRTdHJlYW0ob3V0KTsKK2ZpbmFsIGJ5dGVbXSBidWZmZXIgPSBuZXcgYnl0ZVtidWZmZXJzaXplXTsKK2ludCBuID0gMDsKK3doaWxlICgtMSAhPSAobiA9IGluLnJlYWQoYnVmZmVyKSkpIHsKKyAgICBiek91dC53cml0ZShidWZmZXIsIDAsIG4pOworfQorYnpPdXQuY2xvc2UoKTsKK2luLmNsb3NlKCk7CitdXT48L3NvdXJjZT4KKworICAgICAgPC9zdWJzZWN0aW9uPgorCisgICAgICA8c3Vic2VjdGlvbiBuYW1lPSJERUZMQVRFIj4KKworICAgICAgICA8cD5UaGUgaW1wbGVtZW50YXRpb24gb2YgdGhlIERFRkxBVEUvSU5GTEFURSBjb2RlIHVzZWQgYnkgdGhpcworICAgICAgICBwYWNrYWdlIGlzIHByb3ZpZGVkIGJ5IHRoZSA8Y29kZT5qYXZhLnV0aWwuemlwPC9jb2RlPiBwYWNrYWdlCisgICAgICAgIG9mIHRoZSBKYXZhIGNsYXNzIGxpYnJhcnkuPC9wPgorCisgICAgICAgIDxwPlVuY29tcHJlc3NpbmcgYSBnaXZlbiBERUZMQVRFIGNvbXByZXNzZWQgZmlsZSAoeW91IHdvdWxkCisgICAgICAgICAgY2VydGFpbmx5IGFkZCBleGNlcHRpb24gaGFuZGxpbmcgYW5kIG1ha2Ugc3VyZSBhbGwgc3RyZWFtcworICAgICAgICAgIGdldCBjbG9zZWQgcHJvcGVybHkpOjwvcD4KKzxzb3VyY2U+PCFbQ0RBVEFbCitJbnB1dFN0cmVhbSBmaW4gPSBGaWxlcy5uZXdJbnB1dFN0cmVhbShQYXRocy5nZXQoInNvbWUtZmlsZSIpKTsKK0J1ZmZlcmVkSW5wdXRTdHJlYW0gaW4gPSBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShmaW4pOworT3V0cHV0U3RyZWFtIG91dCA9IEZpbGVzLm5ld091dHB1dFN0cmVhbShQYXRocy5nZXQoImFyY2hpdmUudGFyIikpOworRGVmbGF0ZUNvbXByZXNzb3JJbnB1dFN0cmVhbSBkZWZJbiA9IG5ldyBEZWZsYXRlQ29tcHJlc3NvcklucHV0U3RyZWFtKGluKTsKK2ZpbmFsIGJ5dGVbXSBidWZmZXIgPSBuZXcgYnl0ZVtidWZmZXJzaXplXTsKK2ludCBuID0gMDsKK3doaWxlICgtMSAhPSAobiA9IGRlZkluLnJlYWQoYnVmZmVyKSkpIHsKKyAgICBvdXQud3JpdGUoYnVmZmVyLCAwLCBuKTsKK30KK291dC5jbG9zZSgpOworZGVmSW4uY2xvc2UoKTsKK11dPjwvc291cmNlPgorCisgICAgICAgIDxwPkNvbXByZXNzaW5nIGEgZ2l2ZW4gZmlsZSB1c2luZyBERUZMQVRFICh5b3Ugd291bGQKKyAgICAgICAgICBjZXJ0YWlubHkgYWRkIGV4Y2VwdGlvbiBoYW5kbGluZyBhbmQgbWFrZSBzdXJlIGFsbCBzdHJlYW1zCisgICAgICAgICAgZ2V0IGNsb3NlZCBwcm9wZXJseSk6PC9wPgorPHNvdXJjZT48IVtDREFUQVsKK0lucHV0U3RyZWFtIGluID0gRmlsZXMubmV3SW5wdXRTdHJlYW0oUGF0aHMuZ2V0KCJhcmNoaXZlLnRhciIpKTsKK091dHB1dFN0cmVhbSBmb3V0ID0gRmlsZXMubmV3T3V0cHV0U3RyZWFtKFBhdGhzLmdldCgic29tZS1maWxlIikpOworQnVmZmVyZWRPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IEJ1ZmZlcmVkT3V0cHV0U3RyZWFtKGZvdXQpOworRGVmbGF0ZUNvbXByZXNzb3JPdXRwdXRTdHJlYW0gZGVmT3V0ID0gbmV3IERlZmxhdGVDb21wcmVzc29yT3V0cHV0U3RyZWFtKG91dCk7CitmaW5hbCBieXRlW10gYnVmZmVyID0gbmV3IGJ5dGVbYnVmZmVyc2l6ZV07CitpbnQgbiA9IDA7Cit3aGlsZSAoLTEgIT0gKG4gPSBpbi5yZWFkKGJ1ZmZlcikpKSB7CisgICAgZGVmT3V0LndyaXRlKGJ1ZmZlciwgMCwgbik7Cit9CitkZWZPdXQuY2xvc2UoKTsKK2luLmNsb3NlKCk7CitdXT48L3NvdXJjZT4KKworICAgICAgPC9zdWJzZWN0aW9uPgorCisgICAgICA8c3Vic2VjdGlvbiBuYW1lPSJERUZMQVRFNjQiPgorCisgICAgICAgIDxwPlVuY29tcHJlc3NpbmcgYSBnaXZlbiBERUZMQVRFNjQgY29tcHJlc3NlZCBmaWxlICh5b3Ugd291bGQKKyAgICAgICAgICBjZXJ0YWlubHkgYWRkIGV4Y2VwdGlvbiBoYW5kbGluZyBhbmQgbWFrZSBzdXJlIGFsbCBzdHJlYW1zCisgICAgICAgICAgZ2V0IGNsb3NlZCBwcm9wZXJseSk6PC9wPgorPHNvdXJjZT48IVtDREFUQVsKK0lucHV0U3RyZWFtIGZpbiA9IEZpbGVzLm5ld0lucHV0U3RyZWFtKFBhdGhzLmdldCgic29tZS1maWxlIikpOworQnVmZmVyZWRJbnB1dFN0cmVhbSBpbiA9IG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKGZpbik7CitPdXRwdXRTdHJlYW0gb3V0ID0gRmlsZXMubmV3T3V0cHV0U3RyZWFtKFBhdGhzLmdldCgiYXJjaGl2ZS50YXIiKSk7CitEZWZsYXRlNjRDb21wcmVzc29ySW5wdXRTdHJlYW0gZGVmSW4gPSBuZXcgRGVmbGF0ZTY0Q29tcHJlc3NvcklucHV0U3RyZWFtKGluKTsKK2ZpbmFsIGJ5dGVbXSBidWZmZXIgPSBuZXcgYnl0ZVtidWZmZXJzaXplXTsKK2ludCBuID0gMDsKK3doaWxlICgtMSAhPSAobiA9IGRlZkluLnJlYWQoYnVmZmVyKSkpIHsKKyAgICBvdXQud3JpdGUoYnVmZmVyLCAwLCBuKTsKK30KK291dC5jbG9zZSgpOworZGVmSW4uY2xvc2UoKTsKK11dPjwvc291cmNlPgorCisgICAgICA8L3N1YnNlY3Rpb24+CisKKyAgICAgIDxzdWJzZWN0aW9uIG5hbWU9Imd6aXAiPgorCisgICAgICAgIDxwPlRoZSBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgREVGTEFURS9JTkZMQVRFIGNvZGUgdXNlZCBieSB0aGlzCisgICAgICAgIHBhY2thZ2UgaXMgcHJvdmlkZWQgYnkgdGhlIDxjb2RlPmphdmEudXRpbC56aXA8L2NvZGU+IHBhY2thZ2UKKyAgICAgICAgb2YgdGhlIEphdmEgY2xhc3MgbGlicmFyeS48L3A+CisKKyAgICAgICAgPHA+VW5jb21wcmVzc2luZyBhIGdpdmVuIGd6aXAgY29tcHJlc3NlZCBmaWxlICh5b3Ugd291bGQKKyAgICAgICAgICBjZXJ0YWlubHkgYWRkIGV4Y2VwdGlvbiBoYW5kbGluZyBhbmQgbWFrZSBzdXJlIGFsbCBzdHJlYW1zCisgICAgICAgICAgZ2V0IGNsb3NlZCBwcm9wZXJseSk6PC9wPgorPHNvdXJjZT48IVtDREFUQVsKK0lucHV0U3RyZWFtIGZpbiA9IEZpbGVzLm5ld0lucHV0U3RyZWFtKFBhdGhzLmdldCgiYXJjaGl2ZS50YXIuZ3oiKSk7CitCdWZmZXJlZElucHV0U3RyZWFtIGluID0gbmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0oZmluKTsKK091dHB1dFN0cmVhbSBvdXQgPSBGaWxlcy5uZXdPdXRwdXRTdHJlYW0oUGF0aHMuZ2V0KCJhcmNoaXZlLnRhciIpKTsKK0d6aXBDb21wcmVzc29ySW5wdXRTdHJlYW0gZ3pJbiA9IG5ldyBHemlwQ29tcHJlc3NvcklucHV0U3RyZWFtKGluKTsKK2ZpbmFsIGJ5dGVbXSBidWZmZXIgPSBuZXcgYnl0ZVtidWZmZXJzaXplXTsKK2ludCBuID0gMDsKK3doaWxlICgtMSAhPSAobiA9IGd6SW4ucmVhZChidWZmZXIpKSkgeworICAgIG91dC53cml0ZShidWZmZXIsIDAsIG4pOworfQorb3V0LmNsb3NlKCk7CitnekluLmNsb3NlKCk7CitdXT48L3NvdXJjZT4KKworICAgICAgICA8cD5Db21wcmVzc2luZyBhIGdpdmVuIGZpbGUgdXNpbmcgZ3ppcCAoeW91IHdvdWxkCisgICAgICAgICAgY2VydGFpbmx5IGFkZCBleGNlcHRpb24gaGFuZGxpbmcgYW5kIG1ha2Ugc3VyZSBhbGwgc3RyZWFtcworICAgICAgICAgIGdldCBjbG9zZWQgcHJvcGVybHkpOjwvcD4KKzxzb3VyY2U+PCFbQ0RBVEFbCitJbnB1dFN0cmVhbSBpbiA9IEZpbGVzLm5ld0lucHV0U3RyZWFtKFBhdGhzLmdldCgiYXJjaGl2ZS50YXIiKSk7CitPdXRwdXRTdHJlYW0gZm91dCA9IEZpbGVzLm5ld091dHB1dFN0cmVhbShQYXRocy5nZXQoImFyY2hpdmUudGFyLmd6IikpOworQnVmZmVyZWRPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IEJ1ZmZlcmVkT3V0cHV0U3RyZWFtKGZvdXQpOworR3ppcENvbXByZXNzb3JPdXRwdXRTdHJlYW0gZ3pPdXQgPSBuZXcgR3ppcENvbXByZXNzb3JPdXRwdXRTdHJlYW0ob3V0KTsKK2ZpbmFsIGJ5dGVbXSBidWZmZXIgPSBuZXcgYnl0ZVtidWZmZXJzaXplXTsKK2ludCBuID0gMDsKK3doaWxlICgtMSAhPSAobiA9IGluLnJlYWQoYnVmZmVyKSkpIHsKKyAgICBnek91dC53cml0ZShidWZmZXIsIDAsIG4pOworfQorZ3pPdXQuY2xvc2UoKTsKK2luLmNsb3NlKCk7CitdXT48L3NvdXJjZT4KKworICAgICAgPC9zdWJzZWN0aW9uPgorCisgICAgICA8c3Vic2VjdGlvbiBuYW1lPSJMWjQiPgorCisgICAgICAgIDxwPlRoZXJlIGFyZSB0d28gZGlmZmVyZW50ICJmb3JtYXRzIiB1c2VkIGZvciA8YQorICAgICAgICBocmVmPSJodHRwOi8vbHo0LmdpdGh1Yi5pby9sejQvIj5sejQ8L2E+LiBUaGUgZm9ybWF0IGNhbGxlZAorICAgICAgICAiYmxvY2sgZm9ybWF0IiBvbmx5IGNvbnRhaW5zIHRoZSByYXcgY29tcHJlc3NlZCBkYXRhIHdoaWxlIHRoZQorICAgICAgICBvdGhlciBwcm92aWRlcyBhIGhpZ2hlciBsZXZlbCAiZnJhbWUgZm9ybWF0IiAtIENvbW1vbnMKKyAgICAgICAgQ29tcHJlc3Mgb2ZmZXJzIHR3byBkaWZmZXJlbnQgc3RyZWFtIGNsYXNzZXMgZm9yIHJlYWRpbmcgb3IKKyAgICAgICAgd3JpdGluZyBlaXRoZXIgZm9ybWF0LjwvcD4KKworICAgICAgICA8cD5VbmNvbXByZXNzaW5nIGEgZ2l2ZW4gZnJhbWUgTFo0IGZpbGUgKHlvdSB3b3VsZAorICAgICAgICAgIGNlcnRhaW5seSBhZGQgZXhjZXB0aW9uIGhhbmRsaW5nIGFuZCBtYWtlIHN1cmUgYWxsIHN0cmVhbXMKKyAgICAgICAgICBnZXQgY2xvc2VkIHByb3Blcmx5KTo8L3A+Cis8c291cmNlPjwhW0NEQVRBWworSW5wdXRTdHJlYW0gZmluID0gRmlsZXMubmV3SW5wdXRTdHJlYW0oUGF0aHMuZ2V0KCJhcmNoaXZlLnRhci5sejQiKSk7CitCdWZmZXJlZElucHV0U3RyZWFtIGluID0gbmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0oZmluKTsKK091dHB1dFN0cmVhbSBvdXQgPSBGaWxlcy5uZXdPdXRwdXRTdHJlYW0oUGF0aHMuZ2V0KCJhcmNoaXZlLnRhciIpKTsKK0ZyYW1lZExaNENvbXByZXNzb3JJbnB1dFN0cmVhbSB6SW4gPSBuZXcgRnJhbWVkTFo0Q29tcHJlc3NvcklucHV0U3RyZWFtKGluKTsKK2ZpbmFsIGJ5dGVbXSBidWZmZXIgPSBuZXcgYnl0ZVtidWZmZXJzaXplXTsKK2ludCBuID0gMDsKK3doaWxlICgtMSAhPSAobiA9IHpJbi5yZWFkKGJ1ZmZlcikpKSB7CisgICAgb3V0LndyaXRlKGJ1ZmZlciwgMCwgbik7Cit9CitvdXQuY2xvc2UoKTsKK3pJbi5jbG9zZSgpOworXV0+PC9zb3VyY2U+CisKKyAgICAgICAgPHA+Q29tcHJlc3NpbmcgYSBnaXZlbiBmaWxlIHVzaW5nIHRoZSBMWjQgZnJhbWUgZm9ybWF0ICh5b3Ugd291bGQKKyAgICAgICAgICBjZXJ0YWlubHkgYWRkIGV4Y2VwdGlvbiBoYW5kbGluZyBhbmQgbWFrZSBzdXJlIGFsbCBzdHJlYW1zCisgICAgICAgICAgZ2V0IGNsb3NlZCBwcm9wZXJseSk6PC9wPgorPHNvdXJjZT48IVtDREFUQVsKK0lucHV0U3RyZWFtIGluID0gRmlsZXMubmV3SW5wdXRTdHJlYW0oUGF0aHMuZ2V0KCJhcmNoaXZlLnRhciIpKTsKK091dHB1dFN0cmVhbSBmb3V0ID0gRmlsZXMubmV3T3V0cHV0U3RyZWFtKFBhdGhzLmdldCgiYXJjaGl2ZS50YXIubHo0IikpOworQnVmZmVyZWRPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IEJ1ZmZlcmVkT3V0cHV0U3RyZWFtKGZvdXQpOworRnJhbWVkTFo0Q29tcHJlc3Nvck91dHB1dFN0cmVhbSBsek91dCA9IG5ldyBGcmFtZWRMWjRDb21wcmVzc29yT3V0cHV0U3RyZWFtKG91dCk7CitmaW5hbCBieXRlW10gYnVmZmVyID0gbmV3IGJ5dGVbYnVmZmVyc2l6ZV07CitpbnQgbiA9IDA7Cit3aGlsZSAoLTEgIT0gKG4gPSBpbi5yZWFkKGJ1ZmZlcikpKSB7CisgICAgbHpPdXQud3JpdGUoYnVmZmVyLCAwLCBuKTsKK30KK2x6T3V0LmNsb3NlKCk7Citpbi5jbG9zZSgpOworXV0+PC9zb3VyY2U+CisKKyAgICAgIDwvc3Vic2VjdGlvbj4KKworICAgICAgPHN1YnNlY3Rpb24gbmFtZT0ibHptYSI+CisKKyAgICAgICAgPHA+VGhlIGltcGxlbWVudGF0aW9uIG9mIHRoaXMgcGFja2FnZSBpcyBwcm92aWRlZCBieSB0aGUKKyAgICAgICAgICBwdWJsaWMgZG9tYWluIDxhIGhyZWY9Imh0dHBzOi8vdHVrYWFuaS5vcmcveHovamF2YS5odG1sIj5YWgorICAgICAgICAgIGZvciBKYXZhPC9hPiBsaWJyYXJ5LjwvcD4KKworICAgICAgICA8cD5VbmNvbXByZXNzaW5nIGEgZ2l2ZW4gbHptYSBjb21wcmVzc2VkIGZpbGUgKHlvdSB3b3VsZAorICAgICAgICAgIGNlcnRhaW5seSBhZGQgZXhjZXB0aW9uIGhhbmRsaW5nIGFuZCBtYWtlIHN1cmUgYWxsIHN0cmVhbXMKKyAgICAgICAgICBnZXQgY2xvc2VkIHByb3Blcmx5KTo8L3A+Cis8c291cmNlPjwhW0NEQVRBWworSW5wdXRTdHJlYW0gZmluID0gRmlsZXMubmV3SW5wdXRTdHJlYW0oUGF0aHMuZ2V0KCJhcmNoaXZlLnRhci5sem1hIikpOworQnVmZmVyZWRJbnB1dFN0cmVhbSBpbiA9IG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKGZpbik7CitPdXRwdXRTdHJlYW0gb3V0ID0gRmlsZXMubmV3T3V0cHV0U3RyZWFtKFBhdGhzLmdldCgiYXJjaGl2ZS50YXIiKSk7CitMWk1BQ29tcHJlc3NvcklucHV0U3RyZWFtIGx6bWFJbiA9IG5ldyBMWk1BQ29tcHJlc3NvcklucHV0U3RyZWFtKGluKTsKK2ZpbmFsIGJ5dGVbXSBidWZmZXIgPSBuZXcgYnl0ZVtidWZmZXJzaXplXTsKK2ludCBuID0gMDsKK3doaWxlICgtMSAhPSAobiA9IHh6SW4ucmVhZChidWZmZXIpKSkgeworICAgIG91dC53cml0ZShidWZmZXIsIDAsIG4pOworfQorb3V0LmNsb3NlKCk7Citsem1hSW4uY2xvc2UoKTsKK11dPjwvc291cmNlPgorCisgICAgICAgIDxwPkNvbXByZXNzaW5nIGEgZ2l2ZW4gZmlsZSB1c2luZyBsem1hICh5b3Ugd291bGQKKyAgICAgICAgICBjZXJ0YWlubHkgYWRkIGV4Y2VwdGlvbiBoYW5kbGluZyBhbmQgbWFrZSBzdXJlIGFsbCBzdHJlYW1zCisgICAgICAgICAgZ2V0IGNsb3NlZCBwcm9wZXJseSk6PC9wPgorPHNvdXJjZT48IVtDREFUQVsKK0lucHV0U3RyZWFtIGluID0gRmlsZXMubmV3SW5wdXRTdHJlYW0oUGF0aHMuZ2V0KCJhcmNoaXZlLnRhciIpKTsKK091dHB1dFN0cmVhbSBmb3V0ID0gRmlsZXMubmV3T3V0cHV0U3RyZWFtKFBhdGhzLmdldCgiYXJjaGl2ZS50YXIubHptYSIpKTsKK0J1ZmZlcmVkT3V0cHV0U3RyZWFtIG91dCA9IG5ldyBCdWZmZXJlZE91dHB1dFN0cmVhbShmb3V0KTsKK0xaTUFDb21wcmVzc29yT3V0cHV0U3RyZWFtIGx6T3V0ID0gbmV3IExaTUFDb21wcmVzc29yT3V0cHV0U3RyZWFtKG91dCk7CitmaW5hbCBieXRlW10gYnVmZmVyID0gbmV3IGJ5dGVbYnVmZmVyc2l6ZV07CitpbnQgbiA9IDA7Cit3aGlsZSAoLTEgIT0gKG4gPSBpbi5yZWFkKGJ1ZmZlcikpKSB7CisgICAgbHpPdXQud3JpdGUoYnVmZmVyLCAwLCBuKTsKK30KK2x6T3V0LmNsb3NlKCk7Citpbi5jbG9zZSgpOworXV0+PC9zb3VyY2U+CisKKyAgICAgIDwvc3Vic2VjdGlvbj4KKworICAgICAgPHN1YnNlY3Rpb24gbmFtZT0iUGFjazIwMCI+CisKKyAgICAgICAgPHA+VGhlIFBhY2syMDAgcGFja2FnZSBoYXMgYSA8YSBocmVmPSJwYWNrMjAwLmh0bWwiPmRlZGljYXRlZAorICAgICAgICAgIGRvY3VtZW50YXRpb24gcGFnZTwvYT4uPC9wPgorCisgICAgICAgIDxwPlRoZSBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzIHBhY2thZ2UgaXMgcHJvdmlkZWQgYnkKKyAgICAgICAgICB0aGUgPGNvZGU+amF2YS51dGlsLnppcDwvY29kZT4gcGFja2FnZSBvZiB0aGUgSmF2YSBjbGFzcworICAgICAgICAgIGxpYnJhcnkuPC9wPgorCisgICAgICAgIDxwPlVuY29tcHJlc3NpbmcgYSBnaXZlbiBwYWNrMjAwIGNvbXByZXNzZWQgZmlsZSAoeW91IHdvdWxkCisgICAgICAgICAgY2VydGFpbmx5IGFkZCBleGNlcHRpb24gaGFuZGxpbmcgYW5kIG1ha2Ugc3VyZSBhbGwgc3RyZWFtcworICAgICAgICAgIGdldCBjbG9zZWQgcHJvcGVybHkpOjwvcD4KKzxzb3VyY2U+PCFbQ0RBVEFbCitJbnB1dFN0cmVhbSBmaW4gPSBGaWxlcy5uZXdJbnB1dFN0cmVhbShQYXRocy5nZXQoImFyY2hpdmUucGFjayIpKTsKK0J1ZmZlcmVkSW5wdXRTdHJlYW0gaW4gPSBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShmaW4pOworT3V0cHV0U3RyZWFtIG91dCA9IEZpbGVzLm5ld091dHB1dFN0cmVhbShQYXRocy5nZXQoImFyY2hpdmUuamFyIikpOworUGFjazIwMENvbXByZXNzb3JJbnB1dFN0cmVhbSBwSW4gPSBuZXcgUGFjazIwMENvbXByZXNzb3JJbnB1dFN0cmVhbShpbik7CitmaW5hbCBieXRlW10gYnVmZmVyID0gbmV3IGJ5dGVbYnVmZmVyc2l6ZV07CitpbnQgbiA9IDA7Cit3aGlsZSAoLTEgIT0gKG4gPSBwSW4ucmVhZChidWZmZXIpKSkgeworICAgIG91dC53cml0ZShidWZmZXIsIDAsIG4pOworfQorb3V0LmNsb3NlKCk7CitwSW4uY2xvc2UoKTsKK11dPjwvc291cmNlPgorCisgICAgICAgIDxwPkNvbXByZXNzaW5nIGEgZ2l2ZW4gamFyIHVzaW5nIHBhY2syMDAgKHlvdSB3b3VsZAorICAgICAgICAgIGNlcnRhaW5seSBhZGQgZXhjZXB0aW9uIGhhbmRsaW5nIGFuZCBtYWtlIHN1cmUgYWxsIHN0cmVhbXMKKyAgICAgICAgICBnZXQgY2xvc2VkIHByb3Blcmx5KTo8L3A+Cis8c291cmNlPjwhW0NEQVRBWworSW5wdXRTdHJlYW0gaW4gPSBGaWxlcy5uZXdJbnB1dFN0cmVhbShQYXRocy5nZXQoImFyY2hpdmUuamFyIikpOworT3V0cHV0U3RyZWFtIGZvdXQgPSBGaWxlcy5uZXdPdXRwdXRTdHJlYW0oUGF0aHMuZ2V0KCJhcmNoaXZlLnBhY2siKSk7CitCdWZmZXJlZE91dHB1dFN0cmVhbSBvdXQgPSBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShmb3V0KTsKK1BhY2syMDBDb21wcmVzc29yT3V0cHV0U3RyZWFtIHBPdXQgPSBuZXcgUGFjazIwMENvbXByZXNzb3JPdXRwdXRTdHJlYW0ob3V0KTsKK2ZpbmFsIGJ5dGVbXSBidWZmZXIgPSBuZXcgYnl0ZVtidWZmZXJzaXplXTsKK2ludCBuID0gMDsKK3doaWxlICgtMSAhPSAobiA9IGluLnJlYWQoYnVmZmVyKSkpIHsKKyAgICBwT3V0LndyaXRlKGJ1ZmZlciwgMCwgbik7Cit9CitwT3V0LmNsb3NlKCk7Citpbi5jbG9zZSgpOworXV0+PC9zb3VyY2U+CisKKyAgICAgIDwvc3Vic2VjdGlvbj4KKworICAgICAgPHN1YnNlY3Rpb24gbmFtZT0iU25hcHB5Ij4KKworICAgICAgICA8cD5UaGVyZSBhcmUgdHdvIGRpZmZlcmVudCAiZm9ybWF0cyIgdXNlZCBmb3IgPGEKKyAgICAgICAgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9zbmFwcHkvIj5TbmFwcHk8L2E+LCBvbmUgb25seQorICAgICAgICBjb250YWlucyB0aGUgcmF3IGNvbXByZXNzZWQgZGF0YSB3aGlsZSB0aGUgb3RoZXIgcHJvdmlkZXMgYQorICAgICAgICBoaWdoZXIgbGV2ZWwgImZyYW1pbmcgZm9ybWF0IiAtIENvbW1vbnMgQ29tcHJlc3Mgb2ZmZXJzIHR3bworICAgICAgICBkaWZmZXJlbnQgc3RyZWFtIGNsYXNzZXMgZm9yIHJlYWRpbmcgZWl0aGVyIGZvcm1hdC48L3A+CisKKyAgICAgICAgPHA+U3RhcnRpbmcgd2l0aCAxLjEyIHdlJ3ZlIGFkZGVkIHN1cHBvcnQgZm9yIGRpZmZlcmVudAorICAgICAgICBkaWFsZWN0cyBvZiB0aGUgZnJhbWluZyBmb3JtYXQgdGhhdCBjYW4gYmUgc3BlY2lmaWVkIHdoZW4KKyAgICAgICAgY29uc3RydWN0aW5nIHRoZSBzdHJlYW0uIFRoZSA8Y29kZT5TVEFOREFSRDwvY29kZT4gZGlhbGVjdAorICAgICAgICBmb2xsb3dzIHRoZSAiZnJhbWluZyBmb3JtYXQiIHNwZWNpZmljYXRpb24gd2hpbGUgdGhlCisgICAgICAgIDxjb2RlPklXT1JLX0FSQ0hJVkU8L2NvZGU+IGRpYWxlY3QgY2FuIGJlIHVzZWQgdG8gcGFyc2UgSVdBCisgICAgICAgIGZpbGVzIHRoYXQgYXJlIHBhcnQgb2YgQXBwbGUncyBpV29yayAxMyBmb3JtYXQuIElmIG5vIGRpYWxlY3QKKyAgICAgICAgaGFzIGJlZW4gc3BlY2lmaWVkLCA8Y29kZT5TVEFOREFSRDwvY29kZT4gaXMgdXNlZC4gT25seSB0aGUKKyAgICAgICAgPGNvZGU+U1RBTkRBUkQ8L2NvZGU+IGZvcm1hdCBjYW4gYmUgZGV0ZWN0ZWQgYnkKKyAgICAgICAgPGNvZGU+Q29tcHJlc3NvclN0cmVhbUZhY3Rvcnk8L2NvZGU+LjwvcD4KKworICAgICAgICA8cD5VbmNvbXByZXNzaW5nIGEgZ2l2ZW4gZnJhbWVkIFNuYXBweSBmaWxlICh5b3Ugd291bGQKKyAgICAgICAgICBjZXJ0YWlubHkgYWRkIGV4Y2VwdGlvbiBoYW5kbGluZyBhbmQgbWFrZSBzdXJlIGFsbCBzdHJlYW1zCisgICAgICAgICAgZ2V0IGNsb3NlZCBwcm9wZXJseSk6PC9wPgorPHNvdXJjZT48IVtDREFUQVsKK0lucHV0U3RyZWFtIGZpbiA9IEZpbGVzLm5ld0lucHV0U3RyZWFtKFBhdGhzLmdldCgiYXJjaGl2ZS50YXIuc3oiKSk7CitCdWZmZXJlZElucHV0U3RyZWFtIGluID0gbmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0oZmluKTsKK091dHB1dFN0cmVhbSBvdXQgPSBGaWxlcy5uZXdPdXRwdXRTdHJlYW0oUGF0aHMuZ2V0KCJhcmNoaXZlLnRhciIpKTsKK0ZyYW1lZFNuYXBweUNvbXByZXNzb3JJbnB1dFN0cmVhbSB6SW4gPSBuZXcgRnJhbWVkU25hcHB5Q29tcHJlc3NvcklucHV0U3RyZWFtKGluKTsKK2ZpbmFsIGJ5dGVbXSBidWZmZXIgPSBuZXcgYnl0ZVtidWZmZXJzaXplXTsKK2ludCBuID0gMDsKK3doaWxlICgtMSAhPSAobiA9IHpJbi5yZWFkKGJ1ZmZlcikpKSB7CisgICAgb3V0LndyaXRlKGJ1ZmZlciwgMCwgbik7Cit9CitvdXQuY2xvc2UoKTsKK3pJbi5jbG9zZSgpOworXV0+PC9zb3VyY2U+CisKKyAgICAgICAgPHA+Q29tcHJlc3NpbmcgYSBnaXZlbiBmaWxlIHVzaW5nIGZyYW1lZCBTbmFwcHkgKHlvdSB3b3VsZAorICAgICAgICAgIGNlcnRhaW5seSBhZGQgZXhjZXB0aW9uIGhhbmRsaW5nIGFuZCBtYWtlIHN1cmUgYWxsIHN0cmVhbXMKKyAgICAgICAgICBnZXQgY2xvc2VkIHByb3Blcmx5KTo8L3A+Cis8c291cmNlPjwhW0NEQVRBWworSW5wdXRTdHJlYW0gaW4gPSBGaWxlcy5uZXdJbnB1dFN0cmVhbShQYXRocy5nZXQoImFyY2hpdmUudGFyIikpOworT3V0cHV0U3RyZWFtIGZvdXQgPSBGaWxlcy5uZXdPdXRwdXRTdHJlYW0oUGF0aHMuZ2V0KCJhcmNoaXZlLnRhci5zeiIpKTsKK0J1ZmZlcmVkT3V0cHV0U3RyZWFtIG91dCA9IG5ldyBCdWZmZXJlZE91dHB1dFN0cmVhbShmb3V0KTsKK0ZyYW1lZFNuYXBweUNvbXByZXNzb3JPdXRwdXRTdHJlYW0gc25PdXQgPSBuZXcgRnJhbWVkU25hcHB5Q29tcHJlc3Nvck91dHB1dFN0cmVhbShvdXQpOworZmluYWwgYnl0ZVtdIGJ1ZmZlciA9IG5ldyBieXRlW2J1ZmZlcnNpemVdOworaW50IG4gPSAwOword2hpbGUgKC0xICE9IChuID0gaW4ucmVhZChidWZmZXIpKSkgeworICAgIHNuT3V0LndyaXRlKGJ1ZmZlciwgMCwgbik7Cit9Citzbk91dC5jbG9zZSgpOworaW4uY2xvc2UoKTsKK11dPjwvc291cmNlPgorCisgICAgICA8L3N1YnNlY3Rpb24+CisKKyAgICAgIDxzdWJzZWN0aW9uIG5hbWU9IlhaIj4KKworICAgICAgICA8cD5UaGUgaW1wbGVtZW50YXRpb24gb2YgdGhpcyBwYWNrYWdlIGlzIHByb3ZpZGVkIGJ5IHRoZQorICAgICAgICAgIHB1YmxpYyBkb21haW4gPGEgaHJlZj0iaHR0cHM6Ly90dWthYW5pLm9yZy94ei9qYXZhLmh0bWwiPlhaCisgICAgICAgICAgZm9yIEphdmE8L2E+IGxpYnJhcnkuPC9wPgorCisgICAgICAgIDxwPldoZW4geW91IHRyeSB0byBvcGVuIGFuIFhaIHN0cmVhbSBmb3IgcmVhZGluZyB1c2luZworICAgICAgICA8Y29kZT5Db21wcmVzc29yU3RyZWFtRmFjdG9yeTwvY29kZT4sIENvbW1vbnMgQ29tcHJlc3Mgd2lsbAorICAgICAgICBjaGVjayB3aGV0aGVyIHRoZSBYWiBmb3IgSmF2YSBsaWJyYXJ5IGlzIGF2YWlsYWJsZS4gIFN0YXJ0aW5nCisgICAgICAgIHdpdGggQ29tcHJlc3MgMS45IHRoZSByZXN1bHQgb2YgdGhpcyBjaGVjayB3aWxsIGJlIGNhY2hlZAorICAgICAgICB1bmxlc3MgQ29tcHJlc3MgZmluZHMgT1NHaSBjbGFzc2VzIGluIGl0cyBjbGFzc3BhdGguICBZb3UgY2FuCisgICAgICAgIHVzZSA8Y29kZT5YWlV0aWxzI3NldENhY2hlWFpBdmFpbGFiaWxpdHk8L2NvZGU+IHRvIG92ZXJycmlkZQorICAgICAgICB0aGlzIGRlZmF1bHQgYmVoYXZpb3IuPC9wPgorCisgICAgICAgIDxwPlVuY29tcHJlc3NpbmcgYSBnaXZlbiBYWiBjb21wcmVzc2VkIGZpbGUgKHlvdSB3b3VsZAorICAgICAgICAgIGNlcnRhaW5seSBhZGQgZXhjZXB0aW9uIGhhbmRsaW5nIGFuZCBtYWtlIHN1cmUgYWxsIHN0cmVhbXMKKyAgICAgICAgICBnZXQgY2xvc2VkIHByb3Blcmx5KTo8L3A+Cis8c291cmNlPjwhW0NEQVRBWworSW5wdXRTdHJlYW0gZmluID0gRmlsZXMubmV3SW5wdXRTdHJlYW0oUGF0aHMuZ2V0KCJhcmNoaXZlLnRhci54eiIpKTsKK0J1ZmZlcmVkSW5wdXRTdHJlYW0gaW4gPSBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShmaW4pOworT3V0cHV0U3RyZWFtIG91dCA9IEZpbGVzLm5ld091dHB1dFN0cmVhbShQYXRocy5nZXQoImFyY2hpdmUudGFyIikpOworWFpDb21wcmVzc29ySW5wdXRTdHJlYW0geHpJbiA9IG5ldyBYWkNvbXByZXNzb3JJbnB1dFN0cmVhbShpbik7CitmaW5hbCBieXRlW10gYnVmZmVyID0gbmV3IGJ5dGVbYnVmZmVyc2l6ZV07CitpbnQgbiA9IDA7Cit3aGlsZSAoLTEgIT0gKG4gPSB4ekluLnJlYWQoYnVmZmVyKSkpIHsKKyAgICBvdXQud3JpdGUoYnVmZmVyLCAwLCBuKTsKK30KK291dC5jbG9zZSgpOworeHpJbi5jbG9zZSgpOworXV0+PC9zb3VyY2U+CisKKyAgICAgICAgPHA+Q29tcHJlc3NpbmcgYSBnaXZlbiBmaWxlIHVzaW5nIFhaICh5b3Ugd291bGQKKyAgICAgICAgICBjZXJ0YWlubHkgYWRkIGV4Y2VwdGlvbiBoYW5kbGluZyBhbmQgbWFrZSBzdXJlIGFsbCBzdHJlYW1zCisgICAgICAgICAgZ2V0IGNsb3NlZCBwcm9wZXJseSk6PC9wPgorPHNvdXJjZT48IVtDREFUQVsKK0lucHV0U3RyZWFtIGluID0gRmlsZXMubmV3SW5wdXRTdHJlYW0oUGF0aHMuZ2V0KCJhcmNoaXZlLnRhciIpKTsKK091dHB1dFN0cmVhbSBmb3V0ID0gRmlsZXMubmV3T3V0cHV0U3RyZWFtKFBhdGhzLmdldCgiYXJjaGl2ZS50YXIueHoiKSk7CitCdWZmZXJlZE91dHB1dFN0cmVhbSBvdXQgPSBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShmb3V0KTsKK1haQ29tcHJlc3Nvck91dHB1dFN0cmVhbSB4ek91dCA9IG5ldyBYWkNvbXByZXNzb3JPdXRwdXRTdHJlYW0ob3V0KTsKK2ZpbmFsIGJ5dGVbXSBidWZmZXIgPSBuZXcgYnl0ZVtidWZmZXJzaXplXTsKK2ludCBuID0gMDsKK3doaWxlICgtMSAhPSAobiA9IGluLnJlYWQoYnVmZmVyKSkpIHsKKyAgICB4ek91dC53cml0ZShidWZmZXIsIDAsIG4pOworfQoreHpPdXQuY2xvc2UoKTsKK2luLmNsb3NlKCk7CitdXT48L3NvdXJjZT4KKworICAgICAgPC9zdWJzZWN0aW9uPgorCisgICAgICA8c3Vic2VjdGlvbiBuYW1lPSJaIj4KKworICAgICAgICA8cD5VbmNvbXByZXNzaW5nIGEgZ2l2ZW4gWiBjb21wcmVzc2VkIGZpbGUgKHlvdSB3b3VsZAorICAgICAgICAgIGNlcnRhaW5seSBhZGQgZXhjZXB0aW9uIGhhbmRsaW5nIGFuZCBtYWtlIHN1cmUgYWxsIHN0cmVhbXMKKyAgICAgICAgICBnZXQgY2xvc2VkIHByb3Blcmx5KTo8L3A+Cis8c291cmNlPjwhW0NEQVRBWworSW5wdXRTdHJlYW0gZmluID0gRmlsZXMubmV3SW5wdXRTdHJlYW0oUGF0aHMuZ2V0KCJhcmNoaXZlLnRhci5aIikpOworQnVmZmVyZWRJbnB1dFN0cmVhbSBpbiA9IG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKGZpbik7CitPdXRwdXRTdHJlYW0gb3V0ID0gRmlsZXMubmV3T3V0cHV0U3RyZWFtKFBhdGhzLmdldCgiYXJjaGl2ZS50YXIiKSk7CitaQ29tcHJlc3NvcklucHV0U3RyZWFtIHpJbiA9IG5ldyBaQ29tcHJlc3NvcklucHV0U3RyZWFtKGluKTsKK2ZpbmFsIGJ5dGVbXSBidWZmZXIgPSBuZXcgYnl0ZVtidWZmZXJzaXplXTsKK2ludCBuID0gMDsKK3doaWxlICgtMSAhPSAobiA9IHpJbi5yZWFkKGJ1ZmZlcikpKSB7CisgICAgb3V0LndyaXRlKGJ1ZmZlciwgMCwgbik7Cit9CitvdXQuY2xvc2UoKTsKK3pJbi5jbG9zZSgpOworXV0+PC9zb3VyY2U+CisKKyAgICAgIDwvc3Vic2VjdGlvbj4KKworICAgICAgPHN1YnNlY3Rpb24gbmFtZT0iWnN0YW5kYXJkIj4KKworICAgICAgICA8cD5UaGUgaW1wbGVtZW50YXRpb24gb2YgdGhpcyBwYWNrYWdlIGlzIHByb3ZpZGVkIGJ5IHRoZQorICAgICAgICAgIDxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9sdWJlbi96c3RkLWpuaSI+WnN0YW5kYXJkIEpOSTwvYT4gbGlicmFyeS48L3A+CisKKyAgICAgICAgPHA+VW5jb21wcmVzc2luZyBhIGdpdmVuIFpzdGFuZGFyZCBjb21wcmVzc2VkIGZpbGUgKHlvdSB3b3VsZAorICAgICAgICAgIGNlcnRhaW5seSBhZGQgZXhjZXB0aW9uIGhhbmRsaW5nIGFuZCBtYWtlIHN1cmUgYWxsIHN0cmVhbXMKKyAgICAgICAgICBnZXQgY2xvc2VkIHByb3Blcmx5KTo8L3A+Cis8c291cmNlPjwhW0NEQVRBWworSW5wdXRTdHJlYW0gZmluID0gRmlsZXMubmV3SW5wdXRTdHJlYW0oUGF0aHMuZ2V0KCJhcmNoaXZlLnRhci56c3RkIikpOworQnVmZmVyZWRJbnB1dFN0cmVhbSBpbiA9IG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKGZpbik7CitPdXRwdXRTdHJlYW0gb3V0ID0gRmlsZXMubmV3T3V0cHV0U3RyZWFtKFBhdGhzLmdldCgiYXJjaGl2ZS50YXIiKSk7Citac3RkQ29tcHJlc3NvcklucHV0U3RyZWFtIHpzSW4gPSBuZXcgWnN0ZENvbXByZXNzb3JJbnB1dFN0cmVhbShpbik7CitmaW5hbCBieXRlW10gYnVmZmVyID0gbmV3IGJ5dGVbYnVmZmVyc2l6ZV07CitpbnQgbiA9IDA7Cit3aGlsZSAoLTEgIT0gKG4gPSB6c0luLnJlYWQoYnVmZmVyKSkpIHsKKyAgICBvdXQud3JpdGUoYnVmZmVyLCAwLCBuKTsKK30KK291dC5jbG9zZSgpOworenNJbi5jbG9zZSgpOworXV0+PC9zb3VyY2U+CisKKyAgICAgICAgPHA+Q29tcHJlc3NpbmcgYSBnaXZlbiBmaWxlIHVzaW5nIHRoZSBac3RhbmRhcmQgZm9ybWF0ICh5b3UKKyAgICAgICAgd291bGQgY2VydGFpbmx5IGFkZCBleGNlcHRpb24gaGFuZGxpbmcgYW5kIG1ha2Ugc3VyZSBhbGwKKyAgICAgICAgc3RyZWFtcyBnZXQgY2xvc2VkIHByb3Blcmx5KTo8L3A+Cis8c291cmNlPjwhW0NEQVRBWworSW5wdXRTdHJlYW0gaW4gPSBGaWxlcy5uZXdJbnB1dFN0cmVhbShQYXRocy5nZXQoImFyY2hpdmUudGFyIikpOworT3V0cHV0U3RyZWFtIGZvdXQgPSBGaWxlcy5uZXdPdXRwdXRTdHJlYW0oUGF0aHMuZ2V0KCJhcmNoaXZlLnRhci56c3RkIikpOworQnVmZmVyZWRPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IEJ1ZmZlcmVkT3V0cHV0U3RyZWFtKGZvdXQpOworWnN0ZENvbXByZXNzb3JPdXRwdXRTdHJlYW0gek91dCA9IG5ldyBac3RkQ29tcHJlc3Nvck91dHB1dFN0cmVhbShvdXQpOworZmluYWwgYnl0ZVtdIGJ1ZmZlciA9IG5ldyBieXRlW2J1ZmZlcnNpemVdOworaW50IG4gPSAwOword2hpbGUgKC0xICE9IChuID0gaW4ucmVhZChidWZmZXIpKSkgeworICAgIHpPdXQud3JpdGUoYnVmZmVyLCAwLCBuKTsKK30KK3pPdXQuY2xvc2UoKTsKK2luLmNsb3NlKCk7CitdXT48L3NvdXJjZT4KKworICAgICAgPC9zdWJzZWN0aW9uPgorICAgIDwvc2VjdGlvbj4KKworICAgIDxzZWN0aW9uIG5hbWU9IkV4dGVuZGluZyBDb21tb25zIENvbXByZXNzIj4KKworICAgICAgICA8cD4KKyAgICAgICAgICBTdGFydGluZyBpbiByZWxlYXNlIDEuMTMsIGl0IGlzIG5vdyBwb3NzaWJsZSB0byBhZGQgQ29tcHJlc3Nvci0gYW5kIEFyY2hpdmVyU3RyZWFtIGltcGxlbWVudGF0aW9ucyB1c2luZyB0aGUgCisgICAgICAgICAgSmF2YSdzIDxhIGhyZWY9Imh0dHBzOi8vZG9jcy5vcmFjbGUuY29tL2phdmFzZS83L2RvY3MvYXBpL2phdmEvdXRpbC9TZXJ2aWNlTG9hZGVyLmh0bWwiPlNlcnZpY2VMb2FkZXI8L2E+IAorICAgICAgICAgIG1lY2hhbmlzbS4KKyAgICAgICAgPC9wPgorCisgICAgPHN1YnNlY3Rpb24gbmFtZT0iRXh0ZW5kaW5nIENvbW1vbnMgQ29tcHJlc3MgQ29tcHJlc3NvcnMiPgorCisgICAgICAgIDxwPgorICAgICAgICAgIFRvIHByb3ZpZGUgeW91ciBvd24gY29tcHJlc3NvciwgeW91IG11c3QgbWFrZSBhdmFpbGFibGUgb24gdGhlIGNsYXNzcGF0aCBhIGZpbGUgY2FsbGVkIAorICAgICAgICAgIDxjb2RlPk1FVEEtSU5GL3NlcnZpY2VzL29yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5Db21wcmVzc29yU3RyZWFtUHJvdmlkZXI8L2NvZGU+LgorICAgICAgICA8L3A+CisgICAgICAgIDxwPgorICAgICAgICAgIFRoaXMgZmlsZSBNVVNUIGNvbnRhaW4gb25lIGZ1bGx5LXF1YWxpZmllZCBjbGFzcyBuYW1lIHBlciBsaW5lLgorICAgICAgICA8L3A+CisgICAgICAgIDxwPgorICAgICAgICAgIEZvciBleGFtcGxlOgorICAgICAgICA8L3A+CisgICAgICAgIDxwcmU+b3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLlRlc3RDb21wcmVzc29yU3RyZWFtUHJvdmlkZXI8L3ByZT4KKyAgICAgICAgPHA+CisgICAgICAgICAgVGhpcyBjbGFzcyBNVVNUIGltcGxlbWVudCB0aGUgQ29tbW9ucyBDb21wcmVzcyBpbnRlcmZhY2UgCisgICAgICAgICAgPGEgaHJlZj0iYXBpZG9jcy9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvQ29tcHJlc3NvclN0cmVhbVByb3ZpZGVyLmh0bWwiPm9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5Db21wcmVzc29yU3RyZWFtUHJvdmlkZXI8L2E+LgorICAgICAgICA8L3A+CisgICAgPC9zdWJzZWN0aW9uPgorCisgICAgPHN1YnNlY3Rpb24gbmFtZT0iRXh0ZW5kaW5nIENvbW1vbnMgQ29tcHJlc3MgQXJjaGl2ZXJzIj4KKworICAgICAgICA8cD4KKyAgICAgICAgICBUbyBwcm92aWRlIHlvdXIgb3duIGNvbXByZXNzb3IsIHlvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIG9uIHRoZSBjbGFzc3BhdGggYSBmaWxlIGNhbGxlZCAKKyAgICAgICAgICA8Y29kZT5NRVRBLUlORi9zZXJ2aWNlcy9vcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLkFyY2hpdmVTdHJlYW1Qcm92aWRlcjwvY29kZT4uCisgICAgICAgIDwvcD4KKyAgICAgICAgPHA+CisgICAgICAgICAgVGhpcyBmaWxlIE1VU1QgY29udGFpbiBvbmUgZnVsbHktcXVhbGlmaWVkIGNsYXNzIG5hbWUgcGVyIGxpbmUuCisgICAgICAgIDwvcD4KKyAgICAgICAgPHA+CisgICAgICAgICAgRm9yIGV4YW1wbGU6CisgICAgICAgIDwvcD4KKyAgICAgICAgPHByZT5vcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLlRlc3RBcmNoaXZlU3RyZWFtUHJvdmlkZXI8L3ByZT4KKyAgICAgICAgPHA+CisgICAgICAgICAgVGhpcyBjbGFzcyBNVVNUIGltcGxlbWVudCB0aGUgQ29tbW9ucyBDb21wcmVzcyBpbnRlcmZhY2UgCisgICAgICAgICAgPGEgaHJlZj0iYXBpZG9jcy9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL0FyY2hpdmVTdHJlYW1Qcm92aWRlci5odG1sIj5vcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLkFyY2hpdmVTdHJlYW1Qcm92aWRlcjwvYT4uCisgICAgICAgIDwvcD4KKyAgICA8L3N1YnNlY3Rpb24+CisKKyAgICA8L3NlY3Rpb24+CisgIDwvYm9keT4KKzwvZG9jdW1lbnQ+CmRpZmYgLS1naXQgYS9zcmMvc2l0ZS94ZG9jL2luZGV4LnhtbCBiL3NyYy9zaXRlL3hkb2MvaW5kZXgueG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ5NGIwNTQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvc2l0ZS94ZG9jL2luZGV4LnhtbApAQCAtMCwwICsxLDEzMCBAQAorPD94bWwgdmVyc2lvbj0iMS4wIj8+Cis8IS0tCisKKyAgIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAgIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisKKyAgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKworICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAgIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisKKy0tPgorPGRvY3VtZW50PgorICAgIDxwcm9wZXJ0aWVzPgorICAgICAgICA8dGl0bGU+T3ZlcnZpZXc8L3RpdGxlPgorICAgICAgICA8YXV0aG9yIGVtYWlsPSJkZXZAY29tbW9ucy5hcGFjaGUub3JnIj5Db21tb25zIERvY3VtZW50YXRpb24gVGVhbTwvYXV0aG9yPgorICAgIDwvcHJvcGVydGllcz4KKyAgICA8Ym9keT4KKyAgICAgICAgPHNlY3Rpb24gbmFtZT0iQXBhY2hlIENvbW1vbnMgQ29tcHJlc3MmI3gyMTIyOyI+CisgICAgICAgICAgICA8cD4KKyAgICAgICAgICAgICAgICBUaGUgQXBhY2hlIENvbW1vbnMgQ29tcHJlc3MgbGlicmFyeSBkZWZpbmVzIGFuIEFQSSBmb3IKKyAgICAgICAgICAgICAgICB3b3JraW5nIHdpdGggYXIsIGNwaW8sIFVuaXggZHVtcCwgdGFyLCB6aXAsIGd6aXAsIFhaLAorICAgICAgICAgICAgICAgIFBhY2syMDAsIGJ6aXAyLCA3eiwgYXJqLCBsem1hLCBzbmFwcHksIERFRkxBVEUsIGx6NCwKKyAgICAgICAgICAgICAgICBCcm90bGksIFpzdGFuZGFyZCwgREVGTEFURTY0IGFuZCBaIGZpbGVzLgorICAgICAgICAgICAgPC9wPgorICAgICAgICAgICAgPHA+CisgICAgICAgICAgICAgICAgVGhlIGNvZGUgaW4gdGhpcyBjb21wb25lbnQgaGFzIG1hbnkgb3JpZ2luczoKKyAgICAgICAgICAgIDwvcD4KKyAgICAgICAgICAgIDx1bD4KKyAgICAgICAgICAgICAgPGxpPlRoZSBiemlwMiwgdGFyIGFuZCB6aXAgc3VwcG9ydCBjYW1lIGZyb20gQXZhbG9uJ3MKKyAgICAgICAgICAgICAgICBFeGNhbGlidXIsIGJ1dCBvcmlnaW5hbGx5IGZyb20gQW50LCBhcyBmYXIgYXMgbGlmZSBpbgorICAgICAgICAgICAgICAgIEFwYWNoZSBnb2VzLiBUaGUgdGFyIHBhY2thZ2UgaXMgb3JpZ2luYWxseSBUaW0gRW5kcmVzJworICAgICAgICAgICAgICAgIHB1YmxpYyBkb21haW4gcGFja2FnZS4gVGhlIGJ6aXAyIHBhY2thZ2UgaXMgYmFzZWQgb24KKyAgICAgICAgICAgICAgICB0aGUgd29yayBkb25lIGJ5IEtlaXJvbiBMaWRkbGUgYXMgd2VsbCBhcyBKdWxpYW4gU2V3YXJkJ3MKKyAgICAgICAgICAgICAgICA8YSBocmVmPSJodHRwOi8vd3d3LmJ6aXAub3JnL2luZGV4Lmh0bWwiPmxpYmJ6aXAyPC9hPi4KKyAgICAgICAgICAgICAgICBJdCBoYXMgbWlncmF0ZWQKKyAgICAgICAgICAgICAgICB2aWE6PGJyLz4gQW50IC0mZ3Q7IEF2YWxvbi1FeGNhbGlidXIgLSZndDsgQ29tbW9ucy1JTworICAgICAgICAgICAgICAgIC0mZ3Q7IENvbW1vbnMtQ29tcHJlc3MuPC9saT4KKyAgICAgICAgICAgICAgPGxpPlRoZSBjcGlvIHBhY2thZ2UgaGFzIGJlZW4gY29udHJpYnV0ZWQgYnkgTWljaGFlbCBLdXNzCisgICAgICAgICAgICAgICAgYW5kCisgICAgICAgICAgICAgICAgdGhlIDxhIGhyZWY9Imh0dHA6Ly9qcnBtLnNvdXJjZWZvcmdlLm5ldC8iPmpSUE08L2E+CisgICAgICAgICAgICAgICAgcHJvamVjdC48L2xpPgorICAgICAgICAgICAgPC91bD4KKworICAgICAgICA8L3NlY3Rpb24+CisKKyAgICAgICAgPHNlY3Rpb24gbmFtZT0iU3RhdHVzIj4KKyAgICAgICAgICA8cD5UaGUgY3VycmVudCByZWxlYXNlIGlzIDEuMTggYW5kIHJlcXVpcmVzIEphdmEgNy48L3A+CisKKyAgICAgICAgICA8cD5CZWxvdyB3ZSBoaWdobGlnaHQgc29tZSBuZXcgZmVhdHVyZXMsIGZvciBhIGZ1bGwgbGlzdAorICAgICAgICAgIG9mIGNoYW5nZXMgc2VlIHRoZSA8YSBocmVmPSJjaGFuZ2VzLXJlcG9ydC5odG1sIj5DaGFuZ2VzCisgICAgICAgICAgUmVwb3J0PC9hPi48L3A+CisKKyAgICAgICAgICA8c3Vic2VjdGlvbiBuYW1lPSJXaGF0J3MgbmV3IGluIDEuMTg/Ij4KKyAgICAgICAgICAgIDx1bD4KKyAgICAgICAgICAgICAgPGxpPlRoZSBDUElPIHBhY2thZ2Ugbm93IHByb3Blcmx5IGhhbmRsZXMgZmlsZSBuYW1lcworICAgICAgICAgICAgICB1c2luZyBhIG11bHQtYnl0ZSBlbmNvZGluZy48L2xpPgorICAgICAgICAgICAgICA8bGk+WmlwQXJjaGl2ZUlucHV0U3RyZWFtIGNhbiBub3cgZGVhbCB3aXRoIEFQSyBmaWxlcworICAgICAgICAgICAgICBjb250YWluaW5nIGFuIEFQSyBzaWduaW5nIGJsb2NrLjwvbGk+CisgICAgICAgICAgICAgIDxsaT5JdCBpcyBub3cgcG9zc2libGUgdG8gc3BlY2lmaXkgdmFyaW91cyBwYXJhbWV0ZXJzCisgICAgICAgICAgICAgIGZvciBac3RkIG91dHB1dC48L2xpPgorICAgICAgICAgICAgPC91bD4KKyAgICAgICAgICA8L3N1YnNlY3Rpb24+CisgICAgICAgIDwvc2VjdGlvbj4KKworICAgICAgICA8c2VjdGlvbiBuYW1lPSJEb2N1bWVudGF0aW9uIj4KKyAgICAgICAgICA8cD5UaGUgY29tcHJlc3MgY29tcG9uZW50IGlzIHNwbGl0IGludG8gPGVtPmNvbXByZXNzb3JzPC9lbT4gYW5kCisgICAgICAgICAgICA8ZW0+YXJjaGl2ZXJzPC9lbT4uICBXaGlsZSA8ZW0+Y29tcHJlc3NvcnM8L2VtPgorICAgICAgICAgICAgKHVuKWNvbXByZXNzIHN0cmVhbXMgdGhhdCB1c3VhbGx5IHN0b3JlIGEgc2luZ2xlCisgICAgICAgICAgICBlbnRyeSwgPGVtPmFyY2hpdmVyczwvZW0+IGRlYWwgd2l0aCBhcmNoaXZlcyB0aGF0IGNvbnRhaW4KKyAgICAgICAgICAgIHN0cnVjdHVyZWQgY29udGVudCByZXByZXNlbnRlZAorICAgICAgICAgICAgYnkgPGNvZGU+QXJjaGl2ZUVudHJ5PC9jb2RlPiBpbnN0YW5jZXMgd2hpY2ggaW4gdHVybgorICAgICAgICAgICAgdXN1YWxseSBjb3JyZXNwb25kIHRvIHNpbmdsZSBmaWxlcyBvciBkaXJlY3Rvcmllcy48L3A+CisKKyAgICAgICAgICA8cD5DdXJyZW50bHkgdGhlIGJ6aXAyLCBQYWNrMjAwLCBYWiwgZ3ppcCwgbHptYSwgYnJvdGxpLAorICAgICAgICAgICAgWnN0YW5kYXJkIGFuZCBaIGZvcm1hdHMgYXJlCisgICAgICAgICAgICBzdXBwb3J0ZWQgYXMgY29tcHJlc3NvcnMgd2hlcmUgZ3ppcCBzdXBwb3J0IGlzIG1vc3RseSBwcm92aWRlZCBieQorICAgICAgICAgICAgdGhlIDxjb2RlPmphdmEudXRpbC56aXA8L2NvZGU+IHBhY2thZ2UgYW5kIFBhY2syMDAgc3VwcG9ydAorICAgICAgICAgICAgYnkgdGhlIDxjb2RlPmphdmEudXRpbC5qYXI8L2NvZGU+IHBhY2thZ2Ugb2YgdGhlIEphdmEKKyAgICAgICAgICAgIGNsYXNzIGxpYnJhcnkuICBYWiBhbmQgbHptYSBzdXBwb3J0IGlzIHByb3ZpZGVkIGJ5IHRoZSBwdWJsaWMKKyAgICAgICAgICAgIGRvbWFpbiA8YSBocmVmPSJodHRwczovL3R1a2Fhbmkub3JnL3h6L2phdmEuaHRtbCI+WFogZm9yCisgICAgICAgICAgICBKYXZhPC9hPiBsaWJyYXJ5LiAgQnJvdGxpIHN1cHBvcnQgaXMgcHJvdmlkZWQgYnkgdGhlIE1JVAorICAgICAgICAgICAgbGljZW5zZWQgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9icm90bGkiPkdvb2dsZQorICAgICAgICAgICAgQnJvdGxpIGRlY29kZXI8L2E+LiBac3RhbmRhcmQgc3VwcG9ydCBpcyBwcm92aWRlZCBieSB0aGUgQlNECisgICAgICAgICAgICBsaWNlbnNlZCA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vbHViZW4venN0ZC1qbmkiPlpzdGQtam5pPC9hPi4KKyAgICAgICAgICAgIEFzIG9mIENvbW1vbnMgQ29tcHJlc3MgMS4xOCBzdXBwb3J0IGZvciB0aGUgREVGTEFURTY0LCBaIGFuZCBCcm90bGkKKyAgICAgICAgICAgIGZvcm1hdHMgaXMgcmVhZC1vbmx5LjwvcD4KKworICAgICAgICAgIDxwPlRoZSBhciwgYXJqLCBjcGlvLCBkdW1wLCB0YXIsIDd6IGFuZCB6aXAgZm9ybWF0cyBhcmUgc3VwcG9ydGVkIGFzCisgICAgICAgICAgICBhcmNoaXZlcnMgd2hlcmUgdGhlIDxhIGhyZWY9InppcC5odG1sIj56aXA8L2E+CisgICAgICAgICAgICBpbXBsZW1lbnRhdGlvbiBwcm92aWRlcyBjYXBhYmlsaXRpZXMgdGhhdCBnbyBiZXlvbmQgdGhlCisgICAgICAgICAgICBmZWF0dXJlcyBmb3VuZCBpbiBqYXZhLnV0aWwuemlwLiAgQXMgb2YgQ29tbW9ucyBDb21wcmVzcworICAgICAgICAgICAgMS4xOCBzdXBwb3J0IGZvciB0aGUgZHVtcCBhbmQgYXJqIGZvcm1hdHMgaXMKKyAgICAgICAgICAgIHJlYWQtb25seSAtIDd6IGNhbiByZWFkIG1vc3QgY29tcHJlc3NlZCBhbmQgZW5jcnlwdGVkCisgICAgICAgICAgICBhcmNoaXZlcyBidXQgb25seSB3cml0ZSB1bmVuY3J5cHRlZCBvbmVzLiAgTFpNQSgyKSBzdXBwb3J0CisgICAgICAgICAgICBpbiA3eiByZXF1aXJlcyA8YSBocmVmPSJodHRwczovL3R1a2Fhbmkub3JnL3h6L2phdmEuaHRtbCI+WFogZm9yCisgICAgICAgICAgICBKYXZhPC9hPiBhcyB3ZWxsLjwvcD4KKworICAgICAgICAgIDxwPlRoZSBjb21wcmVzcyBjb21wb25lbnQgcHJvdmlkZXMgYWJzdHJhY3QgYmFzZSBjbGFzc2VzIGZvcgorICAgICAgICAgICAgY29tcHJlc3NvcnMgYW5kIGFyY2hpdmVycyB0b2dldGhlciB3aXRoIGZhY3RvcmllcyB0aGF0IGNhbgorICAgICAgICAgICAgYmUgdXNlZCB0byBjaG9vc2UgaW1wbGVtZW50YXRpb25zIGJ5IGFsZ29yaXRobSBuYW1lLiAgSW4KKyAgICAgICAgICAgIHRoZSBjYXNlIG9mIGlucHV0IHN0cmVhbXMgdGhlIGZhY3RvcmllcyBjYW4gYWxzbyBiZSB1c2VkCisgICAgICAgICAgICB0byBndWVzcyB0aGUgZm9ybWF0IGFuZCBwcm92aWRlIHRoZSBtYXRjaGluZworICAgICAgICAgICAgaW1wbGVtZW50YXRpb24uPC9wPgorCisgICAgICAgICAgPHVsPgorICAgICAgICAgICAgPGxpPlRoZSA8YSBocmVmPSJleGFtcGxlcy5odG1sIj51c2VyIGd1aWRlPC9hPiBjb250YWlucworICAgICAgICAgICAgbW9yZSBkZXRhaWxlZCBpbmZvcm1hdGlvbiBhbmQgc29tZSBleGFtcGxlcy48L2xpPgorICAgICAgICAgICAgPGxpPlRoZSA8YSBocmVmPSJsaW1pdGF0aW9ucy5odG1sIj5rbm93biBsaW1pdGF0aW9ucyBhbmQKKyAgICAgICAgICAgIHByb2JsZW1zPC9hPiBwYWdlIGxpc3RzIHRoZSBjdXJyZW50bHkga25vd24gcHJvYmxlbXMKKyAgICAgICAgICAgIGdyb3VwZWQgYnkgdGhlIGZvcm1hdCB0aGV5IGFwcGx5IHRvLjwvbGk+CisgICAgICAgICAgICA8bGk+VGhlIDxhIGhyZWY9ImFwaWRvY3MvaW5kZXguaHRtbCI+SmF2YWRvYzwvYT4gb2YgdGhlIGxhdGVzdCBHSVQ8L2xpPgorICAgICAgICAgICAgPGxpPlRoZSA8YSBocmVmPSJodHRwczovL2dpdC13aXAtdXMuYXBhY2hlLm9yZy9yZXBvcy9hc2Y/cD1jb21tb25zLWNvbXByZXNzLmdpdDthPXRyZWUiPkdJVAorICAgICAgICAgICAgICAgIHJlcG9zaXRvcnk8L2E+IGNhbiBiZSBicm93c2VkLjwvbGk+CisgICAgICAgICAgICA8L3VsPgorICAgICAgICA8L3NlY3Rpb24+CisgICAgICAgIDxzZWN0aW9uIG5hbWU9IlJlbGVhc2VzIj4KKyAgICAgICAgICA8cD4KKyAgICAgICAgICAgIDxhIGhyZWY9Imh0dHBzOi8vY29tbW9ucy5hcGFjaGUub3JnL2NvbXByZXNzL2Rvd25sb2FkX2NvbXByZXNzLmNnaSI+RG93bmxvYWQgbm93ITwvYT4KKyAgICAgICAgICA8L3A+CisgICAgICAgIDwvc2VjdGlvbj4KKyAgICA8L2JvZHk+Cis8L2RvY3VtZW50PgpkaWZmIC0tZ2l0IGEvc3JjL3NpdGUveGRvYy9pc3N1ZS10cmFja2luZy54bWwgYi9zcmMvc2l0ZS94ZG9jL2lzc3VlLXRyYWNraW5nLnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42Mzg5ZjkyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3NpdGUveGRvYy9pc3N1ZS10cmFja2luZy54bWwKQEAgLTAsMCArMSwxMDIgQEAKKzw/eG1sIHZlcnNpb249IjEuMCI/PgorPCEtLQorTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCitjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKK3RoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KK1RoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAordGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKworICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKworVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKK1dJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCistLT4KKzwhLS0KKyArPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSsKKyB8KioqKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKioqKnwKKyB8KioqKiAgICAgIFRISVMgRklMRSBJUyBHRU5FUkFURUQgQlkgVEhFIENPTU1PTlMgQlVJTEQgUExVR0lOICAgICAgKioqKnwKKyB8KioqKiAgICAgICAgICAgICAgICAgICAgRE8gTk9UIEVESVQgRElSRUNUTFkgICAgICAgICAgICAgICAgICAgICAgKioqKnwKKyB8KioqKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKioqKnwKKyArPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSsKKyB8IFRFTVBMQVRFIEZJTEU6IGlzc3VlLXRyYWNraW5nLXRlbXBsYXRlLnhtbCAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKyB8IGNvbW1vbnMtYnVpbGQtcGx1Z2luL3RydW5rL3NyYy9tYWluL3Jlc291cmNlcy9jb21tb25zLXhkb2MtdGVtcGxhdGVzIHwKKyArPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSsKKyB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKyB8IDEpIFJlLWdlbmVyYXRlIHVzaW5nOiBtdm4gY29tbW9uczpqaXJhLXBhZ2UgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKyB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKyB8IDIpIFNldCB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXMgaW4gdGhlIGNvbXBvbmVudCdzIHBvbTogICAgICAgICAgICAgIHwKKyB8ICAgIC0gY29tbW9ucy5qaXJhLmlkICAocmVxdWlyZWQsIGFscGhhYmV0aWMsIHVwcGVyIGNhc2UpICAgICAgICAgICAgIHwKKyB8ICAgIC0gY29tbW9ucy5qaXJhLnBpZCAocmVxdWlyZWQsIG51bWVyaWMpICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKyB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKyB8IDMpIEV4YW1wbGUgUHJvcGVydGllcyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKyB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKyB8ICA8cHJvcGVydGllcz4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKyB8ICAgIDxjb21tb25zLmppcmEuaWQ+TUFUSDwvY29tbW9ucy5qaXJhLmlkPiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKyB8ICAgIDxjb21tb25zLmppcmEucGlkPjEyMzEwNDg1PC9jb21tb25zLmppcmEucGlkPiAgICAgICAgICAgICAgICAgICAgIHwKKyB8ICA8L3Byb3BlcnRpZXM+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKyB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKyArPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSsKKy0tPgorPGRvY3VtZW50PgorICA8cHJvcGVydGllcz4KKyAgICA8dGl0bGU+QXBhY2hlIENvbW1vbnMgQ29tcHJlc3MgSXNzdWUgdHJhY2tpbmc8L3RpdGxlPgorICAgIDxhdXRob3IgZW1haWw9ImRldkBjb21tb25zLmFwYWNoZS5vcmciPkFwYWNoZSBDb21tb25zIERvY3VtZW50YXRpb24gVGVhbTwvYXV0aG9yPgorICA8L3Byb3BlcnRpZXM+CisgIDxib2R5PgorCisgICAgPHNlY3Rpb24gbmFtZT0iQXBhY2hlIENvbW1vbnMgQ29tcHJlc3MgSXNzdWUgdHJhY2tpbmciPgorICAgICAgPHA+CisgICAgICBBcGFjaGUgQ29tbW9ucyBDb21wcmVzcyB1c2VzIDxhIGhyZWY9Imh0dHBzOi8vaXNzdWVzLmFwYWNoZS5vcmcvamlyYS8iPkFTRiBKSVJBPC9hPiBmb3IgdHJhY2tpbmcgaXNzdWVzLgorICAgICAgU2VlIHRoZSA8YSBocmVmPSJodHRwczovL2lzc3Vlcy5hcGFjaGUub3JnL2ppcmEvYnJvd3NlL0NPTVBSRVNTIj5BcGFjaGUgQ29tbW9ucyBDb21wcmVzcyBKSVJBIHByb2plY3QgcGFnZTwvYT4uCisgICAgICA8L3A+CisKKyAgICAgIDxwPgorICAgICAgVG8gdXNlIEpJUkEgeW91IG1heSBuZWVkIHRvIDxhIGhyZWY9Imh0dHBzOi8vaXNzdWVzLmFwYWNoZS5vcmcvamlyYS9zZWN1cmUvU2lnbnVwIWRlZmF1bHQuanNwYSI+Y3JlYXRlIGFuIGFjY291bnQ8L2E+CisgICAgICAoaWYgeW91IGhhdmUgcHJldmlvdXNseSBjcmVhdGVkL3VwZGF0ZWQgQ29tbW9ucyBpc3N1ZXMgdXNpbmcgQnVnemlsbGEgYW4gYWNjb3VudCB3aWxsIGhhdmUgYmVlbiBhdXRvbWF0aWNhbGx5CisgICAgICBjcmVhdGVkIGFuZCB5b3UgY2FuIHVzZSB0aGUgPGEgaHJlZj0iaHR0cHM6Ly9pc3N1ZXMuYXBhY2hlLm9yZy9qaXJhL3NlY3VyZS9Gb3Jnb3RQYXNzd29yZCFkZWZhdWx0LmpzcGEiPkZvcmdvdCBQYXNzd29yZDwvYT4KKyAgICAgIHBhZ2UgdG8gZ2V0IGEgbmV3IHBhc3N3b3JkKS4KKyAgICAgIDwvcD4KKworICAgICAgPHA+CisgICAgICBJZiB5b3Ugd291bGQgbGlrZSB0byByZXBvcnQgYSBidWcsIG9yIHJhaXNlIGFuIGVuaGFuY2VtZW50IHJlcXVlc3Qgd2l0aAorICAgICAgQXBhY2hlIENvbW1vbnMgQ29tcHJlc3MgcGxlYXNlIGRvIHRoZSBmb2xsb3dpbmc6CisgICAgICA8b2w+CisgICAgICAgIDxsaT48YSBocmVmPSJodHRwczovL2lzc3Vlcy5hcGFjaGUub3JnL2ppcmEvc2VjdXJlL0lzc3VlTmF2aWdhdG9yLmpzcGE/cmVzZXQ9dHJ1ZSZhbXA7cGlkPTEyMzEwOTA0JmFtcDtzb3J0ZXIvZmllbGQ9aXNzdWVrZXkmYW1wO3NvcnRlci9vcmRlcj1ERVNDJmFtcDtzdGF0dXM9MSZhbXA7c3RhdHVzPTMmYW1wO3N0YXR1cz00Ij5TZWFyY2ggZXhpc3Rpbmcgb3BlbiBidWdzPC9hPi4KKyAgICAgICAgICAgIElmIHlvdSBmaW5kIHlvdXIgaXNzdWUgbGlzdGVkIHRoZW4gcGxlYXNlIGFkZCBhIGNvbW1lbnQgd2l0aCB5b3VyIGRldGFpbHMuPC9saT4KKyAgICAgICAgPGxpPjxhIGhyZWY9Im1haWwtbGlzdHMuaHRtbCI+U2VhcmNoIHRoZSBtYWlsaW5nIGxpc3QgYXJjaGl2ZShzKTwvYT4uCisgICAgICAgICAgICBZb3UgbWF5IGZpbmQgeW91ciBpc3N1ZSBvciBpZGVhIGhhcyBhbHJlYWR5IGJlZW4gZGlzY3Vzc2VkLjwvbGk+CisgICAgICAgIDxsaT5EZWNpZGUgaWYgeW91ciBpc3N1ZSBpcyBhIGJ1ZyBvciBhbiBlbmhhbmNlbWVudC48L2xpPgorICAgICAgICA8bGk+U3VibWl0IGVpdGhlciBhIDxhIGhyZWY9Imh0dHBzOi8vaXNzdWVzLmFwYWNoZS5vcmcvamlyYS9zZWN1cmUvQ3JlYXRlSXNzdWVEZXRhaWxzIWluaXQuanNwYT9waWQ9MTIzMTA5MDQmYW1wO2lzc3VldHlwZT0xJmFtcDtwcmlvcml0eT00JmFtcDthc3NpZ25lZT0tMSI+YnVnIHJlcG9ydDwvYT4KKyAgICAgICAgICAgIG9yIDxhIGhyZWY9Imh0dHBzOi8vaXNzdWVzLmFwYWNoZS5vcmcvamlyYS9zZWN1cmUvQ3JlYXRlSXNzdWVEZXRhaWxzIWluaXQuanNwYT9waWQ9MTIzMTA5MDQmYW1wO2lzc3VldHlwZT00JmFtcDtwcmlvcml0eT00JmFtcDthc3NpZ25lZT0tMSI+ZW5oYW5jZW1lbnQgcmVxdWVzdDwvYT4uPC9saT4KKyAgICAgIDwvb2w+CisgICAgICA8L3A+CisKKyAgICAgIDxwPgorICAgICAgUGxlYXNlIGFsc28gcmVtZW1iZXIgdGhlc2UgcG9pbnRzOgorICAgICAgPHVsPgorICAgICAgICA8bGk+dGhlIG1vcmUgaW5mb3JtYXRpb24geW91IHByb3ZpZGUsIHRoZSBiZXR0ZXIgd2UgY2FuIGhlbHAgeW91PC9saT4KKyAgICAgICAgPGxpPnRlc3QgY2FzZXMgYXJlIHZpdGFsLCBwYXJ0aWN1bGFybHkgZm9yIGFueSBwcm9wb3NlZCBlbmhhbmNlbWVudHM8L2xpPgorICAgICAgICA8bGk+dGhlIGRldmVsb3BlcnMgb2YgQXBhY2hlIENvbW1vbnMgQ29tcHJlc3MgYXJlIGFsbCB1bnBhaWQgdm9sdW50ZWVyczwvbGk+CisgICAgICA8L3VsPgorICAgICAgPC9wPgorCisgICAgICA8cD4KKyAgICAgIEZvciBtb3JlIGluZm9ybWF0aW9uIG9uIHN1YnZlcnNpb24gYW5kIGNyZWF0aW5nIHBhdGNoZXMgc2VlIHRoZQorICAgICAgPGEgaHJlZj0iaHR0cHM6Ly93d3cuYXBhY2hlLm9yZy9kZXYvY29udHJpYnV0b3JzLmh0bWwiPkFwYWNoZSBDb250cmlidXRvcnMgR3VpZGU8L2E+LgorICAgICAgPC9wPgorCisgICAgICA8cD4KKyAgICAgIFlvdSBtYXkgYWxzbyBmaW5kIHRoZXNlIGxpbmtzIHVzZWZ1bDoKKyAgICAgIDx1bD4KKyAgICAgICAgPGxpPjxhIGhyZWY9Imh0dHBzOi8vaXNzdWVzLmFwYWNoZS5vcmcvamlyYS9zZWN1cmUvSXNzdWVOYXZpZ2F0b3IuanNwYT9yZXNldD10cnVlJmFtcDtwaWQ9MTIzMTA5MDQmYW1wO3NvcnRlci9maWVsZD1pc3N1ZWtleSZhbXA7c29ydGVyL29yZGVyPURFU0MmYW1wO3N0YXR1cz0xJmFtcDtzdGF0dXM9MyZhbXA7c3RhdHVzPTQiPkFsbCBPcGVuIEFwYWNoZSBDb21tb25zIENvbXByZXNzIGJ1Z3M8L2E+PC9saT4KKyAgICAgICAgPGxpPjxhIGhyZWY9Imh0dHBzOi8vaXNzdWVzLmFwYWNoZS5vcmcvamlyYS9zZWN1cmUvSXNzdWVOYXZpZ2F0b3IuanNwYT9yZXNldD10cnVlJmFtcDtwaWQ9MTIzMTA5MDQmYW1wO3NvcnRlci9maWVsZD1pc3N1ZWtleSZhbXA7c29ydGVyL29yZGVyPURFU0MmYW1wO3N0YXR1cz01JmFtcDtzdGF0dXM9NiI+QWxsIFJlc29sdmVkIEFwYWNoZSBDb21tb25zIENvbXByZXNzIGJ1Z3M8L2E+PC9saT4KKyAgICAgICAgPGxpPjxhIGhyZWY9Imh0dHBzOi8vaXNzdWVzLmFwYWNoZS5vcmcvamlyYS9zZWN1cmUvSXNzdWVOYXZpZ2F0b3IuanNwYT9yZXNldD10cnVlJmFtcDtwaWQ9MTIzMTA5MDQmYW1wO3NvcnRlci9maWVsZD1pc3N1ZWtleSZhbXA7c29ydGVyL29yZGVyPURFU0MiPkFsbCBBcGFjaGUgQ29tbW9ucyBDb21wcmVzcyBidWdzPC9hPjwvbGk+CisgICAgICA8L3VsPgorICAgICAgPC9wPgorICAgIDwvc2VjdGlvbj4KKyAgPC9ib2R5PgorPC9kb2N1bWVudD4KZGlmZiAtLWdpdCBhL3NyYy9zaXRlL3hkb2MvbGltaXRhdGlvbnMueG1sIGIvc3JjL3NpdGUveGRvYy9saW1pdGF0aW9ucy54bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2U5YTgyNgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9zaXRlL3hkb2MvbGltaXRhdGlvbnMueG1sCkBAIC0wLDAgKzEsMjM1IEBACis8P3htbCB2ZXJzaW9uPSIxLjAiPz4KKzwhLS0KKyAgIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAgIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisKKyAgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKworICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAgIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCistLT4KKzxkb2N1bWVudD4KKyAgIDxwcm9wZXJ0aWVzPgorICAgICAgPHRpdGxlPktub3duIExpbWl0YXRpb25zIGFuZCBQcm9ibGVtczwvdGl0bGU+CisgICA8L3Byb3BlcnRpZXM+CisKKyAgIDxib2R5PgorICAgICA8cD5UaGlzIHBhZ2UgbGlzdHMgdGhlIGtub3duIGxpbWl0YXRpb25zIGFuZCBwcm9ibGVtcyBvZiBBcGFjaGUKKyAgICAgQ29tbW9ucyBDb21wcmVzcyYjeDIxMjI7IGdyb3VwZWQgYnkgdGhlIGFyY2hpdmluZy9jb21wcmVzc2lvbgorICAgICBmb3JtYXQgdGhleSBhcHBseSB0by48L3A+CisKKyAgICAgPHNlY3Rpb24gbmFtZT0iR2VuZXJhbCI+CisgICAgICAgPHVsPgorICAgICAgICAgPGxpPlNldmVyYWwgaW1wbGVtZW50YXRpb25zIG9mIGRlY29tcHJlc3NvcnMgYW5kIHVuYXJjaGl2ZXJzIHdpbGwKKyAgICAgICAgIGludm9rZSA8YQorICAgICAgICAgaHJlZj0iaHR0cHM6Ly9kb2NzLm9yYWNsZS5jb20vamF2YXNlLzEwL2RvY3MvYXBpL2phdmEvaW8vSW5wdXRTdHJlYW0uaHRtbCNza2lwKGxvbmcpIj48Y29kZT5za2lwPC9jb2RlPjwvYT4KKyAgICAgICAgIG9uIHRoZSB1bmRlcmx5aW5nIDxjb2RlPklucHV0U3RyZWFtPC9jb2RlPiB3aGljaCBtYXkgdGhyb3cgYW4KKyAgICAgICAgIDxjb2RlPklPRXhjZXB0aW9uPC9jb2RlPiBpbiBzb21lIHN0cmVhbSBpbXBsZW1lbnRhdGlvbnMuIE9uZQorICAgICAgICAga25vd24gY2FzZSB3aGVyZSB0aGlzIGhhcHBlbnMgaXMgd2hlbiB1c2luZworICAgICAgICAgPGNvZGU+U3lzdGVtLmluPC9jb2RlPiBhcyBpbnB1dC4gSWYgeW91IGVuY291bnRlciBhbgorICAgICAgICAgZXhjZXB0aW9uIHdpdGggYSBtZXNzYWdlIGxpa2UgIklsbGVnYWwgc2VlayIgd2UgcmVjb21tZW5kIHlvdQorICAgICAgICAgd3JhcCB5b3VyIHN0cmVhbSBpbiBhIDxjb2RlPlNraXBTaGllbGRpbmdJbnB1dFN0cmVhbTwvY29kZT4KKyAgICAgICAgIGZyb20gb3VyIHV0aWxzIHBhY2thZ2UgYmVmb3JlIHBhc3NpbmcgaXQgdG8gQ29tcHJlc3MuPC9saT4KKyAgICAgICA8L3VsPgorICAgICA8L3NlY3Rpb24+CisKKyAgICAgPHNlY3Rpb24gbmFtZT0iN1oiPgorICAgICAgIDx1bD4KKyAgICAgICAgIDxsaT50aGUgZm9ybWF0IHJlcXVpcmVzIHRoZSBvdGhlcndpc2Ugb3B0aW9uYWwgPGEKKyAgICAgICAgIGhyZWY9Imh0dHBzOi8vdHVrYWFuaS5vcmcveHovamF2YS5odG1sIj5YWiBmb3IgSmF2YTwvYT4KKyAgICAgICAgIGxpYnJhcnkuPC9saT4KKyAgICAgICAgIDxsaT5vbmx5IDxjb2RlPkZpbGU8L2NvZGU+cyBhcmUgc3VwcG9ydGVkIGFzIGlucHV0L291dHB1dCwKKyAgICAgICAgIG5vdCBzdHJlYW1zLiBTdGFydGluZyB3aXRoIENvbXByZXNzIDEuMTMKKyAgICAgICAgIDxjb2RlPlNlZWthYmxlQnl0ZUNoYW5uZWw8L2NvZGU+IGlzIHN1cHBvcnRlZCBhcyB3ZWxsLjwvbGk+CisgICAgICAgICA8bGk+SW4gQ29tcHJlc3MgMS43CisgICAgICAgICA8Y29kZT5BcmNoaXZlU3RyZWFtRmFjdG9yeTwvY29kZT4gd2lsbCBub3QgYXV0by1kZXRlY3QgN3oKKyAgICAgICAgIGFyY2hpdmVzLCBzdGFydGluZyB3aXRoIDEuOCBpdCB3aWxsIHRocm93IGEKKyAgICAgICAgIDxjb2RlPlN0cmVhbWluZ05vdFN1cHBvcnRlZEV4Y2VwdGlvbjwvY29kZT4gd2hlbiByZWFkaW5nIGZyb20KKyAgICAgICAgIGEgN3ogYXJjaGl2ZS48L2xpPgorICAgICAgICAgPGxpPkVuY3J5cHRpb24sIHNvbGlkIGNvbXByZXNzaW9uIGFuZCBoZWFkZXIgY29tcHJlc3Npb24gYW5kCisgICAgICAgICBhcmUgb25seSBzdXBwb3J0ZWQgd2hlbiByZWFkaW5nIGFyY2hpdmVzPC9saT4KKyAgICAgICAgIDxsaT5Db21tb25zIENvbXByZXNzIDEuMTIgYW5kIGVhcmxpZXIgZGlkbid0IHN1cHBvcnQgd3JpdGluZworICAgICAgICAgTFpNQS48L2xpPgorICAgICAgICAgPGxpPlNldmVyYWwgb2YgdGhlICJtZXRob2RzIiBzdXBwb3J0ZWQgYnkgN3ogYXJlIG5vdAorICAgICAgICAgaW1wbGVtZW50ZWQgaW4gQ29tcHJlc3MuPC9saT4KKyAgICAgICAgIDxsaT5ObyBzdXBwb3J0IGZvciBtdWx0aS12b2x1bWUgYXJjaGl2ZXM8L2xpPgorICAgICAgICAgPGxpPlN1cHBvcnQgZm9yIHNvbWUgQkNKIGZpbHRlcnMgYW5kIHRoZSBERUxUQSBmaWx0ZXIgaGFzCisgICAgICAgICBiZWVuIGFkZGVkIHdpdGggQ29tcHJlc3MgMS44LiAgQmVjYXVzZSBvZiBhIGtub3duIGJ1ZyBpbgorICAgICAgICAgdmVyc2lvbiAxLjQgb2YgdGhlIDxhCisgICAgICAgICBocmVmPSJodHRwczovL3R1a2Fhbmkub3JnL3h6L2phdmEuaHRtbCI+WFogZm9yIEphdmE8L2E+CisgICAgICAgICBsaWJyYXJ5LCBhcmNoaXZlcyB1c2luZyBCQ0ogZmlsdGVycyB3aWxsIGNhdXNlIGFuCisgICAgICAgICA8Y29kZT5Bc3NlcnRpb25FcnJvcjwvY29kZT4gd2hlbiByZWFkLiAgSWYgeW91IG5lZWQgc3VwcG9ydAorICAgICAgICAgZm9yIEJDSiBmaWx0ZXJzIHlvdSBtdXN0IHVzZSBYWiBmb3IgSmF2YSAxLjUgb3IgbGF0ZXIuPC9saT4KKyAgICAgICA8L3VsPgorICAgICA8L3NlY3Rpb24+CisgICAgIDxzZWN0aW9uIG5hbWU9IkFSIj4KKyAgICAgICA8dWw+CisgICAgICAgICA8bGk+QVIgYXJjaGl2ZXMgY2FuIG5vdCBjb250YWluIGRpcmVjdG9yaWVzIC0gdGhpcyBpcyBhCisgICAgICAgICBsaW1pdGF0aW9uIG9mIHRoZSBmb3JtYXQgcmF0aGVyIHRoYW4gb25lIG9mIENvbXByZXNzJworICAgICAgICAgaW1wbGVtZW50YXRpb24uPC9saT4KKyAgICAgICAgIDxsaT5maWxlIG5hbWVzIGxvbmdlciB0aGFuIDE2IGNoYXJhY3RlcnMgYXJlIG9ubHkgZnVsbHkKKyAgICAgICAgIHN1cHBvcnRlZCB1c2luZyB0aGUgQlNEIGRpYWxlY3QsIHRoZSBHTlUvU1JWNCBkaWFsZWN0IGlzIG9ubHkKKyAgICAgICAgIHN1cHBvcnRlZCB3aGVuIHJlYWRpbmcgYXJjaGl2ZXMuPC9saT4KKyAgICAgICA8L3VsPgorICAgICA8L3NlY3Rpb24+CisgICAgIDxzZWN0aW9uIG5hbWU9IkFSSiI+CisgICAgICAgPHVsPgorICAgICAgICAgPGxpPnJlYWQtb25seSBzdXBwb3J0PC9saT4KKyAgICAgICAgIDxsaT5ubyBzdXBwb3J0IGZvciBjb21wcmVzc2lvbiwgZW5jcnlwdGlvbiBvciBtdWx0aS12b2x1bWUKKyAgICAgICAgIGFyY2hpdmVzPC9saT4KKyAgICAgICA8L3VsPgorICAgICA8L3NlY3Rpb24+CisgICAgIDxzZWN0aW9uIG5hbWU9IkJyb3RsaSI+CisgICAgICAgPHVsPgorICAgICAgICAgPGxpPnRoZSBmb3JtYXQgcmVxdWlyZXMgdGhlIG90aGVyd2lzZSBvcHRpb25hbCA8YQorICAgICAgICAgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9icm90bGkiPkdvb2dsZSBCcm90bGkgZGVjPC9hPgorICAgICAgICAgbGlicmFyeS48L2xpPgorICAgICAgICAgPGxpPnJlYWQtb25seSBzdXBwb3J0PC9saT4KKyAgICAgICAgIDxsaT48Y29kZT5Db21wcmVzc29yU3RyZWFtRmFjdG9yeTwvY29kZT4gaXMgbm90IGFibGUgdG8gYXV0by1kZXRlY3QKKyAgICAgICAgIHN0cmVhbXMgdXNpbmcgQnJvdGxpIGNvbXByZXNzaW9uLjwvbGk+CisgICAgICAgPC91bD4KKyAgICAgPC9zZWN0aW9uPgorICAgICA8c2VjdGlvbiBuYW1lPSJCWklQMiI+CisgICAgICAgPHA+VmVyc2lvbnMgb2YgQ29tcHJlc3MgcHJpb3IgdG8gMS40LjEgYXJlIHZ1bG5lcmFibGUgdG8gYQorICAgICAgIHBvc3NpYmxlIGRlbmlhbCBvZiBzZXJ2aWNlIGF0dGFjaywgc2VlIHRoZSA8YQorICAgICAgIGhyZWY9InNlY3VyaXR5Lmh0bWwiPlNlY3VyaXR5IFJlcG9ydHM8L2E+IHBhZ2UgZm9yIGRldGFpbHMuPC9wPgorICAgICA8L3NlY3Rpb24+CisgICAgIDxzZWN0aW9uIG5hbWU9IkNQSU8iPgorICAgICAgIDxwPldlIGFyZSBub3QgYXdhcmUgb2YgYW55IHByb2JsZW1zLjwvcD4KKyAgICAgPC9zZWN0aW9uPgorICAgICA8c2VjdGlvbiBuYW1lPSJERUZMQVRFIj4KKyAgICAgICA8dWw+CisgICAgICAgICA8bGk+PGNvZGU+Q29tcHJlc3NvclN0cmVhbUZhY3Rvcnk8L2NvZGU+IGlzIG5vdCBhYmxlIHRvIGF1dG8tZGV0ZWN0CisgICAgICAgICBzdHJlYW1zIHVzaW5nIERFRkxBVEUgY29tcHJlc3Npb24uPC9saT4KKyAgICAgICA8L3VsPgorICAgICA8L3NlY3Rpb24+CisgICAgIDxzZWN0aW9uIG5hbWU9IkRFRkxBVEU2NCI+CisgICAgICAgPHVsPgorICAgICAgICAgPGxpPjxjb2RlPkNvbXByZXNzb3JTdHJlYW1GYWN0b3J5PC9jb2RlPiBpcyBub3QgYWJsZSB0byBhdXRvLWRldGVjdAorICAgICAgICAgc3RyZWFtcyB1c2luZyBERUZMQVRFNjQgY29tcHJlc3Npb24uPC9saT4KKyAgICAgICAgIDxsaT5yZWFkLW9ubHkgc3VwcG9ydDwvbGk+CisgICAgICAgPC91bD4KKyAgICAgPC9zZWN0aW9uPgorICAgICA8c2VjdGlvbiBuYW1lPSJEVU1QIj4KKyAgICAgICA8dWw+CisgICAgICAgICA8bGk+cmVhZC1vbmx5IHN1cHBvcnQ8L2xpPgorICAgICAgICAgPGxpPm9ubHkgdGhlIG5ldy1mcyBmb3JtYXQgaXMgc3VwcG9ydGVkPC9saT4KKyAgICAgICAgIDxsaT50aGUgb25seSBjb21wcmVzc2lvbiBhbGdvcml0aG0gc3VwcG9ydGVkIGlzIHpsaWI8L2xpPgorICAgICAgIDwvdWw+CisgICAgIDwvc2VjdGlvbj4KKyAgICAgPHNlY3Rpb24gbmFtZT0iR1pJUCI+CisgICAgICAgPHA+V2UgYXJlIG5vdCBhd2FyZSBvZiBhbnkgcHJvYmxlbXMuPC9wPgorICAgICA8L3NlY3Rpb24+CisgICAgIDxzZWN0aW9uIG5hbWU9IkpBUiI+CisgICAgICAgPHA+SkFSIGFyY2hpdmVzIGFyZSBzcGVjaWFsIFpJUCBhcmNoaXZlcywgYWxsIGxpbWl0YXRpb25zIG9mIDxhCisgICAgICAgaHJlZj0iI1pJUCI+WklQPC9hPiBhcHBseSB0byBKQVIgYXMgd2VsbC48L3A+CisgICAgICAgPHVsPgorICAgICAgICAgPGxpPjxjb2RlPkFyY2hpdmVTdHJlYW1GYWN0b3J5PC9jb2RlPiBjYW5ub3QgdGVsbCBKQVIKKyAgICAgICAgIGFyY2hpdmVzIGZyb20gWklQIGFyY2hpdmVzIGFuZCB3aWxsIG5vdCBhdXRvLWRldGVjdAorICAgICAgICAgSkFScy48L2xpPgorICAgICAgICAgPGxpPkNvbXByZXNzIGRvZXNuJ3QgcHJvdmlkZSBzcGVjaWFsIGFjY2VzcyB0byB0aGUgYXJjaGl2ZSdzCisgICAgICAgICBNQU5JRkVTVDwvbGk+CisgICAgICAgPC91bD4KKyAgICAgPC9zZWN0aW9uPgorICAgICA8c2VjdGlvbiBuYW1lPSJMWjQiPgorICAgICAgIDx1bD4KKyAgICAgICAgIDxsaT5JbiB0aGVvcnkgTFo0IGNvbXByZXNzZWQgc3RyZWFtcyBjYW4gY29udGFpbiBsaXRlcmFscyBhbmQKKyAgICAgICAgIGNvcGllcyBvZiBhcmJpdHJhcnkgbGVuZ3RoIHdoaWxlIENvbW1vbnMgQ29tcHJlc3Mgb25seQorICAgICAgICAgc3VwcG9ydHMgc2l6ZXMgdXAgdG8gMjxzdXA+NjM8L3N1cD4gLSAxIChpLmUuICYjeDIyNDg7IDkuMgorICAgICAgICAgRUIpLjwvbGk+CisgICAgICAgPC91bD4KKyAgICAgPC9zZWN0aW9uPgorICAgICA8c2VjdGlvbiBuYW1lPSJMWk1BIj4KKyAgICAgICA8dWw+CisgICAgICAgICA8bGk+dGhlIGZvcm1hdCByZXF1aXJlcyB0aGUgb3RoZXJ3aXNlIG9wdGlvbmFsIDxhCisgICAgICAgICBocmVmPSJodHRwczovL3R1a2Fhbmkub3JnL3h6L2phdmEuaHRtbCI+WFogZm9yIEphdmE8L2E+CisgICAgICAgICBsaWJyYXJ5LjwvbGk+CisgICAgICAgICA8bGk+Q29tbW9ucyBDb21wcmVzcyAxLjEyIGFuZCBlYXJsaWVyIG9ubHkgc3VwcG9ydCByZWFkaW5nCisgICAgICAgICB0aGUgZm9ybWF0PC9saT4KKyAgICAgICA8L3VsPgorICAgICA8L3NlY3Rpb24+CisgICAgIDxzZWN0aW9uIG5hbWU9IlBBQ0syMDAiPgorICAgICAgIDxwPldlIGFyZSBub3QgYXdhcmUgb2YgYW55IHByb2JsZW1zLjwvcD4KKyAgICAgPC9zZWN0aW9uPgorICAgICA8c2VjdGlvbiBuYW1lPSJTTkFQUFkiPgorICAgICAgIDx1bD4KKyAgICAgICAgIDxsaT5Db21tb25zIENvbXByZXNzIDEuMTMgYW5kIGVhcmxpZXIgb25seSBzdXBwb3J0IHJlYWRpbmcKKyAgICAgICAgIHRoZSBmb3JtYXQ8L2xpPgorICAgICAgIDwvdWw+CisgICAgIDwvc2VjdGlvbj4KKyAgICAgPHNlY3Rpb24gbmFtZT0iVEFSIj4KKyAgICAgICA8dWw+CisgICAgICAgICA8bGk+c3BhcnNlIGZpbGVzIGNhbiBuZWl0aGVyIGJlIHJlYWQgbm9yIHdyaXR0ZW48L2xpPgorICAgICAgICAgPGxpPm9ubHkgYSBzdWJzZXQgb2YgdGhlIEdOVSBhbmQgUE9TSVggZXh0ZW5zaW9ucyBhcmUKKyAgICAgICAgIHN1cHBvcnRlZDwvbGk+CisgICAgICAgICA8bGk+SW4gQ29tcHJlc3MgMS42IDxjb2RlPlRhckFyY2hpdmVJbnB1dFN0cmVhbTwvY29kZT4gY291bGQKKyAgICAgICAgIGZhaWwgdG8gcmVhZCB0aGUgZnVsbCBjb250ZW50cyBvZiBhbiBlbnRyeSB1bmxlc3MgdGhlIHN0cmVhbQorICAgICAgICAgd2FzIHdyYXBwZWQgaW4gYSBidWZmZXJpbmcgc3RyZWFtLjwvbGk+CisgICAgICAgPC91bD4KKyAgICAgPC9zZWN0aW9uPgorICAgICA8c2VjdGlvbiBuYW1lPSJYWiI+CisgICAgICAgPHVsPgorICAgICAgICAgPGxpPnRoZSBmb3JtYXQgcmVxdWlyZXMgdGhlIG90aGVyd2lzZSBvcHRpb25hbCA8YQorICAgICAgICAgaHJlZj0iaHR0cHM6Ly90dWthYW5pLm9yZy94ei9qYXZhLmh0bWwiPlhaIGZvciBKYXZhPC9hPgorICAgICAgICAgbGlicmFyeS48L2xpPgorICAgICAgIDwvdWw+CisgICAgIDwvc2VjdGlvbj4KKyAgICAgPHNlY3Rpb24gbmFtZT0iWiI+CisgICAgICAgPHVsPgorICAgICAgICAgPGxpPlByaW9yIHRvIENvbXByZXNzIDEuOC4xCisgICAgICAgICA8Y29kZT5Db21wcmVzc29yU3RyZWFtRmFjdG9yeTwvY29kZT4gd2FzIG5vdCBhYmxlIHRvCisgICAgICAgICBhdXRvLWRldGVjdCBzdHJlYW1zIHVzaW5nIC5aIGNvbXByZXNzaW9uLjwvbGk+CisgICAgICAgICA8bGk+cmVhZC1vbmx5IHN1cHBvcnQ8L2xpPgorICAgICAgIDwvdWw+CisgICAgIDwvc2VjdGlvbj4KKyAgICAgPHNlY3Rpb24gbmFtZT0iWklQIj4KKyAgICAgICA8dWw+CisgICAgICAgICA8bGk+PGNvZGU+WmlwQXJjaGl2ZUlucHV0U3RyZWFtPC9jb2RlPiBpcyBsaW1pdGVkIGFuZCBtYXkKKyAgICAgICAgIGV2ZW4gcmV0dXJuIGZhbHNlIGNvbnRlbnRzIGluIHNvbWUgY2FzZXMsIHVzZQorICAgICAgICAgPGNvZGU+WmlwRmlsZTwvY29kZT4gd2hlbmV2ZXIgcG9zc2libGUuICBTZWUgPGEKKyAgICAgICAgIGhyZWY9InppcC5odG1sI1ppcEFyY2hpdmVJbnB1dFN0cmVhbV92c19aaXBGaWxlIj50aGUgWklQCisgICAgICAgICBkb2N1bWVudGF0aW9uIHBhZ2U8L2E+IGZvciBkZXRhaWxzLiAgVGhpcyBsaW1pdGF0aW9uIGlzIGEKKyAgICAgICAgIHJlc3VsdCBvZiBzdHJlYW1pbmcgZGF0YSB2cyB1c2luZyByYW5kb20gYWNjZXNzIGFuZCBub3QgYQorICAgICAgICAgbGltaXRhdGlvbiBvZiBDb21wcmVzcycgc3BlY2lmaWMgaW1wbGVtZW50YXRpb24uPC9saT4KKyAgICAgICAgIDxsaT5vbmx5IGEgc3Vic2V0IG9mIGNvbXByZXNzaW9uIG1ldGhvZHMgYXJlIHN1cHBvcnRlZCwKKyAgICAgICAgIGluY2x1ZGluZyB0aGUgbW9zdCBjb21tb24gU1RPUkVEIGFuZCBERUZMQVRFZC4gIElNUExPREUsCisgICAgICAgICBTSFJJTkssIERFRkxBVEU2NCBhbmQgQlpJUDIgc3VwcG9ydCBpcyByZWFkLW9ubHkuPC9saT4KKyAgICAgICAgIDxsaT5ubyBzdXBwb3J0IGZvciBlbmNyeXB0aW9uIG9yIG11bHRpLXZvbHVtZSBhcmNoaXZlczwvbGk+CisgICAgICAgICA8bGk+SW4gdmVyc2lvbnMgcHJpb3IgdG8gQ29tcHJlc3MgMS42CisgICAgICAgICA8Y29kZT5aaXBBcmNoaXZlRW50cmllczwvY29kZT4gcmVhZCBmcm9tIGFuIGFyY2hpdmUgd2lsbAorICAgICAgICAgY29udGFpbiBub24temVybyBtaWxsaXNlY29uZCB2YWx1ZXMgd2hlbiB1c2luZyBKYXZhOCByYXRoZXIKKyAgICAgICAgIHRoYW4gdGhlIGV4cGVjdGVkIHR3by1zZWNvbmQgZ3JhbnVsYXJpdHkuPC9saT4KKyAgICAgICAgIDxsaT5Db21wcmVzcyAxLjcgaGFzIGEga25vd24gYnVnIHdoZXJlIHRoZSB2ZXJ5IGZpcnN0IGVudHJ5CisgICAgICAgICBvZiBhbiBhcmNoaXZlIHdpbGwgbm90IGJlIHJlYWQgY29ycmVjdGx5IGJ5CisgICAgICAgICA8Y29kZT5aaXBBcmNoaXZlSW5wdXRTdHJlYW08L2NvZGU+IGlmIGl0IHVzZWQgdGhlIFNUT1JFRAorICAgICAgICAgbWV0aG9kLjwvbGk+CisgICAgICAgICA8bGk+PGNvZGU+WmlwQXJjaGl2ZUVudHJ5I2dldExhc3RNb2RpZmllZERhdGU8L2NvZGU+IHVzZXMKKyAgICAgICAgIDxjb2RlPlppcEVudHJ5I2dldFRpbWU8L2NvZGU+IHVuZGVyIHRoZSBjb3ZlcnMgd2hpY2ggbWF5CisgICAgICAgICByZXR1cm4gZGlmZmVyZW50IHRpbWVzIGZvciB0aGUgc2FtZSBhcmNoaXZlIHdoZW4gdXNpbmcKKyAgICAgICAgIGRpZmZlcmVudCB2ZXJzaW9ucyBvZiBKYXZhLjwvbGk+CisgICAgICAgICA8bGk+SW4gdmVyc2lvbnMgb2YgQ29tcHJlc3MgcHJpb3IgdG8gMS4xNiBhIHNwZWNpYWxseSBjcmFmdGVkCisgICAgICAgICBaSVAgYXJjaGl2ZSBjYW4gYmUgdXNlZCB0byBjYXVzZSBhbiBpbmZpbml0ZSBsb29wIGluc2lkZSBvZgorICAgICAgICAgQ29tcHJlc3MnIGV4dHJhIGZpZWxkIHBhcnNlciB1c2VkIGJ5IHRoZSA8Y29kZT5aaXBGaWxlPC9jb2RlPgorICAgICAgICAgYW5kIDxjb2RlPlppcEFyY2hpdmVJbnB1dFN0cmVhbTwvY29kZT4gY2xhc3Nlcy4gIFRoaXMgY2FuIGJlCisgICAgICAgICB1c2VkIHRvIG1vdW50IGEgZGVuaWFsIG9mIHNlcnZpY2UgYXR0YWNrIGFnYWluc3Qgc2VydmljZXMKKyAgICAgICAgIHRoYXQgdXNlIENvbXByZXNzJyB6aXAgcGFja2FnZS4gU2VlIHRoZSA8YQorICAgICAgICAgaHJlZj0ic2VjdXJpdHkuaHRtbCI+U2VjdXJpdHkgUmVwb3J0czwvYT4gcGFnZSBmb3IKKyAgICAgICAgIGRldGFpbHMuPC9saT4KKyAgICAgICA8L3VsPgorICAgICA8L3NlY3Rpb24+CisgICAgIDxzZWN0aW9uIG5hbWU9IlpzdGFuZGFyZCI+CisgICAgICAgPHVsPgorICAgICAgICAgPGxpPnRoZSBmb3JtYXQgcmVxdWlyZXMgdGhlIG90aGVyd2lzZSBvcHRpb25hbCA8YQorICAgICAgICAgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL2x1YmVuL3pzdGQtam5pIj5ac3RhbmRhcmQgSk5JPC9hPgorICAgICAgICAgbGlicmFyeS48L2xpPgorICAgICAgIDwvdWw+CisgICAgIDwvc2VjdGlvbj4KKyAgIDwvYm9keT4KKzwvZG9jdW1lbnQ+CmRpZmYgLS1naXQgYS9zcmMvc2l0ZS94ZG9jL21haWwtbGlzdHMueG1sIGIvc3JjL3NpdGUveGRvYy9tYWlsLWxpc3RzLnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42YjBiMWE1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3NpdGUveGRvYy9tYWlsLWxpc3RzLnhtbApAQCAtMCwwICsxLDIwNSBAQAorPD94bWwgdmVyc2lvbj0iMS4wIj8+Cis8IS0tCitMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKK2NvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAordGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCit0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorCisgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorCitVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCitkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCitTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCitsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKy0tPgorPCEtLQorICs9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09KworIHwqKioqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKioqfAorIHwqKioqICAgICAgVEhJUyBGSUxFIElTIEdFTkVSQVRFRCBCWSBUSEUgQ09NTU9OUyBCVUlMRCBQTFVHSU4gICAgICAqKioqfAorIHwqKioqICAgICAgICAgICAgICAgICAgICBETyBOT1QgRURJVCBESVJFQ1RMWSAgICAgICAgICAgICAgICAgICAgICAqKioqfAorIHwqKioqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKioqfAorICs9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09KworIHwgVEVNUExBVEUgRklMRTogbWFpbC1saXN0cy10ZW1wbGF0ZS54bWwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAorIHwgY29tbW9ucy1idWlsZC1wbHVnaW4vdHJ1bmsvc3JjL21haW4vcmVzb3VyY2VzL2NvbW1vbnMteGRvYy10ZW1wbGF0ZXMgfAorICs9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09KworIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAorIHwgMSkgUmUtZ2VuZXJhdGUgdXNpbmc6IG12biBjb21tb25zOm1haWwtcGFnZSAgICAgICAgICAgICAgICAgICAgICAgICAgfAorIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAorIHwgMikgU2V0IHRoZSBmb2xsb3dpbmcgcHJvcGVydGllcyBpbiB0aGUgY29tcG9uZW50J3MgcG9tOiAgICAgICAgICAgICAgfAorIHwgICAgLSBjb21tb25zLmNvbXBvbmVudGlkIChyZXF1aXJlZCwgYWxwaGFiZXRpYywgbG93ZXIgY2FzZSkgICAgICAgICAgfAorIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAorIHwgMykgRXhhbXBsZSBQcm9wZXJ0aWVzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAorIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAorIHwgIDxwcm9wZXJ0aWVzPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAorIHwgICAgPGNvbW1vbnMuY29tcG9uZW50aWQ+bWF0aDwvY29tbW9ucy5jb21wb25lbnRpZD4gICAgICAgICAgICAgICAgICAgfAorIHwgIDwvcHJvcGVydGllcz4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAorIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAorICs9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09KworLS0+Cis8ZG9jdW1lbnQ+CisgIDxwcm9wZXJ0aWVzPgorICAgIDx0aXRsZT5BcGFjaGUgQ29tbW9ucyBDb21wcmVzcyBNYWlsaW5nIExpc3RzPC90aXRsZT4KKyAgICA8YXV0aG9yIGVtYWlsPSJkZXZAY29tbW9ucy5hcGFjaGUub3JnIj5BcGFjaGUgQ29tbW9ucyBEb2N1bWVudGF0aW9uIFRlYW08L2F1dGhvcj4KKyAgPC9wcm9wZXJ0aWVzPgorICA8Ym9keT4KKworICAgIDxzZWN0aW9uIG5hbWU9Ik92ZXJ2aWV3Ij4KKyAgICAgIDxwPgorICAgICAgICA8YSBocmVmPSJpbmRleC5odG1sIj5BcGFjaGUgQ29tbW9ucyBDb21wcmVzczwvYT4gc2hhcmVzIG1haWxpbmcgbGlzdHMgd2l0aCBhbGwgdGhlIG90aGVyCisgICAgICAgIDxhIGhyZWY9Imh0dHBzOi8vY29tbW9ucy5hcGFjaGUub3JnL2NvbXBvbmVudHMuaHRtbCI+Q29tbW9ucyBDb21wb25lbnRzPC9hPi4KKyAgICAgICAgVG8gbWFrZSBpdCBlYXNpZXIgZm9yIHBlb3BsZSB0byBvbmx5IHJlYWQgbWVzc2FnZXMgcmVsYXRlZCB0byBjb21wb25lbnRzIHRoZXkgYXJlIGludGVyZXN0ZWQgaW4sCisgICAgICAgIHRoZSBjb252ZW50aW9uIGluIENvbW1vbnMgaXMgdG8gcHJlZml4IHRoZSBzdWJqZWN0IGxpbmUgb2YgbWVzc2FnZXMgd2l0aCB0aGUgY29tcG9uZW50J3MgbmFtZSwKKyAgICAgICAgZm9yIGV4YW1wbGU6CisgICAgICAgIDx1bD4KKyAgICAgICAgICA8bGk+W2NvbXByZXNzXSBQcm9ibGVtIHdpdGggdGhlIC4uLjwvbGk+CisgICAgICAgIDwvdWw+CisgICAgICA8L3A+CisgICAgICA8cD4KKyAgICAgICAgUXVlc3Rpb25zIHJlbGF0ZWQgdG8gdGhlIHVzYWdlIG9mIEFwYWNoZSBDb21tb25zIENvbXByZXNzIHNob3VsZCBiZSBwb3N0ZWQgdG8gdGhlCisgICAgICAgIDxhIGhyZWY9Imh0dHBzOi8vbWFpbC1hcmNoaXZlcy5hcGFjaGUub3JnL21vZF9tYm94L2NvbW1vbnMtdXNlci8iPlVzZXIgTGlzdDwvYT4uCisgICAgICAgIDxiciAvPgorICAgICAgICBUaGUgPGEgaHJlZj0iaHR0cHM6Ly9tYWlsLWFyY2hpdmVzLmFwYWNoZS5vcmcvbW9kX21ib3gvY29tbW9ucy1kZXYvIj5EZXZlbG9wZXIgTGlzdDwvYT4KKyAgICAgICAgaXMgZm9yIHF1ZXN0aW9ucyBhbmQgZGlzY3Vzc2lvbiByZWxhdGVkIHRvIHRoZSBkZXZlbG9wbWVudCBvZiBBcGFjaGUgQ29tbW9ucyBDb21wcmVzcy4KKyAgICAgICAgPGJyIC8+CisgICAgICAgIFBsZWFzZSBkbyBub3QgY3Jvc3MtcG9zdDsgZGV2ZWxvcGVycyBhcmUgYWxzbyBzdWJzY3JpYmVkIHRvIHRoZSB1c2VyIGxpc3QuCisgICAgICAgIDxiciAvPgorICAgICAgICBZb3UgbXVzdCBiZSBzdWJzY3JpYmVkIHRvIHBvc3QgdG8gdGhlIG1haWxpbmcgbGlzdHMuICBGb2xsb3cgdGhlIFN1YnNjcmliZSBsaW5rcyBiZWxvdworICAgICAgICB0byBzdWJzY3JpYmUuCisgICAgICA8L3A+CisgICAgICA8cD4KKyAgICAgICAgPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBwbGVhc2UgZG9uJ3Qgc2VuZCBwYXRjaGVzIG9yIGF0dGFjaG1lbnRzIHRvIGFueSBvZiB0aGUgbWFpbGluZyBsaXN0cy4KKyAgICAgICAgUGF0Y2hlcyBhcmUgYmVzdCBoYW5kbGVkIHZpYSB0aGUgPGEgaHJlZj0iaXNzdWUtdHJhY2tpbmcuaHRtbCI+SXNzdWUgVHJhY2tpbmc8L2E+IHN5c3RlbS4KKyAgICAgICAgT3RoZXJ3aXNlLCBwbGVhc2UgdXBsb2FkIHRoZSBmaWxlIHRvIGEgcHVibGljIHNlcnZlciBhbmQgaW5jbHVkZSB0aGUgVVJMIGluIHRoZSBtYWlsLgorICAgICAgPC9wPgorICAgIDwvc2VjdGlvbj4KKworICAgIDxzZWN0aW9uIG5hbWU9IkFwYWNoZSBDb21tb25zIENvbXByZXNzIE1haWxpbmcgTGlzdHMiPgorICAgICAgPHA+CisgICAgICAgIDxzdHJvbmc+UGxlYXNlIHByZWZpeCB0aGUgc3ViamVjdCBsaW5lIG9mIGFueSBtZXNzYWdlcyBmb3IgPGEgaHJlZj0iaW5kZXguaHRtbCI+QXBhY2hlIENvbW1vbnMgQ29tcHJlc3M8L2E+CisgICAgICAgIHdpdGggPGk+W2NvbXByZXNzXTwvaT48L3N0cm9uZz4gLSA8aT50aGFua3MhPC9pPgorICAgICAgICA8YnIgLz4KKyAgICAgICAgPGJyIC8+CisgICAgICA8L3A+CisKKyAgICAgIDx0YWJsZT4KKyAgICAgICAgPHRyPgorICAgICAgICAgIDx0aD5OYW1lPC90aD4KKyAgICAgICAgICA8dGg+U3Vic2NyaWJlPC90aD4KKyAgICAgICAgICA8dGg+VW5zdWJzY3JpYmU8L3RoPgorICAgICAgICAgIDx0aD5Qb3N0PC90aD4KKyAgICAgICAgICA8dGg+QXJjaGl2ZTwvdGg+CisgICAgICAgICAgPHRoPk90aGVyIEFyY2hpdmVzPC90aD4KKyAgICAgICAgPC90cj4KKworCisgICAgICAgIDx0cj4KKyAgICAgICAgICA8dGQ+CisgICAgICAgICAgICA8c3Ryb25nPkNvbW1vbnMgVXNlciBMaXN0PC9zdHJvbmc+CisgICAgICAgICAgICA8YnIgLz48YnIgLz4KKyAgICAgICAgICAgIFF1ZXN0aW9ucyBvbiB1c2luZyBBcGFjaGUgQ29tbW9ucyBDb21wcmVzcy4KKyAgICAgICAgICAgIDxiciAvPjxiciAvPgorICAgICAgICAgIDwvdGQ+CisgICAgICAgICAgPHRkPjxhIGhyZWY9Im1haWx0bzp1c2VyLXN1YnNjcmliZUBjb21tb25zLmFwYWNoZS5vcmciPlN1YnNjcmliZTwvYT48L3RkPgorICAgICAgICAgIDx0ZD48YSBocmVmPSJtYWlsdG86dXNlci11bnN1YnNjcmliZUBjb21tb25zLmFwYWNoZS5vcmciPlVuc3Vic2NyaWJlPC9hPjwvdGQ+CisgICAgICAgICAgPHRkPjxhIGhyZWY9Im1haWx0bzp1c2VyQGNvbW1vbnMuYXBhY2hlLm9yZz9zdWJqZWN0PVtjb21wcmVzc10iPlBvc3Q8L2E+PC90ZD4KKyAgICAgICAgICA8dGQ+PGEgaHJlZj0iaHR0cHM6Ly9tYWlsLWFyY2hpdmVzLmFwYWNoZS5vcmcvbW9kX21ib3gvY29tbW9ucy11c2VyLyI+bWFpbC1hcmNoaXZlcy5hcGFjaGUub3JnPC9hPjwvdGQ+CisgICAgICAgICAgPHRkPjxhIGhyZWY9Imh0dHBzOi8vbWFya21haWwub3JnL2xpc3Qvb3JnLmFwYWNoZS5jb21tb25zLnVzZXJzLyI+bWFya21haWwub3JnPC9hPjxiciAvPgorICAgICAgICAgICAgICA8YSBocmVmPSJodHRwczovL3d3dy5tYWlsLWFyY2hpdmUuY29tL3VzZXJAY29tbW9ucy5hcGFjaGUub3JnLyI+d3d3Lm1haWwtYXJjaGl2ZS5jb208L2E+PGJyIC8+CisgICAgICAgICAgICAgIDxhIGhyZWY9Imh0dHA6Ly9uZXdzLmdtYW5lLm9yZy9nbWFuZS5jb21wLmpha2FydGEuY29tbW9ucy5kZXZlbCI+bmV3cy5nbWFuZS5vcmc8L2E+CisgICAgICAgICAgPC90ZD4KKyAgICAgICAgPC90cj4KKworCisgICAgICAgIDx0cj4KKyAgICAgICAgICA8dGQ+CisgICAgICAgICAgICA8c3Ryb25nPkNvbW1vbnMgRGV2ZWxvcGVyIExpc3Q8L3N0cm9uZz4KKyAgICAgICAgICAgIDxiciAvPjxiciAvPgorICAgICAgICAgICAgRGlzY3Vzc2lvbiBvZiBkZXZlbG9wbWVudCBvZiBBcGFjaGUgQ29tbW9ucyBDb21wcmVzcy4KKyAgICAgICAgICAgIDxiciAvPjxiciAvPgorICAgICAgICAgIDwvdGQ+CisgICAgICAgICAgPHRkPjxhIGhyZWY9Im1haWx0bzpkZXYtc3Vic2NyaWJlQGNvbW1vbnMuYXBhY2hlLm9yZyI+U3Vic2NyaWJlPC9hPjwvdGQ+CisgICAgICAgICAgPHRkPjxhIGhyZWY9Im1haWx0bzpkZXYtdW5zdWJzY3JpYmVAY29tbW9ucy5hcGFjaGUub3JnIj5VbnN1YnNjcmliZTwvYT48L3RkPgorICAgICAgICAgIDx0ZD48YSBocmVmPSJtYWlsdG86ZGV2QGNvbW1vbnMuYXBhY2hlLm9yZz9zdWJqZWN0PVtjb21wcmVzc10iPlBvc3Q8L2E+PC90ZD4KKyAgICAgICAgICA8dGQ+PGEgaHJlZj0iaHR0cHM6Ly9tYWlsLWFyY2hpdmVzLmFwYWNoZS5vcmcvbW9kX21ib3gvY29tbW9ucy1kZXYvIj5tYWlsLWFyY2hpdmVzLmFwYWNoZS5vcmc8L2E+PC90ZD4KKyAgICAgICAgICA8dGQ+PGEgaHJlZj0iaHR0cHM6Ly9tYXJrbWFpbC5vcmcvbGlzdC9vcmcuYXBhY2hlLmNvbW1vbnMuZGV2LyI+bWFya21haWwub3JnPC9hPjxiciAvPgorICAgICAgICAgICAgICA8YSBocmVmPSJodHRwczovL3d3dy5tYWlsLWFyY2hpdmUuY29tL2RldkBjb21tb25zLmFwYWNoZS5vcmcvIj53d3cubWFpbC1hcmNoaXZlLmNvbTwvYT48YnIgLz4KKyAgICAgICAgICAgICAgPGEgaHJlZj0iaHR0cDovL25ld3MuZ21hbmUub3JnL2dtYW5lLmNvbXAuamFrYXJ0YS5jb21tb25zLmRldmVsIj5uZXdzLmdtYW5lLm9yZzwvYT4KKyAgICAgICAgICA8L3RkPgorICAgICAgICA8L3RyPgorCisKKyAgICAgICAgPHRyPgorICAgICAgICAgIDx0ZD4KKyAgICAgICAgICAgIDxzdHJvbmc+Q29tbW9ucyBJc3N1ZXMgTGlzdDwvc3Ryb25nPgorICAgICAgICAgICAgPGJyIC8+PGJyIC8+CisgICAgICAgICAgICBPbmx5IGZvciBlLW1haWxzIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSA8YSBocmVmPSJpc3N1ZS10cmFja2luZy5odG1sIj5pc3N1ZSB0cmFja2luZzwvYT4gc3lzdGVtLgorICAgICAgICAgICAgPGJyIC8+PGJyIC8+CisgICAgICAgICAgPC90ZD4KKyAgICAgICAgICA8dGQ+PGEgaHJlZj0ibWFpbHRvOmlzc3Vlcy1zdWJzY3JpYmVAY29tbW9ucy5hcGFjaGUub3JnIj5TdWJzY3JpYmU8L2E+PC90ZD4KKyAgICAgICAgICA8dGQ+PGEgaHJlZj0ibWFpbHRvOmlzc3Vlcy11bnN1YnNjcmliZUBjb21tb25zLmFwYWNoZS5vcmciPlVuc3Vic2NyaWJlPC9hPjwvdGQ+CisgICAgICAgICAgPHRkPjxpPnJlYWQgb25seTwvaT48L3RkPgorICAgICAgICAgIDx0ZD48YSBocmVmPSJodHRwczovL21haWwtYXJjaGl2ZXMuYXBhY2hlLm9yZy9tb2RfbWJveC9jb21tb25zLWlzc3Vlcy8iPm1haWwtYXJjaGl2ZXMuYXBhY2hlLm9yZzwvYT48L3RkPgorICAgICAgICAgIDx0ZD48YSBocmVmPSJodHRwczovL21hcmttYWlsLm9yZy9saXN0L29yZy5hcGFjaGUuY29tbW9ucy5pc3N1ZXMvIj5tYXJrbWFpbC5vcmc8L2E+PGJyIC8+CisgICAgICAgICAgICAgIDxhIGhyZWY9Imh0dHBzOi8vd3d3Lm1haWwtYXJjaGl2ZS5jb20vaXNzdWVzQGNvbW1vbnMuYXBhY2hlLm9yZy8iPnd3dy5tYWlsLWFyY2hpdmUuY29tPC9hPgorICAgICAgICAgIDwvdGQ+CisgICAgICAgIDwvdHI+CisKKworICAgICAgICA8dHI+CisgICAgICAgICAgPHRkPgorICAgICAgICAgICAgPHN0cm9uZz5Db21tb25zIENvbW1pdHMgTGlzdDwvc3Ryb25nPgorICAgICAgICAgICAgPGJyIC8+PGJyIC8+CisgICAgICAgICAgICBPbmx5IGZvciBlLW1haWxzIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSA8YSBocmVmPSJzb3VyY2UtcmVwb3NpdG9yeS5odG1sIj5zb3VyY2UgY29udHJvbDwvYT4gc3l0ZW0uCisgICAgICAgICAgICA8YnIgLz48YnIgLz4KKyAgICAgICAgICA8L3RkPgorICAgICAgICAgIDx0ZD48YSBocmVmPSJtYWlsdG86Y29tbWl0cy1zdWJzY3JpYmVAY29tbW9ucy5hcGFjaGUub3JnIj5TdWJzY3JpYmU8L2E+PC90ZD4KKyAgICAgICAgICA8dGQ+PGEgaHJlZj0ibWFpbHRvOmNvbW1pdHMtdW5zdWJzY3JpYmVAY29tbW9ucy5hcGFjaGUub3JnIj5VbnN1YnNjcmliZTwvYT48L3RkPgorICAgICAgICAgIDx0ZD48aT5yZWFkIG9ubHk8L2k+PC90ZD4KKyAgICAgICAgICA8dGQ+PGEgaHJlZj0iaHR0cHM6Ly9tYWlsLWFyY2hpdmVzLmFwYWNoZS5vcmcvbW9kX21ib3gvY29tbW9ucy1jb21taXRzLyI+bWFpbC1hcmNoaXZlcy5hcGFjaGUub3JnPC9hPjwvdGQ+CisgICAgICAgICAgPHRkPjxhIGhyZWY9Imh0dHBzOi8vbWFya21haWwub3JnL2xpc3Qvb3JnLmFwYWNoZS5jb21tb25zLmNvbW1pdHMvIj5tYXJrbWFpbC5vcmc8L2E+PGJyIC8+CisgICAgICAgICAgICAgIDxhIGhyZWY9Imh0dHBzOi8vd3d3Lm1haWwtYXJjaGl2ZS5jb20vY29tbWl0c0Bjb21tb25zLmFwYWNoZS5vcmcvIj53d3cubWFpbC1hcmNoaXZlLmNvbTwvYT4KKyAgICAgICAgICA8L3RkPgorICAgICAgICA8L3RyPgorCisgICAgICA8L3RhYmxlPgorCisgICAgPC9zZWN0aW9uPgorICAgIDxzZWN0aW9uIG5hbWU9IkFwYWNoZSBNYWlsaW5nIExpc3RzIj4KKyAgICAgIDxwPgorICAgICAgICBPdGhlciBtYWlsaW5nIGxpc3RzIHdoaWNoIHlvdSBtYXkgZmluZCB1c2VmdWwgaW5jbHVkZToKKyAgICAgIDwvcD4KKworICAgICAgPHRhYmxlPgorICAgICAgICA8dHI+CisgICAgICAgICAgPHRoPk5hbWU8L3RoPgorICAgICAgICAgIDx0aD5TdWJzY3JpYmU8L3RoPgorICAgICAgICAgIDx0aD5VbnN1YnNjcmliZTwvdGg+CisgICAgICAgICAgPHRoPlBvc3Q8L3RoPgorICAgICAgICAgIDx0aD5BcmNoaXZlPC90aD4KKyAgICAgICAgICA8dGg+T3RoZXIgQXJjaGl2ZXM8L3RoPgorICAgICAgICA8L3RyPgorICAgICAgICA8dHI+CisgICAgICAgICAgPHRkPgorICAgICAgICAgICAgPHN0cm9uZz5BcGFjaGUgQW5ub3VuY2UgTGlzdDwvc3Ryb25nPgorICAgICAgICAgICAgPGJyIC8+PGJyIC8+CisgICAgICAgICAgICBHZW5lcmFsIGFubm91bmNlbWVudHMgb2YgQXBhY2hlIHByb2plY3QgcmVsZWFzZXMuCisgICAgICAgICAgICA8YnIgLz48YnIgLz4KKyAgICAgICAgICA8L3RkPgorICAgICAgICAgIDx0ZD48YSBjbGFzcz0iZXh0ZXJuYWxMaW5rIiBocmVmPSJtYWlsdG86YW5ub3VuY2Utc3Vic2NyaWJlQGFwYWNoZS5vcmciPlN1YnNjcmliZTwvYT48L3RkPgorICAgICAgICAgIDx0ZD48YSBjbGFzcz0iZXh0ZXJuYWxMaW5rIiBocmVmPSJtYWlsdG86YW5ub3VuY2UtdW5zdWJzY3JpYmVAYXBhY2hlLm9yZyI+VW5zdWJzY3JpYmU8L2E+PC90ZD4KKyAgICAgICAgICA8dGQ+PGk+cmVhZCBvbmx5PC9pPjwvdGQ+CisgICAgICAgICAgPHRkPjxhIGNsYXNzPSJleHRlcm5hbExpbmsiIGhyZWY9Imh0dHBzOi8vbWFpbC1hcmNoaXZlcy5hcGFjaGUub3JnL21vZF9tYm94L3d3dy1hbm5vdW5jZS8iPm1haWwtYXJjaGl2ZXMuYXBhY2hlLm9yZzwvYT48L3RkPgorICAgICAgICAgIDx0ZD48YSBjbGFzcz0iZXh0ZXJuYWxMaW5rIiBocmVmPSJodHRwczovL21hcmttYWlsLm9yZy9saXN0L29yZy5hcGFjaGUuYW5ub3VuY2UvIj5tYXJrbWFpbC5vcmc8L2E+PGJyIC8+CisgICAgICAgICAgICAgIDxhIGNsYXNzPSJleHRlcm5hbExpbmsiIGhyZWY9Imh0dHA6Ly9vbGQubmFiYmxlLmNvbS9BcGFjaGUtTmV3cy1hbmQtQW5ub3VuY2UtZjEwOS5odG1sIj5vbGQubmFiYmxlLmNvbTwvYT48YnIgLz4KKyAgICAgICAgICAgICAgPGEgY2xhc3M9ImV4dGVybmFsTGluayIgaHJlZj0iaHR0cHM6Ly93d3cubWFpbC1hcmNoaXZlLmNvbS9hbm5vdW5jZUBhcGFjaGUub3JnLyI+d3d3Lm1haWwtYXJjaGl2ZS5jb208L2E+PGJyIC8+CisgICAgICAgICAgICAgIDxhIGNsYXNzPSJleHRlcm5hbExpbmsiIGhyZWY9Imh0dHA6Ly9uZXdzLmdtYW5lLm9yZy9nbWFuZS5jb21wLmFwYWNoZS5hbm5vdW5jZSI+bmV3cy5nbWFuZS5vcmc8L2E+CisgICAgICAgICAgPC90ZD4KKyAgICAgICAgPC90cj4KKyAgICAgIDwvdGFibGU+CisKKyAgICA8L3NlY3Rpb24+CisgIDwvYm9keT4KKzwvZG9jdW1lbnQ+CmRpZmYgLS1naXQgYS9zcmMvc2l0ZS94ZG9jL3BhY2syMDAueG1sIGIvc3JjL3NpdGUveGRvYy9wYWNrMjAwLnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yODYxY2FhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3NpdGUveGRvYy9wYWNrMjAwLnhtbApAQCAtMCwwICsxLDg5IEBACis8P3htbCB2ZXJzaW9uPSIxLjAiPz4KKzwhLS0KKworICAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAgIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAgIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKworICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorCisgICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKworLS0+Cis8ZG9jdW1lbnQ+CisgIDxwcm9wZXJ0aWVzPgorICAgIDx0aXRsZT5Db21tb25zIENvbXByZXNzIFBhY2syMDAgUGFja2FnZTwvdGl0bGU+CisgICAgPGF1dGhvciBlbWFpbD0iZGV2QGNvbW1vbnMuYXBhY2hlLm9yZyI+Q29tbW9ucyBEb2N1bWVudGF0aW9uIFRlYW08L2F1dGhvcj4KKyAgPC9wcm9wZXJ0aWVzPgorICA8Ym9keT4KKyAgICA8c2VjdGlvbiBuYW1lPSJUaGUgUGFjazIwMCBwYWNrYWdlIj4KKworICAgICAgPHA+VGhlIFBhY2syMDAgYWxnb3JpdGhtIGlzIG5vdCBhIGdlbmVyYWwgcHVycG9zZSBjb21wcmVzc2lvbgorICAgICAgYWxnb3JpdGhtIGJ1dCBvbmUgc3BlY2lhbGl6ZWQgZm9yIGNvbXByZXNzaW5nIEpBUiBhcmNoaXZlcy4gIEpBUgorICAgICAgYXJjaGl2ZXMgY29tcHJlc3NlZCB3aXRoIFBhY2syMDAgd2lsbCBpbiBnZW5lcmFsIGJlIGRpZmZlcmVudAorICAgICAgZnJvbSB0aGUgb3JpZ2luYWwgYXJjaGl2ZSB3aGVuIGRlY29tcHJlc3NlZCBhZ2Fpbi4gIE1vcmUKKyAgICAgIGluZm9ybWF0aW9uIGNhbiBiZSBmb3VuZCBpbiB0aGUgSmF2YWRvY3Mgb2YgdGhlIDxhCisgICAgICBocmVmPSJodHRwczovL2RvY3Mub3JhY2xlLmNvbS9qYXZhc2UvNy9kb2NzL2FwaS9qYXZhL3V0aWwvamFyL1BhY2syMDAuUGFja2VyLmh0bWwiPlBhY2syMDAuUGFja2VyCisgICAgICBjbGFzczwvYT4uPC9wPgorCisgICAgICA8cD5XaGlsZSB0aGUgPGNvZGU+cGFjazIwMDwvY29kZT4gY29tbWFuZCBsaW5lIHV0aWxpdHkgb2YgdGhlCisgICAgICBKREsgY3JlYXRlcyBHWmlwIGNvbXByZXNzZWQgYXJjaGl2ZXMgKDxjb2RlPi5wYWNrLmd6PC9jb2RlPikgYnkKKyAgICAgIGRlZmF1bHQsIHRoZSBzdHJlYW1zIHByb3ZpZGVkIGJ5IHRoZSBQYWNrMjAwIHBhY2thZ2Ugb25seQorICAgICAgcGVyZm9ybSB0aGUgYWN0dWFsIFBhY2syMDAgb3BlcmF0aW9uLiAgV3JhcCB0aGVtIGluIGFuCisgICAgICBhZGRpdGlvbmFsIDxjb2RlPkd6aXBDb21wcmVzc29yKElufE91dClwdXRTdHJlYW08L2NvZGU+IGluIG9yZGVyIHRvIGRlYWwKKyAgICAgIHdpdGggZGVmbGF0ZWQgc3RyZWFtcy48L3A+CisKKyAgICAgIDxzdWJzZWN0aW9uIG5hbWU9IlBhY2syMDBTdHJhdGVneSI+CisKKyAgICAgICAgPHA+VGhlIFBhY2syMDAtQVBJIHByb3ZpZGVkIGJ5IHRoZSBqYXZhIGNsYXNzIGxpYnJhcnkgaXMgbm90CisgICAgICAgIHN0cmVhbWluZyBmcmllbmRseSBhcyBpdCB3YW50cyB0byBjb25zdW1lIGl0cyBpbnB1dCBjb21wbGV0ZWx5CisgICAgICAgIGluIGEgc2luZ2xlIG9wZXJhdGlvbi4gIEJlY2F1c2Ugb2YgdGhpcworICAgICAgICA8Y29kZT5QYWNrMjAwQ29tcHJlc3NvcklucHV0U3RyZWFtPC9jb2RlPidzIGNvbnN0cnVjdG9yIHdpbGwgaW1tZWRpYXRlbHkKKyAgICAgICAgdW5wYWNrIHRoZSBzdHJlYW0sIGNhY2hlIHRoZSByZXN1bHRzIGFuZCBwcm92aWRlIGFuIGlucHV0CisgICAgICAgIHN0cmVhbSB0byB0aGUgY2FjaGUuPC9wPgorCisgICAgICAgIDxwPjxjb2RlPlBhY2syMDBDb21wcmVzc29yT3V0cHV0U3RyZWFtPC9jb2RlPiB3aWxsIGNhY2hlIGFsbCBkYXRhIHRoYXQKKyAgICAgICAgaXMgd3JpdHRlbiB0byBpdCBhbmQgdGhlbiBwYWNrIGl0IG9uY2UgdGhlIDxjb2RlPmZpbmlzaDwvY29kZT4KKyAgICAgICAgb3IgPGNvZGU+Y2xvc2U8L2NvZGU+IG1ldGhvZCBpcyBjYWxsZWQuPC9wPgorCisgICAgICAgIDxwPlR3byBkaWZmZXJlbnQgY2FjaGluZyBtb2RlcyBhcmUgYXZhaWxhYmxlIC0gImluIG1lbW9yeSIsCisgICAgICAgIHdoaWNoIGlzIHRoZSBkZWZhdWx0LCBhbmQgInRlbXBvcmFyeSBmaWxlIi4gIEJ5IGRlZmF1bHQgZGF0YQorICAgICAgICBpcyBjYWNoZWQgaW4gbWVtb3J5IGJ1dCB5b3Ugc2hvdWxkIHN3aXRjaCB0byB0aGUgdGVtcG9yYXJ5CisgICAgICAgIGZpbGUgb3B0aW9uIGlmIHlvdXIgYXJjaGl2ZXMgYXJlIHJlYWxseSBiaWcuPC9wPgorCisgICAgICAgIDxwPkdpdmVuIHRoZXJlIGFsd2F5cyBpcyBhbiBpbnRlcm1lZGlhdGUgcmVzdWx0CisgICAgICAgIHRoZSA8Y29kZT5nZXRCeXRlc1JlYWQ8L2NvZGU+IGFuZCA8Y29kZT5nZXRDb3VudDwvY29kZT4KKyAgICAgICAgbWV0aG9kcyBvZiA8Y29kZT5QYWNrMjAwQ29tcHJlc3NvcklucHV0U3RyZWFtPC9jb2RlPiBhcmUKKyAgICAgICAgbWVhbmluZ2xlc3MgKHJlYWQgZnJvbSB0aGUgcmVhbCBzdHJlYW0gb3IgZnJvbSB0aGUKKyAgICAgICAgaW50ZXJtZWRpYXRlIHJlc3VsdD8pICBhbmQgYWx3YXlzIHJldHVybiAwLjwvcD4KKworICAgICAgPC9zdWJzZWN0aW9uPgorCisgICAgICA8c3Vic2VjdGlvbiBuYW1lPSJOb3JtYWxpemF0aW9uIj4KKworICAgICAgICA8cD5BcyBhIHBhY2svdW5wYWNrIGN5Y2xlIG1heSBjcmVhdGUgYSBKQVIgYXJjaGl2ZSB0aGF0IGlzCisgICAgICAgIGRpZmZlcmVudCBmcm9tIHRoZSBvcmlnaW5hbCwgZGlnaXRhbCBzaWduYXR1cmVzIGNyZWF0ZWQgZm9yCisgICAgICAgIHRoZSBpbml0aWFsIEpBUiB3aWxsIGJlIGJyb2tlbiBieSB0aGUgcHJvY2Vzcy4gIFRoZXJlIGlzIGEgd2F5CisgICAgICAgIHRvICJub3JtYWxpemUiIEpBUiBhcmNoaXZlcyBwcmlvciB0byBwYWNraW5nIHRoZW0gdGhhdCBlbnN1cmVzCisgICAgICAgIHNpZ25hdHVyZXMgYXBwbGllZCB0byB0aGUgIm5vcm1hbGl6ZWQiIEpBUiB3aWxsIHN0aWxsIGJlIHZhbGlkCisgICAgICAgIGFmdHJlIGEgcGFjay91bnBhY2sgY3ljbGUgLSBzZWUgPGEKKyAgICAgICAgaHJlZj0iaHR0cHM6Ly9kb3dubG9hZC5vcmFjbGUuY29tL2phdmFzZS83L2RvY3MvYXBpL2phdmEvdXRpbC9qYXIvUGFjazIwMC5QYWNrZXIuaHRtbCI+UGFjazIwMC5QYWNrZXI8L2E+J3MKKyAgICAgICAgamF2YWRvY3MuPC9wPgorCisgICAgICAgIDxwPlRoZSA8Y29kZT5QYWNrMjAwVXRpbHM8L2NvZGU+IGNsYXNzIGluIHRoZQorICAgICAgICA8Y29kZT5wYWNrMjAwPC9jb2RlPiBwYWNrYWdlIHByb3ZpZGVzIHNldmVyYWwgb3ZlcmxvYWRzIG9mIGEKKyAgICAgICAgPGNvZGU+bm9ybWFsaXplPC9jb2RlPiBtZXRob2QgdGhhdCBjYW4gYmUgdXNlZCB0byBwcmVwYXJlIGEKKyAgICAgICAgSkFSIGFyY2hpdmUgaW4gcGxhY2Ugb3IgdG8gYSBzZXBhcmF0ZSBmaWxlLjwvcD4KKworICAgICAgPC9zdWJzZWN0aW9uPgorCisgICAgPC9zZWN0aW9uPgorPC9ib2R5PgorPC9kb2N1bWVudD4KZGlmZiAtLWdpdCBhL3NyYy9zaXRlL3hkb2Mvc2VjdXJpdHktcmVwb3J0cy54bWwgYi9zcmMvc2l0ZS94ZG9jL3NlY3VyaXR5LXJlcG9ydHMueG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNhYTJjMzMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvc2l0ZS94ZG9jL3NlY3VyaXR5LXJlcG9ydHMueG1sCkBAIC0wLDAgKzEsMTQyIEBACis8P3htbCB2ZXJzaW9uPSIxLjAiPz4KKzwhLS0KKworICAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAgIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAgIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKworICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorCisgICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKy0tPgorPGRvY3VtZW50PgorICAgIDxwcm9wZXJ0aWVzPgorICAgICAgICA8dGl0bGU+Q29tbW9ucyBDb21wcmVzcyBTZWN1cml0eSBSZXBvcnRzPC90aXRsZT4KKyAgICAgICAgPGF1dGhvciBlbWFpbD0iZGV2QGNvbW1vbnMuYXBhY2hlLm9yZyI+Q29tbW9ucyBEb2N1bWVudGF0aW9uIFRlYW08L2F1dGhvcj4KKyAgICA8L3Byb3BlcnRpZXM+CisgICAgPGJvZHk+CisgICAgICA8c2VjdGlvbiBuYW1lPSJHZW5lcmFsIEluZm9ybWF0aW9uIj4KKyAgICAgICAgPHA+Rm9yIGluZm9ybWF0aW9uIGFib3V0IHJlcG9ydGluZyBvciBhc2tpbmcgcXVlc3Rpb25zIGFib3V0CisgICAgICAgIHNlY3VyaXR5IHByb2JsZW1zLCBwbGVhc2Ugc2VlIHRoZSA8YQorICAgICAgICBocmVmPSJodHRwczovL2NvbW1vbnMuYXBhY2hlLm9yZy9zZWN1cml0eS5odG1sIj5zZWN1cml0eSBwYWdlCisgICAgICAgIG9mIHRoZSBDb21tb25zIHByb2plY3Q8L2E+LjwvcD4KKyAgICAgIDwvc2VjdGlvbj4KKworICAgICAgPHNlY3Rpb24gbmFtZT0iQXBhY2hlIENvbW1vbnMgQ29tcHJlc3MgU2VjdXJpdHkgVnVsbmVyYWJpbGl0aWVzIj4KKyAgICAgICAgPHA+VGhpcyBwYWdlIGxpc3RzIGFsbCBzZWN1cml0eSB2dWxuZXJhYmlsaXRpZXMgZml4ZWQgaW4KKyAgICAgICAgcmVsZWFzZWQgdmVyc2lvbnMgb2YgQXBhY2hlIENvbW1vbnMgQ29tcHJlc3MuIEVhY2gKKyAgICAgICAgdnVsbmVyYWJpbGl0eSBpcyBnaXZlbiBhIHNlY3VyaXR5IGltcGFjdCByYXRpbmcgYnkgdGhlCisgICAgICAgIGRldmVsb3BtZW50IHRlYW0gLSBwbGVhc2Ugbm90ZSB0aGF0IHRoaXMgcmF0aW5nIG1heSB2YXJ5IGZyb20KKyAgICAgICAgcGxhdGZvcm0gdG8gcGxhdGZvcm0uIFdlIGFsc28gbGlzdCB0aGUgdmVyc2lvbnMgb2YgQ29tbW9ucworICAgICAgICBDb21wcmVzcyB0aGUgZmxhdyBpcyBrbm93biB0byBhZmZlY3QsIGFuZCB3aGVyZSBhIGZsYXcgaGFzIG5vdAorICAgICAgICBiZWVuIHZlcmlmaWVkIGxpc3QgdGhlIHZlcnNpb24gd2l0aCBhIHF1ZXN0aW9uIG1hcmsuPC9wPgorCisgICAgICAgIDxwPlBsZWFzZSBub3RlIHRoYXQgYmluYXJ5IHBhdGNoZXMgYXJlIG5ldmVyIHByb3ZpZGVkLiBJZiB5b3UKKyAgICAgICAgbmVlZCB0byBhcHBseSBhIHNvdXJjZSBjb2RlIHBhdGNoLCB1c2UgdGhlIGJ1aWxkaW5nCisgICAgICAgIGluc3RydWN0aW9ucyBmb3IgdGhlIENvbW1vbnMgQ29tcHJlc3MgdmVyc2lvbiB0aGF0IHlvdSBhcmUKKyAgICAgICAgdXNpbmcuPC9wPgorCisgICAgICAgIDxwPklmIHlvdSBuZWVkIGhlbHAgb24gYnVpbGRpbmcgQ29tbW9ucyBDb21wcmVzcyBvciBvdGhlciBoZWxwCisgICAgICAgIG9uIGZvbGxvd2luZyB0aGUgaW5zdHJ1Y3Rpb25zIHRvIG1pdGlnYXRlIHRoZSBrbm93bgorICAgICAgICB2dWxuZXJhYmlsaXRpZXMgbGlzdGVkIGhlcmUsIHBsZWFzZSBzZW5kIHlvdXIgcXVlc3Rpb25zIHRvIHRoZQorICAgICAgICBwdWJsaWMgPGEgaHJlZj0ibWFpbC1saXN0cy5odG1sIj5Db21wcmVzcyBVc2VycyBtYWlsaW5nCisgICAgICAgIGxpc3Q8L2E+LjwvcD4KKworICAgICAgICA8cD5JZiB5b3UgaGF2ZSBlbmNvdW50ZXJlZCBhbiB1bmxpc3RlZCBzZWN1cml0eSB2dWxuZXJhYmlsaXR5CisgICAgICAgIG9yIG90aGVyIHVuZXhwZWN0ZWQgYmVoYXZpb3VyIHRoYXQgaGFzIHNlY3VyaXR5IGltcGFjdCwgb3IgaWYKKyAgICAgICAgdGhlIGRlc2NyaXB0aW9ucyBoZXJlIGFyZSBpbmNvbXBsZXRlLCBwbGVhc2UgcmVwb3J0IHRoZW0KKyAgICAgICAgcHJpdmF0ZWx5IHRvIHRoZSBBcGFjaGUgU2VjdXJpdHkgVGVhbS4gVGhhbmsgeW91LjwvcD4KKworICAgICAgICA8c3Vic2VjdGlvbiBuYW1lPSJGaXhlZCBpbiBBcGFjaGUgQ29tbW9ucyBDb21wcmVzcyAxLjE4Ij4KKyAgICAgICAgICA8cD48Yj5Mb3c6IERlbmlhbCBvZiBTZXJ2aWNlPC9iPiA8YQorICAgICAgICAgIGhyZWY9Imh0dHBzOi8vY3ZlLm1pdHJlLm9yZy9jZ2ktYmluL2N2ZW5hbWUuY2dpP25hbWU9Q1ZFLTIwMTgtMTE3NzEiPkNWRS0yMDE4LTExNzcxPC9hPjwvcD4KKworICAgICAgICAgIDxwPldoZW4gcmVhZGluZyBhIHNwZWNpYWxseSBjcmFmdGVkIFpJUCBhcmNoaXZlLCB0aGUgcmVhZAorICAgICAgICAgIG1ldGhvZCBvZiA8Y29kZT5aaXBBcmNoaXZlSW5wdXRTdHJlYW08L2NvZGU+IGNhbiBmYWlsIHRvCisgICAgICAgICAgcmV0dXJuIHRoZSBjb3JyZWN0IEVPRiBpbmRpY2F0aW9uIGFmdGVyIHRoZSBlbmQgb2YgdGhlCisgICAgICAgICAgc3RyZWFtIGhhcyBiZWVuIHJlYWNoZWQuIFdoZW4gY29tYmluZWQgd2l0aCBhCisgICAgICAgICAgPGNvZGU+amF2YS5pby5JbnB1dFN0cmVhbVJlYWRlcjwvY29kZT4gdGhpcyBjYW4gbGVhZCB0byBhbgorICAgICAgICAgIGluZmluaXRlIHN0cmVhbSwgd2hpY2ggY2FuIGJlIHVzZWQgdG8gbW91bnQgYSBkZW5pYWwgb2YKKyAgICAgICAgICBzZXJ2aWNlIGF0dGFjayBhZ2FpbnN0IHNlcnZpY2VzIHRoYXQgdXNlIENvbXByZXNzJyB6aXAKKyAgICAgICAgICBwYWNrYWdlPC9wPgorCisgICAgICAgICAgPHA+VGhpcyB3YXMgZml4ZWQgaW4gcmV2aXNpb24gPGEKKyAgICAgICAgICBocmVmPSJodHRwczovL2dpdC13aXAtdXMuYXBhY2hlLm9yZy9yZXBvcy9hc2Y/cD1jb21tb25zLWNvbXByZXNzLmdpdDthPWJsb2JkaWZmO2Y9c3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9aaXBBcmNoaXZlSW5wdXRTdHJlYW0uamF2YTtoPWUxOTk1ZDdhYTUxZGZhYzZhZTkzMzk4N2ZiMGI3NzYwYzYwNzU4MmI7aHA9MGEyYzFhYTAwNjNjNjIwYzg2NzcxNTExOWVhZTIwMTNjODdiNWU3MDtoYj1hNDFjZTY4OTJjYjA1OTBiMmU2NTg3MDQ0MzRhYzBkYmNiNjgzNGM4O2hwYj02NGVkNmRkZTAzYWZiZWY2NzE1ZmRmZGVhYjVmYzA0YmU2MTkyODk5Ij5hNDFjZTY4PC9hPi48L3A+CisKKyAgICAgICAgICA8cD5UaGlzIHdhcyBmaXJzdCByZXBvcnRlZCB0byB0aGUgU2VjdXJpdHkgVGVhbSBvbiAxNCBKdW5lCisgICAgICAgICAgMjAxOCBhbmQgbWFkZSBwdWJsaWMgb24gMTYgQXVndXN0IDIwMTguPC9wPgorCisgICAgICAgICAgPHA+QWZmZWN0czogMS43IC0gMS4xNzwvcD4KKworICAgICAgICA8L3N1YnNlY3Rpb24+CisKKyAgICAgICAgPHN1YnNlY3Rpb24gbmFtZT0iRml4ZWQgaW4gQXBhY2hlIENvbW1vbnMgQ29tcHJlc3MgMS4xNiI+CisgICAgICAgICAgPHA+PGI+TG93OiBEZW5pYWwgb2YgU2VydmljZTwvYj4gPGEKKyAgICAgICAgICBocmVmPSJodHRwczovL2N2ZS5taXRyZS5vcmcvY2dpLWJpbi9jdmVuYW1lLmNnaT9uYW1lPUNWRS0yMDE4LTEzMjQiPkNWRS0yMDE4LTEzMjQ8L2E+PC9wPgorCisgICAgICAgICAgPHA+QSBzcGVjaWFsbHkgY3JhZnRlZCBaSVAgYXJjaGl2ZSBjYW4gYmUgdXNlZCB0byBjYXVzZSBhbgorICAgICAgICAgIGluZmluaXRlIGxvb3AgaW5zaWRlIG9mIENvbXByZXNzJyBleHRyYSBmaWVsZCBwYXJzZXIgdXNlZCBieQorICAgICAgICAgIHRoZSA8Y29kZT5aaXBGaWxlPC9jb2RlPiBhbmQKKyAgICAgICAgICA8Y29kZT5aaXBBcmNoaXZlSW5wdXRTdHJlYW08L2NvZGU+IGNsYXNzZXMuICBUaGlzIGNhbiBiZQorICAgICAgICAgIHVzZWQgdG8gbW91bnQgYSBkZW5pYWwgb2Ygc2VydmljZSBhdHRhY2sgYWdhaW5zdCBzZXJ2aWNlcworICAgICAgICAgIHRoYXQgdXNlIENvbXByZXNzJyB6aXAgcGFja2FnZS48L3A+CisKKyAgICAgICAgICA8cD5UaGlzIHdhcyBmaXhlZCBpbiByZXZpc2lvbiA8YQorICAgICAgICAgIGhyZWY9Imh0dHBzOi8vZ2l0LXdpcC11cy5hcGFjaGUub3JnL3JlcG9zL2FzZj9wPWNvbW1vbnMtY29tcHJlc3MuZ2l0O2E9YmxvYmRpZmY7Zj1zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1gwMDE3X1N0cm9uZ0VuY3J5cHRpb25IZWFkZXIuamF2YTtoPWFjYzNiMjIzNDZiNDk4NDVlODViNWVmMjdhNTgxNGI2OWU4MzQxMzk7aHA9MGZlYjljOThjYzYyMmNkZTFkZWZhM2JiZDI2OGVmODJiNGFlNWMxODtoYj0yYTJmMWRjNDhlMjJhMzRkZGI3MjMyMWE0ZGIyMTFkYTkxYWE5MzNiO2hwYj1kY2IwNDg2ZmI0Y2IyYjY1OTJjMDRkNmVjMmVkYmQzZjY5MGRmNWYyIj4yYTJmMWRjNDwvYT4uPC9wPgorCisgICAgICAgICAgPHA+VGhpcyB3YXMgZmlyc3QgcmVwb3J0ZWQgdG8gdGhlIHByb2plY3QncyBKSVJBIG9uIDxhCisgICAgICAgICAgaHJlZj0iaHR0cHM6Ly9pc3N1ZXMuYXBhY2hlLm9yZy9qaXJhL2Jyb3dzZS9DT01QUkVTUy00MzIiPjE5CisgICAgICAgICAgRGVjZW1iZXIgMjAxNzwvYT4uPC9wPgorCisgICAgICAgICAgPHA+QWZmZWN0czogMS4xMSAtIDEuMTU8L3A+CisKKyAgICAgICAgPC9zdWJzZWN0aW9uPgorCisgICAgICAgIDxzdWJzZWN0aW9uIG5hbWU9IkZpeGVkIGluIEFwYWNoZSBDb21tb25zIENvbXByZXNzIDEuNC4xIj4KKyAgICAgICAgICA8cD48Yj5Mb3c6IERlbmlhbCBvZiBTZXJ2aWNlPC9iPiA8YQorICAgICAgICAgIGhyZWY9Imh0dHBzOi8vY3ZlLm1pdHJlLm9yZy9jZ2ktYmluL2N2ZW5hbWUuY2dpP25hbWU9Q1ZFLTIwMTItMjA5OCI+Q1ZFLTIwMTItMjA5ODwvYT48L3A+CisKKyAgICAgICAgICA8cD5UaGUgYnppcDIgY29tcHJlc3Npbmcgc3RyZWFtcyBpbiBBcGFjaGUgQ29tbW9ucyBDb21wcmVzcworICAgICAgICAgIGludGVybmFsbHkgdXNlIHNvcnRpbmcgYWxnb3JpdGhtcyB3aXRoIHVuYWNjZXB0YWJsZQorICAgICAgICAgIHdvcnN0LWNhc2UgcGVyZm9ybWFuY2Ugb24gdmVyeSByZXBldGl0aXZlIGlucHV0cy4gIEEKKyAgICAgICAgICBzcGVjaWFsbHkgY3JhZnRlZCBpbnB1dCB0byBDb21wcmVzcycKKyAgICAgICAgICA8Y29kZT5CWmlwMkNvbXByZXNzb3JPdXRwdXRTdHJlYW08L2NvZGU+IGNhbiBiZSB1c2VkIHRvIG1ha2UKKyAgICAgICAgICB0aGUgcHJvY2VzcyBzcGVuZCBhIHZlcnkgbG9uZyB0aW1lIHdoaWxlIHVzaW5nIHVwIGFsbAorICAgICAgICAgIGF2YWlsYWJsZSBwcm9jZXNzaW5nIHRpbWUgZWZmZWN0aXZlbHkgbGVhZGluZyB0byBhIGRlbmlhbCBvZgorICAgICAgICAgIHNlcnZpY2UuPC9wPgorCisgICAgICAgICAgPHA+VGhpcyB3YXMgZml4ZWQgaW4gcmV2aXNpb25zCisgICAgICAgICAgPGEgaHJlZj0iaHR0cHM6Ly9zdm4uYXBhY2hlLm9yZy92aWV3dmM/dmlldz1yZXZpc2lvbiZhbXA7cmV2aXNpb249MTMzMjU0MCI+MTMzMjU0MDwvYT4sCisgICAgICAgICAgPGEgaHJlZj0iaHR0cHM6Ly9zdm4uYXBhY2hlLm9yZy92aWV3dmM/dmlldz1yZXZpc2lvbiZhbXA7cmV2aXNpb249MTMzMjU1MiI+MTMzMjU1MjwvYT4sCisgICAgICAgICAgPGEgaHJlZj0iaHR0cHM6Ly9zdm4uYXBhY2hlLm9yZy92aWV3dmM/dmlldz1yZXZpc2lvbiZhbXA7cmV2aXNpb249MTMzMzUyMiI+MTMzMzUyMjwvYT4sCisgICAgICAgICAgPGEgaHJlZj0iaHR0cHM6Ly9zdm4uYXBhY2hlLm9yZy92aWV3dmM/dmlldz1yZXZpc2lvbiZhbXA7cmV2aXNpb249MTMzNzQ0NCI+MTMzNzQ0NDwvYT4sCisgICAgICAgICAgPGEgaHJlZj0iaHR0cHM6Ly9zdm4uYXBhY2hlLm9yZy92aWV3dmM/dmlldz1yZXZpc2lvbiZhbXA7cmV2aXNpb249MTM0MDcxNSI+MTM0MDcxNTwvYT4sCisgICAgICAgICAgPGEgaHJlZj0iaHR0cHM6Ly9zdm4uYXBhY2hlLm9yZy92aWV3dmM/dmlldz1yZXZpc2lvbiZhbXA7cmV2aXNpb249MTM0MDcyMyI+MTM0MDcyMzwvYT4sCisgICAgICAgICAgPGEgaHJlZj0iaHR0cHM6Ly9zdm4uYXBhY2hlLm9yZy92aWV3dmM/dmlldz1yZXZpc2lvbiZhbXA7cmV2aXNpb249MTM0MDc1NyI+MTM0MDc1NzwvYT4sCisgICAgICAgICAgPGEgaHJlZj0iaHR0cHM6Ly9zdm4uYXBhY2hlLm9yZy92aWV3dmM/dmlldz1yZXZpc2lvbiZhbXA7cmV2aXNpb249MTM0MDc4NiI+MTM0MDc4NjwvYT4sCisgICAgICAgICAgPGEgaHJlZj0iaHR0cHM6Ly9zdm4uYXBhY2hlLm9yZy92aWV3dmM/dmlldz1yZXZpc2lvbiZhbXA7cmV2aXNpb249MTM0MDc4NyI+MTM0MDc4NzwvYT4sCisgICAgICAgICAgPGEgaHJlZj0iaHR0cHM6Ly9zdm4uYXBhY2hlLm9yZy92aWV3dmM/dmlldz1yZXZpc2lvbiZhbXA7cmV2aXNpb249MTM0MDc5MCI+MTM0MDc5MDwvYT4sCisgICAgICAgICAgPGEgaHJlZj0iaHR0cHM6Ly9zdm4uYXBhY2hlLm9yZy92aWV3dmM/dmlldz1yZXZpc2lvbiZhbXA7cmV2aXNpb249MTM0MDc5NSI+MTM0MDc5NTwvYT4gYW5kCisgICAgICAgICAgPGEgaHJlZj0iaHR0cHM6Ly9zdm4uYXBhY2hlLm9yZy92aWV3dmM/dmlldz1yZXZpc2lvbiZhbXA7cmV2aXNpb249MTM0MDc5OSI+MTM0MDc5OTwvYT4uPC9wPgorCisgICAgICAgICAgPHA+VGhpcyB3YXMgZmlyc3QgcmVwb3J0ZWQgdG8gdGhlIFNlY3VyaXR5IFRlYW0gb24gMTIgQXByaWwKKyAgICAgICAgICAyMDEyIGFuZCBtYWRlIHB1YmxpYyBvbiAyMyBNYXkgMjAxMi48L3A+CisKKyAgICAgICAgICA8cD5BZmZlY3RzOiAxLjAgLSAxLjQ8L3A+CisKKyAgICAgICAgPC9zdWJzZWN0aW9uPgorICAgICAgPC9zZWN0aW9uPgorCisgICAgICA8c2VjdGlvbiBuYW1lPSJFcnJvcnMgYW5kIE9tbWlzc2lvbnMiPgorICAgICAgICA8cD5QbGVhc2UgcmVwb3J0IGFueSBlcnJvcnMgb3Igb21pc3Npb25zIHRvIDxhCisgICAgICAgIGhyZWY9Im1haWwtbGlzdHMuaHRtbCI+dGhlIGRldiBtYWlsaW5nIGxpc3Q8L2E+LjwvcD4KKyAgICAgIDwvc2VjdGlvbj4KKyAgICA8L2JvZHk+Cis8L2RvY3VtZW50PgpkaWZmIC0tZ2l0IGEvc3JjL3NpdGUveGRvYy90YXIueG1sIGIvc3JjL3NpdGUveGRvYy90YXIueG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMxN2VhOGMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvc2l0ZS94ZG9jL3Rhci54bWwKQEAgLTAsMCArMSwyMjggQEAKKzw/eG1sIHZlcnNpb249IjEuMCI/PgorPCEtLQorCisgICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAgIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAgICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorCisgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisKKyAgIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAgIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAgIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAgIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorCistLT4KKzxkb2N1bWVudD4KKyAgPHByb3BlcnRpZXM+CisgICAgPHRpdGxlPkNvbW1vbnMgQ29tcHJlc3MgVEFSIHBhY2thZ2U8L3RpdGxlPgorICAgIDxhdXRob3IgZW1haWw9ImRldkBjb21tb25zLmFwYWNoZS5vcmciPkNvbW1vbnMgRG9jdW1lbnRhdGlvbiBUZWFtPC9hdXRob3I+CisgIDwvcHJvcGVydGllcz4KKyAgPGJvZHk+CisgICAgPHNlY3Rpb24gbmFtZT0iVGhlIFRBUiBwYWNrYWdlIj4KKworICAgICAgPHA+SW4gYWRkaXRpb24gdG8gdGhlIGluZm9ybWF0aW9uIHN0b3JlZAorICAgICAgaW4gPGNvZGU+QXJjaGl2ZUVudHJ5PC9jb2RlPiBhIDxjb2RlPlRhckFyY2hpdmVFbnRyeTwvY29kZT4KKyAgICAgIHN0b3JlcyB2YXJpb3VzIGF0dHJpYnV0ZXMgaW5jbHVkaW5nIGluZm9ybWF0aW9uIGFib3V0IHRoZQorICAgICAgb3JpZ2luYWwgb3duZXIgYW5kIHBlcm1pc3Npb25zLjwvcD4KKworICAgICAgPHA+VGhlcmUgYXJlIHNldmVyYWwgZGlmZmVyZW50IGRpYWxlY3RzIG9mIHRoZSBUQVIgZm9ybWF0LCBtYXliZQorICAgICAgZXZlbiBkaWZmZXJlbnQgVEFSIGZvcm1hdHMuIFRoZSB0YXIgcGFja2FnZSBjb250YWlucyBzcGVjaWFsCisgICAgICBjYXNlcyBpbiBvcmRlciB0byByZWFkIG1hbnkgb2YgdGhlIGV4aXN0aW5nIGRpYWxlY3RzIGFuZCB3aWxsIGJ5CisgICAgICBkZWZhdWx0IHRyeSB0byBjcmVhdGUgYXJjaGl2ZXMgaW4gdGhlIG9yaWdpbmFsIGZvcm1hdCAob2Z0ZW4KKyAgICAgIGNhbGxlZCAidXN0YXIiKS4gVGhpcyBvcmlnaW5hbCBmb3JtYXQgZGlkbid0IHN1cHBvcnQgZmlsZSBuYW1lcworICAgICAgbG9uZ2VyIHRoYW4gMTAwIGNoYXJhY3RlcnMgb3IgYmlnZ2VyIHRoYW4gOCBHaUIgYW5kIHRoZSB0YXIKKyAgICAgIHBhY2thZ2Ugd2lsbCBieSBkZWZhdWx0IGZhaWwgaWYgeW91IHRyeSB0byB3cml0ZSBhbiBlbnRyeSB0aGF0CisgICAgICBnb2VzIGJleW9uZCB0aG9zZSBsaW1pdHMuICJ1c3RhciIgaXMgdGhlIGNvbW1vbiBkZW5vbWluYXRvciBvZgorICAgICAgYWxsIHRoZSBleGlzdGluZyB0YXIgZGlhbGVjdHMgYW5kIGlzIHVuZGVyc3Rvb2QgYnkgbW9zdCBvZiB0aGUKKyAgICAgIGV4aXN0aW5nIHRvb2xzLjwvcD4KKworICAgICAgPHA+VGhlIHRhciBwYWNrYWdlIGRvZXMgbm90IHN1cHBvcnQgdGhlIGZ1bGwgUE9TSVggdGFyIHN0YW5kYXJkCisgICAgICBub3IgbW9yZSBtb2Rlcm4gR05VIGV4dGVuc2lvbiBvZiBzYWlkIHN0YW5kYXJkLjwvcD4KKworICAgICAgPHN1YnNlY3Rpb24gbmFtZT0iTG9uZyBGaWxlIE5hbWVzIj4KKworICAgICAgICA8cD5UaGUgPGNvZGU+bG9uZ0ZpbGVNb2RlPC9jb2RlPiBvcHRpb24gb2YKKyAgICAgICAgPGNvZGU+VGFyQXJjaGl2ZU91dHB1dFN0cmVhbTwvY29kZT4gY29udHJvbHMgaG93IGZpbGVzIHdpdGgKKyAgICAgICAgbmFtZXMgbG9uZ2VyIHRoYW4gMTAwIGNoYXJhY3RlcnMgYXJlIGhhbmRsZWQuICBUaGUgcG9zc2libGUKKyAgICAgICAgY2hvaWNlcyBhcmU6PC9wPgorCisgICAgICAgIDx1bD4KKyAgICAgICAgICA8bGk+PGNvZGU+TE9OR0ZJTEVfRVJST1I8L2NvZGU+OiB0aHJvdyBhbiBleGNlcHRpb24gaWYgc3VjaCBhCisgICAgICAgICAgZmlsZSBpcyBhZGRlZC4gIFRoaXMgaXMgdGhlIGRlZmF1bHQuPC9saT4KKyAgICAgICAgICA8bGk+PGNvZGU+TE9OR0ZJTEVfVFJVTkNBVEU8L2NvZGU+OiB0cnVuY2F0ZSBzdWNoIG5hbWVzLjwvbGk+CisgICAgICAgICAgPGxpPjxjb2RlPkxPTkdGSUxFX0dOVTwvY29kZT46IHVzZSBhIEdOVSB0YXIgdmFyaWFudCBub3cKKyAgICAgICAgICByZWZlcmVkIHRvIGFzICJvbGRnbnUiIG9mIHN0b3Jpbmcgc3VjaCBuYW1lcy4gIElmIHlvdSBjaG9vc2UKKyAgICAgICAgICB0aGUgR05VIHRhciBvcHRpb24sIHRoZSBhcmNoaXZlIGNhbiBub3QgYmUgZXh0cmFjdGVkIHVzaW5nCisgICAgICAgICAgbWFueSBvdGhlciB0YXIgaW1wbGVtZW50YXRpb25zIGxpa2UgdGhlIG9uZXMgb2YgT3BlbkJTRCwKKyAgICAgICAgICBTb2xhcmlzIG9yIE1hY09TIFguPC9saT4gCisgICAgICAgICAgPGxpPjxjb2RlPkxPTkdGSUxFX1BPU0lYPC9jb2RlPjogdXNlIGEgUEFYIDxhCisgICAgICAgICAgaHJlZj0iaHR0cDovL3B1YnMub3Blbmdyb3VwLm9yZy9vbmxpbmVwdWJzLzAwOTY5NTM5OS91dGlsaXRpZXMvcGF4Lmh0bWwjdGFnXzA0XzEwMF8xM18wMyI+ZXh0ZW5kZWQKKyAgICAgICAgICBoZWFkZXI8L2E+IGFzIGRlZmluZWQgYnkgUE9TSVggMTAwMy4xLiAgTW9zdCBtb2Rlcm4gdGFyCisgICAgICAgICAgaW1wbGVtZW50YXRpb25zIGFyZSBhYmxlIHRvIGV4dHJhY3Qgc3VjaCBhcmNoaXZlcy4gPGVtPnNpbmNlCisgICAgICAgICAgQ29tbW9ucyBDb21wcmVzcyAxLjQ8L2VtPjwvbGk+CisgICAgICAgIDwvdWw+CisKKyAgICAgICAgPHA+PGNvZGU+VGFyQXJjaGl2ZUlucHV0U3RyZWFtPC9jb2RlPiB3aWxsIHJlY29nbml6ZSB0aGUgR05VCisgICAgICAgIHRhciBhcyB3ZWxsIGFzIHRoZSBQT1NJWCBleHRlbnNpb25zIChzdGFydGluZyB3aXRoIENvbW1vbnMKKyAgICAgICAgQ29tcHJlc3MgMS4yKSBmb3IgbG9uZyBmaWxlIG5hbWVzIGFuZCByZWFkcyB0aGUgbG9uZ2VyIG5hbWVzCisgICAgICAgIHRyYW5zcGFyZW50bHkuPC9wPgorICAgICAgPC9zdWJzZWN0aW9uPgorCisgICAgICA8c3Vic2VjdGlvbiBuYW1lPSJCaWcgTnVtZXJpYyBWYWx1ZXMiPgorCisgICAgICAgIDxwPlRoZSA8Y29kZT5iaWdOdW1iZXJNb2RlPC9jb2RlPiBvcHRpb24gb2YKKyAgICAgICAgPGNvZGU+VGFyQXJjaGl2ZU91dHB1dFN0cmVhbTwvY29kZT4gY29udHJvbHMgaG93IGZpbGVzIGxhcmdlcgorICAgICAgICB0aGFuIDhHaUIgb3Igd2l0aCBvdGhlciBiaWcgbnVtZXJpYyB2YWx1ZXMgdGhhdCBjYW4ndCBiZQorICAgICAgICBlbmNvZGVkIGluIHRyYWRpdGlvbmFsIGhlYWRlciBmaWVsZHMgYXJlIGhhbmRsZWQuICBUaGUKKyAgICAgICAgcG9zc2libGUgY2hvaWNlcyBhcmU6PC9wPgorCisgICAgICAgIDx1bD4KKyAgICAgICAgICA8bGk+PGNvZGU+QklHTlVNQkVSX0VSUk9SPC9jb2RlPjogdGhyb3cgYW4gZXhjZXB0aW9uIGlmIHN1Y2ggYW4KKyAgICAgICAgICBlbnRyeSBpcyBhZGRlZC4gIFRoaXMgaXMgdGhlIGRlZmF1bHQuPC9saT4KKyAgICAgICAgICA8bGk+PGNvZGU+QklHTlVNQkVSX1NUQVI8L2NvZGU+OiB1c2UgYSB2YXJpYW50IGZpcnN0CisgICAgICAgICAgaW50cm9kdWNlZCBieSBKJiN4ZjY7cmcgU2NoaWxsaW5nJ3MgPGEKKyAgICAgICAgICBocmVmPSJodHRwOi8vZGV2ZWxvcGVyLmJlcmxpb3MuZGUvcHJvamVjdHMvc3RhciI+c3RhcjwvYT4KKyAgICAgICAgICBhbmQgbGF0ZXIgYWRvcHRlZCBieSBHTlUgYW5kIEJTRCB0YXIuICBUaGlzIG1ldGhvZCBpcyBub3QKKyAgICAgICAgICBzdXBwb3J0ZWQgYnkgYWxsIGltcGxlbWVudGF0aW9ucy48L2xpPgorICAgICAgICAgIDxsaT48Y29kZT5CSUdOVU1CRVJfUE9TSVg8L2NvZGU+OiB1c2UgYSBQQVggPGEKKyAgICAgICAgICBocmVmPSJodHRwOi8vcHVicy5vcGVuZ3JvdXAub3JnL29ubGluZXB1YnMvMDA5Njk1Mzk5L3V0aWxpdGllcy9wYXguaHRtbCN0YWdfMDRfMTAwXzEzXzAzIj5leHRlbmRlZAorICAgICAgICAgIGhlYWRlcjwvYT4gYXMgZGVmaW5lZCBieSBQT1NJWCAxMDAzLjEuICBNb3N0IG1vZGVybiB0YXIKKyAgICAgICAgICBpbXBsZW1lbnRhdGlvbnMgYXJlIGFibGUgdG8gZXh0cmFjdCBzdWNoIGFyY2hpdmVzLjwvbGk+CisgICAgICAgIDwvdWw+CisKKyAgICAgICAgPHA+U3RhcnRpbmcgd2l0aCBDb21tb25zIENvbXByZXNzIDEuNAorICAgICAgICA8Y29kZT5UYXJBcmNoaXZlSW5wdXRTdHJlYW08L2NvZGU+IHdpbGwgcmVjb2duaXplIHRoZSBzdGFyIGFzCisgICAgICAgIHdlbGwgYXMgdGhlIFBPU0lYIGV4dGVuc2lvbnMgZm9yIGJpZyBudW1lcmljIHZhbHVlcyBhbmQgcmVhZHMgdGhlbQorICAgICAgICB0cmFuc3BhcmVudGx5LjwvcD4KKyAgICAgIDwvc3Vic2VjdGlvbj4KKworICAgICAgPHN1YnNlY3Rpb24gbmFtZT0iRmlsZSBOYW1lIEVuY29kaW5nIj4KKyAgICAgICAgPHA+VGhlIG9yaWdpbmFsIHVzdGFyIGZvcm1hdCBvbmx5IHN1cHBvcnRzIDctQml0IEFTQ0lJIGZpbGUKKyAgICAgICAgbmFtZXMsIGxhdGVyIGltcGxlbWVudGF0aW9ucyB1c2UgdGhlIHBsYXRmb3JtJ3MgZGVmYXVsdAorICAgICAgICBlbmNvZGluZyB0byBlbmNvZGUgZmlsZSBuYW1lcy4gIFRoZSBQT1NJWCBzdGFuZGFyZCByZWNvbW1lbmRzCisgICAgICAgIHVzaW5nIFBBWCBleHRlbnNpb24gaGVhZGVycyBmb3Igbm9uLUFTQ0lJIGZpbGUgbmFtZXMKKyAgICAgICAgaW5zdGVhZC48L3A+CisKKyAgICAgICAgPHA+Q29tbW9ucyBDb21wcmVzcyAxLjEgdG8gMS4zIGFzc3VtZWQgZmlsZSBuYW1lcyB3b3VsZCBiZQorICAgICAgICBlbmNvZGVkIHVzaW5nIElTTy04ODU5LTEuICBTdGFydGluZyB3aXRoIENvbW1vbnMgQ29tcHJlc3MgMS40CisgICAgICAgIHlvdSBjYW4gc3BlY2lmeSB0aGUgZW5jb2RpbmcgdG8gZXhwZWN0ICh0byB1c2Ugd2hlbiB3cml0aW5nKQorICAgICAgICBhcyBhIHBhcmFtZXRlciB0byA8Y29kZT5UYXJBcmNoaXZlSW5wdXRTdHJlYW08L2NvZGU+CisgICAgICAgICg8Y29kZT5UYXJBcmNoaXZlT3V0cHV0U3RyZWFtPC9jb2RlPiksIGl0IG5vdyBkZWZhdWx0cyB0byB0aGUKKyAgICAgICAgcGxhdGZvcm0ncyBkZWZhdWx0IGVuY29kaW5nLjwvcD4KKworICAgICAgICA8cD5TaW5jZSBDb21tb25zIENvbXByZXNzIDEuNCBhbm90aGVyIG9wdGlvbmFsIHBhcmFtZXRlciAtCisgICAgICAgIDxjb2RlPmFkZFBheEhlYWRlcnNGb3JOb25Bc2NpaU5hbWVzPC9jb2RlPiAtIG9mCisgICAgICAgIDxjb2RlPlRhckFyY2hpdmVPdXRwdXRTdHJlYW08L2NvZGU+IGNvbnRyb2xzIHdoZXRoZXIgUEFYCisgICAgICAgIGV4dGVuc2lvbiBoZWFkZXJzIHdpbGwgYmUgd3JpdHRlbiBmb3Igbm9uLUFTQ0lJIGZpbGUgbmFtZXMuCisgICAgICAgIEJ5IGRlZmF1bHQgdGhleSB3aWxsIG5vdCBiZSB3cml0dGVuIHRvIHByZXNlcnZlIHNwYWNlLgorICAgICAgICA8Y29kZT5UYXJBcmNoaXZlSW5wdXRTdHJlYW08L2NvZGU+IHdpbGwgcmVhZCB0aGVtCisgICAgICAgIHRyYW5zcGFyZW50bHkgaWYgcHJlc2VudC48L3A+CisgICAgICA8L3N1YnNlY3Rpb24+CisKKyAgICAgIDxzdWJzZWN0aW9uIG5hbWU9IlNwYXJzZSBmaWxlcyI+CisKKyAgICAgICAgPHA+PGNvZGU+VGFyQXJjaGl2ZUlucHV0U3RyZWFtPC9jb2RlPiB3aWxsIHJlY29nbml6ZSBzcGFyc2UKKyAgICAgICAgZmlsZSBlbnRyaWVzIHN0b3JlZCB1c2luZyB0aGUgIm9sZGdudSIgZm9ybWF0CisgICAgICAgICg8Y29kZT4tJiN4MmQ7c3BhcnNlLXZlcnNpb249MC4wPC9jb2RlPiBpbiBHTlUgdGFyKSBidXQgaXMgbm90CisgICAgICAgIGFibGUgdG8gZXh0cmFjdCB0aGVtIGNvcnJlY3RseS4gIDxhIGhyZWY9IiNVbnN1cHBvcnRlZAorICAgICAgICBGZWF0dXJlcyI+PGNvZGU+Y2FuUmVhZEVudHJ5RGF0YTwvY29kZT48L2E+IHdpbGwgcmV0dXJuIGZhbHNlCisgICAgICAgIG9uIHN1Y2ggZW50cmllcy4gIFRoZSBvdGhlciB2YXJpYW50cyBvZiBzcGFyc2UgZmlsZXMgY2FuCisgICAgICAgIGN1cnJlbnRseSBub3QgYmUgZGV0ZWN0ZWQgYXQgYWxsLjwvcD4KKyAgICAgIDwvc3Vic2VjdGlvbj4KKworICAgICAgPHN1YnNlY3Rpb24gbmFtZT0iQ29uc3VtaW5nIEFyY2hpdmVzIENvbXBsZXRlbHkiPgorCisgICAgICAgIDxwPlRoZSBlbmQgb2YgYSB0YXIgYXJjaGl2ZSBpcyBzaWduYWxsZWQgYnkgdHdvIGNvbnNlY3V0aXZlCisgICAgICAgIHJlY29yZHMgb2YgYWxsIHplcm9zLiAgVW5mb3J0dW5hdGVseSBub3QgYWxsIHRhcgorICAgICAgICBpbXBsZW1lbnRhdGlvbnMgYWRoZXJlIHRvIHRoaXMgYW5kIHNvbWUgb25seSB3cml0ZSBvbmUgcmVjb3JkCisgICAgICAgIHRvIGVuZCB0aGUgYXJjaGl2ZS4gIENvbW1vbnMgQ29tcHJlc3Mgd2lsbCBhbHdheXMgd3JpdGUgdHdvCisgICAgICAgIHJlY29yZHMgYnV0IHN0b3AgcmVhZGluZyBhbiBhcmNoaXZlIGFzIHNvb24gYXMgZmluZHMgb25lCisgICAgICAgIHJlY29yZCBvZiBhbGwgemVyb3MuPC9wPgorCisgICAgICAgIDxwPlByaW9yIHRvIHZlcnNpb24gMS41IHRoaXMgY291bGQgbGVhdmUgdGhlIHNlY29uZCBFT0YgcmVjb3JkCisgICAgICAgIGluc2lkZSB0aGUgc3RyZWFtIHdoZW4gPGNvZGU+Z2V0TmV4dEVudHJ5PC9jb2RlPiBvcgorICAgICAgICA8Y29kZT5nZXROZXh0VGFyRW50cnk8L2NvZGU+IHJldHVybmVkIDxjb2RlPm51bGw8L2NvZGU+CisgICAgICAgIFN0YXJ0aW5nIHdpdGggdmVyc2lvbiAxLjUgPGNvZGU+VGFyQXJjaGl2ZUlucHV0U3RyZWFtPC9jb2RlPgorICAgICAgICB3aWxsIHRyeSB0byByZWFkIGEgc2Vjb25kIHJlY29yZCBhcyB3ZWxsIGlmIHByZXNlbnQsCisgICAgICAgIGVmZmVjdGl2ZWx5IGNvbnN1bWluZyB0aGUgYXJjaGl2ZSBjb21wbGV0ZWx5LjwvcD4KKworICAgICAgPC9zdWJzZWN0aW9uPgorCisgICAgICA8c3Vic2VjdGlvbiBuYW1lPSJQQVggRXh0ZW5kZWQgSGVhZGVyIj4KKyAgICAgICAgPHA+VGhlIHRhciBwYWNrYWdlIGhhcyBzdXBwb3J0ZWQgcmVhZGluZyBQQVggZXh0ZW5kZWQgaGVhZGVycworICAgICAgICBzaW5jZSAxLjMgZm9yIGxvY2FsIGhlYWRlcnMgYW5kIDEuMTEgZm9yIGdsb2JhbCBoZWFkZXJzLiBUaGUKKyAgICAgICAgZm9sbG93aW5nIGVudHJpZXMgb2YgUEFYIGhlYWRlcnMgYXJlIGFwcGxpZWQgd2hlbiByZWFkaW5nOjwvcD4KKworICAgICAgICA8ZGw+CisgICAgICAgICAgPGR0PnBhdGg8L2R0PgorICAgICAgICAgIDxkZD5zZXQgdGhlIGVudHJ5J3MgbmFtZTwvZGQ+CisKKyAgICAgICAgICA8ZHQ+bGlua3BhdGg8L2R0PgorICAgICAgICAgIDxkZD5zZXQgdGhlIGVudHJ5J3MgbGluayBuYW1lPC9kZD4KKworICAgICAgICAgIDxkdD5naWQ8L2R0PgorICAgICAgICAgIDxkZD5zZXQgdGhlIGVudHJ5J3MgZ3JvdXAgaWQ8L2RkPgorCisgICAgICAgICAgPGR0PmduYW1lPC9kdD4KKyAgICAgICAgICA8ZGQ+c2V0IHRoZSBlbnRyeSdzIGdyb3VwIG5hbWU8L2RkPgorCisgICAgICAgICAgPGR0PnVpZDwvZHQ+CisgICAgICAgICAgPGRkPnNldCB0aGUgZW50cnkncyB1c2VyIGlkPC9kZD4KKworICAgICAgICAgIDxkdD51bmFtZTwvZHQ+CisgICAgICAgICAgPGRkPnNldCB0aGUgZW50cnkncyB1c2VyIG5hbWU8L2RkPgorCisgICAgICAgICAgPGR0PnNpemU8L2R0PgorICAgICAgICAgIDxkZD5zZXQgdGhlIGVudHJ5J3Mgc2l6ZTwvZGQ+CisKKyAgICAgICAgICA8ZHQ+bXRpbWU8L2R0PgorICAgICAgICAgIDxkZD5zZXQgdGhlIGVudHJ5J3MgbW9kaWZpY2F0aW9uIHRpbWU8L2RkPgorCisgICAgICAgICAgPGR0PlNDSElMWS5kZXZtaW5vcjwvZHQ+CisgICAgICAgICAgPGRkPnNldCB0aGUgZW50cnkncyBtaW5vciBkZXZpY2UgbnVtYmVyPC9kZD4KKworICAgICAgICAgIDxkdD5TQ0hJTFkuZGV2bWFqb3I8L2R0PgorICAgICAgICAgIDxkZD5zZXQgdGhlIGVudHJ5J3MgbWFqb3IgZGV2aWNlIG51bWJlcjwvZGQ+CisgICAgICAgIDwvZGw+CisKKyAgICAgICAgPHA+aW4gYWRkaXRpb24gc29tZSBmaWVsZHMgdXNlZCBieSBHTlUgdGFyIGFuZCBzdGFyIHVzZWQgdG8KKyAgICAgICAgc2lnbmFsIHNwYXJzZSBlbnRyaWVzIGFyZSBzdXBwb3J0ZWQgYW5kIGFyZSB1c2VkIGZvciB0aGUKKyAgICAgICAgPGNvZGU+aXMqR05VU3BhcnNlPC9jb2RlPiBhbmQgPGNvZGU+aXNTdGFyU3BhcnNlPC9jb2RlPgorICAgICAgICBtZXRob2RzLjwvcD4KKworICAgICAgICA8cD5Tb21lIFBBWCBleHRyYSBoZWFkZXJzIG1heSBiZSBzZXQgd2hlbiB3cml0aW5nIGFyY2hpdmVzLAorICAgICAgICBmb3IgZXhhbXBsZSBmb3Igbm9uLUFTQ0lJIG5hbWVzIG9yIGJpZyBudW1lcmljIHZhbHVlcy4gVGhpcworICAgICAgICBkZXBlbmRzIG9uIHZhcmlvdXMgc2V0dGluZyBvZiB0aGUgb3V0cHV0IHN0cmVhbSAtIHNlZSB0aGUKKyAgICAgICAgcHJldmlvdXMgc2VjdGlvbnMuPC9wPgorCisgICAgICAgIDxwPlNpbmNlIDEuMTUgeW91IGNhbiBkaXJlY3RseSBhY2Nlc3MgYWxsIFBBWCBleHRlbnNpb24KKyAgICAgICAgaGVhZGVycyB0aGF0IGhhdmUgYmVlbiBmb3VuZCB3aGVuIHJlYWRpbmcgYW4gZW50cnkgb3Igc3BlY2lmeQorICAgICAgICBleHRyYSBoZWFkZXJzIHRvIGJlIHdyaXR0ZW4gdG8gYSAobG9jYWwpIFBBWCBleHRlbmRlZCBoZWFkZXIKKyAgICAgICAgZW50cnkuPC9wPgorCisgICAgICAgIDxwPlNvbWUgaGludHMgaWYgeW91IHRyeSB0byBzZXQgZXh0ZW5kZWQgaGVhZGVyczo8L3A+CisKKyAgICAgICAgPHVsPgorICAgICAgICAgIDxsaT5wYXggaGVhZGVyIGtleXdvcmRzIHNob3VsZCBiZSBhc2NpaS4gIHN0YXIvZ251dGFyCisgICAgICAgICAgKFNDSElMWS54YXR0ci4qICkgZG8gbm90IGNoZWNrIGZvciB0aGlzLiAgbGliYXJjaGl2ZS9ic2R0YXIKKyAgICAgICAgICAoTElCQVJDSElWRS54YXR0ci4qKSB1c2VzIFVSTC1FbmNvZGluZy48L2xpPgorICAgICAgICAgIDxsaT5wYXggaGVhZGVyIHZhbHVlcyBzaG91bGQgYmUgZW5jb2RlZCBhcyBVVEYtOCBjaGFyYWN0ZXJzCisgICAgICAgICAgKGluY2x1ZGluZyB0cmFpbGluZyA8Y29kZT5cMDwvY29kZT4pLiAgc3Rhci9nbnV0YXIKKyAgICAgICAgICAoU0NISUxZLnhhdHRyLiopIGRvIG5vdCBjaGVjayBmb3IgdGhpcy4gIGxpYmFyY2hpdmUvYnNkdGFyCisgICAgICAgICAgKExJQkFSQ0hJVkUueGF0dHIuKikgZW5jb2RlIHZhbHVlcyB1c2luZyBCYXNlNjQuPC9saT4KKyAgICAgICAgICA8bGk+bGliYXJjaGl2ZS9ic2R0YXIgd2lsbCByZWFkIFNDSElMWS54YXR0ciBoZWFkZXJzLCBidXQKKyAgICAgICAgICB3aWxsIG5vdCBnZW5lcmF0ZSB0aGVtLjwvbGk+CisgICAgICAgICAgPGxpPmdudXRhciB3aWxsIGNvbXBsYWluIGFib3V0IExJQkFSQ0hJVkUueGF0dHIgKGFuZCBhbnkKKyAgICAgICAgICBvdGhlciB1bmtub3duKSBoZWFkZXJzIGFuZCB3aWxsIG5laXRoZXIgZW5jb2RlIG5vciBkZWNvZGUKKyAgICAgICAgICB0aGVtLjwvbGk+CisgICAgICAgIDwvdWw+CisgICAgICA8L3N1YnNlY3Rpb24+CisKKyAgICA8L3NlY3Rpb24+CisgIDwvYm9keT4KKzwvZG9jdW1lbnQ+CmRpZmYgLS1naXQgYS9zcmMvc2l0ZS94ZG9jL3ppcC54bWwgYi9zcmMvc2l0ZS94ZG9jL3ppcC54bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTlmZjVkYwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9zaXRlL3hkb2MvemlwLnhtbApAQCAtMCwwICsxLDU2OCBAQAorPD94bWwgdmVyc2lvbj0iMS4wIj8+Cis8IS0tCisKKyAgIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAgIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisKKyAgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKworICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAgIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisKKy0tPgorPGRvY3VtZW50PgorICA8cHJvcGVydGllcz4KKyAgICA8dGl0bGU+Q29tbW9ucyBDb21wcmVzcyBaSVAgcGFja2FnZTwvdGl0bGU+CisgICAgPGF1dGhvciBlbWFpbD0iZGV2QGNvbW1vbnMuYXBhY2hlLm9yZyI+Q29tbW9ucyBEb2N1bWVudGF0aW9uIFRlYW08L2F1dGhvcj4KKyAgPC9wcm9wZXJ0aWVzPgorICA8Ym9keT4KKyAgICA8c2VjdGlvbiBuYW1lPSJUaGUgWklQIHBhY2thZ2UiPgorCisgICAgICA8cD5UaGUgWklQIHBhY2thZ2UgcHJvdmlkZXMgZmVhdHVyZXMgbm90IGZvdW5kCisgICAgICAgIGluIDxjb2RlPmphdmEudXRpbC56aXA8L2NvZGU+OjwvcD4KKworICAgICAgPHVsPgorICAgICAgICA8bGk+U3VwcG9ydCBmb3IgZW5jb2RpbmdzIG90aGVyIHRoYW4gVVRGLTggZm9yIGZpbGVuYW1lcyBhbmQKKyAgICAgICAgICBjb21tZW50cy4gIFN0YXJ0aW5nIHdpdGggSmF2YTcgdGhpcyBpcyBzdXBwb3J0ZWQKKyAgICAgICAgICBieSA8Y29kZT5qYXZhLnV0aWwuemlwPC9jb2RlPiBhcyB3ZWxsLjwvbGk+CisgICAgICAgIDxsaT5BY2Nlc3MgdG8gaW50ZXJuYWwgYW5kIGV4dGVybmFsIGF0dHJpYnV0ZXMgKHdoaWNoIGFyZSB1c2VkCisgICAgICAgICAgdG8gc3RvcmUgVW5peCBwZXJtaXNzaW9uIGJ5IHNvbWUgemlwIGltcGxlbWVudGF0aW9ucykuPC9saT4KKyAgICAgICAgPGxpPlN0cnVjdHVyZWQgc3VwcG9ydCBmb3IgZXh0cmEgZmllbGRzLjwvbGk+CisgICAgICA8L3VsPgorCisgICAgICA8cD5JbiBhZGRpdGlvbiB0byB0aGUgaW5mb3JtYXRpb24gc3RvcmVkCisgICAgICAgIGluIDxjb2RlPkFyY2hpdmVFbnRyeTwvY29kZT4gYSA8Y29kZT5aaXBBcmNoaXZlRW50cnk8L2NvZGU+CisgICAgICAgIHN0b3JlcyBpbnRlcm5hbCBhbmQgZXh0ZXJuYWwgYXR0cmlidXRlcyBhcyB3ZWxsIGFzIGV4dHJhCisgICAgICAgIGZpZWxkcyB3aGljaCBtYXkgY29udGFpbiBpbmZvcm1hdGlvbiBsaWtlIFVuaXggcGVybWlzc2lvbnMsCisgICAgICAgIGluZm9ybWF0aW9uIGFib3V0IHRoZSBwbGF0Zm9ybSB0aGV5J3ZlIGJlZW4gY3JlYXRlZCBvbiwgdGhlaXIKKyAgICAgICAgbGFzdCBtb2RpZmljYXRpb24gdGltZSBhbmQgYW4gb3B0aW9uYWwgY29tbWVudC48L3A+CisKKyAgICAgIDxzdWJzZWN0aW9uIG5hbWU9IlppcEFyY2hpdmVJbnB1dFN0cmVhbSB2cyBaaXBGaWxlIj4KKworICAgICAgICA8cD5aSVAgYXJjaGl2ZXMgc3RvcmUgYSBhcmNoaXZlIGVudHJpZXMgaW4gc2VxdWVuY2UgYW5kCisgICAgICAgICAgY29udGFpbiBhIHJlZ2lzdHJ5IG9mIGFsbCBlbnRyaWVzIGF0IHRoZSB2ZXJ5IGVuZCBvZiB0aGUKKyAgICAgICAgICBhcmNoaXZlLiAgSXQgaXMgYWNjZXB0YWJsZSBmb3IgYW4gYXJjaGl2ZSB0byBjb250YWluIHNldmVyYWwKKyAgICAgICAgICBlbnRyaWVzIG9mIHRoZSBzYW1lIG5hbWUgYW5kIGhhdmUgdGhlIHJlZ2lzdHJ5IChjYWxsZWQgdGhlCisgICAgICAgICAgY2VudHJhbCBkaXJlY3RvcnkpIGRlY2lkZSB3aGljaCBlbnRyeSBpcyBhY3R1YWxseSB0byBiZSB1c2VkCisgICAgICAgICAgKGlmIGFueSkuPC9wPgorCisgICAgICAgIDxwPkluIGFkZGl0aW9uIHRoZSBaSVAgZm9ybWF0IHN0b3JlcyBjZXJ0YWluIGluZm9ybWF0aW9uIG9ubHkKKyAgICAgICAgICBpbnNpZGUgdGhlIGNlbnRyYWwgZGlyZWN0b3J5IGJ1dCBub3QgdG9nZXRoZXIgd2l0aCB0aGUgZW50cnkKKyAgICAgICAgICBpdHNlbGYsIHRoaXMgaXM6PC9wPgorCisgICAgICAgIDx1bD4KKyAgICAgICAgICA8bGk+aW50ZXJuYWwgYW5kIGV4dGVybmFsIGF0dHJpYnV0ZXM8L2xpPgorICAgICAgICAgIDxsaT5kaWZmZXJlbnQgb3IgYWRkaXRpb25hbCBleHRyYSBmaWVsZHM8L2xpPgorICAgICAgICA8L3VsPgorCisgICAgICAgIDxwPlRoaXMgbWVhbnMgdGhlIFpJUCBmb3JtYXQgY2Fubm90IHJlYWxseSBiZSBwYXJzZWQKKyAgICAgICAgICBjb3JyZWN0bHkgd2hpbGUgcmVhZGluZyBhIG5vbi1zZWVrYWJsZSBzdHJlYW0sIHdoaWNoIGlzIHdoYXQKKyAgICAgICAgICA8Y29kZT5aaXBBcmNoaXZlSW5wdXRTdHJlYW08L2NvZGU+IGlzIGZvcmNlZCB0byBkby4gIEFzIGEKKyAgICAgICAgICByZXN1bHQgPGNvZGU+WmlwQXJjaGl2ZUlucHV0U3RyZWFtPC9jb2RlPjwvcD4KKyAgICAgICAgPHVsPgorICAgICAgICAgIDxsaT5tYXkgcmV0dXJuIGVudHJpZXMgdGhhdCBhcmUgbm90IHBhcnQgb2YgdGhlIGNlbnRyYWwKKyAgICAgICAgICAgIGRpcmVjdG9yeSBhdCBhbGwgYW5kIHNob3VsZG4ndCBiZSBjb25zaWRlcmVkIHBhcnQgb2YgdGhlCisgICAgICAgICAgICBhcmNoaXZlLjwvbGk+CisgICAgICAgICAgPGxpPm1heSByZXR1cm4gc2V2ZXJhbCBlbnRyaWVzIHdpdGggdGhlIHNhbWUgbmFtZS48L2xpPgorICAgICAgICAgIDxsaT53aWxsIG5vdCByZXR1cm4gaW50ZXJuYWwgb3IgZXh0ZXJuYWwgYXR0cmlidXRlcy48L2xpPgorICAgICAgICAgIDxsaT5tYXkgcmV0dXJuIGluY29tcGxldGUgZXh0cmEgZmllbGQgZGF0YS48L2xpPgorICAgICAgICAgIDxsaT5tYXkgcmV0dXJuIHVua25vd24gc2l6ZXMgYW5kIENSQyB2YWx1ZXMgZm9yIGVudHJpZXMKKyAgICAgICAgICB1bnRpbCB0aGUgbmV4dCBlbnRyeSBoYXMgYmVlbiByZWFjaGVkIGlmIHRoZSBhcmNoaXZlIHVzZXMKKyAgICAgICAgICB0aGUgZGF0YSBkZXNjcmlwdG9yIGZlYXR1cmUgKHNlZSBiZWxvdykuPC9saT4KKyAgICAgICAgPC91bD4KKworICAgICAgICA8cD48Y29kZT5aaXBBcmNoaXZlSW5wdXRTdHJlYW08L2NvZGU+IHNoYXJlcyB0aGVzZSBsaW1pdGF0aW9ucworICAgICAgICAgIHdpdGggPGNvZGU+amF2YS51dGlsLnppcC5aaXBJbnB1dFN0cmVhbTwvY29kZT4uPC9wPgorCisgICAgICAgIDxwPjxjb2RlPlppcEZpbGU8L2NvZGU+IGlzIGFibGUgdG8gcmVhZCB0aGUgY2VudHJhbCBkaXJlY3RvcnkKKyAgICAgICAgICBmaXJzdCBhbmQgcHJvdmlkZSBjb3JyZWN0IGFuZCBjb21wbGV0ZSBpbmZvcm1hdGlvbiBvbiBhbnkKKyAgICAgICAgICBaSVAgYXJjaGl2ZS48L3A+CisKKyAgICAgICAgPHA+WklQIGFyY2hpdmVzIGtub3cgYSBmZWF0dXJlIGNhbGxlZCB0aGUgZGF0YSBkZXNjcmlwdG9yCisgICAgICAgICAgd2hpY2ggaXMgYSB3YXkgdG8gc3RvcmUgYW4gZW50cnkncyBsZW5ndGggYWZ0ZXIgdGhlIGVudHJ5J3MKKyAgICAgICAgICBkYXRhLiAgVGhpcyBjYW4gb25seSB3b3JrIHJlbGlhYmx5IGlmIHRoZSBzaXplIGluZm9ybWF0aW9uCisgICAgICAgICAgY2FuIGJlIHRha2VuIGZyb20gdGhlIGNlbnRyYWwgZGlyZWN0b3J5IG9yIHRoZSBkYXRhIGl0c2VsZgorICAgICAgICAgIGNhbiBzaWduYWwgaXQgaXMgY29tcGxldGUsIHdoaWNoIGlzIHRydWUgZm9yIGRhdGEgdGhhdCBpcworICAgICAgICAgIGNvbXByZXNzZWQgdXNpbmcgdGhlIERFRkxBVEVEIGNvbXByZXNzaW9uIGFsZ29yaXRobS48L3A+CisKKyAgICAgICAgPHA+PGNvZGU+WmlwRmlsZTwvY29kZT4gaGFzIGFjY2VzcyB0byB0aGUgY2VudHJhbCBkaXJlY3RvcnkKKyAgICAgICAgICBhbmQgY2FuIGV4dHJhY3QgZW50cmllcyB1c2luZyB0aGUgZGF0YSBkZXNjcmlwdG9yIHJlbGlhYmx5LgorICAgICAgICAgIFRoZSBzYW1lIGlzIHRydWUgZm9yIDxjb2RlPlppcEFyY2hpdmVJbnB1dFN0cmVhbTwvY29kZT4gYXMKKyAgICAgICAgICBsb25nIGFzIHRoZSBlbnRyeSBpcyBERUZMQVRFRC4gIEZvciBTVE9SRUQKKyAgICAgICAgICBlbnRyaWVzIDxjb2RlPlppcEFyY2hpdmVJbnB1dFN0cmVhbTwvY29kZT4gY2FuIHRyeSB0byByZWFkCisgICAgICAgICAgYWhlYWQgdW50aWwgaXQgZmluZHMgdGhlIG5leHQgZW50cnksIGJ1dCB0aGlzIGFwcHJvYWNoIGlzCisgICAgICAgICAgbm90IHNhZmUgYW5kIGhhcyB0byBiZSBlbmFibGVkIGJ5IGEgY29uc3RydWN0b3IgYXJndW1lbnQKKyAgICAgICAgICBleHBsaWNpdGx5LjwvcD4KKworICAgICAgICA8cD5JZiBwb3NzaWJsZSwgeW91IHNob3VsZCBhbHdheXMgcHJlZmVyIDxjb2RlPlppcEZpbGU8L2NvZGU+CisgICAgICAgICAgb3ZlciA8Y29kZT5aaXBBcmNoaXZlSW5wdXRTdHJlYW08L2NvZGU+LjwvcD4KKworICAgICAgICA8cD48Y29kZT5aaXBGaWxlPC9jb2RlPiByZXF1aXJlcyBhCisgICAgICAgIDxjb2RlPlNlZWthYmxlQnl0ZUNoYW5uZWw8L2NvZGU+IHRoYXQgd2lsbCBiZSBvYnRhaW5lZAorICAgICAgICB0cmFuc3BhcmVudGx5IHdoZW4gcmVhZGluZyBmcm9tIGEgZmlsZS4gVGhlIGNsYXNzCisgICAgICAgIDxjb2RlPm9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5TZWVrYWJsZUluTWVtb3J5Qnl0ZUNoYW5uZWw8L2NvZGU+CisgICAgICAgIGFsbG93cyB5b3UgdG8gcmVhZCBmcm9tIGFuIGluLW1lbW9yeSBhcmNoaXZlLjwvcD4KKworICAgICAgPC9zdWJzZWN0aW9uPgorCisgICAgICA8c3Vic2VjdGlvbiBuYW1lPSJaaXBBcmNoaXZlT3V0cHV0U3RyZWFtIiBpZD0iWmlwQXJjaGl2ZU91dHB1dFN0cmVhbSI+CisgICAgICAgIDxwPjxjb2RlPlppcEFyY2hpdmVPdXRwdXRTdHJlYW08L2NvZGU+IGhhcyB0aHJlZSBjb25zdHJ1Y3RvcnMsCisgICAgICAgIG9uZSBvZiB0aGVtIHVzZXMgYSA8Y29kZT5GaWxlPC9jb2RlPiBhcmd1bWVudCwgb25lIGEKKyAgICAgICAgPGNvZGU+U2Vla2FibGVCeXRlQ2hhbm5lbDwvY29kZT4gYW5kIHRoZSBsYXN0IHVzZXMgYW4KKyAgICAgICAgPGNvZGU+T3V0cHV0U3RyZWFtPC9jb2RlPi4gIFRoZSA8Y29kZT5GaWxlPC9jb2RlPiB2ZXJzaW9uIHdpbGwKKyAgICAgICAgdHJ5IHRvIHVzZSA8Y29kZT5TZWVrYWJsZUJ5dGVDaGFubmVsPC9jb2RlPiBhbmQgZmFsbCBiYWNrIHRvCisgICAgICAgIHVzaW5nIGEgPGNvZGU+RmlsZU91dHB1dFN0cmVhbTwvY29kZT4gaW50ZXJuYWxseSBpZiB0aGF0CisgICAgICAgIGZhaWxzLjwvcD4KKworICAgICAgICA8cD5JZiA8Y29kZT5aaXBBcmNoaXZlT3V0cHV0U3RyZWFtPC9jb2RlPiBjYW4KKyAgICAgICAgICB1c2UgPGNvZGU+U2Vla2FibGVCeXRlQ2hhbm5lbDwvY29kZT4gaXQgY2FuIGVtcGxveSBzb21lCisgICAgICAgICAgb3B0aW1pemF0aW9ucyB0aGF0IGxlYWQgdG8gc21hbGxlciBhcmNoaXZlcy4gIEl0IGFsc28gbWFrZXMKKyAgICAgICAgICBpdCBwb3NzaWJsZSB0byBhZGQgdW5jb21wcmVzc2VkICg8Y29kZT5zZXRNZXRob2Q8L2NvZGU+IHVzZWQKKyAgICAgICAgICB3aXRoIDxjb2RlPlNUT1JFRDwvY29kZT4pIGVudHJpZXMgb2YgdW5rbm93biBzaXplIHdoZW4KKyAgICAgICAgICBjYWxsaW5nIDxjb2RlPnB1dEFyY2hpdmVFbnRyeTwvY29kZT4gLSB0aGlzIGlzIG5vdCBhbGxvd2VkCisgICAgICAgICAgaWYgPGNvZGU+WmlwQXJjaGl2ZU91dHB1dFN0cmVhbTwvY29kZT4gaGFzIHRvIHVzZQorICAgICAgICAgIGFuIDxjb2RlPk91dHB1dFN0cmVhbTwvY29kZT4uPC9wPgorCisgICAgICAgIDxwPklmIHlvdSBrbm93IHlvdSBhcmUgd3JpdGluZyB0byBhIGZpbGUsIHlvdSBzaG91bGQgYWx3YXlzCisgICAgICAgIHByZWZlciB0aGUgPGNvZGU+RmlsZTwvY29kZT4tIG9yCisgICAgICAgIDxjb2RlPlNlZWthYmxlQnl0ZUNoYW5uZWw8L2NvZGU+LWFyZyBjb25zdHJ1Y3RvcnMuICBUaGUgY2xhc3MKKyAgICAgICAgPGNvZGU+b3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLlNlZWthYmxlSW5NZW1vcnlCeXRlQ2hhbm5lbDwvY29kZT4KKyAgICAgICAgYWxsb3dzIHlvdSB0byB3cml0ZSB0byBhbiBpbi1tZW1vcnkgYXJjaGl2ZS48L3A+CisKKyAgICAgIDwvc3Vic2VjdGlvbj4KKworICAgICAgPHN1YnNlY3Rpb24gbmFtZT0iRXh0cmEgRmllbGRzIj4KKworICAgICAgICA8cD5JbnNpZGUgYSBaSVAgYXJjaGl2ZSwgYWRkaXRpb25hbCBkYXRhIGNhbiBiZSBhdHRhY2hlZCB0bworICAgICAgICAgIGVhY2ggZW50cnkuICBUaGUgPGNvZGU+amF2YS51dGlsLnppcC5aaXBFbnRyeTwvY29kZT4gY2xhc3MKKyAgICAgICAgICBwcm92aWRlcyBhY2Nlc3MgdG8gdGhpcyB2aWEgdGhlIDxjb2RlPmdldC9zZXRFeHRyYTwvY29kZT4KKyAgICAgICAgICBtZXRob2RzIGFzIGFycmF5cyBvZiA8Y29kZT5ieXRlPC9jb2RlPnMuPC9wPgorCisgICAgICAgIDxwPkFjdHVhbGx5IHRoZSBleHRyYSBkYXRhIGlzIHN1cHBvc2VkIHRvIGJlIG1vcmUgc3RydWN0dXJlZAorICAgICAgICAgIHRoYW4gdGhhdCBhbmQgQ29tcHJlc3MnIFpJUCBwYWNrYWdlIHByb3ZpZGVzIGFjY2VzcyB0byB0aGUKKyAgICAgICAgICBzdHJ1Y3R1cmVkIGRhdGEgYXMgPGNvZGU+RXh0cmFGaWVsZDwvY29kZT4gaW5zdGFuY2VzLiAgT25seQorICAgICAgICAgIGEgc3Vic2V0IG9mIGFsbCBkZWZpbmVkIGV4dHJhIGZpZWxkIGZvcm1hdHMgaXMgc3VwcG9ydGVkIGJ5CisgICAgICAgICAgdGhlIHBhY2thZ2UsIGFueSBvdGhlciBleHRyYSBmaWVsZCB3aWxsIGJlIHN0b3JlZAorICAgICAgICAgIGFzIDxjb2RlPlVucmVjb2duaXplZEV4dHJhRmllbGQ8L2NvZGU+LjwvcD4KKworICAgICAgICA8cD5QcmlvciB0byB2ZXJzaW9uIDEuMSBvZiB0aGlzIGxpYnJhcnkgdHJ5aW5nIHRvIHJlYWQgYW4KKyAgICAgICAgICBhcmNoaXZlIHdpdGggZXh0cmEgZmllbGRzIHRoYXQgZGlkbid0IGZvbGxvdyB0aGUgcmVjb21tZW5kZWQKKyAgICAgICAgICBzdHJ1Y3R1cmUgZm9yIHRob3NlIGZpZWxkcyB3b3VsZCBjYXVzZSBDb21wcmVzcyB0byB0aHJvdyBhbgorICAgICAgICAgIGV4Y2VwdGlvbi4gIFN0YXJ0aW5nIHdpdGggdmVyc2lvbiAxLjEgdGhlc2UgZXh0cmEgZmllbGRzCisgICAgICAgICAgd2lsbCBub3cgYmUgcmVhZAorICAgICAgICAgIGFzIDxjb2RlPlVucGFyc2VhYmxlRXh0cmFGaWVsZERhdGE8L2NvZGU+LjwvcD4KKworICAgICAgPC9zdWJzZWN0aW9uPgorCisgICAgICA8c3Vic2VjdGlvbiBuYW1lPSJFbmNvZGluZyIgaWQ9ImVuY29kaW5nIj4KKworICAgICAgICA8cD5UcmFkaXRpb25hbGx5IHRoZSBaSVAgYXJjaGl2ZSBmb3JtYXQgdXNlcyBDb2RlUGFnZSA0MzcgYXMKKyAgICAgICAgICBlbmNvZGluZyBmb3IgZmlsZSBuYW1lLCB3aGljaCBpcyBub3Qgc3VmZmljaWVudCBmb3IgbWFueQorICAgICAgICAgIGludGVybmF0aW9uYWwgY2hhcmFjdGVyIHNldHMuPC9wPgorCisgICAgICAgIDxwPk92ZXIgdGltZSBkaWZmZXJlbnQgYXJjaGl2ZXJzIGhhdmUgY2hvc2VuIGRpZmZlcmVudCB3YXlzIHRvCisgICAgICAgICAgd29yayBhcm91bmQgdGhlIGxpbWl0YXRpb24gLSB0aGUgPGNvZGU+amF2YS51dGlsLnppcDwvY29kZT4KKyAgICAgICAgICBwYWNrYWdlcyBzaW1wbHkgdXNlcyBVVEYtOCBhcyBpdHMgZW5jb2RpbmcgZm9yIGV4YW1wbGUuPC9wPgorCisgICAgICAgIDxwPkFudCBoYXMgYmVlbiBvZmZlcmluZyB0aGUgZW5jb2RpbmcgYXR0cmlidXRlIG9mIHRoZSB6aXAgYW5kCisgICAgICAgICAgdW56aXAgdGFzayBhcyBhIHdheSB0byBleHBsaWNpdGx5IHNwZWNpZnkgdGhlIGVuY29kaW5nIHRvCisgICAgICAgICAgdXNlIChvciBleHBlY3QpIHNpbmNlIEFudCAxLjQuICBJdCBkZWZhdWx0cyB0byB0aGUKKyAgICAgICAgICBwbGF0Zm9ybSdzIGRlZmF1bHQgZW5jb2RpbmcgZm9yIHppcCBhbmQgVVRGLTggZm9yIGphciBhbmQKKyAgICAgICAgICBvdGhlciBqYXItbGlrZSB0YXNrcyAod2FyLCBlYXIsIC4uLikgYXMgd2VsbCBhcyB0aGUgdW56aXAKKyAgICAgICAgICBmYW1pbHkgb2YgdGFza3MuPC9wPgorCisgICAgICAgIDxwPk1vcmUgcmVjZW50IHZlcnNpb25zIG9mIHRoZSBaSVAgc3BlY2lmaWNhdGlvbiBpbnRyb2R1Y2UKKyAgICAgICAgICBzb21ldGhpbmcgY2FsbGVkIHRoZSAmcXVvdDtsYW5ndWFnZSBlbmNvZGluZyBmbGFnJnF1b3Q7CisgICAgICAgICAgd2hpY2ggY2FuIGJlIHVzZWQgdG8gc2lnbmFsIHRoYXQgYSBmaWxlIG5hbWUgaGFzIGJlZW4KKyAgICAgICAgICBlbmNvZGVkIHVzaW5nIFVURi04LiAgQWxsIFpJUC1hcmNoaXZlcyB3cml0dGVuIGJ5IENvbXByZXNzCisgICAgICAgICAgd2lsbCBzZXQgdGhpcyBmbGFnLCBpZiB0aGUgZW5jb2RpbmcgaGFzIGJlZW4gc2V0IHRvIFVURi04LgorICAgICAgICAgIE91ciBpbnRlcm9wZXJhYmlsaXR5IHRlc3RzIHdpdGggZXhpc3RpbmcgYXJjaGl2ZXJzIGRpZG4ndAorICAgICAgICAgIHNob3cgYW55IGlsbCBlZmZlY3RzIChpbiBmYWN0LCBtb3N0IGFyY2hpdmVycyBpZ25vcmUgdGhlCisgICAgICAgICAgZmxhZyB0byBkYXRlKSwgYnV0IHlvdSBjYW4gdHVybiBvZmYgdGhlICJsYW5ndWFnZSBlbmNvZGluZworICAgICAgICAgIGZsYWciIGJ5IHNldHRpbmcgdGhlIGF0dHJpYnV0ZQorICAgICAgICAgIDxjb2RlPnVzZUxhbmd1YWdlRW5jb2RpbmdGbGFnPC9jb2RlPiB0byA8Y29kZT5mYWxzZTwvY29kZT4gb24gdGhlCisgICAgICAgICAgPGNvZGU+WmlwQXJjaGl2ZU91dHB1dFN0cmVhbTwvY29kZT4gaWYgeW91IHNob3VsZCBlbmNvdW50ZXIKKyAgICAgICAgICBwcm9ibGVtcy48L3A+CisKKyAgICAgICAgPHA+VGhlIDxjb2RlPlppcEZpbGU8L2NvZGU+CisgICAgICAgICAgYW5kIDxjb2RlPlppcEFyY2hpdmVJbnB1dFN0cmVhbTwvY29kZT4gY2xhc3NlcyB3aWxsCisgICAgICAgICAgcmVjb2duaXplIHRoZSBsYW5ndWFnZSBlbmNvZGluZyBmbGFnIGFuZCBpZ25vcmUgdGhlIGVuY29kaW5nCisgICAgICAgICAgc2V0IGluIHRoZSBjb25zdHJ1Y3RvciBpZiBpdCBoYXMgYmVlbiBmb3VuZC48L3A+CisKKyAgICAgICAgPHA+VGhlIEluZm9aSVAgZGV2ZWxvcGVycyBoYXZlIGludHJvZHVjZWQgbmV3IFpJUCBleHRyYSBmaWVsZHMKKyAgICAgICAgICB0aGF0IGNhbiBiZSB1c2VkIHRvIGFkZCBhbiBhZGRpdGlvbmFsIFVURi04IGVuY29kZWQgZmlsZQorICAgICAgICAgIG5hbWUgdG8gdGhlIGVudHJ5J3MgbWV0YWRhdGEuICBNb3N0IGFyY2hpdmVycyBpZ25vcmUgdGhlc2UKKyAgICAgICAgICBleHRyYSBmaWVsZHMuICA8Y29kZT5aaXBBcmNoaXZlT3V0cHV0U3RyZWFtPC9jb2RlPiBzdXBwb3J0cworICAgICAgICAgIGFuIG9wdGlvbiA8Y29kZT5jcmVhdGVVbmljb2RlRXh0cmFGaWVsZHM8L2NvZGU+IHdoaWNoIG1ha2VzCisgICAgICAgICAgaXQgd3JpdGUgdGhlc2UgZXh0cmEgZmllbGRzIGVpdGhlciBmb3IgYWxsIGVudHJpZXMKKyAgICAgICAgICAoImFsd2F5cyIpIG9yIG9ubHkgdGhvc2Ugd2hvc2UgbmFtZSBjYW5ub3QgYmUgZW5jb2RlZCB1c2luZworICAgICAgICAgIHRoZSBzcGVjaWZpZWQgZW5jb2RpbmcgKG5vdC1lbmNvZGVhYmxlKSwgaXQgZGVmYXVsdHMgdG8KKyAgICAgICAgICAibmV2ZXIiIHNpbmNlIHRoZSBleHRyYSBmaWVsZHMgY3JlYXRlIGJpZ2dlciBhcmNoaXZlcy48L3A+CisKKyAgICAgICAgPHA+VGhlIGZhbGxiYWNrVG9VVEY4IGF0dHJpYnV0ZQorICAgICAgICAgIG9mIDxjb2RlPlppcEFyY2hpdmVPdXRwdXRTdHJlYW08L2NvZGU+IGNhbiBiZSB1c2VkIHRvIGNyZWF0ZQorICAgICAgICAgIGFyY2hpdmVzIHRoYXQgdXNlIHRoZSBzcGVjaWZpZWQgZW5jb2RpbmcgaW4gdGhlIG1ham9yaXR5IG9mCisgICAgICAgICAgY2FzZXMgYnV0IFVURi04IGFuZCB0aGUgbGFuZ3VhZ2UgZW5jb2RpbmcgZmxhZyBmb3IgZmlsZW5hbWVzCisgICAgICAgICAgdGhhdCBjYW5ub3QgYmUgZW5jb2RlZCB1c2luZyB0aGUgc3BlY2lmaWVkIGVuY29kaW5nLjwvcD4KKworICAgICAgICA8cD5UaGUgPGNvZGU+WmlwRmlsZTwvY29kZT4KKyAgICAgICAgICBhbmQgPGNvZGU+WmlwQXJjaGl2ZUlucHV0U3RyZWFtPC9jb2RlPiBjbGFzc2VzIHJlY29nbml6ZSB0aGUKKyAgICAgICAgICBVbmljb2RlIGV4dHJhIGZpZWxkcyBieSBkZWZhdWx0IGFuZCByZWFkIHRoZSBmaWxlIG5hbWUKKyAgICAgICAgICBpbmZvcm1hdGlvbiBmcm9tIHRoZW0sIHVubGVzcyB5b3Ugc2V0IHRoZSBjb25zdHJ1Y3RvciBwYXJhbWV0ZXIKKyAgICAgICAgICA8Y29kZT5zY2FuRm9yVW5pY29kZUV4dHJhRmllbGRzPC9jb2RlPiB0byBmYWxzZS48L3A+CisKKyAgICAgICAgPGg0PlJlY29tbWVuZGF0aW9ucyBmb3IgSW50ZXJvcGVyYWJpbGl0eTwvaDQ+CisKKyAgICAgICAgPHA+VGhlIG9wdGltYWwgc2V0dGluZyBvZiBmbGFncyBkZXBlbmRzIG9uIHRoZSBhcmNoaXZlcnMgeW91CisgICAgICAgICAgZXhwZWN0IGFzIGNvbnN1bWVycy9wcm9kdWNlcnMgb2YgdGhlIFpJUCBhcmNoaXZlcy4gIEJlbG93CisgICAgICAgICAgYXJlIHNvbWUgdGVzdCByZXN1bHRzIHdoaWNoIG1heSBiZSBzdXBlcnNlZGVkIHdpdGggbGF0ZXIKKyAgICAgICAgICB2ZXJzaW9ucyBvZiBlYWNoIHRvb2wuPC9wPgorCisgICAgICAgIDx1bD4KKyAgICAgICAgICA8bGk+VGhlIGphdmEudXRpbC56aXAgcGFja2FnZSB1c2VkIGJ5IHRoZSBqYXIgZXhlY3V0YWJsZSBvcgorICAgICAgICAgICAgdG8gcmVhZCBqYXJzIGZyb20geW91ciBDTEFTU1BBVEggcmVhZHMgYW5kIHdyaXRlcyBVVEYtOAorICAgICAgICAgICAgbmFtZXMsIGl0IGRvZXNuJ3Qgc2V0IG9yIHJlY29nbml6ZSBhbnkgZmxhZ3Mgb3IgVW5pY29kZQorICAgICAgICAgICAgZXh0cmEgZmllbGRzLjwvbGk+CisKKyAgICAgICAgICA8bGk+U3RhcnRpbmcgd2l0aCBKYXZhNyA8Y29kZT5qYXZhLnV0aWwuemlwPC9jb2RlPiB3cml0ZXMKKyAgICAgICAgICAgIFVURi04IGJ5IGRlZmF1bHQgYW5kIHVzZXMgdGhlIGxhbmd1YWdlIGVuY29kaW5nIGZsYWcuICBJdAorICAgICAgICAgICAgaXMgcG9zc2libGUgdG8gc3BlY2lmeSBhIGRpZmZlcmVudCBlbmNvZGluZyB3aGVuCisgICAgICAgICAgICByZWFkaW5nL3dyaXRpbmcgWklQcyB2aWEgbmV3IGNvbnN0cnVjdG9ycy4gIFRoZSBwYWNrYWdlCisgICAgICAgICAgICBub3cgcmVjb2duaXplcyB0aGUgbGFuZ3VhZ2UgZW5jb2RpbmcgZmxhZyB3aGVuIHJlYWRpbmcgYW5kCisgICAgICAgICAgICBpZ25vcmVzIHRoZSBVbmljb2RlIGV4dHJhIGZpZWxkcy48L2xpPgorCisgICAgICAgICAgPGxpPjdaaXAgd3JpdGVzIENvZGVQYWdlIDQzNyBieSBkZWZhdWx0IGJ1dCB1c2VzIFVURi04IGFuZAorICAgICAgICAgICAgdGhlIGxhbmd1YWdlIGVuY29kaW5nIGZsYWcgd2hlbiB3cml0aW5nIGVudHJpZXMgdGhhdAorICAgICAgICAgICAgY2Fubm90IGJlIGVuY29kZWQgYXMgQ29kZVBhZ2UgNDM3IChzaW1pbGFyIHRvIHRoZSB6aXAgdGFzaworICAgICAgICAgICAgd2l0aCBmYWxsYmFja3RvVVRGOCBzZXQgdG8gdHJ1ZSkuICBJdCByZWNvZ25pemVzIHRoZQorICAgICAgICAgICAgbGFuZ3VhZ2UgZW5jb2RpbmcgZmxhZyB3aGVuIHJlYWRpbmcgYW5kIGlnbm9yZXMgdGhlCisgICAgICAgICAgICBVbmljb2RlIGV4dHJhIGZpZWxkcy48L2xpPgorCisgICAgICAgICAgPGxpPldpblpJUCB3cml0ZXMgQ29kZVBhZ2UgNDM3IGFuZCB1c2VzIFVuaWNvZGUgZXh0cmEgZmllbGRzCisgICAgICAgICAgICBieSBkZWZhdWx0LiAgSXQgcmVjb2duaXplcyB0aGUgVW5pY29kZSBleHRyYSBmaWVsZCBhbmQgdGhlCisgICAgICAgICAgICBsYW5ndWFnZSBlbmNvZGluZyBmbGFnIHdoZW4gcmVhZGluZy48L2xpPgorCisgICAgICAgICAgPGxpPldpbmRvd3MnICJjb21wcmVzc2VkIGZvbGRlciIgZmVhdHVyZSBkb2Vzbid0IHJlY29nbml6ZQorICAgICAgICAgICAgYW55IGZsYWcgb3IgZXh0cmEgZmllbGQgYW5kIGNyZWF0ZXMgYXJjaGl2ZXMgdXNpbmcgdGhlCisgICAgICAgICAgICBwbGF0Zm9ybXMgZGVmYXVsdCBlbmNvZGluZyAtIGFuZCBleHBlY3RzIGFyY2hpdmVzIHRvIGJlIGluCisgICAgICAgICAgICB0aGF0IGVuY29kaW5nIHdoZW4gcmVhZGluZyB0aGVtLjwvbGk+CisKKyAgICAgICAgICA8bGk+SW5mb1pJUCBiYXNlZCB0b29scyBjYW4gcmVjb2duaXplIGFuZCB3cml0ZSBib3RoLCBpdCBpcworICAgICAgICAgICAgYSBjb21waWxlIHRpbWUgb3B0aW9uIGFuZCBkZXBlbmRzIG9uIHRoZSBwbGF0Zm9ybSBzbyB5b3VyCisgICAgICAgICAgICBtaWxlYWdlIG1heSB2YXJ5LjwvbGk+CisKKyAgICAgICAgICA8bGk+UEtXQVJFIHppcCB0b29scyByZWNvZ25pemUgYm90aCBhbmQgcHJlZmVyIHRoZSBsYW5ndWFnZQorICAgICAgICAgICAgZW5jb2RpbmcgZmxhZy4gIFRoZXkgY3JlYXRlIGFyY2hpdmVzIHVzaW5nIENvZGVQYWdlIDQzNyBpZgorICAgICAgICAgICAgcG9zc2libGUgYW5kIFVURi04IHBsdXMgdGhlIGxhbmd1YWdlIGVuY29kaW5nIGZsYWcgZm9yCisgICAgICAgICAgICBmaWxlIG5hbWVzIHRoYXQgY2Fubm90IGJlIGVuY29kZWQgYXMgQ29kZVBhZ2UgNDM3LjwvbGk+CisgICAgICAgIDwvdWw+CisgICAgICAgIAorICAgICAgICA8cD5Tbywgd2hhdCB0byBkbz88L3A+CisKKyAgICAgICAgPHA+SWYgeW91IGFyZSBjcmVhdGluZyBqYXJzLCB0aGVuIGphdmEudXRpbC56aXAgaXMgeW91ciBtYWluCisgICAgICAgICAgY29uc3VtZXIuICBXZSByZWNvbW1lbmQgeW91IHNldCB0aGUgZW5jb2RpbmcgdG8gVVRGLTggYW5kCisgICAgICAgICAga2VlcCB0aGUgbGFuZ3VhZ2UgZW5jb2RpbmcgZmxhZyBlbmFibGVkLiAgVGhlIGZsYWcgd29uJ3QKKyAgICAgICAgICBoZWxwIG9yIGh1cnQgamF2YS51dGlsLnppcCBwcmlvciB0byBKYXZhNyBidXQgYXJjaGl2ZXJzIHRoYXQKKyAgICAgICAgICBzdXBwb3J0IGl0IHdpbGwgc2hvdyB0aGUgY29ycmVjdCBmaWxlIG5hbWVzLjwvcD4KKworICAgICAgICA8cD5Gb3IgbWF4aW11bSBpbnRlcm9wIGl0IGlzIHByb2JhYmx5IGJlc3QgdG8gc2V0IHRoZSBlbmNvZGluZworICAgICAgICAgIHRvIFVURi04LCBlbmFibGUgdGhlIGxhbmd1YWdlIGVuY29kaW5nIGZsYWcgYW5kIGNyZWF0ZQorICAgICAgICAgIFVuaWNvZGUgZXh0cmEgZmllbGRzIHdoZW4gd3JpdGluZyBaSVBzLiAgU3VjaCBhcmNoaXZlcworICAgICAgICAgIHNob3VsZCBiZSBleHRyYWN0ZWQgY29ycmVjdGx5IGJ5IGphdmEudXRpbC56aXAsIDdaaXAsCisgICAgICAgICAgV2luWklQLCBQS1dBUkUgdG9vbHMgYW5kIG1vc3QgbGlrZWx5IEluZm9aSVAgdG9vbHMuICBUaGV5CisgICAgICAgICAgd2lsbCBiZSB1bnVzYWJsZSB3aXRoIFdpbmRvd3MnICJjb21wcmVzc2VkIGZvbGRlcnMiIGZlYXR1cmUKKyAgICAgICAgICBhbmQgYmlnZ2VyIHRoYW4gYXJjaGl2ZXMgd2l0aG91dCB0aGUgVW5pY29kZSBleHRyYSBmaWVsZHMsCisgICAgICAgICAgdGhvdWdoLjwvcD4KKworICAgICAgICA8cD5JZiBXaW5kb3dzJyAiY29tcHJlc3NlZCBmb2xkZXJzIiBpcyB5b3VyIHByaW1hcnkgY29uc3VtZXIsCisgICAgICAgICAgdGhlbiB5b3VyIGJlc3Qgb3B0aW9uIGlzIHRvIGV4cGxpY2l0bHkgc2V0IHRoZSBlbmNvZGluZyB0bworICAgICAgICAgIHRoZSB0YXJnZXQgcGxhdGZvcm0uICBZb3UgbWF5IHdhbnQgdG8gZW5hYmxlIGNyZWF0aW9uIG9mCisgICAgICAgICAgVW5pY29kZSBleHRyYSBmaWVsZHMgc28gdGhlIHRvb2xzIHRoYXQgc3VwcG9ydCB0aGVtIHdpbGwKKyAgICAgICAgICBleHRyYWN0IHRoZSBmaWxlIG5hbWVzIGNvcnJlY3RseS48L3A+CisgICAgICA8L3N1YnNlY3Rpb24+CisKKyAgICAgIDxzdWJzZWN0aW9uIG5hbWU9IkVuY3J5cHRpb24gYW5kIEFsdGVybmF0aXZlIENvbXByZXNzaW9uIEFsZ29yaXRobXMiCisgICAgICAgICAgICAgICAgICBpZD0iZW5jcnlwdGlvbiI+CisgICAgICAgIAorICAgICAgICA8cD5JbiBtb3N0IGNhc2VzIGVudHJpZXMgb2YgYW4gYXJjaGl2ZSBhcmUgbm90IGVuY3J5cHRlZCBhbmQKKyAgICAgICAgYXJlIGVpdGhlciBub3QgY29tcHJlc3NlZCBhdCBhbGwgb3IgdXNlIHRoZSBERUZMQVRFCisgICAgICAgIGFsZ29yaXRobSwgQ29tbW9ucyBDb21wcmVzcycgWklQIGFyY2hpdmVyIHdpbGwgaGFuZGxlIHRoZW0KKyAgICAgICAganVzdCBmaW5lLiAgIEFzIG9mIHZlcnNpb24gMS43LCBDb21tb25zIENvbXByZXNzIGNhbiBhbHNvCisgICAgICAgIGRlY29tcHJlc3MgZW50cmllcyBjb21wcmVzc2VkIHdpdGggdGhlIGxlZ2FjeSBTSFJJTksgYW5kCisgICAgICAgIElNUExPREUgYWxnb3JpdGhtcyBvZiBQS1pJUCAxLnguICBWZXJzaW9uIDEuMTEgb2YgQ29tbW9ucworICAgICAgICBDb21wcmVzcyBhZGRzIHJlYWQtb25seSBzdXBwb3J0IGZvciBCWklQMi4gIFZlcnNpb24gMS4xNiBhZGRzCisgICAgICAgIHJlYWQtb25seSBzdXBwb3J0IGZvciBERUZMQVRFNjQgLSBhbHNvIGtub3duIGFzICJlbmhhbmNlZCBERUZMQVRFIi48L3A+CisKKyAgICAgICAgPHA+VGhlIFpJUCBzcGVjaWZpY2F0aW9uIGFsbG93cyBmb3IgdmFyaW91cyBvdGhlciBjb21wcmVzc2lvbgorICAgICAgICBhbGdvcml0aG1zIGFuZCBhbHNvIHN1cHBvcnRzIHNldmVyYWwgZGlmZmVyZW50IHdheXMgb2YKKyAgICAgICAgZW5jcnlwdGluZyBhcmNoaXZlIGNvbnRlbnRzLiAgTmVpdGhlciBvZiB0aG9zZSBtZXRob2RzIGlzCisgICAgICAgIGN1cnJlbnRseSBzdXBwb3J0ZWQgYnkgQ29tbW9ucyBDb21wcmVzcyBhbmQgYW55IHN1Y2ggZW50cnkgY2FuCisgICAgICAgIG5vdCBiZSBleHRyYWN0ZWQgYnkgdGhlIGFyY2hpdmluZyBjb2RlLjwvcD4KKworICAgICAgICA8cD48Y29kZT5aaXBGaWxlPC9jb2RlPidzIGFuZAorICAgICAgICA8Y29kZT5aaXBBcmNoaXZlSW5wdXRTdHJlYW08L2NvZGU+J3MKKyAgICAgICAgPGNvZGU+Y2FuUmVhZEVudHJ5RGF0YTwvY29kZT4gbWV0aG9kcyB3aWxsIHJldHVybiBmYWxzZSBmb3IKKyAgICAgICAgZW5jcnlwdGVkIGVudHJpZXMgb3IgZW50cmllcyB1c2luZyBhbiB1bnN1cHBvcnRlZCBlbmNyeXB0aW9uCisgICAgICAgIG1lY2hhbmlzbS4gIFVzaW5nIHRoaXMgbWV0aG9kIGl0IGlzIHBvc3NpYmxlIHRvIGF0IGxlYXN0CisgICAgICAgIGRldGVjdCBhbmQgc2tpcCB0aGUgZW50cmllcyB0aGF0IGNhbiBub3QgYmUgZXh0cmFjdGVkLjwvcD4KKworICAgICAgICA8dGFibGU+CisgICAgICAgICAgPHRoZWFkPgorICAgICAgICAgICAgPHRyPgorICAgICAgICAgICAgICA8dGg+VmVyc2lvbiBvZiBBcGFjaGUgQ29tbW9ucyBDb21wcmVzczwvdGg+CisgICAgICAgICAgICAgIDx0aD5TdXBwb3J0ZWQgQ29tcHJlc3Npb24gTWV0aG9kczwvdGg+CisgICAgICAgICAgICAgIDx0aD5TdXBwb3J0ZWQgRW5jcnlwdGlvbiBNZXRob2RzPC90aD4KKyAgICAgICAgICAgIDwvdHI+CisgICAgICAgICAgPC90aGVhZD4KKyAgICAgICAgICA8dGJvZHk+CisgICAgICAgICAgICA8dHI+CisgICAgICAgICAgICAgIDx0ZD4xLjAgdG8gMS42PC90ZD4KKyAgICAgICAgICAgICAgPHRkPlNUT1JFRCwgREVGTEFURTwvdGQ+CisgICAgICAgICAgICAgIDx0ZD4tPC90ZD4KKyAgICAgICAgICAgIDwvdHI+CisgICAgICAgICAgICA8dHI+CisgICAgICAgICAgICAgIDx0ZD4xLjcgdG8gMS4xMDwvdGQ+CisgICAgICAgICAgICAgIDx0ZD5TVE9SRUQsIERFRkxBVEUsIFNIUklOSywgSU1QTE9ERTwvdGQ+CisgICAgICAgICAgICAgIDx0ZD4tPC90ZD4KKyAgICAgICAgICAgIDwvdHI+CisgICAgICAgICAgICA8dHI+CisgICAgICAgICAgICAgIDx0ZD4xLjExIHRvIDEuMTU8L3RkPgorICAgICAgICAgICAgICA8dGQ+U1RPUkVELCBERUZMQVRFLCBTSFJJTkssIElNUExPREUsIEJaSVAyPC90ZD4KKyAgICAgICAgICAgICAgPHRkPi08L3RkPgorICAgICAgICAgICAgPC90cj4KKyAgICAgICAgICAgIDx0cj4KKyAgICAgICAgICAgICAgPHRkPjEuMTYgYW5kIGxhdGVyPC90ZD4KKyAgICAgICAgICAgICAgPHRkPlNUT1JFRCwgREVGTEFURSwgU0hSSU5LLCBJTVBMT0RFLCBCWklQMiwgREVGTEFURTY0CisgICAgICAgICAgICAgIChlbmhhbmNlZCBkZWZsYXRlKTwvdGQ+CisgICAgICAgICAgICAgIDx0ZD4tPC90ZD4KKyAgICAgICAgICAgIDwvdHI+CisgICAgICAgICAgPC90Ym9keT4KKyAgICAgICAgPC90YWJsZT4KKworICAgICAgPC9zdWJzZWN0aW9uPgorCisgICAgICA8c3Vic2VjdGlvbiBuYW1lPSJaaXA2NCBTdXBwb3J0IiBpZD0iemlwNjQiPgorICAgICAgICA8cD5UaGUgdHJhZGl0aW9uYWwgWklQIGZvcm1hdCBpcyBsaW1pdGVkIHRvIGFyY2hpdmUgc2l6ZXMgb2YKKyAgICAgICAgICBmb3VyIGdpYmlieXRlIChhY3R1YWxseSAyPHN1cD4zMjwvc3VwPiAtIDEgYnl0ZXMgJiN4MjI0ODsKKyAgICAgICAgICA0LjMgR0IpIGFuZCA2NTYzNSBlbnRyaWVzLCB3aGVyZSBlYWNoIGluZGl2aWR1YWwgZW50cnkgaXMKKyAgICAgICAgICBsaW1pdGVkIHRvIGZvdXIgZ2liaWJ5dGUgYXMgd2VsbC4gIFRoZXNlIGxpbWl0cyBzZWVtZWQKKyAgICAgICAgICBleGNlc3NpdmUgaW4gdGhlIDE5ODBzLjwvcD4KKworICAgICAgICA8cD5WZXJzaW9uIDQuNSBvZiB0aGUgWklQIHNwZWNpZmljYXRpb24gaW50cm9kdWNlZCB0aGUgc28KKyAgICAgICAgICBjYWxsZWQgIlppcDY0IGV4dGVuc2lvbnMiIHRvIHB1c2ggdGhvc2UgbGltaXRhdGlvbnMgZm9yCisgICAgICAgICAgY29tcHJlc3NlZCBvciB1bmNvbXByZXNzZWQgc2l6ZXMgb2YgdXAgdG8gMTYgZXhiaWJ5dGUKKyAgICAgICAgICAoYWN0dWFsbHkgMjxzdXA+NjQ8L3N1cD4gLSAxIGJ5dGVzICYjeDIyNDg7IDE4LjUgRUIsIGkuZQorICAgICAgICAgIDE4LjUgeCAxMDxzdXA+MTg8L3N1cD4gYnl0ZXMpIGluIGFyY2hpdmVzIHRoYXQgdGhlbXNlbHZlcworICAgICAgICAgIGNhbiB0YWtlIHVwIHRvIDE2IGV4YmlieXRlIGNvbnRhaW5pbmcgbW9yZSB0aGFuCisgICAgICAgICAgMTggeCAxMDxzdXA+MTg8L3N1cD4gZW50cmllcy48L3A+CisKKyAgICAgICAgPHA+QXBhY2hlIENvbW1vbnMgQ29tcHJlc3MgMS4yIGFuZCBlYXJsaWVyIGRvIG5vdCBzdXBwb3J0CisgICAgICAgICAgWmlwNjQgZXh0ZW5zaW9ucyBhdCBhbGwuPC9wPgorCisgICAgICAgIDxwPlN0YXJ0aW5nIHdpdGggQXBhY2hlIENvbW1vbnMgQ29tcHJlc3MKKyAgICAgICAgICAxLjMgPGNvZGU+WmlwQXJjaGl2ZUlucHV0U3RyZWFtPC9jb2RlPgorICAgICAgICAgIGFuZCA8Y29kZT5aaXBGaWxlPC9jb2RlPiB0cmFuc3BhcmVudGx5IHN1cHBvcnQgWmlwNjQKKyAgICAgICAgICBleHRlbnNpb25zLiAgQnkgZGVmYXVsdCA8Y29kZT5aaXBBcmNoaXZlT3V0cHV0U3RyZWFtPC9jb2RlPgorICAgICAgICAgIHN1cHBvcnRzIHRoZW0gdHJhbnNwYXJlbnRseSBhcyB3ZWxsIChpLmUuIGl0IGFkZHMgWmlwNjQKKyAgICAgICAgICBleHRlbnNpb25zIGlmIG5lZWRlZCBhbmQgZG9lc24ndCB1c2UgdGhlbSBmb3IKKyAgICAgICAgICBlbnRyaWVzL2FyY2hpdmVzIHRoYXQgZG9uJ3QgbmVlZCB0aGVtKSBpZiB0aGUgY29tcHJlc3NlZCBhbmQKKyAgICAgICAgICB1bmNvbXByZXNzZWQgc2l6ZXMgb2YgdGhlIGVudHJ5IGFyZSBrbm93bgorICAgICAgICAgIHdoZW4gPGNvZGU+cHV0QXJjaGl2ZUVudHJ5PC9jb2RlPiBpcyBjYWxsZWQKKyAgICAgICAgICBvciA8Y29kZT5aaXBBcmNoaXZlT3V0cHV0U3RyZWFtPC9jb2RlPgorICAgICAgICAgIHVzZXMgPGNvZGU+U2Vla2FibGVCeXRlQ2hhbm5lbDwvY29kZT4KKyAgICAgICAgICAoc2VlIDxhIGhyZWY9IiNaaXBBcmNoaXZlT3V0cHV0U3RyZWFtIj5hYm92ZTwvYT4pLiAgSWYgb25seQorICAgICAgICAgIHRoZSB1bmNvbXByZXNzZWQgc2l6ZSBpcworICAgICAgICAgIGtub3duIDxjb2RlPlppcEFyY2hpdmVPdXRwdXRTdHJlYW08L2NvZGU+IHdpbGwgYXNzdW1lIHRoZQorICAgICAgICAgIGNvbXByZXNzZWQgc2l6ZSB3aWxsIG5vdCBiZSBiaWdnZXIgdGhhbiB0aGUgdW5jb21wcmVzc2VkCisgICAgICAgICAgc2l6ZS48L3A+CisKKyAgICAgICAgPHA+PGNvZGU+WmlwQXJjaGl2ZU91dHB1dFN0cmVhbTwvY29kZT4ncworICAgICAgICAgIDxjb2RlPnNldFVzZVppcDY0PC9jb2RlPiBjYW4gYmUgdXNlZCB0byBjb250cm9sIHRoZSBiZWhhdmlvci4KKyAgICAgICAgICA8Y29kZT5aaXA2NE1vZGUuQXNOZWVkZWQ8L2NvZGU+IGlzIHRoZSBkZWZhdWx0IGJlaGF2aW9yCisgICAgICAgICAgZGVzY3JpYmVkIGluIHRoZSBwcmV2aW91cyBwYXJhZ3JhcGguPC9wPgorCisgICAgICAgIDxwPklmIDxjb2RlPlppcEFyY2hpdmVPdXRwdXRTdHJlYW08L2NvZGU+IGlzIHdyaXRpbmcgdG8gYQorICAgICAgICAgIG5vbi1zZWVrYWJsZSBzdHJlYW0gaXQgaGFzIHRvIGRlY2lkZSB3aGV0aGVyIHRvIHVzZSBaaXA2NAorICAgICAgICAgIGV4dGVuc2lvbnMgb3Igbm90IGJlZm9yZSBpdCBzdGFydHMgd3J0aXRpbmcgdGhlIGVudHJ5IGRhdGEuCisgICAgICAgICAgVGhpcyBtZWFucyB0aGF0IGlmIHRoZSBzaXplIG9mIHRoZSBlbnRyeSBpcyB1bmtub3duCisgICAgICAgICAgd2hlbiA8Y29kZT5wdXRBcmNoaXZlRW50cnk8L2NvZGU+IGlzIGNhbGxlZCBpdCBkb2Vzbid0IGhhdmUKKyAgICAgICAgICBhbnl0aGluZyB0byBiYXNlIHRoZSBkZWNpc2lvbiBvbi4gIEJ5IGRlZmF1bHQgaXQgd2lsbCBub3QKKyAgICAgICAgICB1c2UgWmlwNjQgZXh0ZW5zaW9ucyBpbiBvcmRlciB0byBjcmVhdGUgYXJjaGl2ZXMgdGhhdCBjYW4gYmUKKyAgICAgICAgICBleHRyYWN0ZWQgYnkgb2xkZXIgYXJjaGl2ZXJzIChpdCB3aWxsIGxhdGVyIHRocm93IGFuCisgICAgICAgICAgZXhjZXB0aW9uIGluIDxjb2RlPmNsb3NlRW50cnk8L2NvZGU+IGlmIGl0IGRldGVjdHMgWmlwNjQKKyAgICAgICAgICBleHRlbnNpb25zIGhhZCBiZWVuIG5lZWRlZCkuICBJdCBpcyBwb3NzaWJsZSB0bworICAgICAgICAgIGluc3RydWN0IDxjb2RlPlppcEFyY2hpdmVPdXRwdXRTdHJlYW08L2NvZGU+IHRvIGFsd2F5cworICAgICAgICAgIGNyZWF0ZSBaaXA2NCBleHRlbnNpb25zIGJ5IHVzaW5nCisgICAgICAgICAgdGhlIDxjb2RlPnNldFVzZVppcDY0PC9jb2RlPiB3aXRoIGFuIGFyZ3VtZW50CisgICAgICAgICAgb2YgPGNvZGU+WmlwNjRNb2RlLkFsd2F5czwvY29kZT47IHVzZSB0aGlzIGlmIHlvdSBhcmUKKyAgICAgICAgICB3cml0aW5nIGVudHJpZXMgb2YgdW5rbm93biBzaXplIHRvIGEgc3RyZWFtIGFuZCBleHBlY3Qgc29tZQorICAgICAgICAgIG9mIHRoZW0gdG8gYmUgdG9vIGJpZyB0byBmaXQgaW50byB0aGUgdHJhZGl0aW9uYWwKKyAgICAgICAgICBsaW1pdHMuPC9wPgorCisgICAgICAgIDxwPjxjb2RlPlppcDY0TW9kZS5BbHdheXM8L2NvZGU+IGNyZWF0ZXMgYXJjaGl2ZXMgdGhhdCB1c2UKKyAgICAgICAgICBaaXA2NCBleHRlbnNpb25zIGZvciBhbGwgZW50cmllcywgZXZlbiB0aG9zZSB0aGF0IGRvbid0CisgICAgICAgICAgcmVxdWlyZSB0aGVtLiAgU3VjaCBhcmNoaXZlcyB3aWxsIGJlIHNsaWdodGx5IGJpZ2dlciB0aGFuCisgICAgICAgICAgYXJjaGl2ZXMgY3JlYXRlZCB3aXRoIG9uZSBvZiB0aGUgb3RoZXIgbW9kZXMgYW5kIG5vdCBiZQorICAgICAgICAgIHJlYWRhYmxlIGJ5IHVuYXJjaGl2ZXJzIHRoYXQgZG9uJ3Qgc3VwcG9ydCBaaXA2NAorICAgICAgICAgIGV4dGVuc2lvbnMuPC9wPgorCisgICAgICAgIDxwPjxjb2RlPlppcDY0TW9kZS5OZXZlcjwvY29kZT4gd2lsbCBub3QgdXNlIGFueSBaaXA2NAorICAgICAgICAgIGV4dGVuc2lvbnMgYXQgYWxsIGFuZCBtYXkgbGVhZCB0bworICAgICAgICAgIGEgPGNvZGU+WmlwNjRSZXF1aXJlZEV4Y2VwdGlvbjwvY29kZT4gdG8gYmUgdGhyb3duCisgICAgICAgICAgaWYgPGNvZGU+WmlwQXJjaGl2ZU91dHB1dFN0cmVhbTwvY29kZT4gZGV0ZWN0cyB0aGF0IG9uZSBvZgorICAgICAgICAgIHRoZSBmb3JtYXQncyBsaW1pdHMgaXMgZXhjZWVkZWQuICBBcmNoaXZlcyBjcmVhdGVkIGluIHRoaXMKKyAgICAgICAgICBtb2RlIHdpbGwgYmUgcmVhZGFibGUgYnkgYWxsIHVuYXJjaGl2ZXJzOyB0aGV5IG1heSBiZQorICAgICAgICAgIHNsaWdodGx5IHNtYWxsZXIgdGhhbiBhcmNoaXZlcyBjcmVhdGVkCisgICAgICAgICAgd2l0aCA8Y29kZT5TZWVrYWJsZUJ5dGVDaGFubmVsPC9jb2RlPgorICAgICAgICAgIGluIDxjb2RlPlppcDY0TW9kZS5Bc05lZWRlZDwvY29kZT4gbW9kZSBpZiBzb21lIG9mIHRoZQorICAgICAgICAgIGVudHJpZXMgaGFkIHVua25vd24gc2l6ZXMuPC9wPgorCisgICAgICAgIDxwPlRoZSA8Y29kZT5qYXZhLnV0aWwuemlwPC9jb2RlPiBwYWNrYWdlIGFuZCB0aGUKKyAgICAgICAgICA8Y29kZT5qYXI8L2NvZGU+IGNvbW1hbmQgb2YgSmF2YTUgYW5kIGVhcmxpZXIgY2FuIG5vdCByZWFkCisgICAgICAgICAgWmlwNjQgZXh0ZW5zaW9ucyBhbmQgd2lsbCBmYWlsIGlmIHRoZSBhcmNoaXZlIGNvbnRhaW5zIGFueS4KKyAgICAgICAgICBTbyBpZiB5b3UgaW50ZW5kIHRvIGNyZWF0ZSBhcmNoaXZlcyB0aGF0IEphdmE1IGNhbiBjb25zdW1lCisgICAgICAgICAgeW91IG11c3Qgc2V0IHRoZSBtb2RlIHRvIDxjb2RlPlppcDY0TW9kZS5OZXZlcjwvY29kZT48L3A+CisKKyAgICAgICAgPGg0Pktub3duIExpbWl0YXRpb25zPC9oND4KKworICAgICAgICA8cD5Tb21lIG9mIHRoZSB0aGVvcmV0aWNhbCBsaW1pdHMgb2YgdGhlIGZvcm1hdCBhcmUgbm90CisgICAgICAgICAgcmVhY2hlZCBiZWNhdXNlIEFwYWNoZSBDb21tb25zIENvbXByZXNzJyBvd24gQVBJCisgICAgICAgICAgKDxjb2RlPkFyY2hpdmVFbnRyeTwvY29kZT4ncyBzaXplIGluZm9ybWF0aW9uIHVzZXMKKyAgICAgICAgICBhIDxjb2RlPmxvbmc8L2NvZGU+KSBvciBpdHMgdXNhZ2Ugb2YgSmF2YSBjb2xsZWN0aW9ucworICAgICAgICAgIG9yIDxjb2RlPlNlZWthYmxlQnl0ZUNoYW5uZWw8L2NvZGU+IGludGVybmFsbHkuICBUaGUgdGFibGUKKyAgICAgICAgICBiZWxvdyBzaG93cyB0aGUgdGhlb3JldGljYWwgbGltaXRzIHN1cHBvcnRlZCBieSBBcGFjaGUKKyAgICAgICAgICBDb21tb25zIENvbXByZXNzLiAgSW4gcHJhY3RpY2UgaXQgaXMgdmVyeSBsaWtlbHkgdGhhdCB5b3UnZAorICAgICAgICAgIHJ1biBvdXQgb2YgbWVtb3J5IG9yIHlvdXIgZmlsZSBzeXN0ZW0gd29uJ3QgYWxsb3cgZmlsZXMgdGhhdAorICAgICAgICAgIGJpZyBsb25nIGJlZm9yZSB5b3UgcmVhY2ggZWl0aGVyIGxpbWl0LjwvcD4KKworICAgICAgICA8dGFibGU+CisgICAgICAgICAgPHRoZWFkPgorICAgICAgICAgICAgPHRyPgorICAgICAgICAgICAgICA8dGgvPgorICAgICAgICAgICAgICA8dGg+TWF4LiBTaXplIG9mIEFyY2hpdmU8L3RoPgorICAgICAgICAgICAgICA8dGg+TWF4LiBDb21wcmVzc2VkL1VuY29tcHJlc3NlZCBTaXplIG9mIEVudHJ5PC90aD4KKyAgICAgICAgICAgICAgPHRoPk1heC4gTnVtYmVyIG9mIEVudHJpZXM8L3RoPgorICAgICAgICAgICAgPC90cj4KKyAgICAgICAgICA8L3RoZWFkPgorICAgICAgICAgIDx0Ym9keT4KKyAgICAgICAgICAgIDx0cj4KKyAgICAgICAgICAgICAgPHRkPlpJUCBGb3JtYXQgV2l0aG91dCBaaXAgNjQgRXh0ZW5zaW9uczwvdGQ+CisgICAgICAgICAgICAgIDx0ZD4yPHN1cD4zMjwvc3VwPiAtIDEgYnl0ZXMgJiN4MjI0ODsgNC4zIEdCPC90ZD4KKyAgICAgICAgICAgICAgPHRkPjI8c3VwPjMyPC9zdXA+IC0gMSBieXRlcyAmI3gyMjQ4OyA0LjMgR0I8L3RkPgorICAgICAgICAgICAgICA8dGQ+NjU1MzU8L3RkPgorICAgICAgICAgICAgPC90cj4KKyAgICAgICAgICAgIDx0cj4KKyAgICAgICAgICAgICAgPHRkPlpJUCBGb3JtYXQgdXNpbmcgWmlwIDY0IEV4dGVuc2lvbnM8L3RkPgorICAgICAgICAgICAgICA8dGQ+MjxzdXA+NjQ8L3N1cD4gLSAxIGJ5dGVzICYjeDIyNDg7IDE4LjUgRUI8L3RkPgorICAgICAgICAgICAgICA8dGQ+MjxzdXA+NjQ8L3N1cD4gLSAxIGJ5dGVzICYjeDIyNDg7IDE4LjUgRUI8L3RkPgorICAgICAgICAgICAgICA8dGQ+MjxzdXA+NjQ8L3N1cD4gLSAxICYjeDIyNDg7IDE4LjUgeCAxMDxzdXA+MTg8L3N1cD48L3RkPgorICAgICAgICAgICAgPC90cj4KKyAgICAgICAgICAgIDx0cj4KKyAgICAgICAgICAgICAgPHRkPkNvbW1vbnMgQ29tcHJlc3MgMS4yIGFuZCBlYXJsaWVyPC90ZD4KKyAgICAgICAgICAgICAgPHRkPnVubGltaXRlZCBpbiA8Y29kZT5aaXBBcmNoaXZlSW5wdXRTdHJlYW08L2NvZGU+CisgICAgICAgICAgICAgICAgYW5kIDxjb2RlPlppcEFyY2hpdmVPdXRwdXRTdHJlYW08L2NvZGU+IGFuZAorICAgICAgICAgICAgICAgIDI8c3VwPjMyPC9zdXA+IC0gMSBieXRlcyAmI3gyMjQ4OyA0LjMgR0IKKyAgICAgICAgICAgICAgICBpbiA8Y29kZT5aaXBGaWxlPC9jb2RlPi48L3RkPgorICAgICAgICAgICAgICA8dGQ+MjxzdXA+MzI8L3N1cD4gLSAxIGJ5dGVzICYjeDIyNDg7IDQuMyBHQjwvdGQ+CisgICAgICAgICAgICAgIDx0ZD51bmxpbWl0ZWQgaW4gPGNvZGU+WmlwQXJjaGl2ZUlucHV0U3RyZWFtPC9jb2RlPiwKKyAgICAgICAgICAgICAgICA2NTUzNSBpbiA8Y29kZT5aaXBBcmNoaXZlT3V0cHV0U3RyZWFtPC9jb2RlPgorICAgICAgICAgICAgICAgIGFuZCA8Y29kZT5aaXBGaWxlPC9jb2RlPi48L3RkPgorICAgICAgICAgICAgPC90cj4KKyAgICAgICAgICAgIDx0cj4KKyAgICAgICAgICAgICAgPHRkPkNvbW1vbnMgQ29tcHJlc3MgMS4zIGFuZCBsYXRlcjwvdGQ+CisgICAgICAgICAgICAgIDx0ZD51bmxpbWl0ZWQgaW4gPGNvZGU+WmlwQXJjaGl2ZUlucHV0U3RyZWFtPC9jb2RlPgorICAgICAgICAgICAgICAgIGFuZCA8Y29kZT5aaXBBcmNoaXZlT3V0cHV0U3RyZWFtPC9jb2RlPiBhbmQKKyAgICAgICAgICAgICAgICAyPHN1cD42Mzwvc3VwPiAtIDEgYnl0ZXMgJiN4MjI0ODsgOS4yIEVCCisgICAgICAgICAgICAgICAgaW4gPGNvZGU+WmlwRmlsZTwvY29kZT4uPC90ZD4KKyAgICAgICAgICAgICAgPHRkPjI8c3VwPjYzPC9zdXA+IC0gMSBieXRlcyAmI3gyMjQ4OyA5LjIgRUI8L3RkPgorICAgICAgICAgICAgICA8dGQ+dW5saW1pdGVkIGluIDxjb2RlPlppcEFyY2hpdmVJbnB1dFN0cmVhbTwvY29kZT4sCisgICAgICAgICAgICAgICAgMjxzdXA+MzE8L3N1cD4gLSAxICYjeDIyNDg7IDIuMSBiaWxsaW9uCisgICAgICAgICAgICAgICAgaW4gPGNvZGU+WmlwQXJjaGl2ZU91dHB1dFN0cmVhbTwvY29kZT4KKyAgICAgICAgICAgICAgICBhbmQgPGNvZGU+WmlwRmlsZTwvY29kZT4uPC90ZD4KKyAgICAgICAgICAgIDwvdHI+CisgICAgICAgICAgPC90Ym9keT4KKyAgICAgICAgPC90YWJsZT4KKworICAgICAgICA8aDQ+S25vd24gSW50ZXJvcGVyYWJpbGl0eSBQcm9ibGVtczwvaDQ+CisKKyAgICAgICAgPHA+VGhlIDxjb2RlPmphdmEudXRpbC56aXA8L2NvZGU+IHBhY2thZ2Ugb2YgT3BlbkpESzcgc3VwcG9ydHMKKyAgICAgICAgWmlwIDY0IGV4dGVuc2lvbnMgYnV0IGl0cyA8Y29kZT5aaXBJbnB1dFN0cmVhbTwvY29kZT4gYW5kCisgICAgICAgIDxjb2RlPlppcEZpbGU8L2NvZGU+IGNsYXNzZXMgd2lsbCBiZSB1bmFibGUgdG8gZXh0cmFjdAorICAgICAgICBhcmNoaXZlcyBjcmVhdGVkIHdpdGggQ29tbW9ucyBDb21wcmVzcyAxLjMncworICAgICAgICA8Y29kZT5aaXBBcmNoaXZlT3V0cHV0U3RyZWFtPC9jb2RlPiBpZiB0aGUgYXJjaGl2ZSBjb250YWlucworICAgICAgICBlbnRyaWVzIHRoYXQgdXNlIHRoZSBkYXRhIGRlc2NyaXB0b3IsIGFyZSBzbWFsbGVyIHRoYW4gNCBHaUIKKyAgICAgICAgYW5kIGhhdmUgWmlwIDY0IGV4dGVuc2lvbnMgZW5hYmxlZC4gIEkuZS4gdGhlIGNsYXNzZXMgaW4KKyAgICAgICAgT3BlbkpESyBjdXJyZW50bHkgb25seSBzdXBwb3J0IGFyY2hpdmVzIHRoYXQgdXNlIFppcCA2NAorICAgICAgICBleHRlbnNpb25zIG9ubHkgd2hlbiB0aGV5IGFyZSBhY3R1YWxseSBuZWVkZWQuICBUaGVzZSBjbGFzc2VzCisgICAgICAgIGFyZSB1c2VkIHRvIGxvYWQgSkFSIGZpbGVzIGFuZCBhcmUgdGhlIGJhc2UgZm9yIHRoZQorICAgICAgICA8Y29kZT5qYXI8L2NvZGU+IGNvbW1hbmQgbGluZSB1dGlsaXR5IGFzIHdlbGwuPC9wPgorICAgICAgPC9zdWJzZWN0aW9uPgorCisgICAgICA8c3Vic2VjdGlvbiBuYW1lPSJDb25zdW1pbmcgQXJjaGl2ZXMgQ29tcGxldGVseSI+CisKKyAgICAgICAgPHA+UHJpb3IgdG8gdmVyc2lvbiAxLjUgPGNvZGU+WmlwQXJjaGl2ZUlucHV0U3RyZWFtPC9jb2RlPgorICAgICAgICB3b3VsZCByZXR1cm4gbnVsbCBmcm9tIDxjb2RlPmdldE5leHRFbnRyeTwvY29kZT4gb3IKKyAgICAgICAgPGNvZGU+Z2V0TmV4dFppcEVudHJ5PC9jb2RlPiBhcyBzb29uIGFzIHRoZSBmaXJzdCBjZW50cmFsCisgICAgICAgIGRpcmVjdG9yeSBoZWFkZXIgb2YgdGhlIGFyY2hpdmUgd2FzIGZvdW5kLCBsZWF2aW5nIHRoZSB3aG9sZQorICAgICAgICBjZW50cmFsIGRpcmVjdG9yeSBpdHNlbGYgdW5yZWFkIGluc2lkZSB0aGUgc3RyZWFtLiAgU3RhcnRpbmcKKyAgICAgICAgd2l0aCB2ZXJzaW9uIDEuNSA8Y29kZT5aaXBBcmNoaXZlSW5wdXRTdHJlYW08L2NvZGU+IHdpbGwgdHJ5CisgICAgICAgIHRvIHJlYWQgdGhlIGFyY2hpdmUgdXAgdG8gYW5kIGluY2x1ZGluZyB0aGUgImVuZCBvZiBjZW50cmFsCisgICAgICAgIGRpcmVjdG9yeSIgcmVjb3JkIGVmZmVjdGl2ZWx5IGNvbnN1bWluZyB0aGUgYXJjaGl2ZQorICAgICAgICBjb21wbGV0ZWx5LjwvcD4KKworICAgICAgPC9zdWJzZWN0aW9uPgorCisgICAgICA8c3Vic2VjdGlvbiBuYW1lPSJTeW1ib2xpYyBMaW5rcyIgaWQ9InN5bWxpbmtzIj4KKworICAgICAgICA8cD5TdGFydGluZyB3aXRoIENvbXByZXNzIDEuNSA8Y29kZT5aaXBBcmNoaXZlRW50cnk8L2NvZGU+CisgICAgICAgIHJlY29nbml6ZXMgVW5peCBTeW1ib2xpYyBMaW5rIGVudHJpZXMgd3JpdHRlbiBieSBJbmZvWklQJ3MKKyAgICAgICAgemlwLjwvcD4KKworICAgICAgICA8cD5UaGUgPGNvZGU+WmlwRmlsZTwvY29kZT4gY2xhc3MgY29udGFpbnMgYSBjb252ZW5pZW5jZQorICAgICAgICBtZXRob2QgdG8gcmVhZCB0aGUgbGluayBuYW1lIG9mIGFuIGVudHJ5LiAgQmFzaWNhbGx5IGFsbCBpdAorICAgICAgICBkb2VzIGlzIHJlYWQgdGhlIGNvbnRlbnRzIG9mIHRoZSBlbnRyeSBhbmQgY29udmVydCBpdCB0bworICAgICAgICBhIHN0cmluZyB1c2luZyB0aGUgZ2l2ZW4gZmlsZSBuYW1lIGVuY29kaW5nIG9mIHRoZQorICAgICAgICBhcmNoaXZlLjwvcD4KKworICAgICAgPC9zdWJzZWN0aW9uPgorCisgICAgICA8c3Vic2VjdGlvbiBuYW1lPSJQYXJhbGxlbCB6aXAgY3JlYXRpb24iIGlkPSJwYXJhbGxlbCI+CisKKyAgICAgICAgPHA+U3RhcnRpbmcgd2l0aCBDb21wcmVzcyAxLjEwIHRoZXJlIGlzIG5vdyBidWlsdC1pbiBzdXBwb3J0IGZvcgorICAgICAgICAgIHBhcmFsbGVsIGNyZWF0aW9uIG9mIHppcCBhcmNoaXZlczwvcD4KKworICAgICAgICAgIDxwPk11bHRpcGxlIHRocmVhZHMgY2FuIHdyaXRlCisgICAgICAgICAgdG8gdGhlaXIgb3duIDxjb2RlPlNjYXR0ZXJaaXBPdXRwdXRTdHJlYW08L2NvZGU+CisgICAgICAgICAgaW5zdGFuY2UgdGhhdCBpcyBiYWNrZWQgdG8gZmlsZSBvciB0byBzb21lIHVzZXItaW1wbGVtZW50ZWQgZm9ybSBvZgorICAgICAgICAgIHN0b3JhZ2UgKGltcGxlbWVudGluZyA8Y29kZT5TY2F0dGVyR2F0aGVyQmFja2luZ1N0b3JlPC9jb2RlPikuPC9wPgorCisgICAgICAgICAgPHA+V2hlbiB0aGUgdGhyZWFkcyBmaW5pc2gsIHRoZXkgY2FuIGpvaW4gdGhlc2Ugc3RyZWFtcyB0b2dldGhlcgorICAgICAgICAgIHRvIGEgY29tcGxldGUgemlwIGZpbGUgdXNpbmcgdGhlIDxjb2RlPndyaXRlVG88L2NvZGU+IG1ldGhvZAorICAgICAgICAgIHRoYXQgd2lsbCB3cml0ZSBhIHNpbmdsZSA8Y29kZT5TY2F0dGVyT3V0cHV0U3RyZWFtPC9jb2RlPiB0byBhIHRhcmdldAorICAgICAgICAgIDxjb2RlPlppcEFyY2hpdmVPdXRwdXRTdHJlYW08L2NvZGU+LjwvcD4KKworICAgICAgICAgIDxwPlRvIGFzc2lzdCB0aGlzIHByb2Nlc3MsIGNsaWVudHMgY2FuIHVzZQorICAgICAgICAgIDxjb2RlPlBhcmFsbGVsU2NhdHRlclppcENyZWF0b3I8L2NvZGU+IHRoYXQgd2lsbCBoYW5kbGUgdGhyZWFkcworICAgICAgICAgIHBvb2xzIGFuZCBjb3JyZWN0IG1lbW9yeSBtb2RlbCBjb25zaXN0ZW5jeSBzbyB0aGUgY2xpZW50CisgICAgICAgICAgY2FuIGF2b2lkIHRoZXNlIGlzc3Vlcy4gUGxlYXNlIG5vdGUgdGhhdCB3aGVuIHdyaXRpbmcgd2VsbC1mb3JtZWQKKyAgICAgICAgICBaaXAgZmlsZXMgdGhpcyB3YXksIGl0IGlzIHVzdWFsbHkgbmVjZXNzYXJ5IHRvIGtlZXAgYQorICAgICAgICAgIHNlcGFyYXRlIDxjb2RlPlNjYXR0ZXJaaXBPdXRwdXRTdHJlYW08L2NvZGU+IHRoYXQgcmVjZWl2ZXMgYWxsIGRpcmVjdG9yaWVzCisgICAgICAgICAgYW5kIHdyaXRlcyB0aGlzIHRvIHRoZSB0YXJnZXQgPGNvZGU+WmlwQXJjaGl2ZU91dHB1dFN0cmVhbTwvY29kZT4gYmVmb3JlCisgICAgICAgICAgdGhlIG9uZXMgY3JlYXRlZCB0aHJvdWdoIDxjb2RlPlBhcmFsbGVsU2NhdHRlclppcENyZWF0b3I8L2NvZGU+LiBUaGlzIGlzIHRoZSByZXNwb25zaWJpbGl0eSBvZiB0aGUgY2xpZW50LjwvcD4KKworICAgICAgICAgIDxwPlRoZXJlIGlzIG5vIGd1YXJhbnRlZSBvZiBvcmRlciBvZiB0aGUgZW50cmllcyB3aGVuIHdyaXRpbmcgYSBaaXAKKyAgICAgICAgICBmaWxlIHdpdGggPGNvZGU+UGFyYWxsZWxTY2F0dGVyWmlwQ3JlYXRvcjwvY29kZT4uPC9wPgorCisgICAgICAgICAgU2VlIHRoZSBleGFtcGxlcyBzZWN0aW9uIGZvciBhIGNvZGUgc2FtcGxlIGRlbW9uc3RyYXRpbmcgaG93IHRvIG1ha2UgYSB6aXAgZmlsZS4KKyAgICAgIDwvc3Vic2VjdGlvbj4KKworICAgIDwvc2VjdGlvbj4KKyAgPC9ib2R5PgorPC9kb2N1bWVudD4KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL0Fic3RyYWN0VGVzdENhc2UuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL0Fic3RyYWN0VGVzdENhc2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41YTUyYWVhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvQWJzdHJhY3RUZXN0Q2FzZS5qYXZhCkBAIC0wLDAgKzEsNDA2IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzOworCitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuKjsKK2ltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5DbG9zZWFibGU7CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZU5vdEZvdW5kRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5uZXQuVVJJOworaW1wb3J0IGphdmEubmV0LlVSTDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZUVudHJ5OworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZUlucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLkFyY2hpdmVTdHJlYW1GYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5JT1V0aWxzOworaW1wb3J0IG9yZy5qdW5pdC5BZnRlcjsKK2ltcG9ydCBvcmcuanVuaXQuQmVmb3JlOworCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQWJzdHJhY3RUZXN0Q2FzZSB7CisKKyAgICBwcm90ZWN0ZWQgRmlsZSBkaXI7CisgICAgcHJvdGVjdGVkIEZpbGUgcmVzdWx0RGlyOworCisgICAgcHJpdmF0ZSBGaWxlIGFyY2hpdmU7IC8vIHVzZWQgdG8gZGVsZXRlIHRoZSBhcmNoaXZlIGluIHRlYXJEb3duCisgICAgcHJvdGVjdGVkIExpc3Q8U3RyaW5nPiBhcmNoaXZlTGlzdDsgLy8gTGlzdHMgdGhlIGNvbnRlbnQgb2YgdGhlIGFyY2hpdmUgYXMgb3JpZ2luYWxseSBjcmVhdGVkCisKKyAgICBwcm90ZWN0ZWQgQXJjaGl2ZVN0cmVhbUZhY3RvcnkgZmFjdG9yeSA9IG5ldyBBcmNoaXZlU3RyZWFtRmFjdG9yeSgpOworCisgICAgQEJlZm9yZQorICAgIHB1YmxpYyB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGRpciA9IG1rZGlyKCJkaXIiKTsKKyAgICAgICAgcmVzdWx0RGlyID0gbWtkaXIoImRpci1yZXN1bHQiKTsKKyAgICAgICAgYXJjaGl2ZSA9IG51bGw7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBGaWxlIG1rZGlyKGZpbmFsIFN0cmluZyBuYW1lKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlIGYgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKG5hbWUsICIiKTsKKyAgICAgICAgZi5kZWxldGUoKTsKKyAgICAgICAgZi5ta2RpcigpOworICAgICAgICByZXR1cm4gZjsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIEZpbGUgZ2V0RmlsZShmaW5hbCBTdHJpbmcgcGF0aCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgVVJMIHVybCA9IEFic3RyYWN0VGVzdENhc2UuY2xhc3MuZ2V0Q2xhc3NMb2FkZXIoKS5nZXRSZXNvdXJjZShwYXRoKTsKKyAgICAgICAgaWYgKHVybCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRmlsZU5vdEZvdW5kRXhjZXB0aW9uKCJjb3VsZG4ndCBmaW5kICIgKyBwYXRoKTsKKyAgICAgICAgfQorICAgICAgICBVUkkgdXJpID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHVyaSA9IHVybC50b1VSSSgpOworICAgICAgICB9IGNhdGNoIChmaW5hbCBqYXZhLm5ldC5VUklTeW50YXhFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihleCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBGaWxlKHVyaSk7CisgICAgfQorCisgICAgQEFmdGVyCisgICAgcHVibGljIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgcm1kaXIoZGlyKTsKKyAgICAgICAgcm1kaXIocmVzdWx0RGlyKTsKKyAgICAgICAgZGlyID0gcmVzdWx0RGlyID0gbnVsbDsKKyAgICAgICAgaWYgKCF0cnlIYXJkVG9EZWxldGUoYXJjaGl2ZSkpIHsKKyAgICAgICAgICAgIC8vIE5vdGU6IHRoaXMgZXhjZXB0aW9uIHdvbid0IGJlIHNob3duIGlmIHRoZSB0ZXN0IGhhcyBhbHJlYWR5IGZhaWxlZAorICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbigiQ291bGQgbm90IGRlbGV0ZSAiK2FyY2hpdmUuZ2V0UGF0aCgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBybWRpcihmaW5hbCBGaWxlIGYpIHsKKyAgICAgICAgZmluYWwgU3RyaW5nW10gcyA9IGYubGlzdCgpOworICAgICAgICBpZiAocyAhPSBudWxsKSB7CisgICAgICAgICAgICBmb3IgKGZpbmFsIFN0cmluZyBlbGVtZW50IDogcykgeworICAgICAgICAgICAgICAgIGZpbmFsIEZpbGUgZmlsZSA9IG5ldyBGaWxlKGYsIGVsZW1lbnQpOworICAgICAgICAgICAgICAgIGlmIChmaWxlLmlzRGlyZWN0b3J5KCkpeworICAgICAgICAgICAgICAgICAgICBybWRpcihmaWxlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZmluYWwgYm9vbGVhbiBvayA9IHRyeUhhcmRUb0RlbGV0ZShmaWxlKTsKKyAgICAgICAgICAgICAgICBpZiAoIW9rICYmIGZpbGUuZXhpc3RzKCkpeworICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkZhaWxlZCB0byBkZWxldGUgIitlbGVtZW50KyIgaW4gIitmLmdldFBhdGgoKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHRyeUhhcmRUb0RlbGV0ZShmKTsgLy8gc2FmZXIgdG8gZGVsZXRlIGFuZCBjaGVjaworICAgICAgICBpZiAoZi5leGlzdHMoKSl7CisgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIkZhaWxlZCB0byBkZWxldGUgIitmLmdldFBhdGgoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIE9OX1dJTkRPV1MgPQorICAgICAgICAgICAgU3lzdGVtLmdldFByb3BlcnR5KCJvcy5uYW1lIikudG9Mb3dlckNhc2UoTG9jYWxlLkVOR0xJU0gpLmNvbnRhaW5zKCJ3aW5kb3dzIik7CisKKyAgICAvKioKKyAgICAgKiBBY2NvbW1vZGF0ZSBXaW5kb3dzIGJ1ZyBlbmNvdW50ZXJlZCBpbiBib3RoIFN1biBhbmQgSUJNIEpES3MuCisgICAgICogT3RoZXJzIHBvc3NpYmxlLiBJZiB0aGUgZGVsZXRlIGRvZXMgbm90IHdvcmssIGNhbGwgU3lzdGVtLmdjKCksCisgICAgICogd2FpdCBhIGxpdHRsZSBhbmQgdHJ5IGFnYWluLgorICAgICAqCisgICAgICogQHJldHVybiB3aGV0aGVyIGRlbGV0aW9uIHdhcyBzdWNjZXNzZnVsCisgICAgICogQHNpbmNlIFN0b2xlbiBmcm9tIEZpbGVVdGlscyBpbiBBbnQgMS44LjAKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gdHJ5SGFyZFRvRGVsZXRlKGZpbmFsIEZpbGUgZikgeworICAgICAgICBpZiAoZiAhPSBudWxsICYmIGYuZXhpc3RzKCkgJiYgIWYuZGVsZXRlKCkpIHsKKyAgICAgICAgICAgIGlmIChPTl9XSU5ET1dTKSB7CisgICAgICAgICAgICAgICAgU3lzdGVtLmdjKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIFRocmVhZC5zbGVlcCgxMCk7CisgICAgICAgICAgICB9IGNhdGNoIChmaW5hbCBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgIC8vIElnbm9yZSBFeGNlcHRpb24KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBmLmRlbGV0ZSgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gYXJjaGl2ZSBvZiB0ZXh0YmFzZWQgZmlsZXMgaW4gc2V2ZXJhbCBkaXJlY3Rvcmllcy4gVGhlCisgICAgICogYXJjaGl2ZXJuYW1lIGlzIHRoZSBmYWN0b3J5IGlkZW50aWZpZXIgZm9yIHRoZSBhcmNoaXZlciwgZm9yIGV4YW1wbGUgemlwLAorICAgICAqIHRhciwgY3BpbywgamFyLCBhci4gVGhlIGFyY2hpdmUgaXMgY3JlYXRlZCBhcyBhIHRlbXAgZmlsZS4KKyAgICAgKgorICAgICAqIFRoZSBhcmNoaXZlIGNvbnRhaW5zIHRoZSBmb2xsb3dpbmcgZmlsZXM6CisgICAgICogPHVsPgorICAgICAqIDxsaT50ZXN0ZGF0YS90ZXN0MS54bWw8L2xpPgorICAgICAqIDxsaT50ZXN0ZGF0YS90ZXN0Mi54bWw8L2xpPgorICAgICAqIDxsaT50ZXN0L3Rlc3QzLnhtbDwvbGk+CisgICAgICogPGxpPmJsYS90ZXN0NC54bWw8L2xpPgorICAgICAqIDxsaT5ibGEvdGVzdDUueG1sPC9saT4KKyAgICAgKiA8bGk+YmxhL2JsdWJiZXIvdGVzdDYueG1sPC9saT4KKyAgICAgKiA8bGk+dGVzdC50eHQ8L2xpPgorICAgICAqIDxsaT5zb21ldGhpbmcvYmxhPC9saT4KKyAgICAgKiA8bGk+dGVzdCB3aXRoIHNwYWNlcy50eHQ8L2xpPgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJjaGl2ZW5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBpZGVudGlmaWVyIG9mIHRoaXMgYXJjaGl2ZQorICAgICAqIEByZXR1cm4gdGhlIG5ld2x5IGNyZWF0ZWQgZmlsZQorICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaW4gY2FzZSBzb21ldGhpbmcgZ29lcyB3cm9uZworICAgICAqLworICAgIHByb3RlY3RlZCBGaWxlIGNyZWF0ZUFyY2hpdmUoZmluYWwgU3RyaW5nIGFyY2hpdmVuYW1lKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQXJjaGl2ZU91dHB1dFN0cmVhbSBvdXQgPSBudWxsOworICAgICAgICBPdXRwdXRTdHJlYW0gc3RyZWFtID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFyY2hpdmUgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKCJ0ZXN0IiwgIi4iICsgYXJjaGl2ZW5hbWUpOworICAgICAgICAgICAgYXJjaGl2ZS5kZWxldGVPbkV4aXQoKTsKKyAgICAgICAgICAgIGFyY2hpdmVMaXN0ID0gbmV3IEFycmF5TGlzdDw+KCk7CisKKyAgICAgICAgICAgIHN0cmVhbSA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKGFyY2hpdmUpOworICAgICAgICAgICAgb3V0ID0gZmFjdG9yeS5jcmVhdGVBcmNoaXZlT3V0cHV0U3RyZWFtKGFyY2hpdmVuYW1lLCBzdHJlYW0pOworCisgICAgICAgICAgICBmaW5hbCBGaWxlIGZpbGUxID0gZ2V0RmlsZSgidGVzdDEueG1sIik7CisgICAgICAgICAgICBmaW5hbCBGaWxlIGZpbGUyID0gZ2V0RmlsZSgidGVzdDIueG1sIik7CisgICAgICAgICAgICBmaW5hbCBGaWxlIGZpbGUzID0gZ2V0RmlsZSgidGVzdDMueG1sIik7CisgICAgICAgICAgICBmaW5hbCBGaWxlIGZpbGU0ID0gZ2V0RmlsZSgidGVzdDQueG1sIik7CisgICAgICAgICAgICBmaW5hbCBGaWxlIGZpbGU1ID0gZ2V0RmlsZSgidGVzdC50eHQiKTsKKyAgICAgICAgICAgIGZpbmFsIEZpbGUgZmlsZTYgPSBnZXRGaWxlKCJ0ZXN0IHdpdGggc3BhY2VzLnR4dCIpOworCisgICAgICAgICAgICBhZGRBcmNoaXZlRW50cnkob3V0LCAidGVzdGRhdGEvdGVzdDEueG1sIiwgZmlsZTEpOworICAgICAgICAgICAgYWRkQXJjaGl2ZUVudHJ5KG91dCwgInRlc3RkYXRhL3Rlc3QyLnhtbCIsIGZpbGUyKTsKKyAgICAgICAgICAgIGFkZEFyY2hpdmVFbnRyeShvdXQsICJ0ZXN0L3Rlc3QzLnhtbCIsIGZpbGUzKTsKKyAgICAgICAgICAgIGFkZEFyY2hpdmVFbnRyeShvdXQsICJibGEvdGVzdDQueG1sIiwgZmlsZTQpOworICAgICAgICAgICAgYWRkQXJjaGl2ZUVudHJ5KG91dCwgImJsYS90ZXN0NS54bWwiLCBmaWxlNCk7CisgICAgICAgICAgICBhZGRBcmNoaXZlRW50cnkob3V0LCAiYmxhL2JsdWJiZXIvdGVzdDYueG1sIiwgZmlsZTQpOworICAgICAgICAgICAgYWRkQXJjaGl2ZUVudHJ5KG91dCwgInRlc3QudHh0IiwgZmlsZTUpOworICAgICAgICAgICAgYWRkQXJjaGl2ZUVudHJ5KG91dCwgInNvbWV0aGluZy9ibGEiLCBmaWxlNik7CisgICAgICAgICAgICBhZGRBcmNoaXZlRW50cnkob3V0LCAidGVzdCB3aXRoIHNwYWNlcy50eHQiLCBmaWxlNik7CisKKyAgICAgICAgICAgIG91dC5maW5pc2goKTsKKyAgICAgICAgICAgIHJldHVybiBhcmNoaXZlOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKG91dCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgb3V0LmNsb3NlKCk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKHN0cmVhbSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgc3RyZWFtLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGQgYW4gZW50cnkgdG8gdGhlIGFyY2hpdmUsIGFuZCBrZWVwIHRyYWNrIG9mIHRoZSBuYW1lcyBpbiBhcmNoaXZlTGlzdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvdXQKKyAgICAgKiBAcGFyYW0gZmlsZTEKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogQHRocm93cyBGaWxlTm90Rm91bmRFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgYWRkQXJjaGl2ZUVudHJ5KGZpbmFsIEFyY2hpdmVPdXRwdXRTdHJlYW0gb3V0LCBmaW5hbCBTdHJpbmcgZmlsZW5hbWUsIGZpbmFsIEZpbGUgaW5maWxlKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBGaWxlTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICBmaW5hbCBBcmNoaXZlRW50cnkgZW50cnkgPSBvdXQuY3JlYXRlQXJjaGl2ZUVudHJ5KGluZmlsZSwgZmlsZW5hbWUpOworICAgICAgICBvdXQucHV0QXJjaGl2ZUVudHJ5KGVudHJ5KTsKKyAgICAgICAgSU9VdGlscy5jb3B5KG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5maWxlKSwgb3V0KTsKKyAgICAgICAgb3V0LmNsb3NlQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgIGFyY2hpdmVMaXN0LmFkZChmaWxlbmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlIGFuIGVtcHR5IGFyY2hpdmUuCisgICAgICogQHBhcmFtIGFyY2hpdmVuYW1lCisgICAgICogQHJldHVybiB0aGUgYXJjaGl2ZSBGaWxlCisgICAgICogQHRocm93cyBFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgRmlsZSBjcmVhdGVFbXB0eUFyY2hpdmUoZmluYWwgU3RyaW5nIGFyY2hpdmVuYW1lKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQXJjaGl2ZU91dHB1dFN0cmVhbSBvdXQgPSBudWxsOworICAgICAgICBPdXRwdXRTdHJlYW0gc3RyZWFtID0gbnVsbDsKKyAgICAgICAgYXJjaGl2ZUxpc3QgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFyY2hpdmUgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKCJlbXB0eSIsICIuIiArIGFyY2hpdmVuYW1lKTsKKyAgICAgICAgICAgIGFyY2hpdmUuZGVsZXRlT25FeGl0KCk7CisgICAgICAgICAgICBzdHJlYW0gPSBuZXcgRmlsZU91dHB1dFN0cmVhbShhcmNoaXZlKTsKKyAgICAgICAgICAgIG91dCA9IGZhY3RvcnkuY3JlYXRlQXJjaGl2ZU91dHB1dFN0cmVhbShhcmNoaXZlbmFtZSwgc3RyZWFtKTsKKyAgICAgICAgICAgIG91dC5maW5pc2goKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmIChvdXQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICAgICAgfSBlbHNlIGlmIChzdHJlYW0gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHN0cmVhbS5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBhcmNoaXZlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhbiBhcmNoaXZlIHdpdGggYSBzaW5nbGUgZmlsZSAidGVzdDEueG1sIi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcmNoaXZlbmFtZQorICAgICAqIEByZXR1cm4gdGhlIGFyY2hpdmUgRmlsZQorICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uCisgICAgICovCisgICAgcHJvdGVjdGVkIEZpbGUgY3JlYXRlU2luZ2xlRW50cnlBcmNoaXZlKGZpbmFsIFN0cmluZyBhcmNoaXZlbmFtZSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEFyY2hpdmVPdXRwdXRTdHJlYW0gb3V0ID0gbnVsbDsKKyAgICAgICAgT3V0cHV0U3RyZWFtIHN0cmVhbSA9IG51bGw7CisgICAgICAgIGFyY2hpdmVMaXN0ID0gbmV3IEFycmF5TGlzdDw+KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhcmNoaXZlID0gRmlsZS5jcmVhdGVUZW1wRmlsZSgiZW1wdHkiLCAiLiIgKyBhcmNoaXZlbmFtZSk7CisgICAgICAgICAgICBhcmNoaXZlLmRlbGV0ZU9uRXhpdCgpOworICAgICAgICAgICAgc3RyZWFtID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0oYXJjaGl2ZSk7CisgICAgICAgICAgICBvdXQgPSBmYWN0b3J5LmNyZWF0ZUFyY2hpdmVPdXRwdXRTdHJlYW0oYXJjaGl2ZW5hbWUsIHN0cmVhbSk7CisgICAgICAgICAgICAvLyBVc2Ugc2hvcnQgZmlsZSBuYW1lIHNvIGRvZXMgbm90IGNhdXNlIHByb2JsZW1zIGZvciBhcgorICAgICAgICAgICAgYWRkQXJjaGl2ZUVudHJ5KG91dCwgInRlc3QxLnhtbCIsIGdldEZpbGUoInRlc3QxLnhtbCIpKTsKKyAgICAgICAgICAgIG91dC5maW5pc2goKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmIChvdXQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICAgICAgfSBlbHNlIGlmIChzdHJlYW0gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHN0cmVhbS5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBhcmNoaXZlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrcyBpZiBhbiBhcmNoaXZlIGNvbnRhaW5zIGFsbCBleHBlY3RlZCBmaWxlcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcmNoaXZlCisgICAgICogICAgICAgICAgICB0aGUgYXJjaGl2ZSB0byBjaGVjaworICAgICAqIEBwYXJhbSBleHBlY3RlZAorICAgICAqICAgICAgICAgICAgYSBsaXN0IHdpdGggZXhwZWN0ZWQgc3RyaW5nIGZpbGVuYW1lcworICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgY2hlY2tBcmNoaXZlQ29udGVudChmaW5hbCBGaWxlIGFyY2hpdmUsIGZpbmFsIExpc3Q8U3RyaW5nPiBleHBlY3RlZCkKKyAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgKElucHV0U3RyZWFtIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShhcmNoaXZlKSkgeworICAgICAgICAgICAgZmluYWwgQnVmZmVyZWRJbnB1dFN0cmVhbSBidWYgPSBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShpcyk7CisgICAgICAgICAgICBmaW5hbCBBcmNoaXZlSW5wdXRTdHJlYW0gaW4gPSBmYWN0b3J5LmNyZWF0ZUFyY2hpdmVJbnB1dFN0cmVhbShidWYpOworICAgICAgICAgICAgdGhpcy5jaGVja0FyY2hpdmVDb250ZW50KGluLCBleHBlY3RlZCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgdGhhdCBhbiBhcmNoaXZlIGlucHV0IHN0cmVhbSBjYW4gYmUgcmVhZCwgYW5kIHRoYXQgdGhlIGZpbGUgZGF0YSBtYXRjaGVzIGZpbGUgc2l6ZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW4KKyAgICAgKiBAcGFyYW0gZXhwZWN0ZWQgbGlzdCBvZiBleHBlY3RlZCBlbnRyaWVzIG9yIHtAY29kZSBudWxsfSBpZiBubyBjaGVjayBvZiBuYW1lcyBkZXNpcmVkCisgICAgICogQHRocm93cyBFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBjaGVja0FyY2hpdmVDb250ZW50KGZpbmFsIEFyY2hpdmVJbnB1dFN0cmVhbSBpbiwgZmluYWwgTGlzdDxTdHJpbmc+IGV4cGVjdGVkKQorICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrQXJjaGl2ZUNvbnRlbnQoaW4sIGV4cGVjdGVkLCB0cnVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgdGhhdCBhbiBhcmNoaXZlIGlucHV0IHN0cmVhbSBjYW4gYmUgcmVhZCwgYW5kIHRoYXQgdGhlIGZpbGUgZGF0YSBtYXRjaGVzIGZpbGUgc2l6ZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW4KKyAgICAgKiBAcGFyYW0gZXhwZWN0ZWQgbGlzdCBvZiBleHBlY3RlZCBlbnRyaWVzIG9yIHtAY29kZSBudWxsfSBpZiBubyBjaGVjayBvZiBuYW1lcyBkZXNpcmVkCisgICAgICogQHBhcmFtIGNsZWFuVXAgQ2xlYW5zIHVwIHJlc291cmNlcyBpZiB0cnVlCisgICAgICogQHJldHVybiByZXR1cm5zIHRoZSBjcmVhdGVkIHJlc3VsdCBmaWxlIGlmIGNsZWFuVXAgPSBmYWxzZSwgb3IgbnVsbCBvdGhlcndpc2UKKyAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgorICAgICAqLworICAgIHByb3RlY3RlZCBGaWxlIGNoZWNrQXJjaGl2ZUNvbnRlbnQoZmluYWwgQXJjaGl2ZUlucHV0U3RyZWFtIGluLCBmaW5hbCBMaXN0PFN0cmluZz4gZXhwZWN0ZWQsIGZpbmFsIGJvb2xlYW4gY2xlYW5VcCkKKyAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlIHJlc3VsdCA9IG1rZGlyKCJkaXItcmVzdWx0Iik7CisgICAgICAgIHJlc3VsdC5kZWxldGVPbkV4aXQoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgQXJjaGl2ZUVudHJ5IGVudHJ5ID0gbnVsbDsKKyAgICAgICAgICAgIHdoaWxlICgoZW50cnkgPSBpbi5nZXROZXh0RW50cnkoKSkgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGZpbmFsIEZpbGUgb3V0ZmlsZSA9IG5ldyBGaWxlKHJlc3VsdC5nZXRDYW5vbmljYWxQYXRoKCkgKyAiL3Jlc3VsdC8iCisgICAgICAgICAgICAgICAgICAgICAgICArIGVudHJ5LmdldE5hbWUoKSk7CisgICAgICAgICAgICAgICAgbG9uZyBjb3BpZWQ9MDsKKyAgICAgICAgICAgICAgICBpZiAoZW50cnkuaXNEaXJlY3RvcnkoKSl7CisgICAgICAgICAgICAgICAgICAgIG91dGZpbGUubWtkaXJzKCk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgb3V0ZmlsZS5nZXRQYXJlbnRGaWxlKCkubWtkaXJzKCk7CisgICAgICAgICAgICAgICAgICAgIHRyeSAoT3V0cHV0U3RyZWFtIG91dCA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKG91dGZpbGUpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBjb3BpZWQgPSBJT1V0aWxzLmNvcHkoaW4sIG91dCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZmluYWwgbG9uZyBzaXplID0gZW50cnkuZ2V0U2l6ZSgpOworICAgICAgICAgICAgICAgIGlmIChzaXplICE9IEFyY2hpdmVFbnRyeS5TSVpFX1VOS05PV04pIHsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJFbnRyeS5zaXplIHNob3VsZCBlcXVhbCBieXRlcyByZWFkLiIsc2l6ZSwgY29waWVkKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBpZiAoIW91dGZpbGUuZXhpc3RzKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgiZXh0cmFjdGlvbiBmYWlsZWQ6ICIgKyBlbnRyeS5nZXROYW1lKCkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoZXhwZWN0ZWQgIT0gbnVsbCAmJiAhZXhwZWN0ZWQucmVtb3ZlKGdldEV4cGVjdGVkU3RyaW5nKGVudHJ5KSkpIHsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBlbnRyeTogIiArIGdldEV4cGVjdGVkU3RyaW5nKGVudHJ5KSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgICAgIGlmIChleHBlY3RlZCAhPSBudWxsICYmIGV4cGVjdGVkLnNpemUoKSA+IDApIHsKKyAgICAgICAgICAgICAgICBmYWlsKGV4cGVjdGVkLnNpemUoKSArICIgbWlzc2luZyBlbnRyaWVzOiAiICsgQXJyYXlzLnRvU3RyaW5nKGV4cGVjdGVkLnRvQXJyYXkoKSkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGV4cGVjdGVkICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMCwgZXhwZWN0ZWQuc2l6ZSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmIChjbGVhblVwKSB7CisgICAgICAgICAgICAgICAgcm1kaXIocmVzdWx0KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIE92ZXJyaWRlIHRoaXMgbWV0aG9kIHRvIGNoYW5nZSB3aGF0IGlzIHRvIGJlIGNvbXBhcmVkIGluIHRoZSBMaXN0LgorICAgICAqIEZvciBleGFtcGxlLCBzaXplICsgbmFtZSBpbnN0ZWFkIG9mIGp1c3QgbmFtZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlbnRyeQorICAgICAqIEByZXR1cm4gcmV0dXJucyB0aGUgZW50cnkgbmFtZQorICAgICAqLworICAgIHByb3RlY3RlZCBTdHJpbmcgZ2V0RXhwZWN0ZWRTdHJpbmcoZmluYWwgQXJjaGl2ZUVudHJ5IGVudHJ5KSB7CisgICAgICAgIHJldHVybiBlbnRyeS5nZXROYW1lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIHRlbXBvcmFyeSBkaXJlY3RvcnkgYW5kIGEgdGVtcG9yYXJ5IGZpbGUgaW5zaWRlIHRoYXQKKyAgICAgKiBkaXJlY3RvcnksIHJldHVybnMgYm90aCBvZiB0aGVtICh0aGUgZGlyZWN0b3J5IGlzIHRoZSBmaXJzdAorICAgICAqIGVsZW1lbnQgb2YgdGhlIHR3byBlbGVtZW50IGFycmF5KS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgRmlsZVtdIGNyZWF0ZVRlbXBEaXJBbmRGaWxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgRmlsZSB0bXBEaXIgPSBjcmVhdGVUZW1wRGlyKCk7CisgICAgICAgIGZpbmFsIEZpbGUgdG1wRmlsZSA9IEZpbGUuY3JlYXRlVGVtcEZpbGUoInRlc3RmaWxlIiwgIiIsIHRtcERpcik7CisgICAgICAgIHRtcEZpbGUuZGVsZXRlT25FeGl0KCk7CisgICAgICAgIHRyeSAoRmlsZU91dHB1dFN0cmVhbSBmb3MgPSBuZXcgRmlsZU91dHB1dFN0cmVhbSh0bXBGaWxlKSkgeworICAgICAgICAgICAgZm9zLndyaXRlKG5ldyBieXRlW10geyAnZicsICdvJywgJ28nIH0pOworICAgICAgICAgICAgcmV0dXJuIG5ldyBGaWxlW10geyB0bXBEaXIsIHRtcEZpbGUgfTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCBGaWxlIGNyZWF0ZVRlbXBEaXIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlIHRtcERpciA9IG1rZGlyKCJ0ZXN0ZGlyIik7CisgICAgICAgIHRtcERpci5kZWxldGVPbkV4aXQoKTsKKyAgICAgICAgcmV0dXJuIHRtcERpcjsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBjbG9zZVF1aWV0bHkoZmluYWwgQ2xvc2VhYmxlIGNsb3NlYWJsZSl7CisgICAgICAgIGlmIChjbG9zZWFibGUgIT0gbnVsbCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBjbG9zZWFibGUuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKGZpbmFsIElPRXhjZXB0aW9uIGlnbm9yZWQpIHsKKyAgICAgICAgICAgICAgICAvLyBpZ25vcmVkCisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgc3RhdGljIGludGVyZmFjZSBTdHJlYW1XcmFwcGVyPEkgZXh0ZW5kcyBJbnB1dFN0cmVhbT4geworICAgICAgICBJIHdyYXAoSW5wdXRTdHJlYW0gaW4pIHRocm93cyBFeGNlcHRpb247CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvQXJjaGl2ZVJlYWRUZXN0LmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9BcmNoaXZlUmVhZFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hZDAxNmEyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvQXJjaGl2ZVJlYWRUZXN0LmphdmEKQEAgLTAsMCArMSwxMTkgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzOworCitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VHJ1ZTsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5mYWlsOworCitpbXBvcnQgamF2YS5pby5CdWZmZXJlZFJlYWRlcjsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlUmVhZGVyOworaW1wb3J0IGphdmEuaW8uRmlsZW5hbWVGaWx0ZXI7CitpbXBvcnQgamF2YS5uZXQuVVJJU3ludGF4RXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLkFyY2hpdmVFbnRyeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLkFyY2hpdmVFeGNlcHRpb247CitpbXBvcnQgb3JnLmp1bml0LkJlZm9yZUNsYXNzOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXIuUnVuV2l0aDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVycy5QYXJhbWV0ZXJpemVkOworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXJzLlBhcmFtZXRlcml6ZWQuUGFyYW1ldGVyczsKKworLyoqCisgKiBUZXN0IHRoYXQgY2FuIHJlYWQgdmFyaW91cyBhcmNoaXZlIGZpbGUgZXhhbXBsZXMuCisgKgorICogVGhpcyBpcyBhIHZlcnkgc2ltcGxlIGltcGxlbWVudGF0aW9uLgorICoKKyAqIEZpbGVzIG11c3QgYmUgaW4gcmVzb3VyY2VzL2FyY2hpdmVzLCBhbmQgdGhlcmUgbXVzdCBiZSBhIGZpbGUudHh0IGNvbnRhaW5pbmcKKyAqIHRoZSBsaXN0IG9mIGZpbGVzIGluIHRoZSBhcmNoaXZlcy4KKyAqLworQFJ1bldpdGgoUGFyYW1ldGVyaXplZC5jbGFzcykKK3B1YmxpYyBjbGFzcyBBcmNoaXZlUmVhZFRlc3QgZXh0ZW5kcyBBYnN0cmFjdFRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIENsYXNzTG9hZGVyIENMQVNTTE9BREVSID0gQXJjaGl2ZVJlYWRUZXN0LmNsYXNzLmdldENsYXNzTG9hZGVyKCk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRmlsZSBBUkNESVI7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQXJyYXlMaXN0PFN0cmluZz4gRklMRUxJU1QgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKworICAgIHN0YXRpYyB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBUkNESVIgPSBuZXcgRmlsZShDTEFTU0xPQURFUi5nZXRSZXNvdXJjZSgiYXJjaGl2ZXMiKS50b1VSSSgpKTsKKyAgICAgICAgfSBjYXRjaCAoVVJJU3ludGF4RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBmaW5hbCBGaWxlIGZpbGU7CisKKyAgICBwdWJsaWMgQXJjaGl2ZVJlYWRUZXN0KGZpbmFsIFN0cmluZyBmaWxlKXsKKyAgICAgICAgdGhpcy5maWxlID0gbmV3IEZpbGUoQVJDRElSLCBmaWxlKTsKKyAgICB9CisKKyAgICBAQmVmb3JlQ2xhc3MKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc2V0VXBGaWxlTGlzdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRUcnVlKEFSQ0RJUi5leGlzdHMoKSk7CisgICAgICAgIGZpbmFsIEZpbGUgbGlzdGluZz0gbmV3IEZpbGUoQVJDRElSLCJmaWxlcy50eHQiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiZmlsZXMudHh0IGlzIHJlYWRhYmxlIixsaXN0aW5nLmNhblJlYWQoKSk7CisgICAgICAgIGZpbmFsIEJ1ZmZlcmVkUmVhZGVyIGJyID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKG5ldyBGaWxlUmVhZGVyKGxpc3RpbmcpKTsKKyAgICAgICAgU3RyaW5nIGxpbmU7CisgICAgICAgIHdoaWxlICgobGluZT1ici5yZWFkTGluZSgpKSE9bnVsbCl7CisgICAgICAgICAgICBpZiAoIWxpbmUuc3RhcnRzV2l0aCgiIyIpKXsKKyAgICAgICAgICAgICAgICBGSUxFTElTVC5hZGQobGluZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgYnIuY2xvc2UoKTsKKyAgICB9CisKKyAgICBAUGFyYW1ldGVycyhuYW1lID0gImZpbGU9ezB9IikKKyAgICBwdWJsaWMgc3RhdGljIENvbGxlY3Rpb248T2JqZWN0W10+IGRhdGEoKSB7CisgICAgICAgIGFzc2VydFRydWUoQVJDRElSLmV4aXN0cygpKTsKKyAgICAgICAgZmluYWwgQ29sbGVjdGlvbjxPYmplY3RbXT4gcGFyYW1zID0gbmV3IEFycmF5TGlzdDw+KCk7CisgICAgICAgIGZvciAoZmluYWwgU3RyaW5nIGYgOiBBUkNESVIubGlzdChuZXcgRmlsZW5hbWVGaWx0ZXIoKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGFjY2VwdChmaW5hbCBGaWxlIGRpciwgZmluYWwgU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gIW5hbWUuZW5kc1dpdGgoIi50eHQiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSkpCisgICAgICAgIHsKKyAgICAgICAgICAgIHBhcmFtcy5hZGQobmV3IE9iamVjdFtdIHsgZiB9KTsKKyAgICAgICAgfQorICAgICAgcmV0dXJuIHBhcmFtczsKKyAgICB9CisKKyAgICAvLyBmaWxlcy50eHQgY29udGFpbnMgc2l6ZSBhbmQgZmlsZW5hbWUKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgU3RyaW5nIGdldEV4cGVjdGVkU3RyaW5nKGZpbmFsIEFyY2hpdmVFbnRyeSBlbnRyeSkgeworICAgICAgICByZXR1cm4gZW50cnkuZ2V0U2l6ZSgpICsgIiAiICsgZW50cnkuZ2V0TmFtZSgpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEFyY2hpdmUoKSB0aHJvd3MgRXhjZXB0aW9ueworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikgLy8gZmlsZUxpc3QgaXMgY29ycmVjdCB0eXBlIGFscmVhZHkKKyAgICAgICAgZmluYWwKKyAgICAgICAgQXJyYXlMaXN0PFN0cmluZz4gZXhwZWN0ZWQ9IChBcnJheUxpc3Q8U3RyaW5nPikgRklMRUxJU1QuY2xvbmUoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgY2hlY2tBcmNoaXZlQ29udGVudChmaWxlLCBleHBlY3RlZCk7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIEFyY2hpdmVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiUHJvYmxlbSBjaGVja2luZyAiK2ZpbGUpOworICAgICAgICB9IGNhdGNoIChmaW5hbCBBc3NlcnRpb25FcnJvciBlKSB7IC8vIHNob3cgZXJyb3IgaW4gY29udGV4dAorICAgICAgICAgICAgZmFpbCgiUHJvYmxlbSBjaGVja2luZyAiICsgZmlsZSArICIgIiArZSk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9BcmNoaXZlVXRpbHNUZXN0LmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9BcmNoaXZlVXRpbHNUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWU0YzUxYgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL0FyY2hpdmVVdGlsc1Rlc3QuamF2YQpAQCAtMCwwICsxLDE1MyBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3M7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnNldmVuei5TZXZlblpBcmNoaXZlRW50cnk7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLkFyY2hpdmVVdGlsczsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0Lio7CisKK3B1YmxpYyBjbGFzcyBBcmNoaXZlVXRpbHNUZXN0IGV4dGVuZHMgQWJzdHJhY3RUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgYnl0ZXNUb1Rlc3QgPSA1MDsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gYnl0ZVRlc3QgPSBuZXcgYnl0ZVtieXRlc1RvVGVzdF07CisgICAgc3RhdGljIHsKKyAgICAgICAgZm9yKGludCBpPTA7IGkgPCBieXRlVGVzdC5sZW5ndGggOykgeworICAgICAgICAgICAgYnl0ZVRlc3RbaV09KGJ5dGUpIGk7CisgICAgICAgICAgICBieXRlVGVzdFtpKzFdPShieXRlKSAtaTsKKyAgICAgICAgICAgIGkgKz0gMjsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdENvbXBhcmVCQSgpeworICAgICAgICBmaW5hbCBieXRlW10gYnVmZmVyMSA9IHsxLDIsM307CisgICAgICAgIGZpbmFsIGJ5dGVbXSBidWZmZXIyID0gezEsMiwzLDB9OworICAgICAgICBmaW5hbCBieXRlW10gYnVmZmVyMyA9IHsxLDIsM307CisgICAgICAgIGFzc2VydFRydWUoQXJjaGl2ZVV0aWxzLmlzRXF1YWwoYnVmZmVyMSwgYnVmZmVyMiwgdHJ1ZSkpOworICAgICAgICBhc3NlcnRGYWxzZShBcmNoaXZlVXRpbHMuaXNFcXVhbChidWZmZXIxLCBidWZmZXIyLCBmYWxzZSkpOworICAgICAgICBhc3NlcnRGYWxzZShBcmNoaXZlVXRpbHMuaXNFcXVhbChidWZmZXIxLCBidWZmZXIyKSk7CisgICAgICAgIGFzc2VydFRydWUoQXJjaGl2ZVV0aWxzLmlzRXF1YWwoYnVmZmVyMiwgYnVmZmVyMSwgdHJ1ZSkpOworICAgICAgICBhc3NlcnRGYWxzZShBcmNoaXZlVXRpbHMuaXNFcXVhbChidWZmZXIyLCBidWZmZXIxLCBmYWxzZSkpOworICAgICAgICBhc3NlcnRGYWxzZShBcmNoaXZlVXRpbHMuaXNFcXVhbChidWZmZXIyLCBidWZmZXIxKSk7CisgICAgICAgIGFzc2VydFRydWUoQXJjaGl2ZVV0aWxzLmlzRXF1YWwoYnVmZmVyMSwgYnVmZmVyMykpOworICAgICAgICBhc3NlcnRUcnVlKEFyY2hpdmVVdGlscy5pc0VxdWFsKGJ1ZmZlcjMsIGJ1ZmZlcjEpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RDb21wYXJlQXNjaWkoKXsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGJ1ZmZlcjEgPSB7J2EnLCdiJywnYyd9OworICAgICAgICBmaW5hbCBieXRlW10gYnVmZmVyMiA9IHsnZCcsJ2UnLCdmJywwfTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShBcmNoaXZlVXRpbHMubWF0Y2hBc2NpaUJ1ZmZlcigiYWJjIiwgYnVmZmVyMSkpOworICAgICAgICBhc3NlcnRGYWxzZShBcmNoaXZlVXRpbHMubWF0Y2hBc2NpaUJ1ZmZlcigiYWJjXDAiLCBidWZmZXIxKSk7CisgICAgICAgIGFzc2VydFRydWUoQXJjaGl2ZVV0aWxzLm1hdGNoQXNjaWlCdWZmZXIoImRlZlwwIiwgYnVmZmVyMikpOworICAgICAgICBhc3NlcnRGYWxzZShBcmNoaXZlVXRpbHMubWF0Y2hBc2NpaUJ1ZmZlcigiZGVmIiwgYnVmZmVyMikpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEFzY2lpQ29udmVyc2lvbnMoKSB7CisgICAgICAgIGFzY2lpVG9CeXRlQW5kQmFja09LKCIiKTsKKyAgICAgICAgYXNjaWlUb0J5dGVBbmRCYWNrT0soImFiY2QiKTsKKyAgICAgICAgYXNjaWlUb0J5dGVBbmRCYWNrRmFpbCgiXHU4MDI1Iik7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBzYW5pdGl6ZVNob3J0ZW5zU3RyaW5nKCkgeworICAgICAgICBmaW5hbCBTdHJpbmcgaW5wdXQgPSAiMDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5IgorICAgICAgICAgICAgKyAiMDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5IgorICAgICAgICAgICAgKyAiMDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5IgorICAgICAgICAgICAgKyAiMDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5IgorICAgICAgICAgICAgKyAiMDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5IjsKKyAgICAgICAgZmluYWwgU3RyaW5nIGV4cGVjdGVkID0gIjAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OSIKKyAgICAgICAgICAgICsgIjAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OSIKKyAgICAgICAgICAgICsgIjAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OSIKKyAgICAgICAgICAgICsgIjAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OSIKKyAgICAgICAgICAgICsgIjAxMjM0NTY3ODkwMS4uLiI7CisgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZCwgQXJjaGl2ZVV0aWxzLnNhbml0aXplKGlucHV0KSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBzYW5pdGl6ZUxlYXZlc1Nob3J0U3RyaW5nc0Fsb25lKCkgeworICAgICAgICBmaW5hbCBTdHJpbmcgaW5wdXQgPSAiMDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5IjsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGlucHV0LCBBcmNoaXZlVXRpbHMuc2FuaXRpemUoaW5wdXQpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHNhbml0aXplUmVtb3Zlc1VucHJpbnRhYmxlQ2hhcmFjdGVycygpIHsKKyAgICAgICAgZmluYWwgU3RyaW5nIGlucHV0ID0gIlxiMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkiOworICAgICAgICBmaW5hbCBTdHJpbmcgZXhwZWN0ZWQgPSAiPzEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5IjsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkLCBBcmNoaXZlVXRpbHMuc2FuaXRpemUoaW5wdXQpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RJc0VxdWFsV2l0aE51bGxXaXRoUG9zaXRpdmUoKSB7CisKKyAgICAgICAgYnl0ZVtdIGJ5dGVBcnJheSA9IG5ldyBieXRlWzhdOworICAgICAgICBieXRlQXJyYXlbMV0gPSAoYnl0ZSkgKC03Nyk7CisKKyAgICAgICAgYXNzZXJ0RmFsc2UoQXJjaGl2ZVV0aWxzLmlzRXF1YWxXaXRoTnVsbChieXRlQXJyYXksIDAsIChieXRlKTAsIGJ5dGVBcnJheSwgKGJ5dGUpMCwgKGJ5dGUpODApKTsKKworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFRvQXNjaWlCeXRlcygpIHsKKworICAgICAgICBieXRlW10gYnl0ZUFycmF5ID0gQXJjaGl2ZVV0aWxzLnRvQXNjaWlCeXRlcygiU09DS0VUIik7CisKKyAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMobmV3IGJ5dGVbXSB7KGJ5dGUpODMsIChieXRlKTc5LCAoYnl0ZSk2NywgKGJ5dGUpNzUsIChieXRlKTY5LCAoYnl0ZSk4NH0sIGJ5dGVBcnJheSk7CisKKyAgICAgICAgYXNzZXJ0RmFsc2UoQXJjaGl2ZVV0aWxzLmlzRXF1YWxXaXRoTnVsbChieXRlQXJyYXksIDAsIDQ2LCBieXRlQXJyYXksIDYzLCAwKSk7CisKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RUb1N0cmluZ1dpdGhOb25OdWxsKCkgeworCisgICAgICAgIFNldmVuWkFyY2hpdmVFbnRyeSBzZXZlblpBcmNoaXZlRW50cnkgPSBuZXcgU2V2ZW5aQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgIFN0cmluZyBzdHJpbmcgPSBBcmNoaXZlVXRpbHMudG9TdHJpbmcoc2V2ZW5aQXJjaGl2ZUVudHJ5KTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIi0gICAgICAgMCBudWxsIiwgc3RyaW5nKTsKKworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdElzRXF1YWwoKSB7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShBcmNoaXZlVXRpbHMuaXNFcXVhbCgoYnl0ZVtdKSBudWxsLCAwLCAwLCAoYnl0ZVtdKSBudWxsLCAwLCAwKSk7CisKKyAgICB9CisKKyAgICBAVGVzdChleHBlY3RlZCA9IFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24uY2xhc3MpCisgICAgcHVibGljIHZvaWQgdGVzdFRvQXNjaWlTdHJpbmdUaHJvd3NTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCkgeworCisgICAgICAgIGJ5dGVbXSBieXRlQXJyYXkgPSBuZXcgYnl0ZVszXTsKKworICAgICAgICBBcmNoaXZlVXRpbHMudG9Bc2NpaVN0cmluZyhieXRlQXJyYXksIDk0MCwgMjczMCk7CisKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYXNjaWlUb0J5dGVBbmRCYWNrT0soZmluYWwgU3RyaW5nIGlucHV0U3RyaW5nKSB7CisgICAgICAgIGFzc2VydEVxdWFscyhpbnB1dFN0cmluZywgQXJjaGl2ZVV0aWxzLnRvQXNjaWlTdHJpbmcoQXJjaGl2ZVV0aWxzLnRvQXNjaWlCeXRlcyhpbnB1dFN0cmluZykpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYXNjaWlUb0J5dGVBbmRCYWNrRmFpbChmaW5hbCBTdHJpbmcgaW5wdXRTdHJpbmcpIHsKKyAgICAgICAgYXNzZXJ0RmFsc2UoaW5wdXRTdHJpbmcuZXF1YWxzKEFyY2hpdmVVdGlscy50b0FzY2lpU3RyaW5nKEFyY2hpdmVVdGlscy50b0FzY2lpQnl0ZXMoaW5wdXRTdHJpbmcpKSkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL0NoYWluaW5nVGVzdENhc2UuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL0NoYWluaW5nVGVzdENhc2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42MmQyNzc5Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvQ2hhaW5pbmdUZXN0Q2FzZS5qYXZhCkBAIC0wLDAgKzEsNTQgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzOworCitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuKjsKKworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVJbnB1dFN0cmVhbTsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMudGFyLlRhckFyY2hpdmVFbnRyeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnRhci5UYXJBcmNoaXZlSW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLmJ6aXAyLkJaaXAyQ29tcHJlc3NvcklucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5nemlwLkd6aXBDb21wcmVzc29ySW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CisKKworcHVibGljIGNsYXNzIENoYWluaW5nVGVzdENhc2UgZXh0ZW5kcyBBYnN0cmFjdFRlc3RDYXNlIHsKKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFRhckd6aXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgRmlsZSBmaWxlID0gZ2V0RmlsZSgiYmxhLnRneiIpOworICAgICAgICBmaW5hbCBUYXJBcmNoaXZlSW5wdXRTdHJlYW0gaXMgPSBuZXcgVGFyQXJjaGl2ZUlucHV0U3RyZWFtKG5ldyBHemlwQ29tcHJlc3NvcklucHV0U3RyZWFtKG5ldyBGaWxlSW5wdXRTdHJlYW0oZmlsZSkpKTsKKyAgICAgICAgZmluYWwgVGFyQXJjaGl2ZUVudHJ5IGVudHJ5ID0gKFRhckFyY2hpdmVFbnRyeSlpcy5nZXROZXh0RW50cnkoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChlbnRyeSk7CisgICAgICAgIGFzc2VydEVxdWFscygidGVzdDEueG1sIiwgZW50cnkuZ2V0TmFtZSgpKTsKKyAgICAgICAgaXMuY2xvc2UoKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RUYXJCemlwMigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlIGZpbGUgPSBnZXRGaWxlKCJibGEudGFyLmJ6MiIpOworICAgICAgICBmaW5hbCBUYXJBcmNoaXZlSW5wdXRTdHJlYW0gaXMgPSBuZXcgVGFyQXJjaGl2ZUlucHV0U3RyZWFtKG5ldyBCWmlwMkNvbXByZXNzb3JJbnB1dFN0cmVhbShuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGUpKSk7CisgICAgICAgIGZpbmFsIFRhckFyY2hpdmVFbnRyeSBlbnRyeSA9IChUYXJBcmNoaXZlRW50cnkpaXMuZ2V0TmV4dEVudHJ5KCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoZW50cnkpOworICAgICAgICBhc3NlcnRFcXVhbHMoInRlc3QxLnhtbCIsIGVudHJ5LmdldE5hbWUoKSk7CisgICAgICAgIGlzLmNsb3NlKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvRGV0ZWN0QXJjaGl2ZXJUZXN0Q2FzZS5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvRGV0ZWN0QXJjaGl2ZXJUZXN0Q2FzZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA3YTBiNzMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9EZXRlY3RBcmNoaXZlclRlc3RDYXNlLmphdmEKQEAgLTAsMCArMSwxNTAgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3M7CisKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC4qOworCitpbXBvcnQgamF2YS5pby5CdWZmZXJlZElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5BcmNoaXZlRXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZUlucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuYXIuQXJBcmNoaXZlSW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5hcmouQXJqQXJjaGl2ZUlucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuY3Bpby5DcGlvQXJjaGl2ZUlucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMudGFyLlRhckFyY2hpdmVJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcC5aaXBBcmNoaXZlSW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBEZXRlY3RBcmNoaXZlclRlc3RDYXNlIGV4dGVuZHMgQWJzdHJhY3RUZXN0Q2FzZSB7CisKKyAgICBmaW5hbCBDbGFzc0xvYWRlciBjbGFzc0xvYWRlciA9IGdldENsYXNzKCkuZ2V0Q2xhc3NMb2FkZXIoKTsKKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdERldGVjdGlvbk5vdEFyY2hpdmUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgZ2V0U3RyZWFtRm9yKCJ0ZXN0LnR4dCIpOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgQXJjaGl2ZUV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChmaW5hbCBBcmNoaXZlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RDT01QUkVTUzExNygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBBcmNoaXZlSW5wdXRTdHJlYW0gdGFyID0gZ2V0U3RyZWFtRm9yKCJDT01QUkVTUy0xMTcudGFyIik7CisgICAgICAgIGFzc2VydE5vdE51bGwodGFyKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh0YXIgaW5zdGFuY2VvZiBUYXJBcmNoaXZlSW5wdXRTdHJlYW0pOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdENPTVBSRVNTMzM1KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEFyY2hpdmVJbnB1dFN0cmVhbSB0YXIgPSBnZXRTdHJlYW1Gb3IoIkNPTVBSRVNTLTMzNS50YXIiKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCh0YXIpOworICAgICAgICBhc3NlcnRUcnVlKHRhciBpbnN0YW5jZW9mIFRhckFyY2hpdmVJbnB1dFN0cmVhbSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGV0ZWN0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisKKyAgICAgICAgZmluYWwgQXJjaGl2ZUlucHV0U3RyZWFtIGFyID0gZ2V0U3RyZWFtRm9yKCJibGEuYXIiKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChhcik7CisgICAgICAgIGFzc2VydFRydWUoYXIgaW5zdGFuY2VvZiBBckFyY2hpdmVJbnB1dFN0cmVhbSk7CisKKyAgICAgICAgZmluYWwgQXJjaGl2ZUlucHV0U3RyZWFtIHRhciA9IGdldFN0cmVhbUZvcigiYmxhLnRhciIpOworICAgICAgICBhc3NlcnROb3ROdWxsKHRhcik7CisgICAgICAgIGFzc2VydFRydWUodGFyIGluc3RhbmNlb2YgVGFyQXJjaGl2ZUlucHV0U3RyZWFtKTsKKworICAgICAgICBmaW5hbCBBcmNoaXZlSW5wdXRTdHJlYW0gemlwID0gZ2V0U3RyZWFtRm9yKCJibGEuemlwIik7CisgICAgICAgIGFzc2VydE5vdE51bGwoemlwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh6aXAgaW5zdGFuY2VvZiBaaXBBcmNoaXZlSW5wdXRTdHJlYW0pOworCisgICAgICAgIGZpbmFsIEFyY2hpdmVJbnB1dFN0cmVhbSBqYXIgPSBnZXRTdHJlYW1Gb3IoImJsYS5qYXIiKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChqYXIpOworICAgICAgICBhc3NlcnRUcnVlKGphciBpbnN0YW5jZW9mIFppcEFyY2hpdmVJbnB1dFN0cmVhbSk7CisKKyAgICAgICAgZmluYWwgQXJjaGl2ZUlucHV0U3RyZWFtIGNwaW8gPSBnZXRTdHJlYW1Gb3IoImJsYS5jcGlvIik7CisgICAgICAgIGFzc2VydE5vdE51bGwoY3Bpbyk7CisgICAgICAgIGFzc2VydFRydWUoY3BpbyBpbnN0YW5jZW9mIENwaW9BcmNoaXZlSW5wdXRTdHJlYW0pOworCisgICAgICAgIGZpbmFsIEFyY2hpdmVJbnB1dFN0cmVhbSBhcmogPSBnZXRTdHJlYW1Gb3IoImJsYS5hcmoiKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChhcmopOworICAgICAgICBhc3NlcnRUcnVlKGFyaiBpbnN0YW5jZW9mIEFyakFyY2hpdmVJbnB1dFN0cmVhbSk7CisKKy8vIE5vdCB5ZXQgaW1wbGVtZW50ZWQKKy8vICAgICAgICBmaW5hbCBBcmNoaXZlSW5wdXRTdHJlYW0gdGd6ID0gZ2V0U3RyZWFtRm9yKCJibGEudGd6Iik7CisvLyAgICAgICAgYXNzZXJ0Tm90TnVsbCh0Z3opOworLy8gICAgICAgIGFzc2VydFRydWUodGd6IGluc3RhbmNlb2YgVGFyQXJjaGl2ZUlucHV0U3RyZWFtKTsKKworICAgIH0KKworICAgIHByaXZhdGUgQXJjaGl2ZUlucHV0U3RyZWFtIGdldFN0cmVhbUZvcihmaW5hbCBTdHJpbmcgcmVzb3VyY2UpCisgICAgICAgICAgICB0aHJvd3MgQXJjaGl2ZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gZmFjdG9yeS5jcmVhdGVBcmNoaXZlSW5wdXRTdHJlYW0oCisgICAgICAgICAgICAgICAgICAgbmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0obmV3IEZpbGVJbnB1dFN0cmVhbSgKKyAgICAgICAgICAgICAgICAgICAgICAgZ2V0RmlsZShyZXNvdXJjZSkpKSk7CisgICAgfQorCisgICAgLy8gQ2hlY2sgdGhhdCB0aGUgZW1wdHkgYXJjaGl2ZXMgY3JlYXRlZCBieSB0aGUgY29kZSBhcmUgcmVhZGFibGUKKworICAgIC8vIE5vdCBwb3NzaWJsZSB0byBkZXRlY3QgZW1wdHkgImFyIiBhcmNoaXZlIGFzIGl0IGlzIGNvbXBsZXRlbHkgZW1wdHkKKy8vICAgIHB1YmxpYyB2b2lkIHRlc3RFbXB0eUFyQXJjaGl2ZSgpIHRocm93cyBFeGNlcHRpb24geworLy8gICAgICAgIGVtcHR5QXJjaGl2ZSgiYXIiKTsKKy8vICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEVtcHR5Q3Bpb0FyY2hpdmUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tFbXB0eUFyY2hpdmUoImNwaW8iKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RFbXB0eUphckFyY2hpdmUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tFbXB0eUFyY2hpdmUoImphciIpOworICAgIH0KKworICAgIC8vIGVtcHR5IHRhciBhcmNoaXZlcyBqdXN0IGhhdmUgNTEyIG51bGwgYnl0ZXMKKy8vICAgIHB1YmxpYyB2b2lkIHRlc3RFbXB0eVRhckFyY2hpdmUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKy8vICAgICAgICBjaGVja0VtcHR5QXJjaGl2ZSgidGFyIik7CisvLyAgICB9CisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW1wdHlaaXBBcmNoaXZlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrRW1wdHlBcmNoaXZlKCJ6aXAiKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY2hlY2tFbXB0eUFyY2hpdmUoZmluYWwgU3RyaW5nIHR5cGUpIHRocm93cyBFeGNlcHRpb257CisgICAgICAgIGZpbmFsIEZpbGUgYXIgPSBjcmVhdGVFbXB0eUFyY2hpdmUodHlwZSk7IC8vIHdpbGwgYmUgZGVsZXRlZCBieSB0ZWFyRG93bigpCisgICAgICAgIGFyLmRlbGV0ZU9uRXhpdCgpOyAvLyBKdXN0IGluIGNhc2UgZmlsZSBjYW5ub3QgYmUgZGVsZXRlZAorICAgICAgICBBcmNoaXZlSW5wdXRTdHJlYW0gYWlzID0gbnVsbDsKKyAgICAgICAgQnVmZmVyZWRJbnB1dFN0cmVhbSBpbiA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbiA9IG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKG5ldyBGaWxlSW5wdXRTdHJlYW0oYXIpKTsKKyAgICAgICAgICAgIGFpcyA9IGZhY3RvcnkuY3JlYXRlQXJjaGl2ZUlucHV0U3RyZWFtKGluKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgQXJjaGl2ZUV4Y2VwdGlvbiBhZSkgeworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIGhhdmUgcmVjb2duaXplZCBlbXB0eSBhcmNoaXZlIGZvciAiK3R5cGUpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKGFpcyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgYWlzLmNsb3NlKCk7IC8vIHdpbGwgY2xvc2UgaW5wdXQgYXMgd2VsbAorICAgICAgICAgICAgfSBlbHNlIGlmIChpbiAhPSBudWxsKXsKKyAgICAgICAgICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvSU9NZXRob2RzVGVzdC5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvSU9NZXRob2RzVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ4MWE5ZDUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9JT01ldGhvZHNUZXN0LmphdmEKQEAgLTAsMCArMSwxOTQgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzOworCitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuKjsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5BcmNoaXZlRW50cnk7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5BcmNoaXZlSW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5BcmNoaXZlT3V0cHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuYXIuQXJBcmNoaXZlRW50cnk7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5jcGlvLkNwaW9BcmNoaXZlRW50cnk7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5qYXIuSmFyQXJjaGl2ZUVudHJ5OworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMudGFyLlRhckFyY2hpdmVFbnRyeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcC5aaXBBcmNoaXZlRW50cnk7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CisKKy8qKgorICogQ2hlY2sgdGhhdCB0aGUgZGlmZmVyZW50IHdyaXRlIG1ldGhvZHMgY3JlYXRlIHRoZSBzYW1lIG91dHB1dC4KKyAqIFRPRE8gcGVyZm9ybSB0aGUgc2FtZSBjaGVja3MgZm9yIHJlYWRzLgorICovCitwdWJsaWMgY2xhc3MgSU9NZXRob2RzVGVzdCBleHRlbmRzIEFic3RyYWN0VGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IGJ5dGVzVG9UZXN0ID0gNTA7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIGJ5dGVUZXN0ID0gbmV3IGJ5dGVbYnl0ZXNUb1Rlc3RdOworICAgIHN0YXRpYyB7CisgICAgICAgIGZvcihpbnQgaT0wOyBpIDwgYnl0ZVRlc3QubGVuZ3RoIDspIHsKKyAgICAgICAgICAgIGJ5dGVUZXN0W2ldPShieXRlKSBpOworICAgICAgICAgICAgYnl0ZVRlc3RbaSsxXT0oYnl0ZSkgLWk7CisgICAgICAgICAgICBpICs9IDI7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RXcml0ZUFyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEFyY2hpdmVFbnRyeSBlbnRyeSA9IG5ldyBBckFyY2hpdmVFbnRyeSgiZHVtbXkiLCBieXRlc1RvVGVzdCk7CisgICAgICAgIGNvbXBhcmVXcml0ZXMoImFyIiwgZW50cnkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFdyaXRlQ3BpbygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBBcmNoaXZlRW50cnkgZW50cnkgPSBuZXcgQ3Bpb0FyY2hpdmVFbnRyeSgiZHVtbXkiLCBieXRlc1RvVGVzdCk7CisgICAgICAgIGNvbXBhcmVXcml0ZXMoImNwaW8iLCBlbnRyeSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0V3JpdGVKYXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgQXJjaGl2ZUVudHJ5IGVudHJ5ID0gbmV3IEphckFyY2hpdmVFbnRyeSgiZHVtbXkiKTsKKyAgICAgICAgY29tcGFyZVdyaXRlcygiamFyIiwgZW50cnkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFdyaXRlVGFyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFRhckFyY2hpdmVFbnRyeSBlbnRyeSA9IG5ldyBUYXJBcmNoaXZlRW50cnkoImR1bW15Iik7CisgICAgICAgIGVudHJ5LnNldFNpemUoYnl0ZXNUb1Rlc3QpOworICAgICAgICBjb21wYXJlV3JpdGVzKCJ0YXIiLCBlbnRyeSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0V3JpdGVaaXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgQXJjaGl2ZUVudHJ5IGVudHJ5ID0gbmV3IFppcEFyY2hpdmVFbnRyeSgiZHVtbXkiKTsKKyAgICAgICAgY29tcGFyZVdyaXRlcygiemlwIiwgZW50cnkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFJlYWRBcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBjb21wYXJlUmVhZHMoImFyIik7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVhZENwaW8oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgY29tcGFyZVJlYWRzKCJjcGlvIik7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVhZEphcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBjb21wYXJlUmVhZHMoImphciIpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFJlYWRUYXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgY29tcGFyZVJlYWRzKCJ0YXIiKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RSZWFkWmlwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGNvbXBhcmVSZWFkcygiemlwIik7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNvbXBhcmVXcml0ZXMoZmluYWwgU3RyaW5nIGFyY2hpdmVyTmFtZSwgZmluYWwgQXJjaGl2ZUVudHJ5IGVudHJ5KSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgT3V0cHV0U3RyZWFtIG91dDEgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIGZpbmFsIE91dHB1dFN0cmVhbSBvdXQyID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICBmaW5hbCBPdXRwdXRTdHJlYW0gb3V0MyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgZmluYWwgQXJjaGl2ZU91dHB1dFN0cmVhbSBhb3MxID0gZmFjdG9yeS5jcmVhdGVBcmNoaXZlT3V0cHV0U3RyZWFtKGFyY2hpdmVyTmFtZSwgb3V0MSk7CisgICAgICAgIGFvczEucHV0QXJjaGl2ZUVudHJ5KGVudHJ5KTsKKyAgICAgICAgZmluYWwgQXJjaGl2ZU91dHB1dFN0cmVhbSBhb3MyID0gZmFjdG9yeS5jcmVhdGVBcmNoaXZlT3V0cHV0U3RyZWFtKGFyY2hpdmVyTmFtZSwgb3V0Mik7CisgICAgICAgIGFvczIucHV0QXJjaGl2ZUVudHJ5KGVudHJ5KTsKKyAgICAgICAgZmluYWwgQXJjaGl2ZU91dHB1dFN0cmVhbSBhb3MzID0gZmFjdG9yeS5jcmVhdGVBcmNoaXZlT3V0cHV0U3RyZWFtKGFyY2hpdmVyTmFtZSwgb3V0Myk7CisgICAgICAgIGFvczMucHV0QXJjaGl2ZUVudHJ5KGVudHJ5KTsKKyAgICAgICAgZm9yIChmaW5hbCBieXRlIGVsZW1lbnQgOiBieXRlVGVzdCkgeworICAgICAgICAgICAgYW9zMS53cml0ZShlbGVtZW50KTsKKyAgICAgICAgfQorICAgICAgICBhb3MxLmNsb3NlQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgIGFvczEuY2xvc2UoKTsKKworICAgICAgICBhb3MyLndyaXRlKGJ5dGVUZXN0KTsKKyAgICAgICAgYW9zMi5jbG9zZUFyY2hpdmVFbnRyeSgpOworICAgICAgICBhb3MyLmNsb3NlKCk7CisKKyAgICAgICAgYW9zMy53cml0ZShieXRlVGVzdCwgMCwgYnl0ZVRlc3QubGVuZ3RoKTsKKyAgICAgICAgYW9zMy5jbG9zZUFyY2hpdmVFbnRyeSgpOworICAgICAgICBhb3MzLmNsb3NlKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiYW9zMUJ5dGVzIT1hb3MyQnl0ZXMiLGFvczEuZ2V0Qnl0ZXNXcml0dGVuKCksYW9zMi5nZXRCeXRlc1dyaXR0ZW4oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYW9zMUJ5dGVzIT1hb3MzQnl0ZXMiLGFvczEuZ2V0Qnl0ZXNXcml0dGVuKCksYW9zMy5nZXRCeXRlc1dyaXR0ZW4oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygib3V0MUxlbiE9b3V0MkxlbiIsb3V0MS50b1N0cmluZygpLmxlbmd0aCgpLG91dDIudG9TdHJpbmcoKS5sZW5ndGgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygib3V0MUxlbiE9b3V0MkxlbiIsb3V0MS50b1N0cmluZygpLmxlbmd0aCgpLG91dDMudG9TdHJpbmcoKS5sZW5ndGgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygib3V0MSE9b3V0MiIsb3V0MS50b1N0cmluZygpLG91dDIudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygib3V0MSE9b3V0MyIsb3V0MS50b1N0cmluZygpLG91dDMudG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNvbXBhcmVSZWFkcyhmaW5hbCBTdHJpbmcgYXJjaGl2ZXJOYW1lKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgT3V0cHV0U3RyZWFtIG91dDEgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIGZpbmFsIE91dHB1dFN0cmVhbSBvdXQyID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICBmaW5hbCBPdXRwdXRTdHJlYW0gb3V0MyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgZmluYWwgRmlsZSBmaWxlID0gY3JlYXRlU2luZ2xlRW50cnlBcmNoaXZlKGFyY2hpdmVyTmFtZSk7CisgICAgICAgIGZpbGUuZGVsZXRlT25FeGl0KCk7CisKKyAgICAgICAgZmluYWwgSW5wdXRTdHJlYW0gaXMxID0gbmV3IEZpbGVJbnB1dFN0cmVhbShmaWxlKTsKKyAgICAgICAgZmluYWwgQXJjaGl2ZUlucHV0U3RyZWFtIGFpczEgPSBmYWN0b3J5LmNyZWF0ZUFyY2hpdmVJbnB1dFN0cmVhbShhcmNoaXZlck5hbWUsIGlzMSk7CisgICAgICAgIGZpbmFsIEFyY2hpdmVFbnRyeSBuZXh0RW50cnkgPSBhaXMxLmdldE5leHRFbnRyeSgpOworICAgICAgICBhc3NlcnROb3ROdWxsKG5leHRFbnRyeSk7CisKKyAgICAgICAgZmluYWwgYnl0ZSBbXSBidWZmID0gbmV3IGJ5dGVbMTBdOyAvLyBzbWFsbCBzbyBtdWx0aXBsZSByZWFkcyBhcmUgbmVlZGVkOworICAgICAgICBmaW5hbCBsb25nIHNpemUgPSBuZXh0RW50cnkuZ2V0U2l6ZSgpOworICAgICAgICBpZiAoc2l6ZSAhPSBBcmNoaXZlRW50cnkuU0laRV9VTktOT1dOKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJTaXplIHNob3VsZCBiZSA+IDAsIGZvdW5kOiAiK3NpemUsIHNpemUgPiAwKTsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIElucHV0U3RyZWFtIGlzMiA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oZmlsZSk7CisgICAgICAgIGZpbmFsIEFyY2hpdmVJbnB1dFN0cmVhbSBhaXMyID0gZmFjdG9yeS5jcmVhdGVBcmNoaXZlSW5wdXRTdHJlYW0oYXJjaGl2ZXJOYW1lLCBpczIpOworICAgICAgICBmaW5hbCBBcmNoaXZlRW50cnkgbmV4dEVudHJ5MiA9IGFpczIuZ2V0TmV4dEVudHJ5KCk7CisgICAgICAgIGFzc2VydE5vdE51bGwobmV4dEVudHJ5Mik7CisgICAgICAgIGFzc2VydEVxdWFscygiRXhwZWN0ZWQgc2FtZSBlbnRyeSBzaXplIiwgc2l6ZSwgbmV4dEVudHJ5Mi5nZXRTaXplKCkpOworCisgICAgICAgIGZpbmFsIElucHV0U3RyZWFtIGlzMyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oZmlsZSk7CisgICAgICAgIGZpbmFsIEFyY2hpdmVJbnB1dFN0cmVhbSBhaXMzID0gZmFjdG9yeS5jcmVhdGVBcmNoaXZlSW5wdXRTdHJlYW0oYXJjaGl2ZXJOYW1lLCBpczMpOworICAgICAgICBmaW5hbCBBcmNoaXZlRW50cnkgbmV4dEVudHJ5MyA9IGFpczMuZ2V0TmV4dEVudHJ5KCk7CisgICAgICAgIGFzc2VydE5vdE51bGwobmV4dEVudHJ5Myk7CisgICAgICAgIGFzc2VydEVxdWFscygiRXhwZWN0ZWQgc2FtZSBlbnRyeSBzaXplIiwgc2l6ZSwgbmV4dEVudHJ5My5nZXRTaXplKCkpOworCisgICAgICAgIGludCBiOworICAgICAgICB3aGlsZSgoYj1haXMxLnJlYWQoKSkgIT0gLTEpeworICAgICAgICAgICAgb3V0MS53cml0ZShiKTsKKyAgICAgICAgfQorICAgICAgICBhaXMxLmNsb3NlKCk7CisKKyAgICAgICAgaW50IGJ5dGVzOworICAgICAgICB3aGlsZSgoYnl0ZXMgPSBhaXMyLnJlYWQoYnVmZikpID4gMCl7CisgICAgICAgICAgICBvdXQyLndyaXRlKGJ1ZmYsIDAsIGJ5dGVzKTsKKyAgICAgICAgfQorICAgICAgICBhaXMyLmNsb3NlKCk7CisKKyAgICAgICAgd2hpbGUoKGJ5dGVzPWFpczMucmVhZChidWZmLCAwICwgYnVmZi5sZW5ndGgpKSA+IDApeworICAgICAgICAgICAgb3V0My53cml0ZShidWZmLCAwLCBieXRlcyk7CisgICAgICAgIH0KKyAgICAgICAgYWlzMy5jbG9zZSgpOworCisgICAgICAgIGFzc2VydEVxdWFscygib3V0MUxlbiE9b3V0MkxlbiIsb3V0MS50b1N0cmluZygpLmxlbmd0aCgpLG91dDIudG9TdHJpbmcoKS5sZW5ndGgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygib3V0MUxlbiE9b3V0M0xlbiIsb3V0MS50b1N0cmluZygpLmxlbmd0aCgpLG91dDMudG9TdHJpbmcoKS5sZW5ndGgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygib3V0MSE9b3V0MiIsb3V0MS50b1N0cmluZygpLG91dDIudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygib3V0MSE9b3V0MyIsb3V0MS50b1N0cmluZygpLG91dDMudG9TdHJpbmcoKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvTW9ja0V2aWxJbnB1dFN0cmVhbS5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvTW9ja0V2aWxJbnB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjljMDNhMjEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9Nb2NrRXZpbElucHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSw0MSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzczsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKKworLyoqCisgKiBTaW1wbGUgbW9jayBJbnB1dFN0cmVhbSB0aGF0IGFsd2F5cyB0aHJvd3MgYW4gSU9FeGNlcHRpb24KKyAqIHdoZW4ge0BsaW5rICNyZWFkKCl9IG9yIHtAbGluayAjcmVhZChieXRlW10sIGludCwgaW50KX0KKyAqIGlzIGNhbGxlZC4KKyAqLworcHVibGljIGNsYXNzIE1vY2tFdmlsSW5wdXRTdHJlYW0gZXh0ZW5kcyBJbnB1dFN0cmVhbSB7CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHJlYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkV2aWwiKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHJlYWQoYnl0ZVtdIGJ5dGVzLCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkV2aWwiKTsKKyAgICB9Cit9CisKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL09zZ2lJVGVzdC5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvT3NnaUlUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmUxM2Q3MQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL09zZ2lJVGVzdC5qYXZhCkBAIC0wLDAgKzEsNTUgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3M7CisKK2ltcG9ydCBzdGF0aWMgb3JnLm9wczRqLnBheC5leGFtLkNvcmVPcHRpb25zLmJ1bmRsZTsKK2ltcG9ydCBzdGF0aWMgb3JnLm9wczRqLnBheC5leGFtLkNvcmVPcHRpb25zLmNvbXBvc2l0ZTsKK2ltcG9ydCBzdGF0aWMgb3JnLm9wczRqLnBheC5leGFtLkNvcmVPcHRpb25zLm1hdmVuQnVuZGxlOworaW1wb3J0IHN0YXRpYyBvcmcub3BzNGoucGF4LmV4YW0uQ29yZU9wdGlvbnMuc3lzdGVtUHJvcGVydHk7CisKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVyLlJ1bldpdGg7CitpbXBvcnQgb3JnLm9wczRqLnBheC5leGFtLkNvbmZpZ3VyYXRpb247CitpbXBvcnQgb3JnLm9wczRqLnBheC5leGFtLk9wdGlvbjsKK2ltcG9ydCBvcmcub3BzNGoucGF4LmV4YW0uanVuaXQuUGF4RXhhbTsKKworQFJ1bldpdGgoUGF4RXhhbS5jbGFzcykKK3B1YmxpYyBjbGFzcyBPc2dpSVRlc3QgeworCisgICAgQENvbmZpZ3VyYXRpb24KKyAgICBwdWJsaWMgT3B0aW9uW10gY29uZmlnKCkgeworICAgICAgICByZXR1cm4gbmV3IE9wdGlvbltdIHsKKyAgICAgICAgICAgIHN5c3RlbVByb3BlcnR5KCJwYXguZXhhbS5vc2dpLnVucmVzb2x2ZWQuZmFpbCIpLnZhbHVlKCJ0cnVlIiksCisgICAgICAgICAgICBtYXZlbkJ1bmRsZSgpLmdyb3VwSWQoIm9yZy5hcGFjaGUuZmVsaXgiKS5hcnRpZmFjdElkKCJvcmcuYXBhY2hlLmZlbGl4LnNjciIpCisgICAgICAgICAgICAgICAgLnZlcnNpb24oIjIuMC4xNCIpLAorICAgICAgICAgICAgbWF2ZW5CdW5kbGUoKS5ncm91cElkKCJvcmcuYXBhY2hlLmZlbGl4IikuYXJ0aWZhY3RJZCgib3JnLmFwYWNoZS5mZWxpeC5jb25maWdhZG1pbiIpCisgICAgICAgICAgICAgICAgLnZlcnNpb24oIjEuOC4xNiIpLAorICAgICAgICAgICAgY29tcG9zaXRlKHN5c3RlbVByb3BlcnR5KCJwYXguZXhhbS5pbnZva2VyIikudmFsdWUoImp1bml0IiksCisgICAgICAgICAgICAgICAgICAgICAgYnVuZGxlKCJsaW5rOmNsYXNzcGF0aDpNRVRBLUlORi9saW5rcy9vcmcub3BzNGoucGF4LnRpcGkuanVuaXQubGluayIpLAorICAgICAgICAgICAgICAgICAgICAgIGJ1bmRsZSgibGluazpjbGFzc3BhdGg6TUVUQS1JTkYvbGlua3Mvb3JnLm9wczRqLnBheC5leGFtLmludm9rZXIuanVuaXQubGluayIpLAorICAgICAgICAgICAgICAgICAgICAgIG1hdmVuQnVuZGxlKCkuZ3JvdXBJZCgib3JnLmFwYWNoZS5zZXJ2aWNlbWl4LmJ1bmRsZXMiKQorICAgICAgICAgICAgICAgICAgICAgICAgICAuYXJ0aWZhY3RJZCgib3JnLmFwYWNoZS5zZXJ2aWNlbWl4LmJ1bmRsZXMuaGFtY3Jlc3QiKS52ZXJzaW9uKCIxLjNfMSIpKSwKKyAgICAgICAgICAgIGJ1bmRsZSgicmVmZXJlbmNlOmZpbGU6dGFyZ2V0L2NsYXNzZXMvIikuc3RhcnQoKQorICAgICAgIH07CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBsb2FkQnVuZGxlKCkgeworICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9BclRlc3RDYXNlLmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvQXJUZXN0Q2FzZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZhZGI3YzMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvQXJUZXN0Q2FzZS5qYXZhCkBAIC0wLDAgKzEsMzczIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVyczsKKworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0Lio7CisKK2ltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLkFic3RyYWN0VGVzdENhc2U7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5hci5BckFyY2hpdmVFbnRyeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLmFyLkFyQXJjaGl2ZUlucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuYXIuQXJBcmNoaXZlT3V0cHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5JT1V0aWxzOworaW1wb3J0IG9yZy5qdW5pdC5JZ25vcmU7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBBclRlc3RDYXNlIGV4dGVuZHMgQWJzdHJhY3RUZXN0Q2FzZSB7CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RBckFyY2hpdmVDcmVhdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlIG91dHB1dCA9IG5ldyBGaWxlKGRpciwgImJsYS5hciIpOworCisgICAgICAgIGZpbmFsIEZpbGUgZmlsZTEgPSBnZXRGaWxlKCJ0ZXN0MS54bWwiKTsKKyAgICAgICAgZmluYWwgRmlsZSBmaWxlMiA9IGdldEZpbGUoInRlc3QyLnhtbCIpOworCisgICAgICAgIGZpbmFsIE91dHB1dFN0cmVhbSBvdXQgPSBuZXcgRmlsZU91dHB1dFN0cmVhbShvdXRwdXQpOworICAgICAgICBmaW5hbCBBcmNoaXZlT3V0cHV0U3RyZWFtIG9zID0gbmV3IEFyY2hpdmVTdHJlYW1GYWN0b3J5KCkuY3JlYXRlQXJjaGl2ZU91dHB1dFN0cmVhbSgiYXIiLCBvdXQpOworICAgICAgICBvcy5wdXRBcmNoaXZlRW50cnkobmV3IEFyQXJjaGl2ZUVudHJ5KCJ0ZXN0MS54bWwiLCBmaWxlMS5sZW5ndGgoKSkpOworICAgICAgICBJT1V0aWxzLmNvcHkobmV3IEZpbGVJbnB1dFN0cmVhbShmaWxlMSksIG9zKTsKKyAgICAgICAgb3MuY2xvc2VBcmNoaXZlRW50cnkoKTsKKworICAgICAgICBvcy5wdXRBcmNoaXZlRW50cnkobmV3IEFyQXJjaGl2ZUVudHJ5KCJ0ZXN0Mi54bWwiLCBmaWxlMi5sZW5ndGgoKSkpOworICAgICAgICBJT1V0aWxzLmNvcHkobmV3IEZpbGVJbnB1dFN0cmVhbShmaWxlMiksIG9zKTsKKyAgICAgICAgb3MuY2xvc2VBcmNoaXZlRW50cnkoKTsKKworICAgICAgICBvcy5jbG9zZSgpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEFyVW5hcmNoaXZlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGUgb3V0cHV0ID0gbmV3IEZpbGUoZGlyLCAiYmxhLmFyIik7CisgICAgICAgIHsKKyAgICAgICAgICAgIGZpbmFsIEZpbGUgZmlsZTEgPSBnZXRGaWxlKCJ0ZXN0MS54bWwiKTsKKyAgICAgICAgICAgIGZpbmFsIEZpbGUgZmlsZTIgPSBnZXRGaWxlKCJ0ZXN0Mi54bWwiKTsKKworICAgICAgICAgICAgZmluYWwgT3V0cHV0U3RyZWFtIG91dCA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKG91dHB1dCk7CisgICAgICAgICAgICBmaW5hbCBBcmNoaXZlT3V0cHV0U3RyZWFtIG9zID0gbmV3IEFyY2hpdmVTdHJlYW1GYWN0b3J5KCkuY3JlYXRlQXJjaGl2ZU91dHB1dFN0cmVhbSgiYXIiLCBvdXQpOworICAgICAgICAgICAgb3MucHV0QXJjaGl2ZUVudHJ5KG5ldyBBckFyY2hpdmVFbnRyeSgidGVzdDEueG1sIiwgZmlsZTEubGVuZ3RoKCkpKTsKKyAgICAgICAgICAgIElPVXRpbHMuY29weShuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGUxKSwgb3MpOworICAgICAgICAgICAgb3MuY2xvc2VBcmNoaXZlRW50cnkoKTsKKworICAgICAgICAgICAgb3MucHV0QXJjaGl2ZUVudHJ5KG5ldyBBckFyY2hpdmVFbnRyeSgidGVzdDIueG1sIiwgZmlsZTIubGVuZ3RoKCkpKTsKKyAgICAgICAgICAgIElPVXRpbHMuY29weShuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGUyKSwgb3MpOworICAgICAgICAgICAgb3MuY2xvc2VBcmNoaXZlRW50cnkoKTsKKyAgICAgICAgICAgIG9zLmNsb3NlKCk7CisgICAgICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFVuQXJBcmNoaXZlIE9wZXJhdGlvbgorICAgICAgICBmaW5hbCBGaWxlIGlucHV0ID0gb3V0cHV0OworICAgICAgICB0cnkgKGZpbmFsIElucHV0U3RyZWFtIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShpbnB1dCk7CisgICAgICAgICAgICAgICAgZmluYWwgQXJjaGl2ZUlucHV0U3RyZWFtIGluID0gbmV3IEFyY2hpdmVTdHJlYW1GYWN0b3J5KCkKKyAgICAgICAgICAgICAgICAgICAgICAgIC5jcmVhdGVBcmNoaXZlSW5wdXRTdHJlYW0obmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0oaXMpKSkgeworICAgICAgICAgICAgZmluYWwgQXJBcmNoaXZlRW50cnkgZW50cnkgPSAoQXJBcmNoaXZlRW50cnkpIGluLmdldE5leHRFbnRyeSgpOworCisgICAgICAgICAgICBmaW5hbCBGaWxlIHRhcmdldCA9IG5ldyBGaWxlKGRpciwgZW50cnkuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIHRyeSAoZmluYWwgT3V0cHV0U3RyZWFtIG91dCA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKHRhcmdldCkpIHsKKyAgICAgICAgICAgICAgICBJT1V0aWxzLmNvcHkoaW4sIG91dCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RBckRlbGV0ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlIG91dHB1dCA9IG5ldyBGaWxlKGRpciwgImJsYS5hciIpOworCisgICAgICAgIGZpbmFsIEZpbGUgZmlsZTEgPSBnZXRGaWxlKCJ0ZXN0MS54bWwiKTsKKyAgICAgICAgZmluYWwgRmlsZSBmaWxlMiA9IGdldEZpbGUoInRlc3QyLnhtbCIpOworICAgICAgICB7CisgICAgICAgICAgICAvLyBjcmVhdGUKKworICAgICAgICAgICAgZmluYWwgT3V0cHV0U3RyZWFtIG91dCA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKG91dHB1dCk7CisgICAgICAgICAgICBmaW5hbCBBcmNoaXZlT3V0cHV0U3RyZWFtIG9zID0gbmV3IEFyY2hpdmVTdHJlYW1GYWN0b3J5KCkuY3JlYXRlQXJjaGl2ZU91dHB1dFN0cmVhbSgiYXIiLCBvdXQpOworICAgICAgICAgICAgb3MucHV0QXJjaGl2ZUVudHJ5KG5ldyBBckFyY2hpdmVFbnRyeSgidGVzdDEueG1sIiwgZmlsZTEubGVuZ3RoKCkpKTsKKyAgICAgICAgICAgIElPVXRpbHMuY29weShuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGUxKSwgb3MpOworICAgICAgICAgICAgb3MuY2xvc2VBcmNoaXZlRW50cnkoKTsKKworICAgICAgICAgICAgb3MucHV0QXJjaGl2ZUVudHJ5KG5ldyBBckFyY2hpdmVFbnRyeSgidGVzdDIueG1sIiwgZmlsZTIubGVuZ3RoKCkpKTsKKyAgICAgICAgICAgIElPVXRpbHMuY29weShuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGUyKSwgb3MpOworICAgICAgICAgICAgb3MuY2xvc2VBcmNoaXZlRW50cnkoKTsKKyAgICAgICAgICAgIG9zLmNsb3NlKCk7CisgICAgICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydEVxdWFscyg4CisgICAgICAgICAgICAgICAgICAgICArIDYwICsgZmlsZTEubGVuZ3RoKCkgKyAoZmlsZTEubGVuZ3RoKCkgJSAyKQorICAgICAgICAgICAgICAgICAgICAgKyA2MCArIGZpbGUyLmxlbmd0aCgpICsgKGZpbGUyLmxlbmd0aCgpICUgMiksCisgICAgICAgICAgICAgICAgICAgICBvdXRwdXQubGVuZ3RoKCkpOworCisgICAgICAgIGZpbmFsIEZpbGUgb3V0cHV0MiA9IG5ldyBGaWxlKGRpciwgImJsYTIuYXIiKTsKKworICAgICAgICBpbnQgY29waWVkID0gMDsKKyAgICAgICAgaW50IGRlbGV0ZWQgPSAwOworCisgICAgICAgIHsKKyAgICAgICAgICAgIC8vIHJlbW92ZSBhbGwgYnV0IG9uZSBmaWxlCisKKyAgICAgICAgICAgIGZpbmFsIElucHV0U3RyZWFtIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShvdXRwdXQpOworICAgICAgICAgICAgZmluYWwgT3V0cHV0U3RyZWFtIG9zID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0ob3V0cHV0Mik7CisgICAgICAgICAgICBmaW5hbCBBcmNoaXZlT3V0cHV0U3RyZWFtIGFvcyA9IG5ldyBBcmNoaXZlU3RyZWFtRmFjdG9yeSgpLmNyZWF0ZUFyY2hpdmVPdXRwdXRTdHJlYW0oImFyIiwgb3MpOworICAgICAgICAgICAgZmluYWwgQXJjaGl2ZUlucHV0U3RyZWFtIGFpcyA9IG5ldyBBcmNoaXZlU3RyZWFtRmFjdG9yeSgpLmNyZWF0ZUFyY2hpdmVJbnB1dFN0cmVhbShuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShpcykpOworICAgICAgICAgICAgd2hpbGUodHJ1ZSkgeworICAgICAgICAgICAgICAgIGZpbmFsIEFyQXJjaGl2ZUVudHJ5IGVudHJ5ID0gKEFyQXJjaGl2ZUVudHJ5KWFpcy5nZXROZXh0RW50cnkoKTsKKyAgICAgICAgICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBpZiAoInRlc3QxLnhtbCIuZXF1YWxzKGVudHJ5LmdldE5hbWUoKSkpIHsKKyAgICAgICAgICAgICAgICAgICAgYW9zLnB1dEFyY2hpdmVFbnRyeShlbnRyeSk7CisgICAgICAgICAgICAgICAgICAgIElPVXRpbHMuY29weShhaXMsIGFvcyk7CisgICAgICAgICAgICAgICAgICAgIGFvcy5jbG9zZUFyY2hpdmVFbnRyeSgpOworICAgICAgICAgICAgICAgICAgICBjb3BpZWQrKzsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBJT1V0aWxzLmNvcHkoYWlzLCBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCkpOworICAgICAgICAgICAgICAgICAgICBkZWxldGVkKys7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICB9CisgICAgICAgICAgICBhaXMuY2xvc2UoKTsKKyAgICAgICAgICAgIGFvcy5jbG9zZSgpOworICAgICAgICAgICAgaXMuY2xvc2UoKTsKKyAgICAgICAgICAgIG9zLmNsb3NlKCk7CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgY29waWVkKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGRlbGV0ZWQpOworICAgICAgICBhc3NlcnRFcXVhbHMoOAorICAgICAgICAgICAgICAgICAgICAgKyA2MCArIGZpbGUxLmxlbmd0aCgpICsgKGZpbGUxLmxlbmd0aCgpICUgMiksCisgICAgICAgICAgICAgICAgICAgICBvdXRwdXQyLmxlbmd0aCgpKTsKKworICAgICAgICBsb25nIGZpbGVzID0gMDsKKyAgICAgICAgbG9uZyBzdW0gPSAwOworCisgICAgICAgIHsKKyAgICAgICAgICAgIGZpbmFsIElucHV0U3RyZWFtIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShvdXRwdXQyKTsKKyAgICAgICAgICAgIGZpbmFsIEFyY2hpdmVJbnB1dFN0cmVhbSBhaXMgPSBuZXcgQXJjaGl2ZVN0cmVhbUZhY3RvcnkoKS5jcmVhdGVBcmNoaXZlSW5wdXRTdHJlYW0obmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0oaXMpKTsKKyAgICAgICAgICAgIHdoaWxlKHRydWUpIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBBckFyY2hpdmVFbnRyeSBlbnRyeSA9IChBckFyY2hpdmVFbnRyeSlhaXMuZ2V0TmV4dEVudHJ5KCk7CisgICAgICAgICAgICAgICAgaWYgKGVudHJ5ID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgSU9VdGlscy5jb3B5KGFpcywgbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpKTsKKworICAgICAgICAgICAgICAgIHN1bSArPSAgZW50cnkuZ2V0TGVuZ3RoKCk7CisgICAgICAgICAgICAgICAgZmlsZXMrKzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFpcy5jbG9zZSgpOworICAgICAgICAgICAgaXMuY2xvc2UoKTsKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydEVxdWFscygxLCBmaWxlcyk7CisgICAgICAgIGFzc2VydEVxdWFscyhmaWxlMS5sZW5ndGgoKSwgc3VtKTsKKworICAgIH0KKworICAgIC8vIFRPRE86IHJldmlzaXQgLSBkb2VzIEFSIG5vdCBzdXBwb3J0IHN0b3JpbmcgZGlyZWN0b3JpZXM/CisgICAgQElnbm9yZQorICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgWHRlc3REaXJlY3RvcnlFbnRyeUZyb21GaWxlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGVbXSB0bXAgPSBjcmVhdGVUZW1wRGlyQW5kRmlsZSgpOworICAgICAgICBGaWxlIGFyY2hpdmUgPSBudWxsOworICAgICAgICBBckFyY2hpdmVPdXRwdXRTdHJlYW0gYW9zID0gbnVsbDsKKyAgICAgICAgQXJBcmNoaXZlSW5wdXRTdHJlYW0gYWlzID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFyY2hpdmUgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKCJ0ZXN0LiIsICIuYXIiLCB0bXBbMF0pOworICAgICAgICAgICAgYXJjaGl2ZS5kZWxldGVPbkV4aXQoKTsKKyAgICAgICAgICAgIGFvcyA9IG5ldyBBckFyY2hpdmVPdXRwdXRTdHJlYW0obmV3IEZpbGVPdXRwdXRTdHJlYW0oYXJjaGl2ZSkpOworICAgICAgICAgICAgZmluYWwgbG9uZyBiZWZvcmVBcmNoaXZlV3JpdGUgPSB0bXBbMF0ubGFzdE1vZGlmaWVkKCk7CisgICAgICAgICAgICBmaW5hbCBBckFyY2hpdmVFbnRyeSBpbiA9IG5ldyBBckFyY2hpdmVFbnRyeSh0bXBbMF0sICJmb28iKTsKKyAgICAgICAgICAgIGFvcy5wdXRBcmNoaXZlRW50cnkoaW4pOworICAgICAgICAgICAgYW9zLmNsb3NlQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgICAgICBhb3MuY2xvc2UoKTsKKyAgICAgICAgICAgIGFvcyA9IG51bGw7CisgICAgICAgICAgICBhaXMgPSBuZXcgQXJBcmNoaXZlSW5wdXRTdHJlYW0obmV3IEZpbGVJbnB1dFN0cmVhbShhcmNoaXZlKSk7CisgICAgICAgICAgICBmaW5hbCBBckFyY2hpdmVFbnRyeSBvdXQgPSBhaXMuZ2V0TmV4dEFyRW50cnkoKTsKKyAgICAgICAgICAgIGFpcy5jbG9zZSgpOworICAgICAgICAgICAgYWlzID0gbnVsbDsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwob3V0KTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZm9vLyIsIG91dC5nZXROYW1lKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIG91dC5nZXRTaXplKCkpOworICAgICAgICAgICAgLy8gQVIgc3RvcmVzIHRpbWUgd2l0aCBhIGdyYW51bGFyaXR5IG9mIDEgc2Vjb25kCisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoYmVmb3JlQXJjaGl2ZVdyaXRlIC8gMTAwMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICBvdXQuZ2V0TGFzdE1vZGlmaWVkRGF0ZSgpLmdldFRpbWUoKSAvIDEwMDApOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShvdXQuaXNEaXJlY3RvcnkoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAoYWlzICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBhaXMuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChhb3MgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGFvcy5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdHJ5SGFyZFRvRGVsZXRlKGFyY2hpdmUpOworICAgICAgICAgICAgdHJ5SGFyZFRvRGVsZXRlKHRtcFsxXSk7CisgICAgICAgICAgICBybWRpcih0bXBbMF0pOworICAgICAgICB9CisgICAgfQorCisgICAgLy8gVE9ETzogcmV2aXNpdCAtIGRvZXMgQVIgbm90IHN1cHBvcnQgc3RvcmluZyBkaXJlY3Rvcmllcz8KKyAgICBASWdub3JlCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBYdGVzdEV4cGxpY2l0RGlyZWN0b3J5RW50cnkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgRmlsZVtdIHRtcCA9IGNyZWF0ZVRlbXBEaXJBbmRGaWxlKCk7CisgICAgICAgIEZpbGUgYXJjaGl2ZSA9IG51bGw7CisgICAgICAgIEFyQXJjaGl2ZU91dHB1dFN0cmVhbSBhb3MgPSBudWxsOworICAgICAgICBBckFyY2hpdmVJbnB1dFN0cmVhbSBhaXMgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXJjaGl2ZSA9IEZpbGUuY3JlYXRlVGVtcEZpbGUoInRlc3QuIiwgIi5hciIsIHRtcFswXSk7CisgICAgICAgICAgICBhcmNoaXZlLmRlbGV0ZU9uRXhpdCgpOworICAgICAgICAgICAgYW9zID0gbmV3IEFyQXJjaGl2ZU91dHB1dFN0cmVhbShuZXcgRmlsZU91dHB1dFN0cmVhbShhcmNoaXZlKSk7CisgICAgICAgICAgICBmaW5hbCBsb25nIGJlZm9yZUFyY2hpdmVXcml0ZSA9IHRtcFswXS5sYXN0TW9kaWZpZWQoKTsKKyAgICAgICAgICAgIGZpbmFsIEFyQXJjaGl2ZUVudHJ5IGluID0gbmV3IEFyQXJjaGl2ZUVudHJ5KCJmb28iLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG1wWzFdLmxhc3RNb2RpZmllZCgpIC8gMTAwMCk7CisgICAgICAgICAgICBhb3MucHV0QXJjaGl2ZUVudHJ5KGluKTsKKyAgICAgICAgICAgIGFvcy5jbG9zZUFyY2hpdmVFbnRyeSgpOworICAgICAgICAgICAgYW9zLmNsb3NlKCk7CisgICAgICAgICAgICBhb3MgPSBudWxsOworICAgICAgICAgICAgYWlzID0gbmV3IEFyQXJjaGl2ZUlucHV0U3RyZWFtKG5ldyBGaWxlSW5wdXRTdHJlYW0oYXJjaGl2ZSkpOworICAgICAgICAgICAgZmluYWwgQXJBcmNoaXZlRW50cnkgb3V0ID0gYWlzLmdldE5leHRBckVudHJ5KCk7CisgICAgICAgICAgICBhaXMuY2xvc2UoKTsKKyAgICAgICAgICAgIGFpcyA9IG51bGw7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKG91dCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImZvby8iLCBvdXQuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygwLCBvdXQuZ2V0U2l6ZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhiZWZvcmVBcmNoaXZlV3JpdGUgLyAxMDAwLAorICAgICAgICAgICAgICAgICAgICAgICAgIG91dC5nZXRMYXN0TW9kaWZpZWREYXRlKCkuZ2V0VGltZSgpIC8gMTAwMCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKG91dC5pc0RpcmVjdG9yeSgpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmIChhaXMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGFpcy5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGFvcyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgYW9zLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnlIYXJkVG9EZWxldGUoYXJjaGl2ZSk7CisgICAgICAgICAgICB0cnlIYXJkVG9EZWxldGUodG1wWzFdKTsKKyAgICAgICAgICAgIHJtZGlyKHRtcFswXSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RGaWxlRW50cnlGcm9tRmlsZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlW10gdG1wID0gY3JlYXRlVGVtcERpckFuZEZpbGUoKTsKKyAgICAgICAgRmlsZSBhcmNoaXZlID0gbnVsbDsKKyAgICAgICAgQXJBcmNoaXZlT3V0cHV0U3RyZWFtIGFvcyA9IG51bGw7CisgICAgICAgIEFyQXJjaGl2ZUlucHV0U3RyZWFtIGFpcyA9IG51bGw7CisgICAgICAgIEZpbGVJbnB1dFN0cmVhbSBmaXMgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXJjaGl2ZSA9IEZpbGUuY3JlYXRlVGVtcEZpbGUoInRlc3QuIiwgIi5hciIsIHRtcFswXSk7CisgICAgICAgICAgICBhcmNoaXZlLmRlbGV0ZU9uRXhpdCgpOworICAgICAgICAgICAgYW9zID0gbmV3IEFyQXJjaGl2ZU91dHB1dFN0cmVhbShuZXcgRmlsZU91dHB1dFN0cmVhbShhcmNoaXZlKSk7CisgICAgICAgICAgICBmaW5hbCBBckFyY2hpdmVFbnRyeSBpbiA9IG5ldyBBckFyY2hpdmVFbnRyeSh0bXBbMV0sICJmb28iKTsKKyAgICAgICAgICAgIGFvcy5wdXRBcmNoaXZlRW50cnkoaW4pOworICAgICAgICAgICAgZmluYWwgYnl0ZVtdIGIgPSBuZXcgYnl0ZVsoaW50KSB0bXBbMV0ubGVuZ3RoKCldOworICAgICAgICAgICAgZmlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbSh0bXBbMV0pOworICAgICAgICAgICAgd2hpbGUgKGZpcy5yZWFkKGIpID4gMCkgeworICAgICAgICAgICAgICAgIGFvcy53cml0ZShiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZpcy5jbG9zZSgpOworICAgICAgICAgICAgZmlzID0gbnVsbDsKKyAgICAgICAgICAgIGFvcy5jbG9zZUFyY2hpdmVFbnRyeSgpOworICAgICAgICAgICAgYW9zLmNsb3NlKCk7CisgICAgICAgICAgICBhb3MgPSBudWxsOworICAgICAgICAgICAgYWlzID0gbmV3IEFyQXJjaGl2ZUlucHV0U3RyZWFtKG5ldyBGaWxlSW5wdXRTdHJlYW0oYXJjaGl2ZSkpOworICAgICAgICAgICAgZmluYWwgQXJBcmNoaXZlRW50cnkgb3V0ID0gYWlzLmdldE5leHRBckVudHJ5KCk7CisgICAgICAgICAgICBhaXMuY2xvc2UoKTsKKyAgICAgICAgICAgIGFpcyA9IG51bGw7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKG91dCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImZvbyIsIG91dC5nZXROYW1lKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHRtcFsxXS5sZW5ndGgoKSwgb3V0LmdldFNpemUoKSk7CisgICAgICAgICAgICAvLyBBUiBzdG9yZXMgdGltZSB3aXRoIGEgZ3JhbnVsYXJpdHkgb2YgMSBzZWNvbmQKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyh0bXBbMV0ubGFzdE1vZGlmaWVkKCkgLyAxMDAwLAorICAgICAgICAgICAgICAgICAgICAgICAgIG91dC5nZXRMYXN0TW9kaWZpZWREYXRlKCkuZ2V0VGltZSgpIC8gMTAwMCk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShvdXQuaXNEaXJlY3RvcnkoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAoYWlzICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBhaXMuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChhb3MgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGFvcy5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdHJ5SGFyZFRvRGVsZXRlKGFyY2hpdmUpOworICAgICAgICAgICAgaWYgKGZpcyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgZmlzLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnlIYXJkVG9EZWxldGUodG1wWzFdKTsKKyAgICAgICAgICAgIHJtZGlyKHRtcFswXSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RFeHBsaWNpdEZpbGVFbnRyeSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlW10gdG1wID0gY3JlYXRlVGVtcERpckFuZEZpbGUoKTsKKyAgICAgICAgRmlsZSBhcmNoaXZlID0gbnVsbDsKKyAgICAgICAgQXJBcmNoaXZlT3V0cHV0U3RyZWFtIGFvcyA9IG51bGw7CisgICAgICAgIEFyQXJjaGl2ZUlucHV0U3RyZWFtIGFpcyA9IG51bGw7CisgICAgICAgIEZpbGVJbnB1dFN0cmVhbSBmaXMgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXJjaGl2ZSA9IEZpbGUuY3JlYXRlVGVtcEZpbGUoInRlc3QuIiwgIi5hciIsIHRtcFswXSk7CisgICAgICAgICAgICBhcmNoaXZlLmRlbGV0ZU9uRXhpdCgpOworICAgICAgICAgICAgYW9zID0gbmV3IEFyQXJjaGl2ZU91dHB1dFN0cmVhbShuZXcgRmlsZU91dHB1dFN0cmVhbShhcmNoaXZlKSk7CisgICAgICAgICAgICBmaW5hbCBBckFyY2hpdmVFbnRyeSBpbiA9IG5ldyBBckFyY2hpdmVFbnRyeSgiZm9vIiwgdG1wWzFdLmxlbmd0aCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRtcFsxXS5sYXN0TW9kaWZpZWQoKSAvIDEwMDApOworICAgICAgICAgICAgYW9zLnB1dEFyY2hpdmVFbnRyeShpbik7CisgICAgICAgICAgICBmaW5hbCBieXRlW10gYiA9IG5ldyBieXRlWyhpbnQpIHRtcFsxXS5sZW5ndGgoKV07CisgICAgICAgICAgICBmaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKHRtcFsxXSk7CisgICAgICAgICAgICB3aGlsZSAoZmlzLnJlYWQoYikgPiAwKSB7CisgICAgICAgICAgICAgICAgYW9zLndyaXRlKGIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZmlzLmNsb3NlKCk7CisgICAgICAgICAgICBmaXMgPSBudWxsOworICAgICAgICAgICAgYW9zLmNsb3NlQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgICAgICBhb3MuY2xvc2UoKTsKKyAgICAgICAgICAgIGFvcyA9IG51bGw7CisgICAgICAgICAgICBhaXMgPSBuZXcgQXJBcmNoaXZlSW5wdXRTdHJlYW0obmV3IEZpbGVJbnB1dFN0cmVhbShhcmNoaXZlKSk7CisgICAgICAgICAgICBmaW5hbCBBckFyY2hpdmVFbnRyeSBvdXQgPSBhaXMuZ2V0TmV4dEFyRW50cnkoKTsKKyAgICAgICAgICAgIGFpcy5jbG9zZSgpOworICAgICAgICAgICAgYWlzID0gbnVsbDsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwob3V0KTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZm9vIiwgb3V0LmdldE5hbWUoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHModG1wWzFdLmxlbmd0aCgpLCBvdXQuZ2V0U2l6ZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyh0bXBbMV0ubGFzdE1vZGlmaWVkKCkgLyAxMDAwLAorICAgICAgICAgICAgICAgICAgICAgICAgIG91dC5nZXRMYXN0TW9kaWZpZWREYXRlKCkuZ2V0VGltZSgpIC8gMTAwMCk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShvdXQuaXNEaXJlY3RvcnkoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAoYWlzICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBhaXMuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChhb3MgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGFvcy5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdHJ5SGFyZFRvRGVsZXRlKGFyY2hpdmUpOworICAgICAgICAgICAgaWYgKGZpcyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgZmlzLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnlIYXJkVG9EZWxldGUodG1wWzFdKTsKKyAgICAgICAgICAgIHJtZGlyKHRtcFswXSk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvQXJjaGl2ZU91dHB1dFN0cmVhbVRlc3QuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9BcmNoaXZlT3V0cHV0U3RyZWFtVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBlZDg3OGIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvQXJjaGl2ZU91dHB1dFN0cmVhbVRlc3QuamF2YQpAQCAtMCwwICsxLDIwOCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnM7CisKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC4qOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5BYnN0cmFjdFRlc3RDYXNlOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuYXIuQXJBcmNoaXZlRW50cnk7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5jcGlvLkNwaW9BcmNoaXZlRW50cnk7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5qYXIuSmFyQXJjaGl2ZUVudHJ5OworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMudGFyLlRhckFyY2hpdmVFbnRyeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcC5aaXBBcmNoaXZlRW50cnk7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLklPVXRpbHM7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CisKK3B1YmxpYyBjbGFzcyBBcmNoaXZlT3V0cHV0U3RyZWFtVGVzdCBleHRlbmRzIEFic3RyYWN0VGVzdENhc2UgeworCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RmluaXNoKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIE91dHB1dFN0cmVhbSBvdXQxID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworCisgICAgICAgIEFyY2hpdmVPdXRwdXRTdHJlYW0gYW9zMSA9IGZhY3RvcnkuY3JlYXRlQXJjaGl2ZU91dHB1dFN0cmVhbSgiemlwIiwgb3V0MSk7CisgICAgICAgIGFvczEucHV0QXJjaGl2ZUVudHJ5KG5ldyBaaXBBcmNoaXZlRW50cnkoImR1bW15IikpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYW9zMS5maW5pc2goKTsKKyAgICAgICAgICAgIGZhaWwoIkFmdGVyIHB1dEFyY2hpdmUgc2hvdWxkIGZvbGxvdyBjbG9zZUFyY2hpdmUiKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgSU9FeGNlcHRpb24gaW8pIHsKKyAgICAgICAgICAgIC8vIEV4Y2VwdGlvbiBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgYW9zMSA9IGZhY3RvcnkuY3JlYXRlQXJjaGl2ZU91dHB1dFN0cmVhbSgiamFyIiwgb3V0MSk7CisgICAgICAgIGFvczEucHV0QXJjaGl2ZUVudHJ5KG5ldyBKYXJBcmNoaXZlRW50cnkoImR1bW15IikpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYW9zMS5maW5pc2goKTsKKyAgICAgICAgICAgIGZhaWwoIkFmdGVyIHB1dEFyY2hpdmUgc2hvdWxkIGZvbGxvdyBjbG9zZUFyY2hpdmUiKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgSU9FeGNlcHRpb24gaW8pIHsKKyAgICAgICAgICAgIC8vIEV4Y2VwdGlvbiBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgYW9zMSA9IGZhY3RvcnkuY3JlYXRlQXJjaGl2ZU91dHB1dFN0cmVhbSgiYXIiLCBvdXQxKTsKKyAgICAgICAgYW9zMS5wdXRBcmNoaXZlRW50cnkobmV3IEFyQXJjaGl2ZUVudHJ5KCJkdW1teSIsIDEwMCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYW9zMS5maW5pc2goKTsKKyAgICAgICAgICAgIGZhaWwoIkFmdGVyIHB1dEFyY2hpdmUgc2hvdWxkIGZvbGxvdyBjbG9zZUFyY2hpdmUiKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgSU9FeGNlcHRpb24gaW8pIHsKKyAgICAgICAgICAgIC8vIEV4Y2VwdGlvbiBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgYW9zMSA9IGZhY3RvcnkuY3JlYXRlQXJjaGl2ZU91dHB1dFN0cmVhbSgiY3BpbyIsIG91dDEpOworICAgICAgICBhb3MxLnB1dEFyY2hpdmVFbnRyeShuZXcgQ3Bpb0FyY2hpdmVFbnRyeSgiZHVtbXkiKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhb3MxLmZpbmlzaCgpOworICAgICAgICAgICAgZmFpbCgiQWZ0ZXIgcHV0QXJjaGl2ZSBzaG91bGQgZm9sbG93IGNsb3NlQXJjaGl2ZSIpOworICAgICAgICB9IGNhdGNoIChmaW5hbCBJT0V4Y2VwdGlvbiBpbykgeworICAgICAgICAgICAgLy8gRXhjZXB0aW9uIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBhb3MxID0gZmFjdG9yeS5jcmVhdGVBcmNoaXZlT3V0cHV0U3RyZWFtKCJ0YXIiLCBvdXQxKTsKKyAgICAgICAgYW9zMS5wdXRBcmNoaXZlRW50cnkobmV3IFRhckFyY2hpdmVFbnRyeSgiZHVtbXkiKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhb3MxLmZpbmlzaCgpOworICAgICAgICAgICAgZmFpbCgiQWZ0ZXIgcHV0QXJjaGl2ZSBzaG91bGQgZm9sbG93IGNsb3NlQXJjaGl2ZSIpOworICAgICAgICB9IGNhdGNoIChmaW5hbCBJT0V4Y2VwdGlvbiBpbykgeworICAgICAgICAgICAgLy8gRXhjZXB0aW9uIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RPcHRpb25hbEZpbmlzaCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBPdXRwdXRTdHJlYW0gb3V0MSA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKworICAgICAgICB0cnkgKEFyY2hpdmVPdXRwdXRTdHJlYW0gYW9zMSA9IGZhY3RvcnkuY3JlYXRlQXJjaGl2ZU91dHB1dFN0cmVhbSgiemlwIiwgb3V0MSkpIHsKKyAgICAgICAgICAgIGFvczEucHV0QXJjaGl2ZUVudHJ5KG5ldyBaaXBBcmNoaXZlRW50cnkoImR1bW15IikpOworICAgICAgICAgICAgYW9zMS5jbG9zZUFyY2hpdmVFbnRyeSgpOworICAgICAgICB9CisKKyAgICAgICAgZmluYWwgQXJjaGl2ZU91dHB1dFN0cmVhbSBmaW5pc2hUZXN0OworICAgICAgICB0cnkgKEFyY2hpdmVPdXRwdXRTdHJlYW0gYW9zMSA9IGZhY3RvcnkuY3JlYXRlQXJjaGl2ZU91dHB1dFN0cmVhbSgiamFyIiwgb3V0MSkpIHsKKyAgICAgICAgICAgIGZpbmlzaFRlc3QgPSBhb3MxOworICAgICAgICAgICAgYW9zMS5wdXRBcmNoaXZlRW50cnkobmV3IEphckFyY2hpdmVFbnRyeSgiZHVtbXkiKSk7CisgICAgICAgICAgICBhb3MxLmNsb3NlQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZpbmlzaFRlc3QuZmluaXNoKCk7CisgICAgICAgICAgICBmYWlsKCJmaW5pc2goKSBjYW5ub3QgZm9sbG93IGNsb3NlKCkiKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgSU9FeGNlcHRpb24gaW8pIHsKKyAgICAgICAgICAgIC8vIEV4Y2VwdGlvbiBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIGZpbmlzaFRlc3QuY2xvc2UoKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RDYWxsU2VxdWVuY2VBcigpIHRocm93cyBFeGNlcHRpb257CisgICAgICAgIGRvQ2FsbFNlcXVlbmNlKCJBciIpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdENhbGxTZXF1ZW5jZUNwaW8oKSB0aHJvd3MgRXhjZXB0aW9ueworICAgICAgICBkb0NhbGxTZXF1ZW5jZSgiQ3BpbyIpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdENhbGxTZXF1ZW5jZUphcigpIHRocm93cyBFeGNlcHRpb257CisgICAgICAgIGRvQ2FsbFNlcXVlbmNlKCJKYXIiKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RDYWxsU2VxdWVuY2VUYXIoKSB0aHJvd3MgRXhjZXB0aW9ueworICAgICAgICBkb0NhbGxTZXF1ZW5jZSgiVGFyIik7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2FsbFNlcXVlbmNlWmlwKCkgdGhyb3dzIEV4Y2VwdGlvbnsKKyAgICAgICAgZG9DYWxsU2VxdWVuY2UoIlppcCIpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBkb0NhbGxTZXF1ZW5jZShmaW5hbCBTdHJpbmcgYXJjaGl2ZVR5cGUpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBPdXRwdXRTdHJlYW0gb3V0MSA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgZmluYWwgRmlsZSBkdW1teSA9IGdldEZpbGUoInRlc3QxLnhtbCIpOyAvLyBuZWVkIGEgcmVhbCBmaWxlCisKKyAgICAgICAgQXJjaGl2ZU91dHB1dFN0cmVhbSBhb3MxOworICAgICAgICBhb3MxID0gZmFjdG9yeS5jcmVhdGVBcmNoaXZlT3V0cHV0U3RyZWFtKGFyY2hpdmVUeXBlLCBvdXQxKTsKKyAgICAgICAgYW9zMS5wdXRBcmNoaXZlRW50cnkoYW9zMS5jcmVhdGVBcmNoaXZlRW50cnkoZHVtbXksICJkdW1teSIpKTsKKyAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oZHVtbXkpKSB7CisgICAgICAgICAgICBJT1V0aWxzLmNvcHkoaXMsIGFvczEpOworICAgICAgICB9CisgICAgICAgIGFvczEuY2xvc2VBcmNoaXZlRW50cnkoKTsKKyAgICAgICAgYW9zMS5jbG9zZSgpOyAvLyBvbWl0dGVkIGZpbmlzaAorCisgICAgICAgIC8vIFRPRE8gLSBjaGVjayBpZiBhcmNoaXZlcyBlbnN1cmUgdGhhdCBkYXRhIGhhcyBiZWVuIHdyaXR0ZW4gdG8gdGhlIHN0cmVhbT8KKworICAgICAgICBhb3MxID0gZmFjdG9yeS5jcmVhdGVBcmNoaXZlT3V0cHV0U3RyZWFtKGFyY2hpdmVUeXBlLCBvdXQxKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFvczEuY2xvc2VBcmNoaXZlRW50cnkoKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCBoYXZlIHJhaXNlZCBJT0V4Y2VwdGlvbiAtIGNsb3NlQXJjaGl2ZUVudHJ5KCkgY2FsbGVkIGJlZm9yZSBwdXRBcmNoaXZlRW50cnkoKSIpOworICAgICAgICB9IGNhdGNoIChmaW5hbCBJT0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgYW9zMS5wdXRBcmNoaXZlRW50cnkoYW9zMS5jcmVhdGVBcmNoaXZlRW50cnkoZHVtbXksICJkdW1teSIpKTsKKyAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oZHVtbXkpKSB7CisgICAgICAgICAgICBJT1V0aWxzLmNvcHkoaXMsIGFvczEpOworICAgICAgICB9CisKKyAgICAgICAgLy8gVE9ETyBjaGVjayBpZiBzZWNvbmQgcHV0QXJjaGl2ZUVudHJ5KCkgY2FuIGZvbGxvdyB3aXRob3V0IGNsb3NlQUU/CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFvczEuZmluaXNoKCk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgaGF2ZSByYWlzZWQgSU9FeGNlcHRpb24gLSBmaW5pc2goKSBjYWxsZWQgYmVmb3JlIGNsb3NlQXJjaGl2ZUVudHJ5KCkiKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgSU9FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgYW9zMS5jbG9zZSgpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIGhhdmUgcmFpc2VkIElPRXhjZXB0aW9uIC0gY2xvc2UoKSBjYWxsZWQgYmVmb3JlIGNsb3NlQXJjaGl2ZUVudHJ5KCkiKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgSU9FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIGFvczEgPSBjcmVhdGVBcmNoaXZlV2l0aER1bW15RW50cnkoYXJjaGl2ZVR5cGUsIG91dDEsIGR1bW15KTsKKyAgICAgICAgYW9zMS5jbG9zZUFyY2hpdmVFbnRyeSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYW9zMS5jbG9zZUFyY2hpdmVFbnRyeSgpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIGhhdmUgcmFpc2VkIElPRXhjZXB0aW9uIC0gY2xvc2VBcmNoaXZlRW50cnkoKSBjYWxsZWQgd2l0aCBubyBvcGVuIGVudHJ5Iik7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIElPRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBhb3MxID0gY3JlYXRlQXJjaGl2ZVdpdGhEdW1teUVudHJ5KGFyY2hpdmVUeXBlLCBvdXQxLCBkdW1teSk7CisgICAgICAgIGFvczEuY2xvc2VBcmNoaXZlRW50cnkoKTsKKyAgICAgICAgYW9zMS5maW5pc2goKTsKKyAgICAgICAgYW9zMS5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYW9zMS5maW5pc2goKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCBoYXZlIHJhaXNlZCBJT0V4Y2VwdGlvbiAtIGZpbmlzaCgpIGNhbGxlZCBhZnRlciBjbG9zZSgpIik7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIElPRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIEFyY2hpdmVPdXRwdXRTdHJlYW0gY3JlYXRlQXJjaGl2ZVdpdGhEdW1teUVudHJ5KFN0cmluZyBhcmNoaXZlVHlwZSwgT3V0cHV0U3RyZWFtIG91dDEsIEZpbGUgZHVtbXkpCisgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBBcmNoaXZlT3V0cHV0U3RyZWFtIGFvczEgPSBmYWN0b3J5LmNyZWF0ZUFyY2hpdmVPdXRwdXRTdHJlYW0oYXJjaGl2ZVR5cGUsIG91dDEpOworICAgICAgICBhb3MxLnB1dEFyY2hpdmVFbnRyeShhb3MxLmNyZWF0ZUFyY2hpdmVFbnRyeShkdW1teSwgImR1bW15IikpOworICAgICAgICB0cnkgKElucHV0U3RyZWFtIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShkdW1teSkpIHsKKyAgICAgICAgICAgIElPVXRpbHMuY29weShpcywgYW9zMSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGFvczE7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL0FyY2hpdmVTZXJ2aWNlTG9hZGVyVGVzdC5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL0FyY2hpdmVTZXJ2aWNlTG9hZGVyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkxMDc5N2QKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvQXJjaGl2ZVNlcnZpY2VMb2FkZXJUZXN0LmphdmEKQEAgLTAsMCArMSw0MCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVyczsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLlRlc3RBcmNoaXZlU3RyZWFtUHJvdmlkZXIuQXJjaGl2ZUludm9jYXRpb25Db25maXJtYXRpb25FeGNlcHRpb247CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CisKK3B1YmxpYyBjbGFzcyBBcmNoaXZlU2VydmljZUxvYWRlclRlc3QgeworCisgICAgQFRlc3QoZXhwZWN0ZWQgPSBBcmNoaXZlSW52b2NhdGlvbkNvbmZpcm1hdGlvbkV4Y2VwdGlvbi5jbGFzcykKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW5wdXRTdHJlYW0oKSB0aHJvd3MgQXJjaGl2ZUV4Y2VwdGlvbiB7CisgICAgICAgIG5ldyBBcmNoaXZlU3RyZWFtRmFjdG9yeSgpLmNyZWF0ZUFyY2hpdmVJbnB1dFN0cmVhbSgiQXJjaGl2ZVRlc3RJbnB1dDEiLCBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0obmV3IGJ5dGVbXSB7fSkpOworICAgIH0KKworICAgIEBUZXN0KGV4cGVjdGVkID0gQXJjaGl2ZUludm9jYXRpb25Db25maXJtYXRpb25FeGNlcHRpb24uY2xhc3MpCisgICAgcHVibGljIHZvaWQgdGVzdE91dHB1dFN0cmVhbSgpIHRocm93cyBBcmNoaXZlRXhjZXB0aW9uIHsKKyAgICAgICAgbmV3IEFyY2hpdmVTdHJlYW1GYWN0b3J5KCkuY3JlYXRlQXJjaGl2ZU91dHB1dFN0cmVhbSgiQXJjaGl2ZVRlc3RPdXRwdXQxIiwgbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9BcmNoaXZlU3RyZWFtRmFjdG9yeVRlc3QuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9BcmNoaXZlU3RyZWFtRmFjdG9yeVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNzExM2FjCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL0FyY2hpdmVTdHJlYW1GYWN0b3J5VGVzdC5qYXZhCkBAIC0wLDAgKzEsNDMzIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVyczsKKworaW1wb3J0IHN0YXRpYyBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuQWJzdHJhY3RUZXN0Q2FzZS5nZXRGaWxlOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEVxdWFsczsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnROdWxsOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydFRydWU7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuZmFpbDsKKworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZDsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5Nb2NrRXZpbElucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuYXJqLkFyakFyY2hpdmVJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLmNwaW8uQ3Bpb0FyY2hpdmVJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLmR1bXAuRHVtcEFyY2hpdmVJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLmphci5KYXJBcmNoaXZlSW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy50YXIuVGFyQXJjaGl2ZUlucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwLlppcEFyY2hpdmVJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworcHVibGljIGNsYXNzIEFyY2hpdmVTdHJlYW1GYWN0b3J5VGVzdCB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVU5LTk9XTiA9ICI/PyI7CisKKyAgICAvKioKKyAgICAgKiBzZWUgaHR0cHM6Ly9pc3N1ZXMuYXBhY2hlLm9yZy9qaXJhL2Jyb3dzZS9DT01QUkVTUy0xNzEKKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHNob3J0VGV4dEZpbGVzQXJlTm9UQVJzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgQXJjaGl2ZVN0cmVhbUZhY3RvcnkoKQorICAgICAgICAgICAgICAgIC5jcmVhdGVBcmNoaXZlSW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKCJUaGlzIGNlcnRhaW5seSBpcyBub3QgYSB0YXIgYXJjaGl2ZSwgcmVhbGx5LCBubyBraWRkaW5nIi5nZXRCeXRlcygpKSk7CisgICAgICAgICAgICBmYWlsKCJjcmVhdGVkIGFuIGlucHV0IHN0cmVhbSBmb3IgYSBub24tYXJjaGl2ZSIpOworICAgICAgICB9IGNhdGNoIChmaW5hbCBBcmNoaXZlRXhjZXB0aW9uIGFlKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKGFlLmdldE1lc3NhZ2UoKS5zdGFydHNXaXRoKCJObyBBcmNoaXZlciBmb3VuZCIpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIHNlZSBodHRwczovL2lzc3Vlcy5hcGFjaGUub3JnL2ppcmEvYnJvd3NlL0NPTVBSRVNTLTE5MQorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgYWlmZkZpbGVzQXJlTm9UQVJzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSAoRmlsZUlucHV0U3RyZWFtIGZpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oInNyYy90ZXN0L3Jlc291cmNlcy90ZXN0QUlGRi5haWYiKSkgeworICAgICAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBpcyA9IG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKGZpcykpIHsKKyAgICAgICAgICAgICAgICBuZXcgQXJjaGl2ZVN0cmVhbUZhY3RvcnkoKS5jcmVhdGVBcmNoaXZlSW5wdXRTdHJlYW0oaXMpOworICAgICAgICAgICAgICAgIGZhaWwoImNyZWF0ZWQgYW4gaW5wdXQgc3RyZWFtIGZvciBhIG5vbi1hcmNoaXZlIik7CisgICAgICAgICAgICB9IGNhdGNoIChmaW5hbCBBcmNoaXZlRXhjZXB0aW9uIGFlKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZShhZS5nZXRNZXNzYWdlKCkuc3RhcnRzV2l0aCgiTm8gQXJjaGl2ZXIgZm91bmQiKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RDT01QUkVTUzIwOSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgKEZpbGVJbnB1dFN0cmVhbSBmaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKCJzcmMvdGVzdC9yZXNvdXJjZXMvdGVzdENvbXByZXNzMjA5LmRvYyIpKSB7CisgICAgICAgICAgICB0cnkgKElucHV0U3RyZWFtIGJpcyA9IG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKGZpcykpIHsKKyAgICAgICAgICAgICAgICBuZXcgQXJjaGl2ZVN0cmVhbUZhY3RvcnkoKS5jcmVhdGVBcmNoaXZlSW5wdXRTdHJlYW0oYmlzKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJjcmVhdGVkIGFuIGlucHV0IHN0cmVhbSBmb3IgYSBub24tYXJjaGl2ZSIpOworICAgICAgICAgICAgfSBjYXRjaCAoZmluYWwgQXJjaGl2ZUV4Y2VwdGlvbiBhZSkgeworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoYWUuZ2V0TWVzc2FnZSgpLnN0YXJ0c1dpdGgoIk5vIEFyY2hpdmVyIGZvdW5kIikpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QoZXhwZWN0ZWQgPSBTdHJlYW1pbmdOb3RTdXBwb3J0ZWRFeGNlcHRpb24uY2xhc3MpCisgICAgcHVibGljIHZvaWQgY2FudFJlYWQ3ekZyb21TdHJlYW0oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgbmV3IEFyY2hpdmVTdHJlYW1GYWN0b3J5KCkKKyAgICAgICAgICAgIC5jcmVhdGVBcmNoaXZlSW5wdXRTdHJlYW0oQXJjaGl2ZVN0cmVhbUZhY3RvcnkuU0VWRU5fWiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKG5ldyBieXRlWzBdKSk7CisgICAgfQorCisgICAgQFRlc3QoZXhwZWN0ZWQgPSBTdHJlYW1pbmdOb3RTdXBwb3J0ZWRFeGNlcHRpb24uY2xhc3MpCisgICAgcHVibGljIHZvaWQgY2FudFdyaXRlN3pUb1N0cmVhbSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBuZXcgQXJjaGl2ZVN0cmVhbUZhY3RvcnkoKQorICAgICAgICAgICAgLmNyZWF0ZUFyY2hpdmVPdXRwdXRTdHJlYW0oQXJjaGl2ZVN0cmVhbUZhY3RvcnkuU0VWRU5fWiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBjYXNlIGZvcgorICAgICAqIDxhIGhyZWY9Imh0dHBzOi8vaXNzdWVzLmFwYWNoZS5vcmcvamlyYS9icm93c2UvQ09NUFJFU1MtMjY3IgorICAgICAqID5DT01QUkVTUy0yNjc8L2E+LgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgZGV0ZWN0c0FuZFRocm93c0Zvcjd6KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSAoRmlsZUlucHV0U3RyZWFtIGZpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oInNyYy90ZXN0L3Jlc291cmNlcy9ibGEuN3oiKSkgeworICAgICAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBiaXMgPSBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShmaXMpKSB7CisgICAgICAgICAgICAgICAgbmV3IEFyY2hpdmVTdHJlYW1GYWN0b3J5KCkuY3JlYXRlQXJjaGl2ZUlucHV0U3RyZWFtKGJpcyk7CisgICAgICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgYSBTdHJlYW1pbmdOb3RTdXBwb3J0ZWRFeGNlcHRpb24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKGZpbmFsIFN0cmVhbWluZ05vdFN1cHBvcnRlZEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhBcmNoaXZlU3RyZWFtRmFjdG9yeS5TRVZFTl9aLCBleC5nZXRGb3JtYXQoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGNhc2UgZm9yCisgICAgICogPGEgaHJlZj0iaHR0cHM6Ly9pc3N1ZXMuYXBhY2hlLm9yZy9qaXJhL2Jyb3dzZS9DT01QUkVTUy0yMDgiCisgICAgICogPkNPTVBSRVNTLTIwODwvYT4uCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBza2lwc1BLMDBQcmVmaXgoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IChGaWxlSW5wdXRTdHJlYW0gZmlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbSgic3JjL3Rlc3QvcmVzb3VyY2VzL0NPTVBSRVNTLTIwOC56aXAiKSkgeworICAgICAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBiaXMgPSBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShmaXMpKSB7CisgICAgICAgICAgICAgICAgdHJ5IChBcmNoaXZlSW5wdXRTdHJlYW0gYWlzID0gbmV3IEFyY2hpdmVTdHJlYW1GYWN0b3J5KCkuY3JlYXRlQXJjaGl2ZUlucHV0U3RyZWFtKGJpcykpIHsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZShhaXMgaW5zdGFuY2VvZiBaaXBBcmNoaXZlSW5wdXRTdHJlYW0pOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEVuY29kaW5nQ3RvcigpIHsKKyAgICAgICAgQXJjaGl2ZVN0cmVhbUZhY3RvcnkgZmFjID0gbmV3IEFyY2hpdmVTdHJlYW1GYWN0b3J5KCk7CisgICAgICAgIGFzc2VydE51bGwoZmFjLmdldEVudHJ5RW5jb2RpbmcoKSk7CisgICAgICAgIGZhYyA9IG5ldyBBcmNoaXZlU3RyZWFtRmFjdG9yeShudWxsKTsKKyAgICAgICAgYXNzZXJ0TnVsbChmYWMuZ2V0RW50cnlFbmNvZGluZygpKTsKKyAgICAgICAgZmFjID0gbmV3IEFyY2hpdmVTdHJlYW1GYWN0b3J5KCJVVEYtOCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlVURi04IiwgZmFjLmdldEVudHJ5RW5jb2RpbmcoKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKQorICAgIHB1YmxpYyB2b2lkIHRlc3RFbmNvZGluZ0RlcHJlY2F0ZWQoKSB7CisgICAgICAgIEFyY2hpdmVTdHJlYW1GYWN0b3J5IGZhYyA9IG5ldyBBcmNoaXZlU3RyZWFtRmFjdG9yeSgpOworICAgICAgICBhc3NlcnROdWxsKGZhYy5nZXRFbnRyeUVuY29kaW5nKCkpOworICAgICAgICBmYWMuc2V0RW50cnlFbmNvZGluZygiVVRGLTgiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJVVEYtOCIsIGZhYy5nZXRFbnRyeUVuY29kaW5nKCkpOworICAgICAgICBmYWMuc2V0RW50cnlFbmNvZGluZygiVVNfQVNDSUkiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJVU19BU0NJSSIsIGZhYy5nZXRFbnRyeUVuY29kaW5nKCkpOworICAgICAgICBmYWMgPSBuZXcgQXJjaGl2ZVN0cmVhbUZhY3RvcnkoIlVURi04Iik7CisgICAgICAgIGFzc2VydEVxdWFscygiVVRGLTgiLCBmYWMuZ2V0RW50cnlFbmNvZGluZygpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZhYy5zZXRFbnRyeUVuY29kaW5nKCJVU19BU0NJSSIpOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpc2UpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBzdGF0aWMgY2xhc3MgVGVzdERhdGEgeworICAgICAgICBmaW5hbCBTdHJpbmcgdGVzdEZpbGU7CisgICAgICAgIGZpbmFsIFN0cmluZyBleHBlY3RlZEVuY29kaW5nOworICAgICAgICBmaW5hbCBBcmNoaXZlU3RyZWFtRmFjdG9yeSBmYWM7CisgICAgICAgIGZpbmFsIFN0cmluZyBmaWVsZE5hbWU7CisgICAgICAgIGZpbmFsIFN0cmluZyB0eXBlOworICAgICAgICBmaW5hbCBib29sZWFuIGhhc091dHB1dFN0cmVhbTsKKworICAgICAgICBUZXN0RGF0YShmaW5hbCBTdHJpbmcgdGVzdEZpbGUsIGZpbmFsIFN0cmluZyB0eXBlLCBmaW5hbCBib29sZWFuIGhhc091dCwgZmluYWwgU3RyaW5nIGV4cGVjdGVkRW5jb2RpbmcsIGZpbmFsIEFyY2hpdmVTdHJlYW1GYWN0b3J5IGZhYywgZmluYWwgU3RyaW5nIGZpZWxkTmFtZSkgeworICAgICAgICAgICAgdGhpcy50ZXN0RmlsZSA9IHRlc3RGaWxlOworICAgICAgICAgICAgdGhpcy5leHBlY3RlZEVuY29kaW5nID0gZXhwZWN0ZWRFbmNvZGluZzsKKyAgICAgICAgICAgIHRoaXMuZmFjID0gZmFjOworICAgICAgICAgICAgdGhpcy5maWVsZE5hbWUgPSBmaWVsZE5hbWU7CisgICAgICAgICAgICB0aGlzLnR5cGUgPSB0eXBlOworICAgICAgICAgICAgdGhpcy5oYXNPdXRwdXRTdHJlYW0gPSBoYXNPdXQ7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgICAgIHJldHVybiAiVGVzdERhdGEgW3Rlc3RGaWxlPSIgKyB0ZXN0RmlsZSArICIsIGV4cGVjdGVkRW5jb2Rpbmc9IiArIGV4cGVjdGVkRW5jb2RpbmcgKyAiLCBmYWM9IiArIGZhYworICAgICAgICAgICAgICAgICAgICArICIsIGZpZWxkTmFtZT0iICsgZmllbGROYW1lICsgIiwgdHlwZT0iICsgdHlwZSArICIsIGhhc091dHB1dFN0cmVhbT0iICsgaGFzT3V0cHV0U3RyZWFtICsgIl0iOworICAgICAgICB9CisgICAgfQorCisgICAgQFN1cHByZXNzV2FybmluZ3MoImRlcHJlY2F0aW9uIikgLy8gdGVzdCBvZiBkZXByZWNhdGVkIG1ldGhvZAorICAgIHN0YXRpYyBBcmNoaXZlU3RyZWFtRmFjdG9yeSBnZXRGYWN0b3J5KGZpbmFsIFN0cmluZyBlbnRyeUVuY29kaW5nKSB7CisgICAgICAgIGZpbmFsIEFyY2hpdmVTdHJlYW1GYWN0b3J5IGZhYyA9IG5ldyBBcmNoaXZlU3RyZWFtRmFjdG9yeSgpOworICAgICAgICBmYWMuc2V0RW50cnlFbmNvZGluZyhlbnRyeUVuY29kaW5nKTsKKyAgICAgICAgcmV0dXJuIGZhYzsKKyAgICB9CisgICAgLy8gVGhlIGRpZmZlcmVudCBmYWN0b3J5IHR5cGVzCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQXJjaGl2ZVN0cmVhbUZhY3RvcnkgRkFDVE9SWSA9IG5ldyBBcmNoaXZlU3RyZWFtRmFjdG9yeSgpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEFyY2hpdmVTdHJlYW1GYWN0b3J5IEZBQ1RPUllfVVRGOCA9IG5ldyBBcmNoaXZlU3RyZWFtRmFjdG9yeSgiVVRGLTgiKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBBcmNoaXZlU3RyZWFtRmFjdG9yeSBGQUNUT1JZX0FTQ0lJID0gbmV3IEFyY2hpdmVTdHJlYW1GYWN0b3J5KCJBU0NJSSIpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEFyY2hpdmVTdHJlYW1GYWN0b3J5IEZBQ1RPUllfU0VUX1VURjggPSBnZXRGYWN0b3J5KCJVVEYtOCIpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEFyY2hpdmVTdHJlYW1GYWN0b3J5IEZBQ1RPUllfU0VUX0FTQ0lJID0gZ2V0RmFjdG9yeSgiQVNDSUkiKTsKKworICAgIC8vIERlZmF1bHQgZW5jb2RpbmcgaWYgbm9uZSBpcyBwcm92aWRlZCAobm90IGV2ZW4gbnVsbCkKKyAgICAvLyBUaGUgdGVzdCBjdXJyZW50bHkgYXNzdW1lcyB0aGF0IHRoZSBvdXRwdXQgZGVmYXVsdCBpcyB0aGUgc2FtZSBhcyB0aGUgaW5wdXQgZGVmYXVsdAorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBBUkpfREVGQVVMVDsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRFVNUF9ERUZBVUxUOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFpJUF9ERUZBVUxUID0gZ2V0RmllbGQobmV3IFppcEFyY2hpdmVJbnB1dFN0cmVhbShudWxsKSwiZW5jb2RpbmciKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ1BJT19ERUZBVUxUID0gZ2V0RmllbGQobmV3IENwaW9BcmNoaXZlSW5wdXRTdHJlYW0obnVsbCksImVuY29kaW5nIik7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRBUl9ERUZBVUxUID0gZ2V0RmllbGQobmV3IFRhckFyY2hpdmVJbnB1dFN0cmVhbShudWxsKSwiZW5jb2RpbmciKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgSkFSX0RFRkFVTFQgPSBnZXRGaWVsZChuZXcgSmFyQXJjaGl2ZUlucHV0U3RyZWFtKG51bGwpLCJlbmNvZGluZyIpOworCisgICAgc3RhdGljIHsKKyAgICAgICAgU3RyaW5nIGRmbHQ7CisgICAgICAgIGRmbHQgPSBVTktOT1dOOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZGZsdCA9IGdldEZpZWxkKG5ldyBBcmpBcmNoaXZlSW5wdXRTdHJlYW0obmV3IEZpbGVJbnB1dFN0cmVhbShnZXRGaWxlKCJibGEuYXJqIikpKSwgImNoYXJzZXROYW1lIik7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICB9CisgICAgICAgIEFSSl9ERUZBVUxUID0gZGZsdDsKKyAgICAgICAgZGZsdCA9IFVOS05PV047CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkZmx0ID0gZ2V0RmllbGQobmV3IER1bXBBcmNoaXZlSW5wdXRTdHJlYW0obmV3IEZpbGVJbnB1dFN0cmVhbShnZXRGaWxlKCJibGEuZHVtcCIpKSksICJlbmNvZGluZyIpOworICAgICAgICB9IGNhdGNoIChmaW5hbCBFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgfQorICAgICAgICBEVU1QX0RFRkFVTFQgPSBkZmx0OworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdERldGVjdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmb3IgKFN0cmluZyBleHRlbnNpb24gOiBuZXcgU3RyaW5nW117CisgICAgICAgICAgICAgICAgQXJjaGl2ZVN0cmVhbUZhY3RvcnkuQVIsCisgICAgICAgICAgICAgICAgQXJjaGl2ZVN0cmVhbUZhY3RvcnkuQVJKLAorICAgICAgICAgICAgICAgIEFyY2hpdmVTdHJlYW1GYWN0b3J5LkNQSU8sCisgICAgICAgICAgICAgICAgQXJjaGl2ZVN0cmVhbUZhY3RvcnkuRFVNUCwKKyAgICAgICAgICAgICAgICAvLyBDb21wcmVzcyBkb2Vzbid0IGtub3cgaG93IHRvIGRldGVjdCBKQVJzLCBzZWUgQ09NUFJFU1MtOTEKKyAvLyAgICAgICAgICAgICAgIEFyY2hpdmVTdHJlYW1GYWN0b3J5LkpBUiwKKyAgICAgICAgICAgICAgICBBcmNoaXZlU3RyZWFtRmFjdG9yeS5TRVZFTl9aLAorICAgICAgICAgICAgICAgIEFyY2hpdmVTdHJlYW1GYWN0b3J5LlRBUiwKKyAgICAgICAgICAgICAgICBBcmNoaXZlU3RyZWFtRmFjdG9yeS5aSVAKKyAgICAgICAgfSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGV4dGVuc2lvbiwgZGV0ZWN0KCJibGEuIitleHRlbnNpb24pKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBcmNoaXZlU3RyZWFtRmFjdG9yeS5kZXRlY3QobmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKG5ldyBieXRlWzBdKSkpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkbid0IGJlIGFibGUgdG8gZGV0ZWN0IGVtcHR5IHN0cmVhbSIpOworICAgICAgICB9IGNhdGNoIChBcmNoaXZlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiTm8gQXJjaGl2ZXIgZm91bmQgZm9yIHRoZSBzdHJlYW0gc2lnbmF0dXJlIiwgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEFyY2hpdmVTdHJlYW1GYWN0b3J5LmRldGVjdChudWxsKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZG4ndCBiZSBhYmxlIHRvIGRldGVjdCBudWxsIHN0cmVhbSIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJTdHJlYW0gbXVzdCBub3QgYmUgbnVsbC4iLCBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgQXJjaGl2ZVN0cmVhbUZhY3RvcnkuZGV0ZWN0KG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKG5ldyBNb2NrRXZpbElucHV0U3RyZWFtKCkpKTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIEFyY2hpdmVFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoQXJjaGl2ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIklPRXhjZXB0aW9uIHdoaWxlIHJlYWRpbmcgc2lnbmF0dXJlLiIsIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgU3RyaW5nIGRldGVjdChTdHJpbmcgcmVzb3VyY2UpIHRocm93cyBJT0V4Y2VwdGlvbiwgQXJjaGl2ZUV4Y2VwdGlvbiB7CisgICAgICAgIHRyeShJbnB1dFN0cmVhbSBpbiA9IG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKG5ldyBGaWxlSW5wdXRTdHJlYW0oCisgICAgICAgICAgICAgICAgZ2V0RmlsZShyZXNvdXJjZSkpKSkgeworICAgICAgICAgICAgcmV0dXJuIEFyY2hpdmVTdHJlYW1GYWN0b3J5LmRldGVjdChpbik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBzdGF0aWMgZmluYWwgVGVzdERhdGFbXSBURVNUUyA9IHsKKyAgICAgICAgbmV3IFRlc3REYXRhKCJibGEuYXJqIiwgQXJjaGl2ZVN0cmVhbUZhY3RvcnkuQVJKLCBmYWxzZSwgQVJKX0RFRkFVTFQsIEZBQ1RPUlksICJjaGFyc2V0TmFtZSIpLAorICAgICAgICBuZXcgVGVzdERhdGEoImJsYS5hcmoiLCBBcmNoaXZlU3RyZWFtRmFjdG9yeS5BUkosIGZhbHNlLCAiVVRGLTgiLCBGQUNUT1JZX1VURjgsICJjaGFyc2V0TmFtZSIpLAorICAgICAgICBuZXcgVGVzdERhdGEoImJsYS5hcmoiLCBBcmNoaXZlU3RyZWFtRmFjdG9yeS5BUkosIGZhbHNlLCAiQVNDSUkiLCBGQUNUT1JZX0FTQ0lJLCAiY2hhcnNldE5hbWUiKSwKKyAgICAgICAgbmV3IFRlc3REYXRhKCJibGEuYXJqIiwgQXJjaGl2ZVN0cmVhbUZhY3RvcnkuQVJKLCBmYWxzZSwgIlVURi04IiwgRkFDVE9SWV9TRVRfVVRGOCwgImNoYXJzZXROYW1lIiksCisgICAgICAgIG5ldyBUZXN0RGF0YSgiYmxhLmFyaiIsIEFyY2hpdmVTdHJlYW1GYWN0b3J5LkFSSiwgZmFsc2UsICJBU0NJSSIsIEZBQ1RPUllfU0VUX0FTQ0lJLCAiY2hhcnNldE5hbWUiKSwKKworICAgICAgICBuZXcgVGVzdERhdGEoImJsYS5jcGlvIiwgQXJjaGl2ZVN0cmVhbUZhY3RvcnkuQ1BJTywgdHJ1ZSwgQ1BJT19ERUZBVUxULCBGQUNUT1JZLCAiZW5jb2RpbmciKSwKKyAgICAgICAgbmV3IFRlc3REYXRhKCJibGEuY3BpbyIsIEFyY2hpdmVTdHJlYW1GYWN0b3J5LkNQSU8sIHRydWUsICJVVEYtOCIsIEZBQ1RPUllfVVRGOCwgImVuY29kaW5nIiksCisgICAgICAgIG5ldyBUZXN0RGF0YSgiYmxhLmNwaW8iLCBBcmNoaXZlU3RyZWFtRmFjdG9yeS5DUElPLCB0cnVlLCAiQVNDSUkiLCBGQUNUT1JZX0FTQ0lJLCAiZW5jb2RpbmciKSwKKyAgICAgICAgbmV3IFRlc3REYXRhKCJibGEuY3BpbyIsIEFyY2hpdmVTdHJlYW1GYWN0b3J5LkNQSU8sIHRydWUsICJVVEYtOCIsIEZBQ1RPUllfU0VUX1VURjgsICJlbmNvZGluZyIpLAorICAgICAgICBuZXcgVGVzdERhdGEoImJsYS5jcGlvIiwgQXJjaGl2ZVN0cmVhbUZhY3RvcnkuQ1BJTywgdHJ1ZSwgIkFTQ0lJIiwgRkFDVE9SWV9TRVRfQVNDSUksICJlbmNvZGluZyIpLAorCisgICAgICAgIG5ldyBUZXN0RGF0YSgiYmxhLmR1bXAiLCBBcmNoaXZlU3RyZWFtRmFjdG9yeS5EVU1QLCBmYWxzZSwgRFVNUF9ERUZBVUxULCBGQUNUT1JZLCAiZW5jb2RpbmciKSwKKyAgICAgICAgbmV3IFRlc3REYXRhKCJibGEuZHVtcCIsIEFyY2hpdmVTdHJlYW1GYWN0b3J5LkRVTVAsIGZhbHNlLCAiVVRGLTgiLCBGQUNUT1JZX1VURjgsICJlbmNvZGluZyIpLAorICAgICAgICBuZXcgVGVzdERhdGEoImJsYS5kdW1wIiwgQXJjaGl2ZVN0cmVhbUZhY3RvcnkuRFVNUCwgZmFsc2UsICJBU0NJSSIsIEZBQ1RPUllfQVNDSUksICJlbmNvZGluZyIpLAorICAgICAgICBuZXcgVGVzdERhdGEoImJsYS5kdW1wIiwgQXJjaGl2ZVN0cmVhbUZhY3RvcnkuRFVNUCwgZmFsc2UsICJVVEYtOCIsIEZBQ1RPUllfU0VUX1VURjgsICJlbmNvZGluZyIpLAorICAgICAgICBuZXcgVGVzdERhdGEoImJsYS5kdW1wIiwgQXJjaGl2ZVN0cmVhbUZhY3RvcnkuRFVNUCwgZmFsc2UsICJBU0NJSSIsIEZBQ1RPUllfU0VUX0FTQ0lJLCAiZW5jb2RpbmciKSwKKworICAgICAgICBuZXcgVGVzdERhdGEoImJsYS50YXIiLCBBcmNoaXZlU3RyZWFtRmFjdG9yeS5UQVIsIHRydWUsIFRBUl9ERUZBVUxULCBGQUNUT1JZLCAiZW5jb2RpbmciKSwKKyAgICAgICAgbmV3IFRlc3REYXRhKCJibGEudGFyIiwgQXJjaGl2ZVN0cmVhbUZhY3RvcnkuVEFSLCB0cnVlLCAiVVRGLTgiLCBGQUNUT1JZX1VURjgsICJlbmNvZGluZyIpLAorICAgICAgICBuZXcgVGVzdERhdGEoImJsYS50YXIiLCBBcmNoaXZlU3RyZWFtRmFjdG9yeS5UQVIsIHRydWUsICJBU0NJSSIsIEZBQ1RPUllfQVNDSUksICJlbmNvZGluZyIpLAorICAgICAgICBuZXcgVGVzdERhdGEoImJsYS50YXIiLCBBcmNoaXZlU3RyZWFtRmFjdG9yeS5UQVIsIHRydWUsICJVVEYtOCIsIEZBQ1RPUllfU0VUX1VURjgsICJlbmNvZGluZyIpLAorICAgICAgICBuZXcgVGVzdERhdGEoImJsYS50YXIiLCBBcmNoaXZlU3RyZWFtRmFjdG9yeS5UQVIsIHRydWUsICJBU0NJSSIsIEZBQ1RPUllfU0VUX0FTQ0lJLCAiZW5jb2RpbmciKSwKKworICAgICAgICBuZXcgVGVzdERhdGEoImJsYS5qYXIiLCBBcmNoaXZlU3RyZWFtRmFjdG9yeS5KQVIsIHRydWUsIEpBUl9ERUZBVUxULCBGQUNUT1JZLCAiZW5jb2RpbmciKSwKKyAgICAgICAgbmV3IFRlc3REYXRhKCJibGEuamFyIiwgQXJjaGl2ZVN0cmVhbUZhY3RvcnkuSkFSLCB0cnVlLCAiVVRGLTgiLCBGQUNUT1JZX1VURjgsICJlbmNvZGluZyIpLAorICAgICAgICBuZXcgVGVzdERhdGEoImJsYS5qYXIiLCBBcmNoaXZlU3RyZWFtRmFjdG9yeS5KQVIsIHRydWUsICJBU0NJSSIsIEZBQ1RPUllfQVNDSUksICJlbmNvZGluZyIpLAorICAgICAgICBuZXcgVGVzdERhdGEoImJsYS5qYXIiLCBBcmNoaXZlU3RyZWFtRmFjdG9yeS5KQVIsIHRydWUsICJVVEYtOCIsIEZBQ1RPUllfU0VUX1VURjgsICJlbmNvZGluZyIpLAorICAgICAgICBuZXcgVGVzdERhdGEoImJsYS5qYXIiLCBBcmNoaXZlU3RyZWFtRmFjdG9yeS5KQVIsIHRydWUsICJBU0NJSSIsIEZBQ1RPUllfU0VUX0FTQ0lJLCAiZW5jb2RpbmciKSwKKworICAgICAgICBuZXcgVGVzdERhdGEoImJsYS56aXAiLCBBcmNoaXZlU3RyZWFtRmFjdG9yeS5aSVAsIHRydWUsIFpJUF9ERUZBVUxULCBGQUNUT1JZLCAiZW5jb2RpbmciKSwKKyAgICAgICAgbmV3IFRlc3REYXRhKCJibGEuemlwIiwgQXJjaGl2ZVN0cmVhbUZhY3RvcnkuWklQLCB0cnVlLCAiVVRGLTgiLCBGQUNUT1JZX1VURjgsICJlbmNvZGluZyIpLAorICAgICAgICBuZXcgVGVzdERhdGEoImJsYS56aXAiLCBBcmNoaXZlU3RyZWFtRmFjdG9yeS5aSVAsIHRydWUsICJBU0NJSSIsIEZBQ1RPUllfQVNDSUksICJlbmNvZGluZyIpLAorICAgICAgICBuZXcgVGVzdERhdGEoImJsYS56aXAiLCBBcmNoaXZlU3RyZWFtRmFjdG9yeS5aSVAsIHRydWUsICJVVEYtOCIsIEZBQ1RPUllfU0VUX1VURjgsICJlbmNvZGluZyIpLAorICAgICAgICBuZXcgVGVzdERhdGEoImJsYS56aXAiLCBBcmNoaXZlU3RyZWFtRmFjdG9yeS5aSVAsIHRydWUsICJBU0NJSSIsIEZBQ1RPUllfU0VUX0FTQ0lJLCAiZW5jb2RpbmciKSwKKyAgICB9OworCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW5jb2RpbmdJbnB1dFN0cmVhbUF1dG9kZXRlY3QoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IGZhaWxlZCA9IDA7CisgICAgICAgIGZvciAoaW50IGkgPSAxOyBpIDw9IFRFU1RTLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBmaW5hbCBUZXN0RGF0YSB0ZXN0ID0gVEVTVFNbaSAtIDFdOworICAgICAgICAgICAgdHJ5IChmaW5hbCBBcmNoaXZlSW5wdXRTdHJlYW0gYWlzID0gZ2V0SW5wdXRTdHJlYW1Gb3IodGVzdC50ZXN0RmlsZSwgdGVzdC5mYWMpKSB7CisgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIGZpZWxkID0gZ2V0RmllbGQoYWlzLCB0ZXN0LmZpZWxkTmFtZSk7CisgICAgICAgICAgICAgICAgaWYgKCFlcSh0ZXN0LmV4cGVjdGVkRW5jb2RpbmcsIGZpZWxkKSkgeworICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkZhaWxlZCB0ZXN0ICIgKyBpICsgIi4gZXhwZWN0ZWQ6ICIgKyB0ZXN0LmV4cGVjdGVkRW5jb2RpbmcgKyAiIGFjdHVhbDogIiArIGZpZWxkCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIHR5cGU6ICIgKyB0ZXN0LnR5cGUpOworICAgICAgICAgICAgICAgICAgICBmYWlsZWQrKzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKGZhaWxlZCA+IDApIHsKKyAgICAgICAgICAgIGZhaWwoIlRlc3RzIGZhaWxlZDogIiArIGZhaWxlZCArICIgb3V0IG9mICIgKyBURVNUUy5sZW5ndGgpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW5jb2RpbmdJbnB1dFN0cmVhbSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBpbnQgZmFpbGVkID0gMDsKKyAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPD0gVEVTVFMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGZpbmFsIFRlc3REYXRhIHRlc3QgPSBURVNUU1tpIC0gMV07CisgICAgICAgICAgICB0cnkgKGZpbmFsIEFyY2hpdmVJbnB1dFN0cmVhbSBhaXMgPSBnZXRJbnB1dFN0cmVhbUZvcih0ZXN0LnR5cGUsIHRlc3QudGVzdEZpbGUsIHRlc3QuZmFjKSkgeworICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBmaWVsZCA9IGdldEZpZWxkKGFpcywgdGVzdC5maWVsZE5hbWUpOworICAgICAgICAgICAgICAgIGlmICghZXEodGVzdC5leHBlY3RlZEVuY29kaW5nLCBmaWVsZCkpIHsKKyAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJGYWlsZWQgdGVzdCAiICsgaSArICIuIGV4cGVjdGVkOiAiICsgdGVzdC5leHBlY3RlZEVuY29kaW5nICsgIiBhY3R1YWw6ICIgKyBmaWVsZAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiB0eXBlOiAiICsgdGVzdC50eXBlKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbGVkKys7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChmYWlsZWQgPiAwKSB7CisgICAgICAgICAgICBmYWlsKCJUZXN0cyBmYWlsZWQ6ICIgKyBmYWlsZWQgKyAiIG91dCBvZiAiICsgVEVTVFMubGVuZ3RoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEVuY29kaW5nT3V0cHV0U3RyZWFtKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGludCBmYWlsZWQgPSAwOworICAgICAgICBmb3IoaW50IGkgPSAxOyBpIDw9IFRFU1RTLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBmaW5hbCBUZXN0RGF0YSB0ZXN0ID0gVEVTVFNbaS0xXTsKKyAgICAgICAgICAgIGlmICh0ZXN0Lmhhc091dHB1dFN0cmVhbSkgeworICAgICAgICAgICAgICAgIHRyeSAoZmluYWwgQXJjaGl2ZU91dHB1dFN0cmVhbSBhaXMgPSBnZXRPdXRwdXRTdHJlYW1Gb3IodGVzdC50eXBlLCB0ZXN0LmZhYykpIHsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIGZpZWxkID0gZ2V0RmllbGQoYWlzLCB0ZXN0LmZpZWxkTmFtZSk7CisgICAgICAgICAgICAgICAgICAgIGlmICghZXEodGVzdC5leHBlY3RlZEVuY29kaW5nLCBmaWVsZCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiRmFpbGVkIHRlc3QgIiArIGkgKyAiLiBleHBlY3RlZDogIiArIHRlc3QuZXhwZWN0ZWRFbmNvZGluZyArICIgYWN0dWFsOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgZmllbGQgKyAiIHR5cGU6ICIgKyB0ZXN0LnR5cGUpOworICAgICAgICAgICAgICAgICAgICAgICAgZmFpbGVkKys7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKGZhaWxlZCA+IDApIHsKKyAgICAgICAgICAgIGZhaWwoIlRlc3RzIGZhaWxlZDogIiArIGZhaWxlZCArICIgb3V0IG9mICIgKyBURVNUUy5sZW5ndGgpOworICAgICAgICB9CisgICAgfQorCisgICAgLy8gZXF1YWxzIGFsbG93aW5nIG51bGwKKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGVxKGZpbmFsIFN0cmluZyBleHAsIGZpbmFsIFN0cmluZyBhY3QpIHsKKyAgICAgICAgaWYgKGV4cCA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gYWN0ID09IG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGV4cC5lcXVhbHMoYWN0KTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZ2V0RmllbGQoZmluYWwgT2JqZWN0IGluc3RhbmNlLCBmaW5hbCBTdHJpbmcgbmFtZSkgeworICAgICAgICBmaW5hbCBDbGFzczw/PiBjbHMgPSBpbnN0YW5jZS5nZXRDbGFzcygpOworICAgICAgICBGaWVsZCBmbGQ7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmbGQgPSBjbHMuZ2V0RGVjbGFyZWRGaWVsZChuYW1lKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgTm9TdWNoRmllbGRFeGNlcHRpb24gbnNmZSkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGZsZCA9IGNscy5nZXRTdXBlcmNsYXNzKCkuZ2V0RGVjbGFyZWRGaWVsZChuYW1lKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChmaW5hbCBOb1N1Y2hGaWVsZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiQ2Fubm90IGZpbmQgIiArIG5hbWUgKyAiIGluIGNsYXNzICIgKyBpbnN0YW5jZS5nZXRDbGFzcygpLmdldFNpbXBsZU5hbWUoKSk7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBVTktOT1dOOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBmaW5hbCBib29sZWFuIGlzQWNjZXNzaWJsZSA9IGZsZC5pc0FjY2Vzc2libGUoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlmICghaXNBY2Nlc3NpYmxlKSB7CisgICAgICAgICAgICAgICAgZmxkLnNldEFjY2Vzc2libGUodHJ1ZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmaW5hbCBPYmplY3Qgb2JqZWN0ID0gZmxkLmdldChpbnN0YW5jZSk7CisgICAgICAgICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgU3RyaW5nIHx8IG9iamVjdCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIChTdHJpbmcpIG9iamVjdDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiV3JvbmcgdHlwZTogIiArIG9iamVjdC5nZXRDbGFzcygpLmdldENhbm9uaWNhbE5hbWUoKSArICIgZm9yICIgKyBuYW1lICsgIiBpbiBjbGFzcyAiICsgaW5zdGFuY2UuZ2V0Q2xhc3MoKS5nZXRTaW1wbGVOYW1lKCkpOworICAgICAgICAgICAgcmV0dXJuIFVOS05PV047CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgcmV0dXJuIFVOS05PV047CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAoIWlzQWNjZXNzaWJsZSkgeworICAgICAgICAgICAgICAgIGZsZC5zZXRBY2Nlc3NpYmxlKGlzQWNjZXNzaWJsZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIEFyY2hpdmVJbnB1dFN0cmVhbSBnZXRJbnB1dFN0cmVhbUZvcihmaW5hbCBTdHJpbmcgcmVzb3VyY2UsIGZpbmFsIEFyY2hpdmVTdHJlYW1GYWN0b3J5IGZhY3RvcnkpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIEFyY2hpdmVFeGNlcHRpb24geworICAgICAgICByZXR1cm4gZmFjdG9yeS5jcmVhdGVBcmNoaXZlSW5wdXRTdHJlYW0oCisgICAgICAgICAgICAgICAgICAgbmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0obmV3IEZpbGVJbnB1dFN0cmVhbSgKKyAgICAgICAgICAgICAgICAgICAgICAgZ2V0RmlsZShyZXNvdXJjZSkpKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBBcmNoaXZlSW5wdXRTdHJlYW0gZ2V0SW5wdXRTdHJlYW1Gb3IoZmluYWwgU3RyaW5nIHR5cGUsIGZpbmFsIFN0cmluZyByZXNvdXJjZSwgZmluYWwgQXJjaGl2ZVN0cmVhbUZhY3RvcnkgZmFjdG9yeSkKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgQXJjaGl2ZUV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBmYWN0b3J5LmNyZWF0ZUFyY2hpdmVJbnB1dFN0cmVhbSgKKyAgICAgICAgICAgICAgICAgICB0eXBlLAorICAgICAgICAgICAgICAgICAgIG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKG5ldyBGaWxlSW5wdXRTdHJlYW0oCisgICAgICAgICAgICAgICAgICAgICAgIGdldEZpbGUocmVzb3VyY2UpKSkpOworICAgIH0KKworICAgIHByaXZhdGUgQXJjaGl2ZU91dHB1dFN0cmVhbSBnZXRPdXRwdXRTdHJlYW1Gb3IoZmluYWwgU3RyaW5nIHR5cGUsIGZpbmFsIEFyY2hpdmVTdHJlYW1GYWN0b3J5IGZhY3RvcnkpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIEFyY2hpdmVFeGNlcHRpb24geworICAgICAgICByZXR1cm4gZmFjdG9yeS5jcmVhdGVBcmNoaXZlT3V0cHV0U3RyZWFtKHR5cGUsIG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL0NwaW9UZXN0Q2FzZS5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL0NwaW9UZXN0Q2FzZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJhZDAxNjEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvQ3Bpb1Rlc3RDYXNlLmphdmEKQEAgLTAsMCArMSwyOTcgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzOworCitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuKjsKKworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLkFic3RyYWN0VGVzdENhc2U7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5jcGlvLkNwaW9BcmNoaXZlRW50cnk7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5jcGlvLkNwaW9BcmNoaXZlSW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5jcGlvLkNwaW9BcmNoaXZlT3V0cHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuY3Bpby5DcGlvQ29uc3RhbnRzOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5JT1V0aWxzOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworCitwdWJsaWMgZmluYWwgY2xhc3MgQ3Bpb1Rlc3RDYXNlIGV4dGVuZHMgQWJzdHJhY3RUZXN0Q2FzZSB7CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RDcGlvQXJjaGl2ZUNyZWF0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGUgb3V0cHV0ID0gbmV3IEZpbGUoZGlyLCAiYmxhLmNwaW8iKTsKKworICAgICAgICBmaW5hbCBGaWxlIGZpbGUxID0gZ2V0RmlsZSgidGVzdDEueG1sIik7CisgICAgICAgIGZpbmFsIEZpbGUgZmlsZTIgPSBnZXRGaWxlKCJ0ZXN0Mi54bWwiKTsKKworICAgICAgICBmaW5hbCBPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0ob3V0cHV0KTsKKyAgICAgICAgZmluYWwgQXJjaGl2ZU91dHB1dFN0cmVhbSBvcyA9IG5ldyBBcmNoaXZlU3RyZWFtRmFjdG9yeSgpLmNyZWF0ZUFyY2hpdmVPdXRwdXRTdHJlYW0oImNwaW8iLCBvdXQpOworICAgICAgICBvcy5wdXRBcmNoaXZlRW50cnkobmV3IENwaW9BcmNoaXZlRW50cnkoInRlc3QxLnhtbCIsIGZpbGUxLmxlbmd0aCgpKSk7CisgICAgICAgIElPVXRpbHMuY29weShuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGUxKSwgb3MpOworICAgICAgICBvcy5jbG9zZUFyY2hpdmVFbnRyeSgpOworCisgICAgICAgIG9zLnB1dEFyY2hpdmVFbnRyeShuZXcgQ3Bpb0FyY2hpdmVFbnRyeSgidGVzdDIueG1sIiwgZmlsZTIubGVuZ3RoKCkpKTsKKyAgICAgICAgSU9VdGlscy5jb3B5KG5ldyBGaWxlSW5wdXRTdHJlYW0oZmlsZTIpLCBvcyk7CisgICAgICAgIG9zLmNsb3NlQXJjaGl2ZUVudHJ5KCk7CisKKyAgICAgICAgb3MuY2xvc2UoKTsKKyAgICAgICAgb3V0LmNsb3NlKCk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q3Bpb1VuYXJjaGl2ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlIG91dHB1dCA9IG5ldyBGaWxlKGRpciwgImJsYS5jcGlvIik7CisgICAgICAgIGZpbmFsIEZpbGUgZmlsZTEgPSBnZXRGaWxlKCJ0ZXN0MS54bWwiKTsKKyAgICAgICAgZmluYWwgRmlsZSBmaWxlMiA9IGdldEZpbGUoInRlc3QyLnhtbCIpOworICAgICAgICBmaW5hbCBsb25nIGZpbGUxTGVuZ3RoID0gZmlsZTEubGVuZ3RoKCk7CisgICAgICAgIGZpbmFsIGxvbmcgZmlsZTJMZW5ndGggPSBmaWxlMi5sZW5ndGgoKTsKKworICAgICAgICB7CisgICAgICAgICAgICBmaW5hbCBPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0ob3V0cHV0KTsKKyAgICAgICAgICAgIGZpbmFsIEFyY2hpdmVPdXRwdXRTdHJlYW0gb3MgPSBuZXcgQXJjaGl2ZVN0cmVhbUZhY3RvcnkoKS5jcmVhdGVBcmNoaXZlT3V0cHV0U3RyZWFtKCJjcGlvIiwgb3V0KTsKKyAgICAgICAgICAgIENwaW9BcmNoaXZlRW50cnkgZW50cnkgPSBuZXcgQ3Bpb0FyY2hpdmVFbnRyeSgidGVzdDEueG1sIiwgZmlsZTFMZW5ndGgpOworICAgICAgICAgICAgZW50cnkuc2V0TW9kZShDcGlvQ29uc3RhbnRzLkNfSVNSRUcpOworICAgICAgICAgICAgb3MucHV0QXJjaGl2ZUVudHJ5KGVudHJ5KTsKKyAgICAgICAgICAgIElPVXRpbHMuY29weShuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGUxKSwgb3MpOworICAgICAgICAgICAgb3MuY2xvc2VBcmNoaXZlRW50cnkoKTsKKworICAgICAgICAgICAgZW50cnkgPSBuZXcgQ3Bpb0FyY2hpdmVFbnRyeSgidGVzdDIueG1sIiwgZmlsZTJMZW5ndGgpOworICAgICAgICAgICAgZW50cnkuc2V0TW9kZShDcGlvQ29uc3RhbnRzLkNfSVNSRUcpOworICAgICAgICAgICAgb3MucHV0QXJjaGl2ZUVudHJ5KGVudHJ5KTsKKyAgICAgICAgICAgIElPVXRpbHMuY29weShuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGUyKSwgb3MpOworICAgICAgICAgICAgb3MuY2xvc2VBcmNoaXZlRW50cnkoKTsKKyAgICAgICAgICAgIG9zLmZpbmlzaCgpOworICAgICAgICAgICAgb3MuY2xvc2UoKTsKKyAgICAgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICB9CisKKyAgICAgICAgLy8gVW5hcmNoaXZlIE9wZXJhdGlvbgorICAgICAgICBmaW5hbCBGaWxlIGlucHV0ID0gb3V0cHV0OworICAgICAgICBmaW5hbCBJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpOworICAgICAgICBmaW5hbCBBcmNoaXZlSW5wdXRTdHJlYW0gaW4gPSBuZXcgQXJjaGl2ZVN0cmVhbUZhY3RvcnkoKS5jcmVhdGVBcmNoaXZlSW5wdXRTdHJlYW0oImNwaW8iLCBpcyk7CisKKworICAgICAgICBmaW5hbCBNYXA8U3RyaW5nLCBGaWxlPiByZXN1bHQgPSBuZXcgSGFzaE1hcDw+KCk7CisgICAgICAgIEFyY2hpdmVFbnRyeSBlbnRyeSA9IG51bGw7CisgICAgICAgIHdoaWxlICgoZW50cnkgPSBpbi5nZXROZXh0RW50cnkoKSkgIT0gbnVsbCkgeworICAgICAgICAgICAgZmluYWwgRmlsZSBjcGlvZ2V0ID0gbmV3IEZpbGUoZGlyLCBlbnRyeS5nZXROYW1lKCkpOworICAgICAgICAgICAgZmluYWwgT3V0cHV0U3RyZWFtIG91dCA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKGNwaW9nZXQpOworICAgICAgICAgICAgSU9VdGlscy5jb3B5KGluLCBvdXQpOworICAgICAgICAgICAgb3V0LmNsb3NlKCk7CisgICAgICAgICAgICByZXN1bHQucHV0KGVudHJ5LmdldE5hbWUoKSwgY3Bpb2dldCk7CisgICAgICAgIH0KKyAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgaXMuY2xvc2UoKTsKKworICAgICAgICBGaWxlIHQgPSByZXN1bHQuZ2V0KCJ0ZXN0MS54bWwiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRXhwZWN0ZWQgIiArIHQuZ2V0QWJzb2x1dGVQYXRoKCkgKyAiIHRvIGV4aXN0IiwgdC5leGlzdHMoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygibGVuZ3RoIG9mICIgKyB0LmdldEFic29sdXRlUGF0aCgpLCBmaWxlMUxlbmd0aCwgdC5sZW5ndGgoKSk7CisKKyAgICAgICAgdCA9IHJlc3VsdC5nZXQoInRlc3QyLnhtbCIpOworICAgICAgICBhc3NlcnRUcnVlKCJFeHBlY3RlZCAiICsgdC5nZXRBYnNvbHV0ZVBhdGgoKSArICIgdG8gZXhpc3QiLCB0LmV4aXN0cygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJsZW5ndGggb2YgIiArIHQuZ2V0QWJzb2x1dGVQYXRoKCksIGZpbGUyTGVuZ3RoLCB0Lmxlbmd0aCgpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3REaXJlY3RvcnlFbnRyeUZyb21GaWxlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGVbXSB0bXAgPSBjcmVhdGVUZW1wRGlyQW5kRmlsZSgpOworICAgICAgICBGaWxlIGFyY2hpdmUgPSBudWxsOworICAgICAgICBDcGlvQXJjaGl2ZU91dHB1dFN0cmVhbSB0b3MgPSBudWxsOworICAgICAgICBDcGlvQXJjaGl2ZUlucHV0U3RyZWFtIHRpcyA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhcmNoaXZlID0gRmlsZS5jcmVhdGVUZW1wRmlsZSgidGVzdC4iLCAiLmNwaW8iLCB0bXBbMF0pOworICAgICAgICAgICAgYXJjaGl2ZS5kZWxldGVPbkV4aXQoKTsKKyAgICAgICAgICAgIHRvcyA9IG5ldyBDcGlvQXJjaGl2ZU91dHB1dFN0cmVhbShuZXcgRmlsZU91dHB1dFN0cmVhbShhcmNoaXZlKSk7CisgICAgICAgICAgICBmaW5hbCBsb25nIGJlZm9yZUFyY2hpdmVXcml0ZSA9IHRtcFswXS5sYXN0TW9kaWZpZWQoKTsKKyAgICAgICAgICAgIGZpbmFsIENwaW9BcmNoaXZlRW50cnkgaW4gPSBuZXcgQ3Bpb0FyY2hpdmVFbnRyeSh0bXBbMF0sICJmb28iKTsKKyAgICAgICAgICAgIHRvcy5wdXRBcmNoaXZlRW50cnkoaW4pOworICAgICAgICAgICAgdG9zLmNsb3NlQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgICAgICB0b3MuY2xvc2UoKTsKKyAgICAgICAgICAgIHRvcyA9IG51bGw7CisgICAgICAgICAgICB0aXMgPSBuZXcgQ3Bpb0FyY2hpdmVJbnB1dFN0cmVhbShuZXcgRmlsZUlucHV0U3RyZWFtKGFyY2hpdmUpKTsKKyAgICAgICAgICAgIGZpbmFsIENwaW9BcmNoaXZlRW50cnkgb3V0ID0gdGlzLmdldE5leHRDUElPRW50cnkoKTsKKyAgICAgICAgICAgIHRpcy5jbG9zZSgpOworICAgICAgICAgICAgdGlzID0gbnVsbDsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwob3V0KTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZm9vIiwgb3V0LmdldE5hbWUoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMCwgb3V0LmdldFNpemUoKSk7CisgICAgICAgICAgICAvLyBDUElPIHN0b3JlcyB0aW1lIHdpdGggYSBncmFudWxhcml0eSBvZiAxIHNlY29uZAorICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGJlZm9yZUFyY2hpdmVXcml0ZSAvIDEwMDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgb3V0LmdldExhc3RNb2RpZmllZERhdGUoKS5nZXRUaW1lKCkgLyAxMDAwKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUob3V0LmlzRGlyZWN0b3J5KCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKHRpcyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGlzLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAodG9zICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0b3MuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRyeUhhcmRUb0RlbGV0ZShhcmNoaXZlKTsKKyAgICAgICAgICAgIHRyeUhhcmRUb0RlbGV0ZSh0bXBbMV0pOworICAgICAgICAgICAgcm1kaXIodG1wWzBdKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEV4cGxpY2l0RGlyZWN0b3J5RW50cnkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgRmlsZVtdIHRtcCA9IGNyZWF0ZVRlbXBEaXJBbmRGaWxlKCk7CisgICAgICAgIEZpbGUgYXJjaGl2ZSA9IG51bGw7CisgICAgICAgIENwaW9BcmNoaXZlT3V0cHV0U3RyZWFtIHRvcyA9IG51bGw7CisgICAgICAgIENwaW9BcmNoaXZlSW5wdXRTdHJlYW0gdGlzID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFyY2hpdmUgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKCJ0ZXN0LiIsICIuY3BpbyIsIHRtcFswXSk7CisgICAgICAgICAgICBhcmNoaXZlLmRlbGV0ZU9uRXhpdCgpOworICAgICAgICAgICAgdG9zID0gbmV3IENwaW9BcmNoaXZlT3V0cHV0U3RyZWFtKG5ldyBGaWxlT3V0cHV0U3RyZWFtKGFyY2hpdmUpKTsKKyAgICAgICAgICAgIGZpbmFsIGxvbmcgYmVmb3JlQXJjaGl2ZVdyaXRlID0gdG1wWzBdLmxhc3RNb2RpZmllZCgpOworICAgICAgICAgICAgZmluYWwgQ3Bpb0FyY2hpdmVFbnRyeSBpbiA9IG5ldyBDcGlvQXJjaGl2ZUVudHJ5KCJmb28vIik7CisgICAgICAgICAgICBpbi5zZXRUaW1lKGJlZm9yZUFyY2hpdmVXcml0ZSAvIDEwMDApOworICAgICAgICAgICAgaW4uc2V0TW9kZShDcGlvQ29uc3RhbnRzLkNfSVNESVIpOworICAgICAgICAgICAgdG9zLnB1dEFyY2hpdmVFbnRyeShpbik7CisgICAgICAgICAgICB0b3MuY2xvc2VBcmNoaXZlRW50cnkoKTsKKyAgICAgICAgICAgIHRvcy5jbG9zZSgpOworICAgICAgICAgICAgdG9zID0gbnVsbDsKKyAgICAgICAgICAgIHRpcyA9IG5ldyBDcGlvQXJjaGl2ZUlucHV0U3RyZWFtKG5ldyBGaWxlSW5wdXRTdHJlYW0oYXJjaGl2ZSkpOworICAgICAgICAgICAgZmluYWwgQ3Bpb0FyY2hpdmVFbnRyeSBvdXQgPSB0aXMuZ2V0TmV4dENQSU9FbnRyeSgpOworICAgICAgICAgICAgdGlzLmNsb3NlKCk7CisgICAgICAgICAgICB0aXMgPSBudWxsOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChvdXQpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJmb28vIiwgb3V0LmdldE5hbWUoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMCwgb3V0LmdldFNpemUoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoYmVmb3JlQXJjaGl2ZVdyaXRlIC8gMTAwMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICBvdXQuZ2V0TGFzdE1vZGlmaWVkRGF0ZSgpLmdldFRpbWUoKSAvIDEwMDApOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShvdXQuaXNEaXJlY3RvcnkoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAodGlzICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aXMuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICh0b3MgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRvcy5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdHJ5SGFyZFRvRGVsZXRlKGFyY2hpdmUpOworICAgICAgICAgICAgdHJ5SGFyZFRvRGVsZXRlKHRtcFsxXSk7CisgICAgICAgICAgICBybWRpcih0bXBbMF0pOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RmlsZUVudHJ5RnJvbUZpbGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgRmlsZVtdIHRtcCA9IGNyZWF0ZVRlbXBEaXJBbmRGaWxlKCk7CisgICAgICAgIEZpbGUgYXJjaGl2ZSA9IG51bGw7CisgICAgICAgIENwaW9BcmNoaXZlT3V0cHV0U3RyZWFtIHRvcyA9IG51bGw7CisgICAgICAgIENwaW9BcmNoaXZlSW5wdXRTdHJlYW0gdGlzID0gbnVsbDsKKyAgICAgICAgRmlsZUlucHV0U3RyZWFtIGZpcyA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhcmNoaXZlID0gRmlsZS5jcmVhdGVUZW1wRmlsZSgidGVzdC4iLCAiLmNwaW8iLCB0bXBbMF0pOworICAgICAgICAgICAgYXJjaGl2ZS5kZWxldGVPbkV4aXQoKTsKKyAgICAgICAgICAgIHRvcyA9IG5ldyBDcGlvQXJjaGl2ZU91dHB1dFN0cmVhbShuZXcgRmlsZU91dHB1dFN0cmVhbShhcmNoaXZlKSk7CisgICAgICAgICAgICBmaW5hbCBDcGlvQXJjaGl2ZUVudHJ5IGluID0gbmV3IENwaW9BcmNoaXZlRW50cnkodG1wWzFdLCAiZm9vIik7CisgICAgICAgICAgICB0b3MucHV0QXJjaGl2ZUVudHJ5KGluKTsKKyAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBiID0gbmV3IGJ5dGVbKGludCkgdG1wWzFdLmxlbmd0aCgpXTsKKyAgICAgICAgICAgIGZpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0odG1wWzFdKTsKKyAgICAgICAgICAgIHdoaWxlIChmaXMucmVhZChiKSA+IDApIHsKKyAgICAgICAgICAgICAgICB0b3Mud3JpdGUoYik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmaXMuY2xvc2UoKTsKKyAgICAgICAgICAgIGZpcyA9IG51bGw7CisgICAgICAgICAgICB0b3MuY2xvc2VBcmNoaXZlRW50cnkoKTsKKyAgICAgICAgICAgIHRvcy5jbG9zZSgpOworICAgICAgICAgICAgdG9zID0gbnVsbDsKKyAgICAgICAgICAgIHRpcyA9IG5ldyBDcGlvQXJjaGl2ZUlucHV0U3RyZWFtKG5ldyBGaWxlSW5wdXRTdHJlYW0oYXJjaGl2ZSkpOworICAgICAgICAgICAgZmluYWwgQ3Bpb0FyY2hpdmVFbnRyeSBvdXQgPSB0aXMuZ2V0TmV4dENQSU9FbnRyeSgpOworICAgICAgICAgICAgdGlzLmNsb3NlKCk7CisgICAgICAgICAgICB0aXMgPSBudWxsOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChvdXQpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJmb28iLCBvdXQuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyh0bXBbMV0ubGVuZ3RoKCksIG91dC5nZXRTaXplKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHRtcFsxXS5sYXN0TW9kaWZpZWQoKSAvIDEwMDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgb3V0LmdldExhc3RNb2RpZmllZERhdGUoKS5nZXRUaW1lKCkgLyAxMDAwKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKG91dC5pc0RpcmVjdG9yeSgpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmICh0aXMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRpcy5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHRvcyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgdG9zLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnlIYXJkVG9EZWxldGUoYXJjaGl2ZSk7CisgICAgICAgICAgICBpZiAoZmlzICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBmaXMuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRyeUhhcmRUb0RlbGV0ZSh0bXBbMV0pOworICAgICAgICAgICAgcm1kaXIodG1wWzBdKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEV4cGxpY2l0RmlsZUVudHJ5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGVbXSB0bXAgPSBjcmVhdGVUZW1wRGlyQW5kRmlsZSgpOworICAgICAgICBGaWxlIGFyY2hpdmUgPSBudWxsOworICAgICAgICBDcGlvQXJjaGl2ZU91dHB1dFN0cmVhbSB0b3MgPSBudWxsOworICAgICAgICBDcGlvQXJjaGl2ZUlucHV0U3RyZWFtIHRpcyA9IG51bGw7CisgICAgICAgIEZpbGVJbnB1dFN0cmVhbSBmaXMgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXJjaGl2ZSA9IEZpbGUuY3JlYXRlVGVtcEZpbGUoInRlc3QuIiwgIi5jcGlvIiwgdG1wWzBdKTsKKyAgICAgICAgICAgIGFyY2hpdmUuZGVsZXRlT25FeGl0KCk7CisgICAgICAgICAgICB0b3MgPSBuZXcgQ3Bpb0FyY2hpdmVPdXRwdXRTdHJlYW0obmV3IEZpbGVPdXRwdXRTdHJlYW0oYXJjaGl2ZSkpOworICAgICAgICAgICAgZmluYWwgQ3Bpb0FyY2hpdmVFbnRyeSBpbiA9IG5ldyBDcGlvQXJjaGl2ZUVudHJ5KCJmb28iKTsKKyAgICAgICAgICAgIGluLnNldFRpbWUodG1wWzFdLmxhc3RNb2RpZmllZCgpIC8gMTAwMCk7CisgICAgICAgICAgICBpbi5zZXRTaXplKHRtcFsxXS5sZW5ndGgoKSk7CisgICAgICAgICAgICBpbi5zZXRNb2RlKENwaW9Db25zdGFudHMuQ19JU1JFRyk7CisgICAgICAgICAgICB0b3MucHV0QXJjaGl2ZUVudHJ5KGluKTsKKyAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBiID0gbmV3IGJ5dGVbKGludCkgdG1wWzFdLmxlbmd0aCgpXTsKKyAgICAgICAgICAgIGZpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0odG1wWzFdKTsKKyAgICAgICAgICAgIHdoaWxlIChmaXMucmVhZChiKSA+IDApIHsKKyAgICAgICAgICAgICAgICB0b3Mud3JpdGUoYik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmaXMuY2xvc2UoKTsKKyAgICAgICAgICAgIGZpcyA9IG51bGw7CisgICAgICAgICAgICB0b3MuY2xvc2VBcmNoaXZlRW50cnkoKTsKKyAgICAgICAgICAgIHRvcy5jbG9zZSgpOworICAgICAgICAgICAgdG9zID0gbnVsbDsKKyAgICAgICAgICAgIHRpcyA9IG5ldyBDcGlvQXJjaGl2ZUlucHV0U3RyZWFtKG5ldyBGaWxlSW5wdXRTdHJlYW0oYXJjaGl2ZSkpOworICAgICAgICAgICAgZmluYWwgQ3Bpb0FyY2hpdmVFbnRyeSBvdXQgPSB0aXMuZ2V0TmV4dENQSU9FbnRyeSgpOworICAgICAgICAgICAgdGlzLmNsb3NlKCk7CisgICAgICAgICAgICB0aXMgPSBudWxsOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChvdXQpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJmb28iLCBvdXQuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyh0bXBbMV0ubGVuZ3RoKCksIG91dC5nZXRTaXplKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHRtcFsxXS5sYXN0TW9kaWZpZWQoKSAvIDEwMDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgb3V0LmdldExhc3RNb2RpZmllZERhdGUoKS5nZXRUaW1lKCkgLyAxMDAwKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKG91dC5pc0RpcmVjdG9yeSgpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmICh0aXMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRpcy5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHRvcyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgdG9zLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnlIYXJkVG9EZWxldGUoYXJjaGl2ZSk7CisgICAgICAgICAgICBpZiAoZmlzICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBmaXMuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRyeUhhcmRUb0RlbGV0ZSh0bXBbMV0pOworICAgICAgICAgICAgcm1kaXIodG1wWzBdKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9EdW1wVGVzdENhc2UuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9EdW1wVGVzdENhc2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44Njc1OTAyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL0R1bXBUZXN0Q2FzZS5qYXZhCkBAIC0wLDAgKzEsMTIyIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVyczsKKworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0Lio7CisKK2ltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuQWJzdHJhY3RUZXN0Q2FzZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLmR1bXAuRHVtcEFyY2hpdmVJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuSU9VdGlsczsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworcHVibGljIGZpbmFsIGNsYXNzIER1bXBUZXN0Q2FzZSBleHRlbmRzIEFic3RyYWN0VGVzdENhc2UgeworCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RHVtcFVuYXJjaGl2ZUFsbCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB1bmFyY2hpdmVBbGwoZ2V0RmlsZSgiYmxhLmR1bXAiKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29tcHJlc3NlZER1bXBVbmFyY2hpdmVBbGwoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdW5hcmNoaXZlQWxsKGdldEZpbGUoImJsYS56LmR1bXAiKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHVuYXJjaGl2ZUFsbChmaW5hbCBGaWxlIGlucHV0KSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgSW5wdXRTdHJlYW0gaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGlucHV0KTsKKyAgICAgICAgQXJjaGl2ZUlucHV0U3RyZWFtIGluID0gbnVsbDsKKyAgICAgICAgT3V0cHV0U3RyZWFtIG91dCA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbiA9IG5ldyBBcmNoaXZlU3RyZWFtRmFjdG9yeSgpCisgICAgICAgICAgICAgICAgLmNyZWF0ZUFyY2hpdmVJbnB1dFN0cmVhbSgiZHVtcCIsIGlzKTsKKworICAgICAgICAgICAgQXJjaGl2ZUVudHJ5IGVudHJ5ID0gaW4uZ2V0TmV4dEVudHJ5KCk7CisgICAgICAgICAgICB3aGlsZSAoZW50cnkgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGZpbmFsIEZpbGUgYXJjaGl2ZUVudHJ5ID0gbmV3IEZpbGUoZGlyLCBlbnRyeS5nZXROYW1lKCkpOworICAgICAgICAgICAgICAgIGFyY2hpdmVFbnRyeS5nZXRQYXJlbnRGaWxlKCkubWtkaXJzKCk7CisgICAgICAgICAgICAgICAgaWYgKGVudHJ5LmlzRGlyZWN0b3J5KCkpIHsKKyAgICAgICAgICAgICAgICAgICAgYXJjaGl2ZUVudHJ5Lm1rZGlyKCk7CisgICAgICAgICAgICAgICAgICAgIGVudHJ5ID0gaW4uZ2V0TmV4dEVudHJ5KCk7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBvdXQgPSBuZXcgRmlsZU91dHB1dFN0cmVhbShhcmNoaXZlRW50cnkpOworICAgICAgICAgICAgICAgIElPVXRpbHMuY29weShpbiwgb3V0KTsKKyAgICAgICAgICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICBvdXQgPSBudWxsOworICAgICAgICAgICAgICAgIGVudHJ5ID0gaW4uZ2V0TmV4dEVudHJ5KCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAob3V0ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChpbiAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlzLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RBcmNoaXZlRGV0ZWN0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFyY2hpdmVEZXRlY3Rpb24oZ2V0RmlsZSgiYmxhLmR1bXAiKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29tcHJlc3NlZEFyY2hpdmVEZXRlY3Rpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXJjaGl2ZURldGVjdGlvbihnZXRGaWxlKCJibGEuei5kdW1wIikpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhcmNoaXZlRGV0ZWN0aW9uKGZpbmFsIEZpbGUgZikgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSAoSW5wdXRTdHJlYW0gaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGYpKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoRHVtcEFyY2hpdmVJbnB1dFN0cmVhbS5jbGFzcywKKyAgICAgICAgICAgICAgICAgICAgbmV3IEFyY2hpdmVTdHJlYW1GYWN0b3J5KCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY3JlYXRlQXJjaGl2ZUlucHV0U3RyZWFtKG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKGlzKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0Q2xhc3MoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RDaGVja0FyY2hpdmUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tEdW1wQXJjaGl2ZShnZXRGaWxlKCJibGEuZHVtcCIpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RDaGVja0NvbXByZXNzZWRBcmNoaXZlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrRHVtcEFyY2hpdmUoZ2V0RmlsZSgiYmxhLnouZHVtcCIpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY2hlY2tEdW1wQXJjaGl2ZShmaW5hbCBGaWxlIGYpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBBcnJheUxpc3Q8U3RyaW5nPiBleHBlY3RlZCA9IG5ldyBBcnJheUxpc3Q8PigpOworICAgICAgICBleHBlY3RlZC5hZGQoIiIpOworICAgICAgICBleHBlY3RlZC5hZGQoImxvc3QrZm91bmQvIik7CisgICAgICAgIGV4cGVjdGVkLmFkZCgidGVzdDEueG1sIik7CisgICAgICAgIGV4cGVjdGVkLmFkZCgidGVzdDIueG1sIik7CisgICAgICAgIHRyeSAoSW5wdXRTdHJlYW0gaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGYpKSB7CisgICAgICAgICAgICBjaGVja0FyY2hpdmVDb250ZW50KG5ldyBEdW1wQXJjaGl2ZUlucHV0U3RyZWFtKGlzKSwKKyAgICAgICAgICAgICAgICAgICAgZXhwZWN0ZWQpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL0V4Y2VwdGlvbk1lc3NhZ2VUZXN0LmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvRXhjZXB0aW9uTWVzc2FnZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNjRkNzkyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL0V4Y2VwdGlvbk1lc3NhZ2VUZXN0LmphdmEKQEAgLTAsMCArMSw4MSBAQAorcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzOworCitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuKjsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwdWJsaWMgY2xhc3MgRXhjZXB0aW9uTWVzc2FnZVRlc3QgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEFSQ0hJVkVSX05VTExfTUVTU0FHRSA9ICJBcmNoaXZlcm5hbWUgbXVzdCBub3QgYmUgbnVsbC4iOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIElOUFVUU1RSRUFNX05VTExfTUVTU0FHRSA9ICJJbnB1dFN0cmVhbSBtdXN0IG5vdCBiZSBudWxsLiI7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgT1VUUFVUU1RSRUFNX05VTExfTUVTU0FHRSA9ICJPdXRwdXRTdHJlYW0gbXVzdCBub3QgYmUgbnVsbC4iOworCisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RNZXNzYWdlV2hlbkFyY2hpdmVyTmFtZUlzTnVsbF8xKCl7CisgICAgICAgIHRyeXsKKyAgICAgICAgICAgIG5ldyBBcmNoaXZlU3RyZWFtRmFjdG9yeSgpLmNyZWF0ZUFyY2hpdmVJbnB1dFN0cmVhbShudWxsLCBTeXN0ZW0uaW4pOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHJhaXNlIGFuIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi4iKTsKKyAgICAgICAgfWNhdGNoIChmaW5hbCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKEFSQ0hJVkVSX05VTExfTUVTU0FHRSwgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9IGNhdGNoIChmaW5hbCBBcmNoaXZlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkFyY2hpdmVFeGNlcHRpb24gbm90IGV4cGVjdGVkIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RNZXNzYWdlV2hlbklucHV0U3RyZWFtSXNOdWxsKCl7CisgICAgICAgIHRyeXsKKyAgICAgICAgICAgIG5ldyBBcmNoaXZlU3RyZWFtRmFjdG9yeSgpLmNyZWF0ZUFyY2hpdmVJbnB1dFN0cmVhbSgiemlwIiwgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgcmFpc2UgYW4gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLiIpOworICAgICAgICB9Y2F0Y2ggKGZpbmFsIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoSU5QVVRTVFJFQU1fTlVMTF9NRVNTQUdFLCBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIEFyY2hpdmVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiQXJjaGl2ZUV4Y2VwdGlvbiBub3QgZXhwZWN0ZWQiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdE1lc3NhZ2VXaGVuQXJjaGl2ZXJOYW1lSXNOdWxsXzIoKXsKKyAgICAgICAgdHJ5eworICAgICAgICAgICAgbmV3IEFyY2hpdmVTdHJlYW1GYWN0b3J5KCkuY3JlYXRlQXJjaGl2ZU91dHB1dFN0cmVhbShudWxsLCBTeXN0ZW0ub3V0KTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCByYWlzZSBhbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24uIik7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoQVJDSElWRVJfTlVMTF9NRVNTQUdFLCBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIEFyY2hpdmVFeGNlcHRpb24gZSl7CisgICAgICAgICAgICBmYWlsKCJBcmNoaXZlRXhjZXB0aW9uIG5vdCBleHBlY3RlZCIpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWVzc2FnZVdoZW5PdXRwdXRTdHJlYW1Jc051bGwoKXsKKyAgICAgICAgdHJ5eworICAgICAgICAgICAgbmV3IEFyY2hpdmVTdHJlYW1GYWN0b3J5KCkuY3JlYXRlQXJjaGl2ZU91dHB1dFN0cmVhbSgiemlwIiwgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgcmFpc2UgYW4gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLiIpOworICAgICAgICB9IGNhdGNoIChmaW5hbCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKE9VVFBVVFNUUkVBTV9OVUxMX01FU1NBR0UsIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgQXJjaGl2ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJBcmNoaXZlRXhjZXB0aW9uIG5vdCBleHBlY3RlZCIpOworICAgICAgICB9CisgICAgfQorCit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL0phclRlc3RDYXNlLmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvSmFyVGVzdENhc2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNzE3ZTdhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL0phclRlc3RDYXNlLmphdmEKQEAgLTAsMCArMSwxMTMgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzOworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLkFic3RyYWN0VGVzdENhc2U7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXAuWmlwQXJjaGl2ZUVudHJ5OworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5JT1V0aWxzOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworCitwdWJsaWMgZmluYWwgY2xhc3MgSmFyVGVzdENhc2UgZXh0ZW5kcyBBYnN0cmFjdFRlc3RDYXNlIHsKKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEphckFyY2hpdmVDcmVhdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlIG91dHB1dCA9IG5ldyBGaWxlKGRpciwgImJsYS5qYXIiKTsKKworICAgICAgICBmaW5hbCBGaWxlIGZpbGUxID0gZ2V0RmlsZSgidGVzdDEueG1sIik7CisgICAgICAgIGZpbmFsIEZpbGUgZmlsZTIgPSBnZXRGaWxlKCJ0ZXN0Mi54bWwiKTsKKworICAgICAgICBmaW5hbCBPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0ob3V0cHV0KTsKKworICAgICAgICBmaW5hbCBBcmNoaXZlT3V0cHV0U3RyZWFtIG9zID0gbmV3IEFyY2hpdmVTdHJlYW1GYWN0b3J5KCkuY3JlYXRlQXJjaGl2ZU91dHB1dFN0cmVhbSgiamFyIiwgb3V0KTsKKworICAgICAgICBvcy5wdXRBcmNoaXZlRW50cnkobmV3IFppcEFyY2hpdmVFbnRyeSgidGVzdGRhdGEvdGVzdDEueG1sIikpOworICAgICAgICBJT1V0aWxzLmNvcHkobmV3IEZpbGVJbnB1dFN0cmVhbShmaWxlMSksIG9zKTsKKyAgICAgICAgb3MuY2xvc2VBcmNoaXZlRW50cnkoKTsKKworICAgICAgICBvcy5wdXRBcmNoaXZlRW50cnkobmV3IFppcEFyY2hpdmVFbnRyeSgidGVzdGRhdGEvdGVzdDIueG1sIikpOworICAgICAgICBJT1V0aWxzLmNvcHkobmV3IEZpbGVJbnB1dFN0cmVhbShmaWxlMiksIG9zKTsKKyAgICAgICAgb3MuY2xvc2VBcmNoaXZlRW50cnkoKTsKKworICAgICAgICBvcy5jbG9zZSgpOworICAgIH0KKworCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SmFyVW5hcmNoaXZlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGUgaW5wdXQgPSBnZXRGaWxlKCJibGEuamFyIik7CisgICAgICAgIGZpbmFsIElucHV0U3RyZWFtIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShpbnB1dCk7CisgICAgICAgIGZpbmFsIEFyY2hpdmVJbnB1dFN0cmVhbSBpbiA9IG5ldyBBcmNoaXZlU3RyZWFtRmFjdG9yeSgpLmNyZWF0ZUFyY2hpdmVJbnB1dFN0cmVhbSgiamFyIiwgaXMpOworCisgICAgICAgIFppcEFyY2hpdmVFbnRyeSBlbnRyeSA9IChaaXBBcmNoaXZlRW50cnkpaW4uZ2V0TmV4dEVudHJ5KCk7CisgICAgICAgIEZpbGUgbyA9IG5ldyBGaWxlKGRpciwgZW50cnkuZ2V0TmFtZSgpKTsKKyAgICAgICAgby5nZXRQYXJlbnRGaWxlKCkubWtkaXJzKCk7CisgICAgICAgIE91dHB1dFN0cmVhbSBvdXQgPSBuZXcgRmlsZU91dHB1dFN0cmVhbShvKTsKKyAgICAgICAgSU9VdGlscy5jb3B5KGluLCBvdXQpOworICAgICAgICBvdXQuY2xvc2UoKTsKKworICAgICAgICBlbnRyeSA9IChaaXBBcmNoaXZlRW50cnkpaW4uZ2V0TmV4dEVudHJ5KCk7CisgICAgICAgIG8gPSBuZXcgRmlsZShkaXIsIGVudHJ5LmdldE5hbWUoKSk7CisgICAgICAgIG8uZ2V0UGFyZW50RmlsZSgpLm1rZGlycygpOworICAgICAgICBvdXQgPSBuZXcgRmlsZU91dHB1dFN0cmVhbShvKTsKKyAgICAgICAgSU9VdGlscy5jb3B5KGluLCBvdXQpOworICAgICAgICBvdXQuY2xvc2UoKTsKKworICAgICAgICBlbnRyeSA9IChaaXBBcmNoaXZlRW50cnkpaW4uZ2V0TmV4dEVudHJ5KCk7CisgICAgICAgIG8gPSBuZXcgRmlsZShkaXIsIGVudHJ5LmdldE5hbWUoKSk7CisgICAgICAgIG8uZ2V0UGFyZW50RmlsZSgpLm1rZGlycygpOworICAgICAgICBvdXQgPSBuZXcgRmlsZU91dHB1dFN0cmVhbShvKTsKKyAgICAgICAgSU9VdGlscy5jb3B5KGluLCBvdXQpOworICAgICAgICBvdXQuY2xvc2UoKTsKKworICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICBpcy5jbG9zZSgpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEphclVuYXJjaGl2ZUFsbCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlIGlucHV0ID0gZ2V0RmlsZSgiYmxhLmphciIpOworICAgICAgICBmaW5hbCBJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpOworICAgICAgICBmaW5hbCBBcmNoaXZlSW5wdXRTdHJlYW0gaW4gPSBuZXcgQXJjaGl2ZVN0cmVhbUZhY3RvcnkoKS5jcmVhdGVBcmNoaXZlSW5wdXRTdHJlYW0oImphciIsIGlzKTsKKworICAgICAgICBBcmNoaXZlRW50cnkgZW50cnkgPSBpbi5nZXROZXh0RW50cnkoKTsKKyAgICAgICAgd2hpbGUgKGVudHJ5ICE9IG51bGwpIHsKKyAgICAgICAgICAgIGZpbmFsIEZpbGUgYXJjaGl2ZUVudHJ5ID0gbmV3IEZpbGUoZGlyLCBlbnRyeS5nZXROYW1lKCkpOworICAgICAgICAgICAgYXJjaGl2ZUVudHJ5LmdldFBhcmVudEZpbGUoKS5ta2RpcnMoKTsKKyAgICAgICAgICAgIGlmKGVudHJ5LmlzRGlyZWN0b3J5KCkpeworICAgICAgICAgICAgICAgIGFyY2hpdmVFbnRyeS5ta2RpcigpOworICAgICAgICAgICAgICAgIGVudHJ5ID0gaW4uZ2V0TmV4dEVudHJ5KCk7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmaW5hbCBPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0oYXJjaGl2ZUVudHJ5KTsKKyAgICAgICAgICAgIElPVXRpbHMuY29weShpbiwgb3V0KTsKKyAgICAgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICAgICAgZW50cnkgPSBpbi5nZXROZXh0RW50cnkoKTsKKyAgICAgICAgfQorCisgICAgICAgIGluLmNsb3NlKCk7CisgICAgICAgIGlzLmNsb3NlKCk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvTG9uZ1BhdGhUZXN0LmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvTG9uZ1BhdGhUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTJmNDdiYQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9Mb25nUGF0aFRlc3QuamF2YQpAQCAtMCwwICsxLDE2NyBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzOworCitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VHJ1ZTsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5mYWlsOworCitpbXBvcnQgamF2YS5pby5CdWZmZXJlZElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRSZWFkZXI7CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZVJlYWRlcjsKK2ltcG9ydCBqYXZhLmlvLkZpbGVuYW1lRmlsdGVyOworaW1wb3J0IGphdmEubmV0LlVSSVN5bnRheEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLkFzc2VydGlvbkZhaWxlZEVycm9yOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5BYnN0cmFjdFRlc3RDYXNlOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuYXIuQXJBcmNoaXZlSW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5jcGlvLkNwaW9BcmNoaXZlSW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy50YXIuVGFyQXJjaGl2ZUVudHJ5OworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMudGFyLlRhckFyY2hpdmVJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcC5aaXBBcmNoaXZlSW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmp1bml0LkJlZm9yZUNsYXNzOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXIuUnVuV2l0aDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVycy5QYXJhbWV0ZXJpemVkOworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXJzLlBhcmFtZXRlcml6ZWQuUGFyYW1ldGVyczsKKworLyoqCisgKiBUZXN0IHRoYXQgY2FuIHJlYWQgdmFyaW91cyB0YXIgZmlsZSBleGFtcGxlcy4KKyAqCisgICogRmlsZXMgbXVzdCBiZSBpbiByZXNvdXJjZXMvbG9uZ3BhdGgsIGFuZCB0aGVyZSBtdXN0IGJlIGEgZmlsZS50eHQgY29udGFpbmluZworICogdGhlIGxpc3Qgb2YgZmlsZXMgaW4gdGhlIGFyY2hpdmVzLgorKi8KK0BSdW5XaXRoKFBhcmFtZXRlcml6ZWQuY2xhc3MpCitwdWJsaWMgY2xhc3MgTG9uZ1BhdGhUZXN0IGV4dGVuZHMgQWJzdHJhY3RUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBDbGFzc0xvYWRlciBDTEFTU0xPQURFUiA9IExvbmdQYXRoVGVzdC5jbGFzcy5nZXRDbGFzc0xvYWRlcigpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEZpbGUgQVJDRElSOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEFycmF5TGlzdDxTdHJpbmc+IEZJTEVMSVNUID0gbmV3IEFycmF5TGlzdDw+KCk7CisKKyAgICBzdGF0aWMgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgQVJDRElSID0gbmV3IEZpbGUoQ0xBU1NMT0FERVIuZ2V0UmVzb3VyY2UoImxvbmdwYXRoIikudG9VUkkoKSk7CisgICAgICAgIH0gY2F0Y2ggKFVSSVN5bnRheEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgZmluYWwgRmlsZSBmaWxlOworCisKKworICAgIHB1YmxpYyBMb25nUGF0aFRlc3QoZmluYWwgU3RyaW5nIGZpbGUpeworICAgICAgICB0aGlzLmZpbGUgPSBuZXcgRmlsZShBUkNESVIsIGZpbGUpOworICAgIH0KKworICAgIEBCZWZvcmVDbGFzcworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXRVcEZpbGVMaXN0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydFRydWUoQVJDRElSLmV4aXN0cygpKTsKKyAgICAgICAgZmluYWwgRmlsZSBsaXN0aW5nPSBuZXcgRmlsZShBUkNESVIsImZpbGVzLnR4dCIpOworICAgICAgICBhc3NlcnRUcnVlKCJmaWxlcy50eHQgaXMgcmVhZGFibGUiLGxpc3RpbmcuY2FuUmVhZCgpKTsKKyAgICAgICAgZmluYWwgQnVmZmVyZWRSZWFkZXIgYnIgPSBuZXcgQnVmZmVyZWRSZWFkZXIobmV3IEZpbGVSZWFkZXIobGlzdGluZykpOworICAgICAgICBTdHJpbmcgbGluZTsKKyAgICAgICAgd2hpbGUgKChsaW5lPWJyLnJlYWRMaW5lKCkpIT1udWxsKXsKKyAgICAgICAgICAgIGlmICghbGluZS5zdGFydHNXaXRoKCIjIikpeworICAgICAgICAgICAgICAgIEZJTEVMSVNULmFkZChsaW5lKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBici5jbG9zZSgpOworICAgIH0KKworICAgIEBQYXJhbWV0ZXJzKG5hbWUgPSAiZmlsZT17MH0iKQorICAgIHB1YmxpYyBzdGF0aWMgQ29sbGVjdGlvbjxPYmplY3RbXT4gZGF0YSgpIHsKKyAgICAgICAgZmluYWwgQ29sbGVjdGlvbjxPYmplY3RbXT4gcGFyYW1zID0gbmV3IEFycmF5TGlzdDw+KCk7CisgICAgICAgIGZvciAoZmluYWwgU3RyaW5nIGYgOiBBUkNESVIubGlzdChuZXcgRmlsZW5hbWVGaWx0ZXIoKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGFjY2VwdChmaW5hbCBGaWxlIGRpciwgZmluYWwgU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gIW5hbWUuZW5kc1dpdGgoIi50eHQiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSkpCisgICAgICAgIHsKKyAgICAgICAgICAgIHBhcmFtcy5hZGQobmV3IE9iamVjdFtdIHsgZiB9KTsKKyAgICAgICAgfQorICAgICAgcmV0dXJuIHBhcmFtczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgU3RyaW5nIGdldEV4cGVjdGVkU3RyaW5nKGZpbmFsIEFyY2hpdmVFbnRyeSBlbnRyeSkgeworICAgICAgICBpZiAoZW50cnkgaW5zdGFuY2VvZiBUYXJBcmNoaXZlRW50cnkpIHsKKyAgICAgICAgICAgIGZpbmFsIFRhckFyY2hpdmVFbnRyeSB0YXJFbnRyeSA9IChUYXJBcmNoaXZlRW50cnkpIGVudHJ5OworICAgICAgICAgICAgaWYgKHRhckVudHJ5LmlzU3ltYm9saWNMaW5rKCkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gdGFyRW50cnkuZ2V0TmFtZSgpICsgIiAtPiAiICsgdGFyRW50cnkuZ2V0TGlua05hbWUoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZW50cnkuZ2V0TmFtZSgpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEFyY2hpdmUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpIC8vIGZpbGVMaXN0IGlzIG9mIGNvcnJlY3QgdHlwZQorICAgICAgICBmaW5hbAorICAgICAgICBBcnJheUxpc3Q8U3RyaW5nPiBleHBlY3RlZCA9IChBcnJheUxpc3Q8U3RyaW5nPikgRklMRUxJU1QuY2xvbmUoKTsKKyAgICAgICAgZmluYWwgU3RyaW5nIG5hbWUgPSBmaWxlLmdldE5hbWUoKTsKKyAgICAgICAgaWYgKCJtaW5vdGF1ci5qYXIiLmVxdWFscyhuYW1lKSB8fCAibWlub3RhdXItMC5qYXIiLmVxdWFscyhuYW1lKSl7CisgICAgICAgICAgICBleHBlY3RlZC5hZGQoIk1FVEEtSU5GLyIpOworICAgICAgICAgICAgZXhwZWN0ZWQuYWRkKCJNRVRBLUlORi9NQU5JRkVTVC5NRiIpOworICAgICAgICB9CisgICAgICAgIGZpbmFsIEFyY2hpdmVJbnB1dFN0cmVhbSBhaXMgPSBmYWN0b3J5LmNyZWF0ZUFyY2hpdmVJbnB1dFN0cmVhbShuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGUpKSk7CisgICAgICAgIC8vIGNoZWNrIGlmIGV4cGVjdGVkIHR5cGUgcmVjb2duaXplZAorICAgICAgICBpZiAobmFtZS5lbmRzV2l0aCgiLnRhciIpKXsKKyAgICAgICAgICAgIGFzc2VydFRydWUoYWlzIGluc3RhbmNlb2YgVGFyQXJjaGl2ZUlucHV0U3RyZWFtKTsKKyAgICAgICAgfSBlbHNlIGlmIChuYW1lLmVuZHNXaXRoKCIuamFyIikgfHwgbmFtZS5lbmRzV2l0aCgiLnppcCIpKXsKKyAgICAgICAgICAgIGFzc2VydFRydWUoYWlzIGluc3RhbmNlb2YgWmlwQXJjaGl2ZUlucHV0U3RyZWFtKTsKKyAgICAgICAgfSBlbHNlIGlmIChuYW1lLmVuZHNXaXRoKCIuY3BpbyIpKXsKKyAgICAgICAgICAgIGFzc2VydFRydWUoYWlzIGluc3RhbmNlb2YgQ3Bpb0FyY2hpdmVJbnB1dFN0cmVhbSk7CisgICAgICAgICAgICAvLyBIYWNrOiBjcGlvIGRvZXMgbm90IGFkZCB0cmFpbGluZyAiLyIgdG8gZGlyZWN0b3J5IG5hbWVzCisgICAgICAgICAgICBmb3IoaW50IGk9MDsgaSA8IGV4cGVjdGVkLnNpemUoKTsgaSsrKXsKKyAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgZW50ID0gZXhwZWN0ZWQuZ2V0KGkpOworICAgICAgICAgICAgICAgIGlmIChlbnQuZW5kc1dpdGgoIi8iKSl7CisgICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkLnNldChpLCBlbnQuc3Vic3RyaW5nKDAsIGVudC5sZW5ndGgoKS0xKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgaWYgKG5hbWUuZW5kc1dpdGgoIi5hciIpKXsKKyAgICAgICAgICAgIGFzc2VydFRydWUoYWlzIGluc3RhbmNlb2YgQXJBcmNoaXZlSW5wdXRTdHJlYW0pOworICAgICAgICAgICAgLy8gQ1BJTyBkb2VzIG5vdCBzdG9yZSBkaXJlY3RvcmllcyBvciBkaXJlY3RvcnkgbmFtZXMKKyAgICAgICAgICAgIGV4cGVjdGVkLmNsZWFyKCk7CisgICAgICAgICAgICBmb3IgKGZpbmFsIFN0cmluZyBlbnQgOiBGSUxFTElTVCkgeworICAgICAgICAgICAgICAgIGlmICghZW50LmVuZHNXaXRoKCIvIikpIHsvLyBub3QgYSBkaXJlY3RvcnkKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGxhc3RTbGFzaCA9IGVudC5sYXN0SW5kZXhPZignLycpOworICAgICAgICAgICAgICAgICAgICBpZiAobGFzdFNsYXNoID49IDApIHsgLy8gZXh0cmFjdCBwYXRoIG5hbWUKKyAgICAgICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkLmFkZChlbnQuc3Vic3RyaW5nKGxhc3RTbGFzaCArIDEsIGVudC5sZW5ndGgoKSkpOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgZXhwZWN0ZWQuYWRkKGVudCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGZpbGUgdHlwZTogIituYW1lKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgY2hlY2tBcmNoaXZlQ29udGVudChhaXMsIGV4cGVjdGVkKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgQXNzZXJ0aW9uRmFpbGVkRXJyb3IgZSkgeworICAgICAgICAgICAgZmFpbCgiRXJyb3IgcHJvY2Vzc2luZyAiK2ZpbGUuZ2V0TmFtZSgpKyIgIitlKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGFpcy5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL0xvbmdTeW1MaW5rVGVzdC5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL0xvbmdTeW1MaW5rVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI0ZDBjZjQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvTG9uZ1N5bUxpbmtUZXN0LmphdmEKQEAgLTAsMCArMSwxNjYgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVyczsKKworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydFRydWU7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuZmFpbDsKKworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkUmVhZGVyOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVSZWFkZXI7CitpbXBvcnQgamF2YS5pby5GaWxlbmFtZUZpbHRlcjsKK2ltcG9ydCBqYXZhLm5ldC5VUklTeW50YXhFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5Bc3NlcnRpb25GYWlsZWRFcnJvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuQWJzdHJhY3RUZXN0Q2FzZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLmFyLkFyQXJjaGl2ZUlucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuY3Bpby5DcGlvQXJjaGl2ZUlucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMudGFyLlRhckFyY2hpdmVFbnRyeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnRhci5UYXJBcmNoaXZlSW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXAuWmlwQXJjaGl2ZUlucHV0U3RyZWFtOworaW1wb3J0IG9yZy5qdW5pdC5CZWZvcmVDbGFzczsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVyLlJ1bldpdGg7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lcnMuUGFyYW1ldGVyaXplZDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVycy5QYXJhbWV0ZXJpemVkLlBhcmFtZXRlcnM7CisKKy8qKgorICogVGVzdCB0aGF0IGNhbiByZWFkIHZhcmlvdXMgdGFyIGZpbGUgZXhhbXBsZXMuCisgKgorICAqIEZpbGVzIG11c3QgYmUgaW4gcmVzb3VyY2VzL2xvbmdzeW1saW5rLCBhbmQgdGhlcmUgbXVzdCBiZSBhIGZpbGUudHh0IGNvbnRhaW5pbmcKKyAqIHRoZSBsaXN0IG9mIGZpbGVzIGluIHRoZSBhcmNoaXZlcy4KKyovCitAUnVuV2l0aChQYXJhbWV0ZXJpemVkLmNsYXNzKQorcHVibGljIGNsYXNzIExvbmdTeW1MaW5rVGVzdCBleHRlbmRzIEFic3RyYWN0VGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQ2xhc3NMb2FkZXIgQ0xBU1NMT0FERVIgPSBMb25nU3ltTGlua1Rlc3QuY2xhc3MuZ2V0Q2xhc3NMb2FkZXIoKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBGaWxlIEFSQ0RJUjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBBcnJheUxpc3Q8U3RyaW5nPiBGSUxFTElTVCA9IG5ldyBBcnJheUxpc3Q8PigpOworCisgICAgc3RhdGljIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEFSQ0RJUiA9IG5ldyBGaWxlKENMQVNTTE9BREVSLmdldFJlc291cmNlKCJsb25nc3ltbGluayIpLnRvVVJJKCkpOworICAgICAgICB9IGNhdGNoIChVUklTeW50YXhFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIGZpbmFsIEZpbGUgZmlsZTsKKworICAgIHB1YmxpYyBMb25nU3ltTGlua1Rlc3QoZmluYWwgU3RyaW5nIGZpbGUpeworICAgICAgICB0aGlzLmZpbGUgPSBuZXcgRmlsZShBUkNESVIsIGZpbGUpOworICAgIH0KKworICAgIEBCZWZvcmVDbGFzcworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXRVcEZpbGVMaXN0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydFRydWUoQVJDRElSLmV4aXN0cygpKTsKKyAgICAgICAgZmluYWwgRmlsZSBsaXN0aW5nPSBuZXcgRmlsZShBUkNESVIsImZpbGVzLnR4dCIpOworICAgICAgICBhc3NlcnRUcnVlKCJmaWxlcy50eHQgaXMgcmVhZGFibGUiLGxpc3RpbmcuY2FuUmVhZCgpKTsKKyAgICAgICAgZmluYWwgQnVmZmVyZWRSZWFkZXIgYnIgPSBuZXcgQnVmZmVyZWRSZWFkZXIobmV3IEZpbGVSZWFkZXIobGlzdGluZykpOworICAgICAgICBTdHJpbmcgbGluZTsKKyAgICAgICAgd2hpbGUgKChsaW5lPWJyLnJlYWRMaW5lKCkpIT1udWxsKXsKKyAgICAgICAgICAgIGlmICghbGluZS5zdGFydHNXaXRoKCIjIikpeworICAgICAgICAgICAgICAgIEZJTEVMSVNULmFkZChsaW5lKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBici5jbG9zZSgpOworICAgIH0KKworICAgIEBQYXJhbWV0ZXJzKG5hbWUgPSAiZmlsZT17MH0iKQorICAgIHB1YmxpYyBzdGF0aWMgQ29sbGVjdGlvbjxPYmplY3RbXT4gZGF0YSgpIHsKKyAgICAgICAgZmluYWwgQ29sbGVjdGlvbjxPYmplY3RbXT4gcGFyYW1zID0gbmV3IEFycmF5TGlzdDw+KCk7CisgICAgICAgIGZvciAoZmluYWwgU3RyaW5nIGYgOiBBUkNESVIubGlzdChuZXcgRmlsZW5hbWVGaWx0ZXIoKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGFjY2VwdChmaW5hbCBGaWxlIGRpciwgZmluYWwgU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gIW5hbWUuZW5kc1dpdGgoIi50eHQiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSkpCisgICAgICAgIHsKKyAgICAgICAgICAgIHBhcmFtcy5hZGQobmV3IE9iamVjdFtdIHsgZiB9KTsKKyAgICAgICAgfQorICAgICAgcmV0dXJuIHBhcmFtczsKKyAgICB9CisKKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBTdHJpbmcgZ2V0RXhwZWN0ZWRTdHJpbmcoZmluYWwgQXJjaGl2ZUVudHJ5IGVudHJ5KSB7CisgICAgICAgIGlmIChlbnRyeSBpbnN0YW5jZW9mIFRhckFyY2hpdmVFbnRyeSkgeworICAgICAgICAgICAgZmluYWwgVGFyQXJjaGl2ZUVudHJ5IHRhckVudHJ5ID0gKFRhckFyY2hpdmVFbnRyeSkgZW50cnk7CisgICAgICAgICAgICBpZiAodGFyRW50cnkuaXNTeW1ib2xpY0xpbmsoKSkgeworICAgICAgICAgICAgICAgIHJldHVybiB0YXJFbnRyeS5nZXROYW1lKCkgKyAiIC0+ICIgKyB0YXJFbnRyeS5nZXRMaW5rTmFtZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBlbnRyeS5nZXROYW1lKCk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QXJjaGl2ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikgLy8gZmlsZUxpc3QgaXMgb2YgY29ycmVjdCB0eXBlCisgICAgICAgIGZpbmFsCisgICAgICAgIEFycmF5TGlzdDxTdHJpbmc+IGV4cGVjdGVkID0gKEFycmF5TGlzdDxTdHJpbmc+KSBGSUxFTElTVC5jbG9uZSgpOworICAgICAgICBmaW5hbCBTdHJpbmcgbmFtZSA9IGZpbGUuZ2V0TmFtZSgpOworICAgICAgICBpZiAoIm1pbm90YXVyLmphciIuZXF1YWxzKG5hbWUpIHx8ICJtaW5vdGF1ci0wLmphciIuZXF1YWxzKG5hbWUpKXsKKyAgICAgICAgICAgIGV4cGVjdGVkLmFkZCgiTUVUQS1JTkYvIik7CisgICAgICAgICAgICBleHBlY3RlZC5hZGQoIk1FVEEtSU5GL01BTklGRVNULk1GIik7CisgICAgICAgIH0KKyAgICAgICAgZmluYWwgQXJjaGl2ZUlucHV0U3RyZWFtIGFpcyA9IGZhY3RvcnkuY3JlYXRlQXJjaGl2ZUlucHV0U3RyZWFtKG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKG5ldyBGaWxlSW5wdXRTdHJlYW0oZmlsZSkpKTsKKyAgICAgICAgLy8gY2hlY2sgaWYgZXhwZWN0ZWQgdHlwZSByZWNvZ25pemVkCisgICAgICAgIGlmIChuYW1lLmVuZHNXaXRoKCIudGFyIikpeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShhaXMgaW5zdGFuY2VvZiBUYXJBcmNoaXZlSW5wdXRTdHJlYW0pOworICAgICAgICB9IGVsc2UgaWYgKG5hbWUuZW5kc1dpdGgoIi5qYXIiKSB8fCBuYW1lLmVuZHNXaXRoKCIuemlwIikpeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShhaXMgaW5zdGFuY2VvZiBaaXBBcmNoaXZlSW5wdXRTdHJlYW0pOworICAgICAgICB9IGVsc2UgaWYgKG5hbWUuZW5kc1dpdGgoIi5jcGlvIikpeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShhaXMgaW5zdGFuY2VvZiBDcGlvQXJjaGl2ZUlucHV0U3RyZWFtKTsKKyAgICAgICAgICAgIC8vIEhhY2s6IGNwaW8gZG9lcyBub3QgYWRkIHRyYWlsaW5nICIvIiB0byBkaXJlY3RvcnkgbmFtZXMKKyAgICAgICAgICAgIGZvcihpbnQgaT0wOyBpIDwgZXhwZWN0ZWQuc2l6ZSgpOyBpKyspeworICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBlbnQgPSBleHBlY3RlZC5nZXQoaSk7CisgICAgICAgICAgICAgICAgaWYgKGVudC5lbmRzV2l0aCgiLyIpKXsKKyAgICAgICAgICAgICAgICAgICAgZXhwZWN0ZWQuc2V0KGksIGVudC5zdWJzdHJpbmcoMCwgZW50Lmxlbmd0aCgpLTEpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSBpZiAobmFtZS5lbmRzV2l0aCgiLmFyIikpeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShhaXMgaW5zdGFuY2VvZiBBckFyY2hpdmVJbnB1dFN0cmVhbSk7CisgICAgICAgICAgICAvLyBDUElPIGRvZXMgbm90IHN0b3JlIGRpcmVjdG9yaWVzIG9yIGRpcmVjdG9yeSBuYW1lcworICAgICAgICAgICAgZXhwZWN0ZWQuY2xlYXIoKTsKKyAgICAgICAgICAgIGZvciAoZmluYWwgU3RyaW5nIGVudCA6IEZJTEVMSVNUKSB7CisgICAgICAgICAgICAgICAgaWYgKCFlbnQuZW5kc1dpdGgoIi8iKSkgey8vIG5vdCBhIGRpcmVjdG9yeQorICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgbGFzdFNsYXNoID0gZW50Lmxhc3RJbmRleE9mKCcvJyk7CisgICAgICAgICAgICAgICAgICAgIGlmIChsYXN0U2xhc2ggPj0gMCkgeyAvLyBleHRyYWN0IHBhdGggbmFtZQorICAgICAgICAgICAgICAgICAgICAgICAgZXhwZWN0ZWQuYWRkKGVudC5zdWJzdHJpbmcobGFzdFNsYXNoICsgMSwgZW50Lmxlbmd0aCgpKSk7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICBleHBlY3RlZC5hZGQoZW50KTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZmlsZSB0eXBlOiAiK25hbWUpOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjaGVja0FyY2hpdmVDb250ZW50KGFpcywgZXhwZWN0ZWQpOworICAgICAgICB9IGNhdGNoIChmaW5hbCBBc3NlcnRpb25GYWlsZWRFcnJvciBlKSB7CisgICAgICAgICAgICBmYWlsKCJFcnJvciBwcm9jZXNzaW5nICIrZmlsZS5nZXROYW1lKCkrIiAiK2UpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgYWlzLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvU2V2ZW5aVGVzdENhc2UuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9TZXZlblpUZXN0Q2FzZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBiNWJkOTUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvU2V2ZW5aVGVzdENhc2UuamF2YQpAQCAtMCwwICsxLDIzNCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICoKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzOworCitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuKjsKKworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmF4LmNyeXB0by5DaXBoZXI7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuQWJzdHJhY3RUZXN0Q2FzZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnNldmVuei5TZXZlblpBcmNoaXZlRW50cnk7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5zZXZlbnouU2V2ZW5aRmlsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnNldmVuei5TZXZlblpNZXRob2Q7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5zZXZlbnouU2V2ZW5aT3V0cHV0RmlsZTsKK2ltcG9ydCBvcmcuanVuaXQuQXNzdW1lOworaW1wb3J0IG9yZy5qdW5pdC5CZWZvcmU7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CisKK3B1YmxpYyBjbGFzcyBTZXZlblpUZXN0Q2FzZSBleHRlbmRzIEFic3RyYWN0VGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBGaWxlIG91dHB1dDsKKyAgICBwcml2YXRlIGZpbmFsIEZpbGUgZmlsZTEsIGZpbGUyOworCisgICAgcHVibGljIFNldmVuWlRlc3RDYXNlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmlsZTEgPSBnZXRGaWxlKCJ0ZXN0MS54bWwiKTsKKyAgICAgICAgZmlsZTIgPSBnZXRGaWxlKCJ0ZXN0Mi54bWwiKTsKKyAgICB9CisKKyAgICBAQmVmb3JlCisgICAgcHVibGljIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgb3V0cHV0ID0gbmV3IEZpbGUoZGlyLCAiYmxhLjd6Iik7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V2ZW5aQXJjaGl2ZUNyZWF0aW9uVXNpbmdDb3B5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RTZXZlblpBcmNoaXZlQ3JlYXRpb24oU2V2ZW5aTWV0aG9kLkNPUFkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFNldmVuWkFyY2hpdmVDcmVhdGlvblVzaW5nTFpNQSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0U2V2ZW5aQXJjaGl2ZUNyZWF0aW9uKFNldmVuWk1ldGhvZC5MWk1BKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RTZXZlblpBcmNoaXZlQ3JlYXRpb25Vc2luZ0xaTUEyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RTZXZlblpBcmNoaXZlQ3JlYXRpb24oU2V2ZW5aTWV0aG9kLkxaTUEyKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RTZXZlblpBcmNoaXZlQ3JlYXRpb25Vc2luZ0JaSVAyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RTZXZlblpBcmNoaXZlQ3JlYXRpb24oU2V2ZW5aTWV0aG9kLkJaSVAyKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RTZXZlblpBcmNoaXZlQ3JlYXRpb25Vc2luZ0RlZmxhdGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdFNldmVuWkFyY2hpdmVDcmVhdGlvbihTZXZlblpNZXRob2QuREVGTEFURSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RTZXZlblpBcmNoaXZlQ3JlYXRpb24oZmluYWwgU2V2ZW5aTWV0aG9kIG1ldGhvZCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGNyZWF0ZUFyY2hpdmUobWV0aG9kKTsKKyAgICAgICAgdHJ5IChTZXZlblpGaWxlIGFyY2hpdmUgPSBuZXcgU2V2ZW5aRmlsZShvdXRwdXQpKSB7CisgICAgICAgICAgICBTZXZlblpBcmNoaXZlRW50cnkgZW50cnk7CisKKyAgICAgICAgICAgIGVudHJ5ID0gYXJjaGl2ZS5nZXROZXh0RW50cnkoKTsKKyAgICAgICAgICAgIGFzc2VydCAoZW50cnkgIT0gbnVsbCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoZW50cnkuZ2V0TmFtZSgpLCBmaWxlMS5nZXROYW1lKCkpOworCisgICAgICAgICAgICBlbnRyeSA9IGFyY2hpdmUuZ2V0TmV4dEVudHJ5KCk7CisgICAgICAgICAgICBhc3NlcnQgKGVudHJ5ICE9IG51bGwpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGVudHJ5LmdldE5hbWUoKSwgZmlsZTIuZ2V0TmFtZSgpKTsKKworICAgICAgICAgICAgYXNzZXJ0IChhcmNoaXZlLmdldE5leHRFbnRyeSgpID09IG51bGwpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNyZWF0ZUFyY2hpdmUoZmluYWwgU2V2ZW5aTWV0aG9kIG1ldGhvZCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFNldmVuWk91dHB1dEZpbGUgb3V0QXJjaGl2ZSA9IG5ldyBTZXZlblpPdXRwdXRGaWxlKG91dHB1dCk7CisgICAgICAgIG91dEFyY2hpdmUuc2V0Q29udGVudENvbXByZXNzaW9uKG1ldGhvZCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTZXZlblpBcmNoaXZlRW50cnkgZW50cnk7CisKKyAgICAgICAgICAgIGVudHJ5ID0gb3V0QXJjaGl2ZS5jcmVhdGVBcmNoaXZlRW50cnkoZmlsZTEsIGZpbGUxLmdldE5hbWUoKSk7CisgICAgICAgICAgICBvdXRBcmNoaXZlLnB1dEFyY2hpdmVFbnRyeShlbnRyeSk7CisgICAgICAgICAgICBjb3B5KGZpbGUxLCBvdXRBcmNoaXZlKTsKKyAgICAgICAgICAgIG91dEFyY2hpdmUuY2xvc2VBcmNoaXZlRW50cnkoKTsKKworICAgICAgICAgICAgZW50cnkgPSBvdXRBcmNoaXZlLmNyZWF0ZUFyY2hpdmVFbnRyeShmaWxlMiwgZmlsZTIuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIG91dEFyY2hpdmUucHV0QXJjaGl2ZUVudHJ5KGVudHJ5KTsKKyAgICAgICAgICAgIGNvcHkoZmlsZTIsIG91dEFyY2hpdmUpOworICAgICAgICAgICAgb3V0QXJjaGl2ZS5jbG9zZUFyY2hpdmVFbnRyeSgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgb3V0QXJjaGl2ZS5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBzaW5nbGVCeXRlUmVhZENvbnNpc3RlbnRseVJldHVybnNNaW51c09uZUF0RW9mVXNpbmdDb3B5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHNpbmdsZUJ5dGVSZWFkQ29uc2lzdGVudGx5UmV0dXJuc01pbnVzT25lQXRFb2YoU2V2ZW5aTWV0aG9kLkNPUFkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgc2luZ2xlQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZlVzaW5nTFpNQSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzaW5nbGVCeXRlUmVhZENvbnNpc3RlbnRseVJldHVybnNNaW51c09uZUF0RW9mKFNldmVuWk1ldGhvZC5MWk1BKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHNpbmdsZUJ5dGVSZWFkQ29uc2lzdGVudGx5UmV0dXJuc01pbnVzT25lQXRFb2ZVc2luZ0xaTUEyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHNpbmdsZUJ5dGVSZWFkQ29uc2lzdGVudGx5UmV0dXJuc01pbnVzT25lQXRFb2YoU2V2ZW5aTWV0aG9kLkxaTUEyKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHNpbmdsZUJ5dGVSZWFkQ29uc2lzdGVudGx5UmV0dXJuc01pbnVzT25lQXRFb2ZVc2luZ0JaSVAyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHNpbmdsZUJ5dGVSZWFkQ29uc2lzdGVudGx5UmV0dXJuc01pbnVzT25lQXRFb2YoU2V2ZW5aTWV0aG9kLkJaSVAyKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHNpbmdsZUJ5dGVSZWFkQ29uc2lzdGVudGx5UmV0dXJuc01pbnVzT25lQXRFb2ZVc2luZ0RlZmxhdGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc2luZ2xlQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZihTZXZlblpNZXRob2QuREVGTEFURSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBzaW5nbGVCeXRlUmVhZENvbnNpc3RlbnRseVJldHVybnNNaW51c09uZUF0RW9mVXNpbmdBRVMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzdW1lU3Ryb25nQ3J5cHRvSXNBdmFpbGFibGUoKTsKKyAgICAgICAgdHJ5IChTZXZlblpGaWxlIGFyY2hpdmUgPSBuZXcgU2V2ZW5aRmlsZShnZXRGaWxlKCJibGEuZW5jcnlwdGVkLjd6IiksICJmb28iLnRvQ2hhckFycmF5KCkpKSB7CisgICAgICAgICAgICBzaW5nbGVCeXRlUmVhZENvbnNpc3RlbnRseVJldHVybnNNaW51c09uZUF0RW9mKGFyY2hpdmUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHNpbmdsZUJ5dGVSZWFkQ29uc2lzdGVudGx5UmV0dXJuc01pbnVzT25lQXRFb2YoZmluYWwgU2V2ZW5aTWV0aG9kIG1ldGhvZCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGNyZWF0ZUFyY2hpdmUobWV0aG9kKTsKKyAgICAgICAgdHJ5IChTZXZlblpGaWxlIGFyY2hpdmUgPSBuZXcgU2V2ZW5aRmlsZShvdXRwdXQpKSB7CisgICAgICAgICAgICBzaW5nbGVCeXRlUmVhZENvbnNpc3RlbnRseVJldHVybnNNaW51c09uZUF0RW9mKGFyY2hpdmUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHNpbmdsZUJ5dGVSZWFkQ29uc2lzdGVudGx5UmV0dXJuc01pbnVzT25lQXRFb2YoU2V2ZW5aRmlsZSBhcmNoaXZlKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU2V2ZW5aQXJjaGl2ZUVudHJ5IGVudHJ5ID0gYXJjaGl2ZS5nZXROZXh0RW50cnkoKTsKKyAgICAgICAgZW50cnkgPSBhcmNoaXZlLmdldE5leHRFbnRyeSgpOworICAgICAgICByZWFkRnVsbHkoYXJjaGl2ZSk7CisgICAgICAgIGFzc2VydEVxdWFscygtMSwgYXJjaGl2ZS5yZWFkKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIGFyY2hpdmUucmVhZCgpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIG11bHRpQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZlVzaW5nTFpNQSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBtdWx0aUJ5dGVSZWFkQ29uc2lzdGVudGx5UmV0dXJuc01pbnVzT25lQXRFb2YoU2V2ZW5aTWV0aG9kLkxaTUEpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgbXVsdGlCeXRlUmVhZENvbnNpc3RlbnRseVJldHVybnNNaW51c09uZUF0RW9mVXNpbmdMWk1BMigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBtdWx0aUJ5dGVSZWFkQ29uc2lzdGVudGx5UmV0dXJuc01pbnVzT25lQXRFb2YoU2V2ZW5aTWV0aG9kLkxaTUEyKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIG11bHRpQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZlVzaW5nQlpJUDIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgbXVsdGlCeXRlUmVhZENvbnNpc3RlbnRseVJldHVybnNNaW51c09uZUF0RW9mKFNldmVuWk1ldGhvZC5CWklQMik7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBtdWx0aUJ5dGVSZWFkQ29uc2lzdGVudGx5UmV0dXJuc01pbnVzT25lQXRFb2ZVc2luZ0RlZmxhdGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgbXVsdGlCeXRlUmVhZENvbnNpc3RlbnRseVJldHVybnNNaW51c09uZUF0RW9mKFNldmVuWk1ldGhvZC5ERUZMQVRFKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIG11bHRpQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZlVzaW5nQUVTKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc3VtZVN0cm9uZ0NyeXB0b0lzQXZhaWxhYmxlKCk7CisgICAgICAgIHRyeSAoU2V2ZW5aRmlsZSBhcmNoaXZlID0gbmV3IFNldmVuWkZpbGUoZ2V0RmlsZSgiYmxhLmVuY3J5cHRlZC43eiIpLCAiZm9vIi50b0NoYXJBcnJheSgpKSkgeworICAgICAgICAgICAgbXVsdGlCeXRlUmVhZENvbnNpc3RlbnRseVJldHVybnNNaW51c09uZUF0RW9mKGFyY2hpdmUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIG11bHRpQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZihmaW5hbCBTZXZlblpNZXRob2QgbWV0aG9kKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgY3JlYXRlQXJjaGl2ZShtZXRob2QpOworICAgICAgICB0cnkgKFNldmVuWkZpbGUgYXJjaGl2ZSA9IG5ldyBTZXZlblpGaWxlKG91dHB1dCkpIHsKKyAgICAgICAgICAgIG11bHRpQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZihhcmNoaXZlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBtdWx0aUJ5dGVSZWFkQ29uc2lzdGVudGx5UmV0dXJuc01pbnVzT25lQXRFb2YoU2V2ZW5aRmlsZSBhcmNoaXZlKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGJ1ZiA9IG5ldyBieXRlWzJdOworICAgICAgICBTZXZlblpBcmNoaXZlRW50cnkgZW50cnkgPSBhcmNoaXZlLmdldE5leHRFbnRyeSgpOworICAgICAgICBlbnRyeSA9IGFyY2hpdmUuZ2V0TmV4dEVudHJ5KCk7CisgICAgICAgIHJlYWRGdWxseShhcmNoaXZlKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBhcmNoaXZlLnJlYWQoYnVmKSk7CisgICAgICAgIGFzc2VydEVxdWFscygtMSwgYXJjaGl2ZS5yZWFkKGJ1ZikpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBjb3B5KGZpbmFsIEZpbGUgc3JjLCBmaW5hbCBTZXZlblpPdXRwdXRGaWxlIGRzdCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgRmlsZUlucHV0U3RyZWFtIGZpcyA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKHNyYyk7CisgICAgICAgICAgICBmaW5hbCBieXRlW10gYnVmZmVyID0gbmV3IGJ5dGVbOCoxMDI0XTsKKyAgICAgICAgICAgIGludCBieXRlc1JlYWQ7CisgICAgICAgICAgICB3aGlsZSAoKGJ5dGVzUmVhZCA9IGZpcy5yZWFkKGJ1ZmZlcikpID49IDApIHsKKyAgICAgICAgICAgICAgICBkc3Qud3JpdGUoYnVmZmVyLCAwLCBieXRlc1JlYWQpOworICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKGZpcyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgZmlzLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcmVhZEZ1bGx5KGZpbmFsIFNldmVuWkZpbGUgYXJjaGl2ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGJ1ZiA9IG5ldyBieXRlWzEwMjRdOworICAgICAgICBpbnQgeCA9IDA7CisgICAgICAgIHdoaWxlICgwIDw9ICh4ID0gYXJjaGl2ZS5yZWFkKGJ1ZikpKSB7CisgICAgICAgICAgICA7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGFzc3VtZVN0cm9uZ0NyeXB0b0lzQXZhaWxhYmxlKCkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIEFzc3VtZS5hc3N1bWVUcnVlKCJ0ZXN0IHJlcXVpcmVzIHN0cm9uZyBjcnlwdG8iLCBDaXBoZXIuZ2V0TWF4QWxsb3dlZEtleUxlbmd0aCgiQUVTL0VDQi9QS0NTNVBhZGRpbmciKSA+PSAyNTYpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9UYXJUZXN0Q2FzZS5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL1RhclRlc3RDYXNlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDc5MjU4MwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9UYXJUZXN0Q2FzZS5qYXZhCkBAIC0wLDAgKzEsMzMzIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVyczsKKworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0Lio7CisKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5BYnN0cmFjdFRlc3RDYXNlOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMudGFyLlRhckFyY2hpdmVFbnRyeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnRhci5UYXJBcmNoaXZlSW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy50YXIuVGFyQXJjaGl2ZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuQ2hhcnNldE5hbWVzOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5JT1V0aWxzOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworCitwdWJsaWMgZmluYWwgY2xhc3MgVGFyVGVzdENhc2UgZXh0ZW5kcyBBYnN0cmFjdFRlc3RDYXNlIHsKKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFRhckFyY2hpdmVDcmVhdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlIG91dHB1dCA9IG5ldyBGaWxlKGRpciwgImJsYS50YXIiKTsKKyAgICAgICAgZmluYWwgRmlsZSBmaWxlMSA9IGdldEZpbGUoInRlc3QxLnhtbCIpOworICAgICAgICBmaW5hbCBPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0ob3V0cHV0KTsKKyAgICAgICAgZmluYWwgQXJjaGl2ZU91dHB1dFN0cmVhbSBvcyA9IG5ldyBBcmNoaXZlU3RyZWFtRmFjdG9yeSgpLmNyZWF0ZUFyY2hpdmVPdXRwdXRTdHJlYW0oInRhciIsIG91dCk7CisgICAgICAgIGZpbmFsIFRhckFyY2hpdmVFbnRyeSBlbnRyeSA9IG5ldyBUYXJBcmNoaXZlRW50cnkoInRlc3RkYXRhL3Rlc3QxLnhtbCIpOworICAgICAgICBlbnRyeS5zZXRNb2RUaW1lKDApOworICAgICAgICBlbnRyeS5zZXRTaXplKGZpbGUxLmxlbmd0aCgpKTsKKyAgICAgICAgZW50cnkuc2V0VXNlcklkKDApOworICAgICAgICBlbnRyeS5zZXRHcm91cElkKDApOworICAgICAgICBlbnRyeS5zZXRVc2VyTmFtZSgiYXZhbG9uIik7CisgICAgICAgIGVudHJ5LnNldEdyb3VwTmFtZSgiZXhjYWxpYnVyIik7CisgICAgICAgIGVudHJ5LnNldE1vZGUoMDEwMDAwMCk7CisgICAgICAgIG9zLnB1dEFyY2hpdmVFbnRyeShlbnRyeSk7CisgICAgICAgIElPVXRpbHMuY29weShuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGUxKSwgb3MpOworICAgICAgICBvcy5jbG9zZUFyY2hpdmVFbnRyeSgpOworICAgICAgICBvcy5jbG9zZSgpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFRhckFyY2hpdmVMb25nTmFtZUNyZWF0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFN0cmluZyBuYW1lID0gInRlc3RkYXRhLzEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2LnhtbCI7CisgICAgICAgIGZpbmFsIGJ5dGVbXSBieXRlcyA9IG5hbWUuZ2V0Qnl0ZXMoQ2hhcnNldE5hbWVzLlVURl84KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGJ5dGVzLmxlbmd0aCwgOTkpOworCisgICAgICAgIGZpbmFsIEZpbGUgb3V0cHV0ID0gbmV3IEZpbGUoZGlyLCAiYmxhLnRhciIpOworICAgICAgICBmaW5hbCBGaWxlIGZpbGUxID0gZ2V0RmlsZSgidGVzdDEueG1sIik7CisgICAgICAgIGZpbmFsIE91dHB1dFN0cmVhbSBvdXQgPSBuZXcgRmlsZU91dHB1dFN0cmVhbShvdXRwdXQpOworICAgICAgICBmaW5hbCBBcmNoaXZlT3V0cHV0U3RyZWFtIG9zID0gbmV3IEFyY2hpdmVTdHJlYW1GYWN0b3J5KCkuY3JlYXRlQXJjaGl2ZU91dHB1dFN0cmVhbSgidGFyIiwgb3V0KTsKKyAgICAgICAgZmluYWwgVGFyQXJjaGl2ZUVudHJ5IGVudHJ5ID0gbmV3IFRhckFyY2hpdmVFbnRyeShuYW1lKTsKKyAgICAgICAgZW50cnkuc2V0TW9kVGltZSgwKTsKKyAgICAgICAgZW50cnkuc2V0U2l6ZShmaWxlMS5sZW5ndGgoKSk7CisgICAgICAgIGVudHJ5LnNldFVzZXJJZCgwKTsKKyAgICAgICAgZW50cnkuc2V0R3JvdXBJZCgwKTsKKyAgICAgICAgZW50cnkuc2V0VXNlck5hbWUoImF2YWxvbiIpOworICAgICAgICBlbnRyeS5zZXRHcm91cE5hbWUoImV4Y2FsaWJ1ciIpOworICAgICAgICBlbnRyeS5zZXRNb2RlKDAxMDAwMDApOworICAgICAgICBvcy5wdXRBcmNoaXZlRW50cnkoZW50cnkpOworICAgICAgICBmaW5hbCBGaWxlSW5wdXRTdHJlYW0gaW4gPSBuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGUxKTsKKyAgICAgICAgSU9VdGlscy5jb3B5KGluLCBvcyk7CisgICAgICAgIG9zLmNsb3NlQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgIG9zLmNsb3NlKCk7CisgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICBpbi5jbG9zZSgpOworCisKKyAgICAgICAgQXJjaGl2ZU91dHB1dFN0cmVhbSBvczIgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmluYWwgU3RyaW5nIHRvTG9uZ05hbWUgPSAidGVzdGRhdGEvMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3LnhtbCI7CisgICAgICAgICAgICBmaW5hbCBGaWxlIG91dHB1dDIgPSBuZXcgRmlsZShkaXIsICJibGEudGFyIik7CisgICAgICAgICAgICBmaW5hbCBPdXRwdXRTdHJlYW0gb3V0MiA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKG91dHB1dDIpOworICAgICAgICAgICAgb3MyID0gbmV3IEFyY2hpdmVTdHJlYW1GYWN0b3J5KCkuY3JlYXRlQXJjaGl2ZU91dHB1dFN0cmVhbSgidGFyIiwgb3V0Mik7CisgICAgICAgICAgICBmaW5hbCBUYXJBcmNoaXZlRW50cnkgZW50cnkyID0gbmV3IFRhckFyY2hpdmVFbnRyeSh0b0xvbmdOYW1lKTsKKyAgICAgICAgICAgIGVudHJ5Mi5zZXRNb2RUaW1lKDApOworICAgICAgICAgICAgZW50cnkyLnNldFNpemUoZmlsZTEubGVuZ3RoKCkpOworICAgICAgICAgICAgZW50cnkyLnNldFVzZXJJZCgwKTsKKyAgICAgICAgICAgIGVudHJ5Mi5zZXRHcm91cElkKDApOworICAgICAgICAgICAgZW50cnkyLnNldFVzZXJOYW1lKCJhdmFsb24iKTsKKyAgICAgICAgICAgIGVudHJ5Mi5zZXRHcm91cE5hbWUoImV4Y2FsaWJ1ciIpOworICAgICAgICAgICAgZW50cnkyLnNldE1vZGUoMDEwMDAwMCk7CisgICAgICAgICAgICBvczIucHV0QXJjaGl2ZUVudHJ5KGVudHJ5KTsKKyAgICAgICAgICAgIElPVXRpbHMuY29weShuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGUxKSwgb3MyKTsKKyAgICAgICAgICAgIG9zMi5jbG9zZUFyY2hpdmVFbnRyeSgpOworICAgICAgICB9IGNhdGNoKGZpbmFsIElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUodHJ1ZSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAob3MyICE9IG51bGwpeworICAgICAgICAgICAgICAgIG9zMi5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VGFyVW5hcmNoaXZlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGUgaW5wdXQgPSBnZXRGaWxlKCJibGEudGFyIik7CisgICAgICAgIGZpbmFsIElucHV0U3RyZWFtIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShpbnB1dCk7CisgICAgICAgIGZpbmFsIEFyY2hpdmVJbnB1dFN0cmVhbSBpbiA9IG5ldyBBcmNoaXZlU3RyZWFtRmFjdG9yeSgpLmNyZWF0ZUFyY2hpdmVJbnB1dFN0cmVhbSgidGFyIiwgaXMpOworICAgICAgICBmaW5hbCBUYXJBcmNoaXZlRW50cnkgZW50cnkgPSAoVGFyQXJjaGl2ZUVudHJ5KWluLmdldE5leHRFbnRyeSgpOworICAgICAgICBmaW5hbCBPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0obmV3IEZpbGUoZGlyLCBlbnRyeS5nZXROYW1lKCkpKTsKKyAgICAgICAgSU9VdGlscy5jb3B5KGluLCBvdXQpOworICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RDT01QUkVTUzExNCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlIGlucHV0ID0gZ2V0RmlsZSgiQ09NUFJFU1MtMTE0LnRhciIpOworICAgICAgICBmaW5hbCBJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpOworICAgICAgICBmaW5hbCBBcmNoaXZlSW5wdXRTdHJlYW0gaW4gPSBuZXcgVGFyQXJjaGl2ZUlucHV0U3RyZWFtKGlzLAorICAgICAgICAgICAgICAgIENoYXJzZXROYW1lcy5JU09fODg1OV8xKTsKKyAgICAgICAgVGFyQXJjaGl2ZUVudHJ5IGVudHJ5ID0gKFRhckFyY2hpdmVFbnRyeSlpbi5nZXROZXh0RW50cnkoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIzXHUwMGIxXHUwMGIxXHUwMGIxRjA2XHUwMGIxVzIzNDVcdTAwYjFaQlx1MDBiMWxhXHUwMGIxXHUwMGIxXHUwMGIxXHUwMGIxXHUwMGIxXHUwMGIxXHUwMGIxXHUwMGIxQkxBIiwgZW50cnkuZ2V0TmFtZSgpKTsKKyAgICAgICAgZW50cnkgPSAoVGFyQXJjaGl2ZUVudHJ5KWluLmdldE5leHRFbnRyeSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjAzMDItMDYwMS0zXHUwMGIxXHUwMGIxXHUwMGIxRjA2XHUwMGIxVzIzNDVcdTAwYjFaQlx1MDBiMWxhXHUwMGIxXHUwMGIxXHUwMGIxXHUwMGIxXHUwMGIxXHUwMGIxXHUwMGIxXHUwMGIxQkxBIixlbnRyeS5nZXROYW1lKCkpOworICAgICAgICBpbi5jbG9zZSgpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdERpcmVjdG9yeUVudHJ5RnJvbUZpbGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgRmlsZVtdIHRtcCA9IGNyZWF0ZVRlbXBEaXJBbmRGaWxlKCk7CisgICAgICAgIEZpbGUgYXJjaGl2ZSA9IG51bGw7CisgICAgICAgIFRhckFyY2hpdmVPdXRwdXRTdHJlYW0gdG9zID0gbnVsbDsKKyAgICAgICAgVGFyQXJjaGl2ZUlucHV0U3RyZWFtIHRpcyA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhcmNoaXZlID0gRmlsZS5jcmVhdGVUZW1wRmlsZSgidGVzdC4iLCAiLnRhciIsIHRtcFswXSk7CisgICAgICAgICAgICBhcmNoaXZlLmRlbGV0ZU9uRXhpdCgpOworICAgICAgICAgICAgdG9zID0gbmV3IFRhckFyY2hpdmVPdXRwdXRTdHJlYW0obmV3IEZpbGVPdXRwdXRTdHJlYW0oYXJjaGl2ZSkpOworICAgICAgICAgICAgZmluYWwgbG9uZyBiZWZvcmVBcmNoaXZlV3JpdGUgPSB0bXBbMF0ubGFzdE1vZGlmaWVkKCk7CisgICAgICAgICAgICBmaW5hbCBUYXJBcmNoaXZlRW50cnkgaW4gPSBuZXcgVGFyQXJjaGl2ZUVudHJ5KHRtcFswXSwgImZvbyIpOworICAgICAgICAgICAgdG9zLnB1dEFyY2hpdmVFbnRyeShpbik7CisgICAgICAgICAgICB0b3MuY2xvc2VBcmNoaXZlRW50cnkoKTsKKyAgICAgICAgICAgIHRvcy5jbG9zZSgpOworICAgICAgICAgICAgdG9zID0gbnVsbDsKKyAgICAgICAgICAgIHRpcyA9IG5ldyBUYXJBcmNoaXZlSW5wdXRTdHJlYW0obmV3IEZpbGVJbnB1dFN0cmVhbShhcmNoaXZlKSk7CisgICAgICAgICAgICBmaW5hbCBUYXJBcmNoaXZlRW50cnkgb3V0ID0gdGlzLmdldE5leHRUYXJFbnRyeSgpOworICAgICAgICAgICAgdGlzLmNsb3NlKCk7CisgICAgICAgICAgICB0aXMgPSBudWxsOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChvdXQpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJmb28vIiwgb3V0LmdldE5hbWUoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMCwgb3V0LmdldFNpemUoKSk7CisgICAgICAgICAgICAvLyBUQVIgc3RvcmVzIHRpbWUgd2l0aCBhIGdyYW51bGFyaXR5IG9mIDEgc2Vjb25kCisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoYmVmb3JlQXJjaGl2ZVdyaXRlIC8gMTAwMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICBvdXQuZ2V0TGFzdE1vZGlmaWVkRGF0ZSgpLmdldFRpbWUoKSAvIDEwMDApOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShvdXQuaXNEaXJlY3RvcnkoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAodGlzICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aXMuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICh0b3MgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRvcy5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdHJ5SGFyZFRvRGVsZXRlKGFyY2hpdmUpOworICAgICAgICAgICAgdHJ5SGFyZFRvRGVsZXRlKHRtcFsxXSk7CisgICAgICAgICAgICBybWRpcih0bXBbMF0pOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RXhwbGljaXREaXJlY3RvcnlFbnRyeSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlW10gdG1wID0gY3JlYXRlVGVtcERpckFuZEZpbGUoKTsKKyAgICAgICAgRmlsZSBhcmNoaXZlID0gbnVsbDsKKyAgICAgICAgVGFyQXJjaGl2ZU91dHB1dFN0cmVhbSB0b3MgPSBudWxsOworICAgICAgICBUYXJBcmNoaXZlSW5wdXRTdHJlYW0gdGlzID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFyY2hpdmUgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKCJ0ZXN0LiIsICIudGFyIiwgdG1wWzBdKTsKKyAgICAgICAgICAgIGFyY2hpdmUuZGVsZXRlT25FeGl0KCk7CisgICAgICAgICAgICB0b3MgPSBuZXcgVGFyQXJjaGl2ZU91dHB1dFN0cmVhbShuZXcgRmlsZU91dHB1dFN0cmVhbShhcmNoaXZlKSk7CisgICAgICAgICAgICBmaW5hbCBsb25nIGJlZm9yZUFyY2hpdmVXcml0ZSA9IHRtcFswXS5sYXN0TW9kaWZpZWQoKTsKKyAgICAgICAgICAgIGZpbmFsIFRhckFyY2hpdmVFbnRyeSBpbiA9IG5ldyBUYXJBcmNoaXZlRW50cnkoImZvby8iKTsKKyAgICAgICAgICAgIGluLnNldE1vZFRpbWUoYmVmb3JlQXJjaGl2ZVdyaXRlKTsKKyAgICAgICAgICAgIHRvcy5wdXRBcmNoaXZlRW50cnkoaW4pOworICAgICAgICAgICAgdG9zLmNsb3NlQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgICAgICB0b3MuY2xvc2UoKTsKKyAgICAgICAgICAgIHRvcyA9IG51bGw7CisgICAgICAgICAgICB0aXMgPSBuZXcgVGFyQXJjaGl2ZUlucHV0U3RyZWFtKG5ldyBGaWxlSW5wdXRTdHJlYW0oYXJjaGl2ZSkpOworICAgICAgICAgICAgZmluYWwgVGFyQXJjaGl2ZUVudHJ5IG91dCA9IHRpcy5nZXROZXh0VGFyRW50cnkoKTsKKyAgICAgICAgICAgIHRpcy5jbG9zZSgpOworICAgICAgICAgICAgdGlzID0gbnVsbDsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwob3V0KTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZm9vLyIsIG91dC5nZXROYW1lKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIG91dC5nZXRTaXplKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGJlZm9yZUFyY2hpdmVXcml0ZSAvIDEwMDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgb3V0LmdldExhc3RNb2RpZmllZERhdGUoKS5nZXRUaW1lKCkgLyAxMDAwKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUob3V0LmlzRGlyZWN0b3J5KCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKHRpcyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGlzLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAodG9zICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0b3MuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRyeUhhcmRUb0RlbGV0ZShhcmNoaXZlKTsKKyAgICAgICAgICAgIHRyeUhhcmRUb0RlbGV0ZSh0bXBbMV0pOworICAgICAgICAgICAgcm1kaXIodG1wWzBdKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEZpbGVFbnRyeUZyb21GaWxlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGVbXSB0bXAgPSBjcmVhdGVUZW1wRGlyQW5kRmlsZSgpOworICAgICAgICBGaWxlIGFyY2hpdmUgPSBudWxsOworICAgICAgICBUYXJBcmNoaXZlT3V0cHV0U3RyZWFtIHRvcyA9IG51bGw7CisgICAgICAgIFRhckFyY2hpdmVJbnB1dFN0cmVhbSB0aXMgPSBudWxsOworICAgICAgICBGaWxlSW5wdXRTdHJlYW0gZmlzID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFyY2hpdmUgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKCJ0ZXN0LiIsICIudGFyIiwgdG1wWzBdKTsKKyAgICAgICAgICAgIGFyY2hpdmUuZGVsZXRlT25FeGl0KCk7CisgICAgICAgICAgICB0b3MgPSBuZXcgVGFyQXJjaGl2ZU91dHB1dFN0cmVhbShuZXcgRmlsZU91dHB1dFN0cmVhbShhcmNoaXZlKSk7CisgICAgICAgICAgICBmaW5hbCBUYXJBcmNoaXZlRW50cnkgaW4gPSBuZXcgVGFyQXJjaGl2ZUVudHJ5KHRtcFsxXSwgImZvbyIpOworICAgICAgICAgICAgdG9zLnB1dEFyY2hpdmVFbnRyeShpbik7CisgICAgICAgICAgICBmaW5hbCBieXRlW10gYiA9IG5ldyBieXRlWyhpbnQpIHRtcFsxXS5sZW5ndGgoKV07CisgICAgICAgICAgICBmaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKHRtcFsxXSk7CisgICAgICAgICAgICB3aGlsZSAoZmlzLnJlYWQoYikgPiAwKSB7CisgICAgICAgICAgICAgICAgdG9zLndyaXRlKGIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZmlzLmNsb3NlKCk7CisgICAgICAgICAgICBmaXMgPSBudWxsOworICAgICAgICAgICAgdG9zLmNsb3NlQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgICAgICB0b3MuY2xvc2UoKTsKKyAgICAgICAgICAgIHRvcyA9IG51bGw7CisgICAgICAgICAgICB0aXMgPSBuZXcgVGFyQXJjaGl2ZUlucHV0U3RyZWFtKG5ldyBGaWxlSW5wdXRTdHJlYW0oYXJjaGl2ZSkpOworICAgICAgICAgICAgZmluYWwgVGFyQXJjaGl2ZUVudHJ5IG91dCA9IHRpcy5nZXROZXh0VGFyRW50cnkoKTsKKyAgICAgICAgICAgIHRpcy5jbG9zZSgpOworICAgICAgICAgICAgdGlzID0gbnVsbDsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwob3V0KTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZm9vIiwgb3V0LmdldE5hbWUoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHModG1wWzFdLmxlbmd0aCgpLCBvdXQuZ2V0U2l6ZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyh0bXBbMV0ubGFzdE1vZGlmaWVkKCkgLyAxMDAwLAorICAgICAgICAgICAgICAgICAgICAgICAgIG91dC5nZXRMYXN0TW9kaWZpZWREYXRlKCkuZ2V0VGltZSgpIC8gMTAwMCk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShvdXQuaXNEaXJlY3RvcnkoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAodGlzICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aXMuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICh0b3MgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRvcy5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdHJ5SGFyZFRvRGVsZXRlKGFyY2hpdmUpOworICAgICAgICAgICAgaWYgKGZpcyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgZmlzLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnlIYXJkVG9EZWxldGUodG1wWzFdKTsKKyAgICAgICAgICAgIHJtZGlyKHRtcFswXSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RFeHBsaWNpdEZpbGVFbnRyeSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlW10gdG1wID0gY3JlYXRlVGVtcERpckFuZEZpbGUoKTsKKyAgICAgICAgRmlsZSBhcmNoaXZlID0gbnVsbDsKKyAgICAgICAgVGFyQXJjaGl2ZU91dHB1dFN0cmVhbSB0b3MgPSBudWxsOworICAgICAgICBUYXJBcmNoaXZlSW5wdXRTdHJlYW0gdGlzID0gbnVsbDsKKyAgICAgICAgRmlsZUlucHV0U3RyZWFtIGZpcyA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhcmNoaXZlID0gRmlsZS5jcmVhdGVUZW1wRmlsZSgidGVzdC4iLCAiLnRhciIsIHRtcFswXSk7CisgICAgICAgICAgICBhcmNoaXZlLmRlbGV0ZU9uRXhpdCgpOworICAgICAgICAgICAgdG9zID0gbmV3IFRhckFyY2hpdmVPdXRwdXRTdHJlYW0obmV3IEZpbGVPdXRwdXRTdHJlYW0oYXJjaGl2ZSkpOworICAgICAgICAgICAgZmluYWwgVGFyQXJjaGl2ZUVudHJ5IGluID0gbmV3IFRhckFyY2hpdmVFbnRyeSgiZm9vIik7CisgICAgICAgICAgICBpbi5zZXRNb2RUaW1lKHRtcFsxXS5sYXN0TW9kaWZpZWQoKSk7CisgICAgICAgICAgICBpbi5zZXRTaXplKHRtcFsxXS5sZW5ndGgoKSk7CisgICAgICAgICAgICB0b3MucHV0QXJjaGl2ZUVudHJ5KGluKTsKKyAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBiID0gbmV3IGJ5dGVbKGludCkgdG1wWzFdLmxlbmd0aCgpXTsKKyAgICAgICAgICAgIGZpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0odG1wWzFdKTsKKyAgICAgICAgICAgIHdoaWxlIChmaXMucmVhZChiKSA+IDApIHsKKyAgICAgICAgICAgICAgICB0b3Mud3JpdGUoYik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmaXMuY2xvc2UoKTsKKyAgICAgICAgICAgIGZpcyA9IG51bGw7CisgICAgICAgICAgICB0b3MuY2xvc2VBcmNoaXZlRW50cnkoKTsKKyAgICAgICAgICAgIHRvcy5jbG9zZSgpOworICAgICAgICAgICAgdG9zID0gbnVsbDsKKyAgICAgICAgICAgIHRpcyA9IG5ldyBUYXJBcmNoaXZlSW5wdXRTdHJlYW0obmV3IEZpbGVJbnB1dFN0cmVhbShhcmNoaXZlKSk7CisgICAgICAgICAgICBmaW5hbCBUYXJBcmNoaXZlRW50cnkgb3V0ID0gdGlzLmdldE5leHRUYXJFbnRyeSgpOworICAgICAgICAgICAgdGlzLmNsb3NlKCk7CisgICAgICAgICAgICB0aXMgPSBudWxsOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChvdXQpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJmb28iLCBvdXQuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyh0bXBbMV0ubGVuZ3RoKCksIG91dC5nZXRTaXplKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHRtcFsxXS5sYXN0TW9kaWZpZWQoKSAvIDEwMDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgb3V0LmdldExhc3RNb2RpZmllZERhdGUoKS5nZXRUaW1lKCkgLyAxMDAwKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKG91dC5pc0RpcmVjdG9yeSgpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmICh0aXMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRpcy5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHRvcyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgdG9zLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnlIYXJkVG9EZWxldGUoYXJjaGl2ZSk7CisgICAgICAgICAgICBpZiAoZmlzICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBmaXMuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRyeUhhcmRUb0RlbGV0ZSh0bXBbMV0pOworICAgICAgICAgICAgcm1kaXIodG1wWzBdKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdENPTVBSRVNTMTc4KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGUgaW5wdXQgPSBnZXRGaWxlKCJDT01QUkVTUy0xNzgudGFyIik7CisgICAgICAgIGZpbmFsIElucHV0U3RyZWFtIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShpbnB1dCk7CisgICAgICAgIGZpbmFsIEFyY2hpdmVJbnB1dFN0cmVhbSBpbiA9IG5ldyBBcmNoaXZlU3RyZWFtRmFjdG9yeSgpLmNyZWF0ZUFyY2hpdmVJbnB1dFN0cmVhbSgidGFyIiwgaXMpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW4uZ2V0TmV4dEVudHJ5KCk7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBJT0V4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChmaW5hbCBJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmaW5hbCBUaHJvd2FibGUgdCA9IGUuZ2V0Q2F1c2UoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkV4cGVjdGVkIGNhdXNlID0gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIiwgdCBpbnN0YW5jZW9mIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbik7CisgICAgICAgIH0KKyAgICAgICAgaW4uY2xvc2UoKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9UZXN0QXJjaGl2ZVN0cmVhbVByb3ZpZGVyLmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvVGVzdEFyY2hpdmVTdHJlYW1Qcm92aWRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY2YjdmNWUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvVGVzdEFyY2hpdmVTdHJlYW1Qcm92aWRlci5qYXZhCkBAIC0wLDAgKzEsNjMgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnM7CisKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworCitwdWJsaWMgY2xhc3MgVGVzdEFyY2hpdmVTdHJlYW1Qcm92aWRlciBpbXBsZW1lbnRzIEFyY2hpdmVTdHJlYW1Qcm92aWRlciB7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEFyY2hpdmVJbnZvY2F0aW9uQ29uZmlybWF0aW9uRXhjZXB0aW9uIGV4dGVuZHMgQXJjaGl2ZUV4Y2VwdGlvbiB7CisKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7CisKKyAgICAgICAgcHVibGljIEFyY2hpdmVJbnZvY2F0aW9uQ29uZmlybWF0aW9uRXhjZXB0aW9uKGZpbmFsIFN0cmluZyBtZXNzYWdlKSB7CisgICAgICAgICAgICBzdXBlcihtZXNzYWdlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBBcmNoaXZlSW5wdXRTdHJlYW0gY3JlYXRlQXJjaGl2ZUlucHV0U3RyZWFtKGZpbmFsIFN0cmluZyBuYW1lLCBmaW5hbCBJbnB1dFN0cmVhbSBpbiwgZmluYWwgU3RyaW5nIGVuY29kaW5nKSB0aHJvd3MgQXJjaGl2ZUV4Y2VwdGlvbiB7CisgICAgICAgIHRocm93IG5ldyBBcmNoaXZlSW52b2NhdGlvbkNvbmZpcm1hdGlvbkV4Y2VwdGlvbihuYW1lKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQXJjaGl2ZU91dHB1dFN0cmVhbSBjcmVhdGVBcmNoaXZlT3V0cHV0U3RyZWFtKGZpbmFsIFN0cmluZyBuYW1lLCBmaW5hbCBPdXRwdXRTdHJlYW0gb3V0LCBmaW5hbCBTdHJpbmcgZW5jb2RpbmcpIHRocm93cyBBcmNoaXZlRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IEFyY2hpdmVJbnZvY2F0aW9uQ29uZmlybWF0aW9uRXhjZXB0aW9uKG5hbWUpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTZXQ8U3RyaW5nPiBnZXRJbnB1dFN0cmVhbUFyY2hpdmVOYW1lcygpIHsKKyAgICAgICAgZmluYWwgSGFzaFNldDxTdHJpbmc+IHNldCA9IG5ldyBIYXNoU2V0PD4oKTsKKyAgICAgICAgQ29sbGVjdGlvbnMuYWRkQWxsKHNldCwgIkFyY2hpdmVUZXN0SW5wdXQxIik7CisgICAgICAgIHJldHVybiBzZXQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNldDxTdHJpbmc+IGdldE91dHB1dFN0cmVhbUFyY2hpdmVOYW1lcygpIHsKKyAgICAgICAgZmluYWwgSGFzaFNldDxTdHJpbmc+IHNldCA9IG5ldyBIYXNoU2V0PD4oKTsKKyAgICAgICAgQ29sbGVjdGlvbnMuYWRkQWxsKHNldCwgIkFyY2hpdmVUZXN0T3V0cHV0MSIpOworICAgICAgICByZXR1cm4gc2V0OworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL1ppcFRlc3RDYXNlLmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvWmlwVGVzdENhc2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZDBiMTUxCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL1ppcFRlc3RDYXNlLmphdmEKQEAgLTAsMCArMSw3MTAgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzOworCitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuKjsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC56aXAuWmlwRW50cnk7CitpbXBvcnQgamF2YS51dGlsLnppcC5aaXBFeGNlcHRpb247CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuQWJzdHJhY3RUZXN0Q2FzZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcC5aaXA2NE1vZGU7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXAuWmlwQXJjaGl2ZUVudHJ5OworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwLlppcEFyY2hpdmVFbnRyeVByZWRpY2F0ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcC5aaXBBcmNoaXZlSW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXAuWmlwQXJjaGl2ZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcC5aaXBGaWxlOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwLlppcE1ldGhvZDsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuSU9VdGlsczsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuSW5wdXRTdHJlYW1TdGF0aXN0aWNzOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5TZWVrYWJsZUluTWVtb3J5Qnl0ZUNoYW5uZWw7CitpbXBvcnQgb3JnLmp1bml0LkFzc2VydDsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworcHVibGljIGZpbmFsIGNsYXNzIFppcFRlc3RDYXNlIGV4dGVuZHMgQWJzdHJhY3RUZXN0Q2FzZSB7CisgICAgLyoqCisgICAgICogQXJjaGl2ZXMgMiBmaWxlcyBhbmQgdW5hcmNoaXZlcyBpdCBhZ2Fpbi4gSWYgdGhlIGZpbGUgbGVuZ3RoIG9mIHJlc3VsdAorICAgICAqIGFuZCBzb3VyY2UgaXMgdGhlIHNhbWUsIGl0IGxvb2tzIGxpa2UgdGhlIG9wZXJhdGlvbnMgaGF2ZSB3b3JrZWQKKyAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFppcEFyY2hpdmVDcmVhdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBBcmNoaXZlCisgICAgICAgIGZpbmFsIEZpbGUgb3V0cHV0ID0gbmV3IEZpbGUoZGlyLCAiYmxhLnppcCIpOworICAgICAgICBmaW5hbCBGaWxlIGZpbGUxID0gZ2V0RmlsZSgidGVzdDEueG1sIik7CisgICAgICAgIGZpbmFsIEZpbGUgZmlsZTIgPSBnZXRGaWxlKCJ0ZXN0Mi54bWwiKTsKKworICAgICAgICBmaW5hbCBPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0ob3V0cHV0KTsKKyAgICAgICAgQXJjaGl2ZU91dHB1dFN0cmVhbSBvcyA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvcyA9IG5ldyBBcmNoaXZlU3RyZWFtRmFjdG9yeSgpCisgICAgICAgICAgICAgICAgLmNyZWF0ZUFyY2hpdmVPdXRwdXRTdHJlYW0oInppcCIsIG91dCk7CisgICAgICAgICAgICBvcy5wdXRBcmNoaXZlRW50cnkobmV3IFppcEFyY2hpdmVFbnRyeSgidGVzdGRhdGEvdGVzdDEueG1sIikpOworICAgICAgICAgICAgSU9VdGlscy5jb3B5KG5ldyBGaWxlSW5wdXRTdHJlYW0oZmlsZTEpLCBvcyk7CisgICAgICAgICAgICBvcy5jbG9zZUFyY2hpdmVFbnRyeSgpOworCisgICAgICAgICAgICBvcy5wdXRBcmNoaXZlRW50cnkobmV3IFppcEFyY2hpdmVFbnRyeSgidGVzdGRhdGEvdGVzdDIueG1sIikpOworICAgICAgICAgICAgSU9VdGlscy5jb3B5KG5ldyBGaWxlSW5wdXRTdHJlYW0oZmlsZTIpLCBvcyk7CisgICAgICAgICAgICBvcy5jbG9zZUFyY2hpdmVFbnRyeSgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKG9zICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBvcy5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIG91dC5jbG9zZSgpOworCisgICAgICAgIC8vIFVuYXJjaGl2ZSB0aGUgc2FtZQorICAgICAgICBmaW5hbCBMaXN0PEZpbGU+IHJlc3VsdHMgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKworICAgICAgICBmaW5hbCBJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0ob3V0cHV0KTsKKyAgICAgICAgQXJjaGl2ZUlucHV0U3RyZWFtIGluID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGluID0gbmV3IEFyY2hpdmVTdHJlYW1GYWN0b3J5KCkKKyAgICAgICAgICAgICAgICAuY3JlYXRlQXJjaGl2ZUlucHV0U3RyZWFtKCJ6aXAiLCBpcyk7CisKKyAgICAgICAgICAgIFppcEFyY2hpdmVFbnRyeSBlbnRyeSA9IG51bGw7CisgICAgICAgICAgICB3aGlsZSgoZW50cnkgPSAoWmlwQXJjaGl2ZUVudHJ5KWluLmdldE5leHRFbnRyeSgpKSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgZmluYWwgRmlsZSBvdXRmaWxlID0gbmV3IEZpbGUocmVzdWx0RGlyLmdldENhbm9uaWNhbFBhdGgoKSArICIvcmVzdWx0LyIgKyBlbnRyeS5nZXROYW1lKCkpOworICAgICAgICAgICAgICAgIG91dGZpbGUuZ2V0UGFyZW50RmlsZSgpLm1rZGlycygpOworICAgICAgICAgICAgICAgIHRyeSAoT3V0cHV0U3RyZWFtIG8gPSBuZXcgRmlsZU91dHB1dFN0cmVhbShvdXRmaWxlKSkgeworICAgICAgICAgICAgICAgICAgICBJT1V0aWxzLmNvcHkoaW4sIG8pOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXN1bHRzLmFkZChvdXRmaWxlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmIChpbiAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpcy5jbG9zZSgpOworCisgICAgICAgIGFzc2VydEVxdWFscyhyZXN1bHRzLnNpemUoKSwgMik7CisgICAgICAgIEZpbGUgcmVzdWx0ID0gcmVzdWx0cy5nZXQoMCk7CisgICAgICAgIGFzc2VydEVxdWFscyhmaWxlMS5sZW5ndGgoKSwgcmVzdWx0Lmxlbmd0aCgpKTsKKyAgICAgICAgcmVzdWx0ID0gcmVzdWx0cy5nZXQoMSk7CisgICAgICAgIGFzc2VydEVxdWFscyhmaWxlMi5sZW5ndGgoKSwgcmVzdWx0Lmxlbmd0aCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBcmNoaXZlcyAyIGZpbGVzIGFuZCB1bmFyY2hpdmVzIGl0IGFnYWluLiBJZiB0aGUgZmlsZSBjb250ZW50cyBvZiByZXN1bHQKKyAgICAgKiBhbmQgc291cmNlIGlzIHRoZSBzYW1lLCBpdCBsb29rcyBsaWtlIHRoZSBvcGVyYXRpb25zIGhhdmUgd29ya2VkCisgICAgICogQHRocm93cyBFeGNlcHRpb24KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RaaXBBcmNoaXZlQ3JlYXRpb25Jbk1lbW9yeSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlIGZpbGUxID0gZ2V0RmlsZSgidGVzdDEueG1sIik7CisgICAgICAgIGZpbmFsIEZpbGUgZmlsZTIgPSBnZXRGaWxlKCJ0ZXN0Mi54bWwiKTsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGZpbGUxQ29udGVudHMgPSBuZXcgYnl0ZVsoaW50KSBmaWxlMS5sZW5ndGgoKV07CisgICAgICAgIGZpbmFsIGJ5dGVbXSBmaWxlMkNvbnRlbnRzID0gbmV3IGJ5dGVbKGludCkgZmlsZTIubGVuZ3RoKCldOworICAgICAgICBJT1V0aWxzLnJlYWRGdWxseShuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGUxKSwgZmlsZTFDb250ZW50cyk7CisgICAgICAgIElPVXRpbHMucmVhZEZ1bGx5KG5ldyBGaWxlSW5wdXRTdHJlYW0oZmlsZTIpLCBmaWxlMkNvbnRlbnRzKTsKKworICAgICAgICBTZWVrYWJsZUluTWVtb3J5Qnl0ZUNoYW5uZWwgY2hhbm5lbCA9IG5ldyBTZWVrYWJsZUluTWVtb3J5Qnl0ZUNoYW5uZWwoKTsKKyAgICAgICAgdHJ5IChaaXBBcmNoaXZlT3V0cHV0U3RyZWFtIG9zID0gbmV3IFppcEFyY2hpdmVPdXRwdXRTdHJlYW0oY2hhbm5lbCkpIHsKKyAgICAgICAgICAgIG9zLnB1dEFyY2hpdmVFbnRyeShuZXcgWmlwQXJjaGl2ZUVudHJ5KCJ0ZXN0ZGF0YS90ZXN0MS54bWwiKSk7CisgICAgICAgICAgICBvcy53cml0ZShmaWxlMUNvbnRlbnRzKTsKKyAgICAgICAgICAgIG9zLmNsb3NlQXJjaGl2ZUVudHJ5KCk7CisKKyAgICAgICAgICAgIG9zLnB1dEFyY2hpdmVFbnRyeShuZXcgWmlwQXJjaGl2ZUVudHJ5KCJ0ZXN0ZGF0YS90ZXN0Mi54bWwiKSk7CisgICAgICAgICAgICBvcy53cml0ZShmaWxlMkNvbnRlbnRzKTsKKyAgICAgICAgICAgIG9zLmNsb3NlQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgIH0KKworICAgICAgICAvLyBVbmFyY2hpdmUgdGhlIHNhbWUKKyAgICAgICAgZmluYWwgTGlzdDxieXRlW10+IHJlc3VsdHMgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKworICAgICAgICB0cnkgKEFyY2hpdmVJbnB1dFN0cmVhbSBpbiA9IG5ldyBBcmNoaXZlU3RyZWFtRmFjdG9yeSgpCisgICAgICAgICAgICAgLmNyZWF0ZUFyY2hpdmVJbnB1dFN0cmVhbSgiemlwIiwgbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGNoYW5uZWwuYXJyYXkoKSkpKSB7CisKKyAgICAgICAgICAgIFppcEFyY2hpdmVFbnRyeSBlbnRyeTsKKyAgICAgICAgICAgIHdoaWxlKChlbnRyeSA9IChaaXBBcmNoaXZlRW50cnkpaW4uZ2V0TmV4dEVudHJ5KCkpICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBieXRlW10gcmVzdWx0ID0gbmV3IGJ5dGVbKGludCkgZW50cnkuZ2V0U2l6ZSgpXTsKKyAgICAgICAgICAgICAgICBJT1V0aWxzLnJlYWRGdWxseShpbiwgcmVzdWx0KTsKKyAgICAgICAgICAgICAgICByZXN1bHRzLmFkZChyZXN1bHQpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMocmVzdWx0cy5nZXQoMCksIGZpbGUxQ29udGVudHMpOworICAgICAgICBhc3NlcnRBcnJheUVxdWFscyhyZXN1bHRzLmdldCgxKSwgZmlsZTJDb250ZW50cyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2ltcGxlIHVuYXJjaGl2ZSB0ZXN0LiBBc3NlcnRzIG5vdGhpbmcuCisgICAgICogQHRocm93cyBFeGNlcHRpb24KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RaaXBVbmFyY2hpdmUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgRmlsZSBpbnB1dCA9IGdldEZpbGUoImJsYS56aXAiKTsKKyAgICAgICAgdHJ5IChmaW5hbCBJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpOworICAgICAgICAgICAgICAgIGZpbmFsIEFyY2hpdmVJbnB1dFN0cmVhbSBpbiA9IG5ldyBBcmNoaXZlU3RyZWFtRmFjdG9yeSgpLmNyZWF0ZUFyY2hpdmVJbnB1dFN0cmVhbSgiemlwIiwgaXMpKSB7CisgICAgICAgICAgICBmaW5hbCBaaXBBcmNoaXZlRW50cnkgZW50cnkgPSAoWmlwQXJjaGl2ZUVudHJ5KSBpbi5nZXROZXh0RW50cnkoKTsKKyAgICAgICAgICAgIHRyeSAoZmluYWwgT3V0cHV0U3RyZWFtIG91dCA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKG5ldyBGaWxlKGRpciwgZW50cnkuZ2V0TmFtZSgpKSkpIHsKKyAgICAgICAgICAgICAgICBJT1V0aWxzLmNvcHkoaW4sIG91dCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGNhc2UgZm9yCisgICAgICogPGEgaHJlZj0iaHR0cHM6Ly9pc3N1ZXMuYXBhY2hlLm9yZy9qaXJhL2Jyb3dzZS9DT01QUkVTUy0yMDgiCisgICAgICogPkNPTVBSRVNTLTIwODwvYT4uCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2tpcHNQSzAwUHJlZml4KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGUgaW5wdXQgPSBnZXRGaWxlKCJDT01QUkVTUy0yMDguemlwIik7CisgICAgICAgIGZpbmFsIEFycmF5TGlzdDxTdHJpbmc+IGFsID0gbmV3IEFycmF5TGlzdDw+KCk7CisgICAgICAgIGFsLmFkZCgidGVzdDEueG1sIik7CisgICAgICAgIGFsLmFkZCgidGVzdDIueG1sIik7CisgICAgICAgIHRyeSAoSW5wdXRTdHJlYW0gaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGlucHV0KSkgeworICAgICAgICAgICAgY2hlY2tBcmNoaXZlQ29udGVudChuZXcgWmlwQXJjaGl2ZUlucHV0U3RyZWFtKGlzKSwgYWwpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBjYXNlIGZvcgorICAgICAqIDxhIGhyZWY9Imh0dHBzOi8vaXNzdWVzLmFwYWNoZS5vcmcvamlyYS9icm93c2UvQ09NUFJFU1MtOTMiCisgICAgICogPkNPTVBSRVNTLTkzPC9hPi4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RTdXBwb3J0ZWRDb21wcmVzc2lvbk1ldGhvZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8qCisgICAgICAgIFppcEZpbGUgYmxhID0gbmV3IFppcEZpbGUoZ2V0RmlsZSgiYmxhLnppcCIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShibGEuY2FuUmVhZEVudHJ5RGF0YShibGEuZ2V0RW50cnkoInRlc3QxLnhtbCIpKSk7CisgICAgICAgIGJsYS5jbG9zZSgpOworICAgICAgICAqLworCisgICAgICAgIGZpbmFsIFppcEZpbGUgbW9ieSA9IG5ldyBaaXBGaWxlKGdldEZpbGUoIm1vYnkuemlwIikpOworICAgICAgICBmaW5hbCBaaXBBcmNoaXZlRW50cnkgZW50cnkgPSBtb2J5LmdldEVudHJ5KCJSRUFETUUiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJtZXRob2QiLCBaaXBNZXRob2QuVE9LRU5JWkFUSU9OLmdldENvZGUoKSwgZW50cnkuZ2V0TWV0aG9kKCkpOworICAgICAgICBhc3NlcnRGYWxzZShtb2J5LmNhblJlYWRFbnRyeURhdGEoZW50cnkpKTsKKyAgICAgICAgbW9ieS5jbG9zZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgY2FzZSBmb3IgYmVpbmcgYWJsZSB0byBza2lwIGFuIGVudHJ5IGluIGFuCisgICAgICoge0BsaW5rIFppcEFyY2hpdmVJbnB1dFN0cmVhbX0gZXZlbiBpZiB0aGUgY29tcHJlc3Npb24gbWV0aG9kIG9mIHRoYXQKKyAgICAgKiBlbnRyeSBpcyB1bnN1cHBvcnRlZC4KKyAgICAgKgorICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cHM6Ly9pc3N1ZXMuYXBhY2hlLm9yZy9qaXJhL2Jyb3dzZS9DT01QUkVTUy05MyIKKyAgICAgKiAgICAgICAgPkNPTVBSRVNTLTkzPC9hPgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFNraXBFbnRyeVdpdGhVbnN1cHBvcnRlZENvbXByZXNzaW9uTWV0aG9kKCkKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRyeSAoWmlwQXJjaGl2ZUlucHV0U3RyZWFtIHppcCA9IG5ldyBaaXBBcmNoaXZlSW5wdXRTdHJlYW0obmV3IEZpbGVJbnB1dFN0cmVhbShnZXRGaWxlKCJtb2J5LnppcCIpKSkpIHsKKyAgICAgICAgICAgIGZpbmFsIFppcEFyY2hpdmVFbnRyeSBlbnRyeSA9IHppcC5nZXROZXh0WmlwRW50cnkoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygibWV0aG9kIiwgWmlwTWV0aG9kLlRPS0VOSVpBVElPTi5nZXRDb2RlKCksIGVudHJ5LmdldE1ldGhvZCgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiUkVBRE1FIiwgZW50cnkuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKHppcC5jYW5SZWFkRW50cnlEYXRhKGVudHJ5KSk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGFzc2VydE51bGwoemlwLmdldE5leHRaaXBFbnRyeSgpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKGZpbmFsIElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgICAgIGZhaWwoIkNPTVBSRVNTLTkzOiBVbmFibGUgdG8gc2tpcCBhbiB1bnN1cHBvcnRlZCB6aXAgZW50cnkiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrcyBpZiBhbGwgZW50cmllcyBmcm9tIGEgbmVzdGVkIGFyY2hpdmUgY2FuIGJlIHJlYWQuCisgICAgICogVGhlIGFyY2hpdmU6IE9TWF9BcmNoaXZlV2l0aE5lc3RlZEFyY2hpdmUuemlwIGNvbnRhaW5zOgorICAgICAqIE5lc3RlZEFyY2hpdi56aXAgYW5kIHRlc3QueG1sMy4KKyAgICAgKgorICAgICAqIFRoZSBuZXN0ZWQgYXJjaGl2ZTogIE5lc3RlZEFyY2hpdmUuemlwIGNvbnRhaW5zIHRlc3QxLnhtbCBhbmQgdGVzdDIueG1sCisgICAgICoKKyAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdExpc3RBbGxGaWxlc1dpdGhOZXN0ZWRBcmNoaXZlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGUgaW5wdXQgPSBnZXRGaWxlKCJPU1hfQXJjaGl2ZVdpdGhOZXN0ZWRBcmNoaXZlLnppcCIpOworCisgICAgICAgIGZpbmFsIExpc3Q8U3RyaW5nPiByZXN1bHRzID0gbmV3IEFycmF5TGlzdDw+KCk7CisgICAgICAgIGZpbmFsIExpc3Q8WmlwRXhjZXB0aW9uPiBleHBlY3RlZEV4Y2VwdGlvbnMgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKworICAgICAgICBmaW5hbCBJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpOworICAgICAgICBBcmNoaXZlSW5wdXRTdHJlYW0gaW4gPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW4gPSBuZXcgQXJjaGl2ZVN0cmVhbUZhY3RvcnkoKS5jcmVhdGVBcmNoaXZlSW5wdXRTdHJlYW0oInppcCIsIGlzKTsKKworICAgICAgICAgICAgWmlwQXJjaGl2ZUVudHJ5IGVudHJ5ID0gbnVsbDsKKyAgICAgICAgICAgIHdoaWxlICgoZW50cnkgPSAoWmlwQXJjaGl2ZUVudHJ5KSBpbi5nZXROZXh0RW50cnkoKSkgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJlc3VsdHMuYWRkKGVudHJ5LmdldE5hbWUoKSk7CisKKyAgICAgICAgICAgICAgICBmaW5hbCBBcmNoaXZlSW5wdXRTdHJlYW0gbmVzdGVkSW4gPSBuZXcgQXJjaGl2ZVN0cmVhbUZhY3RvcnkoKS5jcmVhdGVBcmNoaXZlSW5wdXRTdHJlYW0oInppcCIsIGluKTsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBaaXBBcmNoaXZlRW50cnkgbmVzdGVkRW50cnkgPSBudWxsOworICAgICAgICAgICAgICAgICAgICB3aGlsZSAoKG5lc3RlZEVudHJ5ID0gKFppcEFyY2hpdmVFbnRyeSkgbmVzdGVkSW4uZ2V0TmV4dEVudHJ5KCkpICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMuYWRkKG5lc3RlZEVudHJ5LmdldE5hbWUoKSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGNhdGNoIChaaXBFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gZXhwZWN0ZWQgc2luY2UgeW91IGNhbm5vdCBjcmVhdGUgYSBmaW5hbCBBcmNoaXZlSW5wdXRTdHJlYW0gZnJvbSB0ZXN0My54bWwKKyAgICAgICAgICAgICAgICAgICAgZXhwZWN0ZWRFeGNlcHRpb25zLmFkZChleCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIC8vIG5lc3RlZCBzdHJlYW0gbXVzdCBub3QgYmUgY2xvc2VkIGhlcmUKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmIChpbiAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpcy5jbG9zZSgpOworCisgICAgICAgIGFzc2VydFRydWUocmVzdWx0cy5jb250YWlucygiTmVzdGVkQXJjaGl2LnppcCIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHRzLmNvbnRhaW5zKCJ0ZXN0MS54bWwiKSk7CisgICAgICAgIGFzc2VydFRydWUocmVzdWx0cy5jb250YWlucygidGVzdDIueG1sIikpOworICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdHMuY29udGFpbnMoInRlc3QzLnhtbCIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGV4cGVjdGVkRXhjZXB0aW9ucy5zaXplKCkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdERpcmVjdG9yeUVudHJ5RnJvbUZpbGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgRmlsZVtdIHRtcCA9IGNyZWF0ZVRlbXBEaXJBbmRGaWxlKCk7CisgICAgICAgIEZpbGUgYXJjaGl2ZSA9IG51bGw7CisgICAgICAgIFppcEFyY2hpdmVPdXRwdXRTdHJlYW0gem9zID0gbnVsbDsKKyAgICAgICAgWmlwRmlsZSB6ZiA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhcmNoaXZlID0gRmlsZS5jcmVhdGVUZW1wRmlsZSgidGVzdC4iLCAiLnppcCIsIHRtcFswXSk7CisgICAgICAgICAgICBhcmNoaXZlLmRlbGV0ZU9uRXhpdCgpOworICAgICAgICAgICAgem9zID0gbmV3IFppcEFyY2hpdmVPdXRwdXRTdHJlYW0oYXJjaGl2ZSk7CisgICAgICAgICAgICBmaW5hbCBsb25nIGJlZm9yZUFyY2hpdmVXcml0ZSA9IHRtcFswXS5sYXN0TW9kaWZpZWQoKTsKKyAgICAgICAgICAgIGZpbmFsIFppcEFyY2hpdmVFbnRyeSBpbiA9IG5ldyBaaXBBcmNoaXZlRW50cnkodG1wWzBdLCAiZm9vIik7CisgICAgICAgICAgICB6b3MucHV0QXJjaGl2ZUVudHJ5KGluKTsKKyAgICAgICAgICAgIHpvcy5jbG9zZUFyY2hpdmVFbnRyeSgpOworICAgICAgICAgICAgem9zLmNsb3NlKCk7CisgICAgICAgICAgICB6b3MgPSBudWxsOworICAgICAgICAgICAgemYgPSBuZXcgWmlwRmlsZShhcmNoaXZlKTsKKyAgICAgICAgICAgIGZpbmFsIFppcEFyY2hpdmVFbnRyeSBvdXQgPSB6Zi5nZXRFbnRyeSgiZm9vLyIpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChvdXQpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJmb28vIiwgb3V0LmdldE5hbWUoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMCwgb3V0LmdldFNpemUoKSk7CisgICAgICAgICAgICAvLyBaSVAgc3RvcmVzIHRpbWUgd2l0aCBhIGdyYW51bGFyaXR5IG9mIDIgc2Vjb25kcworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGJlZm9yZUFyY2hpdmVXcml0ZSAvIDIwMDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgb3V0LmdldExhc3RNb2RpZmllZERhdGUoKS5nZXRUaW1lKCkgLyAyMDAwKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUob3V0LmlzRGlyZWN0b3J5KCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgWmlwRmlsZS5jbG9zZVF1aWV0bHkoemYpOworICAgICAgICAgICAgaWYgKHpvcyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgem9zLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnlIYXJkVG9EZWxldGUoYXJjaGl2ZSk7CisgICAgICAgICAgICB0cnlIYXJkVG9EZWxldGUodG1wWzFdKTsKKyAgICAgICAgICAgIHJtZGlyKHRtcFswXSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RFeHBsaWNpdERpcmVjdG9yeUVudHJ5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGVbXSB0bXAgPSBjcmVhdGVUZW1wRGlyQW5kRmlsZSgpOworICAgICAgICBGaWxlIGFyY2hpdmUgPSBudWxsOworICAgICAgICBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtIHpvcyA9IG51bGw7CisgICAgICAgIFppcEZpbGUgemYgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXJjaGl2ZSA9IEZpbGUuY3JlYXRlVGVtcEZpbGUoInRlc3QuIiwgIi56aXAiLCB0bXBbMF0pOworICAgICAgICAgICAgYXJjaGl2ZS5kZWxldGVPbkV4aXQoKTsKKyAgICAgICAgICAgIHpvcyA9IG5ldyBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtKGFyY2hpdmUpOworICAgICAgICAgICAgZmluYWwgbG9uZyBiZWZvcmVBcmNoaXZlV3JpdGUgPSB0bXBbMF0ubGFzdE1vZGlmaWVkKCk7CisgICAgICAgICAgICBmaW5hbCBaaXBBcmNoaXZlRW50cnkgaW4gPSBuZXcgWmlwQXJjaGl2ZUVudHJ5KCJmb28vIik7CisgICAgICAgICAgICBpbi5zZXRUaW1lKGJlZm9yZUFyY2hpdmVXcml0ZSk7CisgICAgICAgICAgICB6b3MucHV0QXJjaGl2ZUVudHJ5KGluKTsKKyAgICAgICAgICAgIHpvcy5jbG9zZUFyY2hpdmVFbnRyeSgpOworICAgICAgICAgICAgem9zLmNsb3NlKCk7CisgICAgICAgICAgICB6b3MgPSBudWxsOworICAgICAgICAgICAgemYgPSBuZXcgWmlwRmlsZShhcmNoaXZlKTsKKyAgICAgICAgICAgIGZpbmFsIFppcEFyY2hpdmVFbnRyeSBvdXQgPSB6Zi5nZXRFbnRyeSgiZm9vLyIpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChvdXQpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJmb28vIiwgb3V0LmdldE5hbWUoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMCwgb3V0LmdldFNpemUoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoYmVmb3JlQXJjaGl2ZVdyaXRlIC8gMjAwMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICBvdXQuZ2V0TGFzdE1vZGlmaWVkRGF0ZSgpLmdldFRpbWUoKSAvIDIwMDApOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShvdXQuaXNEaXJlY3RvcnkoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBaaXBGaWxlLmNsb3NlUXVpZXRseSh6Zik7CisgICAgICAgICAgICBpZiAoem9zICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICB6b3MuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRyeUhhcmRUb0RlbGV0ZShhcmNoaXZlKTsKKyAgICAgICAgICAgIHRyeUhhcmRUb0RlbGV0ZSh0bXBbMV0pOworICAgICAgICAgICAgcm1kaXIodG1wWzBdKTsKKyAgICAgICAgfQorICAgIH0KKyAgICBTdHJpbmcgZmlyc3RfcGF5bG9hZCA9ICJBQkJBIjsKKyAgICBTdHJpbmcgc2Vjb25kX3BheWxvYWQgPSAiQUFBQUFBQUFBQUFBIjsKKyAgICBaaXBBcmNoaXZlRW50cnlQcmVkaWNhdGUgYWxsRmlsZXNQcmVkaWNhdGUgPSBuZXcgWmlwQXJjaGl2ZUVudHJ5UHJlZGljYXRlKCkgeworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGJvb2xlYW4gdGVzdChmaW5hbCBaaXBBcmNoaXZlRW50cnkgemlwQXJjaGl2ZUVudHJ5KSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgIH07CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RDb3B5UmF3RW50cmllc0Zyb21GaWxlKCkKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisKKyAgICAgICAgZmluYWwgRmlsZVtdIHRtcCA9IGNyZWF0ZVRlbXBEaXJBbmRGaWxlKCk7CisgICAgICAgIGZpbmFsIEZpbGUgcmVmZXJlbmNlID0gY3JlYXRlUmVmZXJlbmNlRmlsZSh0bXBbMF0sIFppcDY0TW9kZS5OZXZlciwgImV4cGVjdGVkLiIpOworCisgICAgICAgIGZpbmFsIEZpbGUgYTEgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKCJzcmMxLiIsICIuemlwIiwgdG1wWzBdKTsKKyAgICAgICAgdHJ5IChmaW5hbCBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtIHpvcyA9IG5ldyBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtKGExKSkgeworICAgICAgICAgICAgem9zLnNldFVzZVppcDY0KFppcDY0TW9kZS5OZXZlcik7CisgICAgICAgICAgICBjcmVhdGVGaXJzdEVudHJ5KHpvcykuY2xvc2UoKTsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIEZpbGUgYTIgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKCJzcmMyLiIsICIuemlwIiwgdG1wWzBdKTsKKyAgICAgICAgdHJ5IChmaW5hbCBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtIHpvczEgPSBuZXcgWmlwQXJjaGl2ZU91dHB1dFN0cmVhbShhMikpIHsKKyAgICAgICAgICAgIHpvczEuc2V0VXNlWmlwNjQoWmlwNjRNb2RlLk5ldmVyKTsKKyAgICAgICAgICAgIGNyZWF0ZVNlY29uZEVudHJ5KHpvczEpLmNsb3NlKCk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgKGZpbmFsIFppcEZpbGUgemYxID0gbmV3IFppcEZpbGUoYTEpOyBmaW5hbCBaaXBGaWxlIHpmMiA9IG5ldyBaaXBGaWxlKGEyKSkgeworICAgICAgICAgICAgZmluYWwgRmlsZSBmaWxlUmVzdWx0ID0gRmlsZS5jcmVhdGVUZW1wRmlsZSgiZmlsZS1hY3R1YWwuIiwgIi56aXAiLCB0bXBbMF0pOworICAgICAgICAgICAgdHJ5IChmaW5hbCBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtIHpvczIgPSBuZXcgWmlwQXJjaGl2ZU91dHB1dFN0cmVhbShmaWxlUmVzdWx0KSkgeworICAgICAgICAgICAgICAgIHpmMS5jb3B5UmF3RW50cmllcyh6b3MyLCBhbGxGaWxlc1ByZWRpY2F0ZSk7CisgICAgICAgICAgICAgICAgemYyLmNvcHlSYXdFbnRyaWVzKHpvczIsIGFsbEZpbGVzUHJlZGljYXRlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIGNvcHlSYXdFbnRyaWVzIGRvZXMgbm90IGFkZCBzdXBlcmZsdW91cyB6aXA2NCBoZWFkZXIgbGlrZSByZWd1bGFyIHppcCBvdXRwdXQgc3RyZWFtCisgICAgICAgICAgICAvLyBkb2VzIHdoZW4gdXNpbmcgWmlwNjRNb2RlLkFzTmVlZGVkIHNvIGFsbCB0aGUgc291cmNlIG1hdGVyaWFsIGhhcyB0byBiZSBaaXA2NE1vZGUuTmV2ZXIsCisgICAgICAgICAgICAvLyBpZiBleGFjdCBiaW5hcnkgZXF1YWxpdHkgaXMgdG8gYmUgYWNoaWV2ZWQKKyAgICAgICAgICAgIGFzc2VydFNhbWVGaWxlQ29udGVudHMocmVmZXJlbmNlLCBmaWxlUmVzdWx0KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdENvcHlSYXdaaXA2NEVudHJ5RnJvbUZpbGUoKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKworICAgICAgICBmaW5hbCBGaWxlW10gdG1wID0gY3JlYXRlVGVtcERpckFuZEZpbGUoKTsKKyAgICAgICAgZmluYWwgRmlsZSByZWZlcmVuY2UgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKCJ6NjRyZWZlcmVuY2UuIiwgIi56aXAiLCB0bXBbMF0pOworICAgICAgICB0cnkgKGZpbmFsIFppcEFyY2hpdmVPdXRwdXRTdHJlYW0gem9zMSA9IG5ldyBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtKHJlZmVyZW5jZSkpIHsKKyAgICAgICAgICAgIHpvczEuc2V0VXNlWmlwNjQoWmlwNjRNb2RlLkFsd2F5cyk7CisgICAgICAgICAgICBjcmVhdGVGaXJzdEVudHJ5KHpvczEpOworICAgICAgICB9CisKKyAgICAgICAgZmluYWwgRmlsZSBhMSA9IEZpbGUuY3JlYXRlVGVtcEZpbGUoInppcDY0c3JjLiIsICIuemlwIiwgdG1wWzBdKTsKKyAgICAgICAgdHJ5IChmaW5hbCBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtIHpvcyA9IG5ldyBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtKGExKSkgeworICAgICAgICAgICAgem9zLnNldFVzZVppcDY0KFppcDY0TW9kZS5BbHdheXMpOworICAgICAgICAgICAgY3JlYXRlRmlyc3RFbnRyeSh6b3MpLmNsb3NlKCk7CisgICAgICAgIH0KKworICAgICAgICBmaW5hbCBGaWxlIGZpbGVSZXN1bHQgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKCJmaWxlLWFjdHVhbC4iLCAiLnppcCIsIHRtcFswXSk7CisgICAgICAgIHRyeSAoZmluYWwgWmlwRmlsZSB6ZjEgPSBuZXcgWmlwRmlsZShhMSkpIHsKKyAgICAgICAgICAgIHRyeSAoZmluYWwgWmlwQXJjaGl2ZU91dHB1dFN0cmVhbSB6b3MyID0gbmV3IFppcEFyY2hpdmVPdXRwdXRTdHJlYW0oZmlsZVJlc3VsdCkpIHsKKyAgICAgICAgICAgICAgICB6b3MyLnNldFVzZVppcDY0KFppcDY0TW9kZS5BbHdheXMpOworICAgICAgICAgICAgICAgIHpmMS5jb3B5UmF3RW50cmllcyh6b3MyLCBhbGxGaWxlc1ByZWRpY2F0ZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRTYW1lRmlsZUNvbnRlbnRzKHJlZmVyZW5jZSwgZmlsZVJlc3VsdCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RVbml4TW9kZUluQWRkUmF3KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKworICAgICAgICBmaW5hbCBGaWxlW10gdG1wID0gY3JlYXRlVGVtcERpckFuZEZpbGUoKTsKKworICAgICAgICBmaW5hbCBGaWxlIGExID0gRmlsZS5jcmVhdGVUZW1wRmlsZSgidW5peE1vZGVCaXRzLiIsICIuemlwIiwgdG1wWzBdKTsKKyAgICAgICAgdHJ5IChmaW5hbCBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtIHpvcyA9IG5ldyBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtKGExKSkgeworCisgICAgICAgICAgICBmaW5hbCBaaXBBcmNoaXZlRW50cnkgYXJjaGl2ZUVudHJ5ID0gbmV3IFppcEFyY2hpdmVFbnRyeSgiZnJlZCIpOworICAgICAgICAgICAgYXJjaGl2ZUVudHJ5LnNldFVuaXhNb2RlKDA2NjQpOworICAgICAgICAgICAgYXJjaGl2ZUVudHJ5LnNldE1ldGhvZChaaXBFbnRyeS5ERUZMQVRFRCk7CisgICAgICAgICAgICB6b3MuYWRkUmF3QXJjaGl2ZUVudHJ5KGFyY2hpdmVFbnRyeSwgbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKCJmdWQiLmdldEJ5dGVzKCkpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSAoZmluYWwgWmlwRmlsZSB6ZjEgPSBuZXcgWmlwRmlsZShhMSkpIHsKKyAgICAgICAgICAgIGZpbmFsIFppcEFyY2hpdmVFbnRyeSBmcmVkID0gemYxLmdldEVudHJ5KCJmcmVkIik7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMDY2NCwgZnJlZC5nZXRVbml4TW9kZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgRmlsZSBjcmVhdGVSZWZlcmVuY2VGaWxlKGZpbmFsIEZpbGUgZGlyZWN0b3J5LCBmaW5hbCBaaXA2NE1vZGUgemlwTW9kZSwgZmluYWwgU3RyaW5nIHByZWZpeCkKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGUgcmVmZXJlbmNlID0gRmlsZS5jcmVhdGVUZW1wRmlsZShwcmVmaXgsICIuemlwIiwgZGlyZWN0b3J5KTsKKyAgICAgICAgdHJ5IChmaW5hbCBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtIHpvcyA9IG5ldyBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtKHJlZmVyZW5jZSkpIHsKKyAgICAgICAgICAgIHpvcy5zZXRVc2VaaXA2NCh6aXBNb2RlKTsKKyAgICAgICAgICAgIGNyZWF0ZUZpcnN0RW50cnkoem9zKTsKKyAgICAgICAgICAgIGNyZWF0ZVNlY29uZEVudHJ5KHpvcyk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlZmVyZW5jZTsKKyAgICB9CisKKyAgICBwcml2YXRlIFppcEFyY2hpdmVPdXRwdXRTdHJlYW0gY3JlYXRlRmlyc3RFbnRyeShmaW5hbCBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtIHpvcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY3JlYXRlQXJjaGl2ZUVudHJ5KGZpcnN0X3BheWxvYWQsIHpvcywgImZpbGUxLnR4dCIpOworICAgICAgICByZXR1cm4gem9zOworICAgIH0KKworICAgIHByaXZhdGUgWmlwQXJjaGl2ZU91dHB1dFN0cmVhbSBjcmVhdGVTZWNvbmRFbnRyeShmaW5hbCBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtIHpvcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY3JlYXRlQXJjaGl2ZUVudHJ5KHNlY29uZF9wYXlsb2FkLCB6b3MsICJmaWxlMi50eHQiKTsKKyAgICAgICAgcmV0dXJuIHpvczsKKyAgICB9CisKKworICAgIHByaXZhdGUgdm9pZCBhc3NlcnRTYW1lRmlsZUNvbnRlbnRzKGZpbmFsIEZpbGUgZXhwZWN0ZWRGaWxlLCBmaW5hbCBGaWxlIGFjdHVhbEZpbGUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIGludCBzaXplID0gKGludCkgTWF0aC5tYXgoZXhwZWN0ZWRGaWxlLmxlbmd0aCgpLCBhY3R1YWxGaWxlLmxlbmd0aCgpKTsKKyAgICAgICAgdHJ5IChmaW5hbCBaaXBGaWxlIGV4cGVjdGVkID0gbmV3IFppcEZpbGUoZXhwZWN0ZWRGaWxlKTsgZmluYWwgWmlwRmlsZSBhY3R1YWwgPSBuZXcgWmlwRmlsZShhY3R1YWxGaWxlKSkgeworICAgICAgICAgICAgZmluYWwgYnl0ZVtdIGV4cGVjdGVkQnVmID0gbmV3IGJ5dGVbc2l6ZV07CisgICAgICAgICAgICBmaW5hbCBieXRlW10gYWN0dWFsQnVmID0gbmV3IGJ5dGVbc2l6ZV07CisKKyAgICAgICAgICAgIGZpbmFsIEVudW1lcmF0aW9uPFppcEFyY2hpdmVFbnRyeT4gYWN0dWFsSW5PcmRlciA9IGFjdHVhbC5nZXRFbnRyaWVzSW5QaHlzaWNhbE9yZGVyKCk7CisgICAgICAgICAgICBmaW5hbCBFbnVtZXJhdGlvbjxaaXBBcmNoaXZlRW50cnk+IGV4cGVjdGVkSW5PcmRlciA9IGV4cGVjdGVkLmdldEVudHJpZXNJblBoeXNpY2FsT3JkZXIoKTsKKworICAgICAgICAgICAgd2hpbGUgKGFjdHVhbEluT3JkZXIuaGFzTW9yZUVsZW1lbnRzKCkpIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBaaXBBcmNoaXZlRW50cnkgYWN0dWFsRWxlbWVudCA9IGFjdHVhbEluT3JkZXIubmV4dEVsZW1lbnQoKTsKKyAgICAgICAgICAgICAgICBmaW5hbCBaaXBBcmNoaXZlRW50cnkgZXhwZWN0ZWRFbGVtZW50ID0gZXhwZWN0ZWRJbk9yZGVyLm5leHRFbGVtZW50KCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkRWxlbWVudC5nZXROYW1lKCksIGFjdHVhbEVsZW1lbnQuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgICAgICAvLyBEb24ndCBjb21wYXJlIHRpbWVzdGFtcHMgc2luY2UgdGhleSBtYXkgdmFyeTsKKyAgICAgICAgICAgICAgICAvLyB0aGVyZSdzIG5vIHN1cHBvcnQgZm9yIHN0dWJiZWQgb3V0IGNsb2NrIChUaW1lU291cmNlKSBpbiBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtCisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkRWxlbWVudC5nZXRNZXRob2QoKSwgYWN0dWFsRWxlbWVudC5nZXRNZXRob2QoKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkRWxlbWVudC5nZXRHZW5lcmFsUHVycG9zZUJpdCgpLCBhY3R1YWxFbGVtZW50LmdldEdlbmVyYWxQdXJwb3NlQml0KCkpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZEVsZW1lbnQuZ2V0Q3JjKCksIGFjdHVhbEVsZW1lbnQuZ2V0Q3JjKCkpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZEVsZW1lbnQuZ2V0Q29tcHJlc3NlZFNpemUoKSwgYWN0dWFsRWxlbWVudC5nZXRDb21wcmVzc2VkU2l6ZSgpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWRFbGVtZW50LmdldFNpemUoKSwgYWN0dWFsRWxlbWVudC5nZXRTaXplKCkpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZEVsZW1lbnQuZ2V0RXh0ZXJuYWxBdHRyaWJ1dGVzKCksIGFjdHVhbEVsZW1lbnQuZ2V0RXh0ZXJuYWxBdHRyaWJ1dGVzKCkpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZEVsZW1lbnQuZ2V0SW50ZXJuYWxBdHRyaWJ1dGVzKCksIGFjdHVhbEVsZW1lbnQuZ2V0SW50ZXJuYWxBdHRyaWJ1dGVzKCkpOworCisgICAgICAgICAgICAgICAgZmluYWwgSW5wdXRTdHJlYW0gYWN0dWFsSXMgPSBhY3R1YWwuZ2V0SW5wdXRTdHJlYW0oYWN0dWFsRWxlbWVudCk7CisgICAgICAgICAgICAgICAgZmluYWwgSW5wdXRTdHJlYW0gZXhwZWN0ZWRJcyA9IGV4cGVjdGVkLmdldElucHV0U3RyZWFtKGV4cGVjdGVkRWxlbWVudCk7CisgICAgICAgICAgICAgICAgSU9VdGlscy5yZWFkRnVsbHkoZXhwZWN0ZWRJcywgZXhwZWN0ZWRCdWYpOworICAgICAgICAgICAgICAgIElPVXRpbHMucmVhZEZ1bGx5KGFjdHVhbElzLCBhY3R1YWxCdWYpOworICAgICAgICAgICAgICAgIGV4cGVjdGVkSXMuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICBhY3R1YWxJcy5jbG9zZSgpOworICAgICAgICAgICAgICAgIEFzc2VydC5hc3NlcnRBcnJheUVxdWFscyhleHBlY3RlZEJ1ZiwgYWN0dWFsQnVmKTsgLy8gQnVmZmVycyBhcmUgbGFyZ2VyIHRoYW4gcGF5bG9hZC4gZG9udCBjYXJlCisgICAgICAgICAgICB9CisKKyAgICAgICAgfQorICAgIH0KKworCisgICAgcHJpdmF0ZSB2b2lkIGNyZWF0ZUFyY2hpdmVFbnRyeShmaW5hbCBTdHJpbmcgcGF5bG9hZCwgZmluYWwgWmlwQXJjaGl2ZU91dHB1dFN0cmVhbSB6b3MsIGZpbmFsIFN0cmluZyBuYW1lKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgWmlwQXJjaGl2ZUVudHJ5IGluID0gbmV3IFppcEFyY2hpdmVFbnRyeShuYW1lKTsKKyAgICAgICAgem9zLnB1dEFyY2hpdmVFbnRyeShpbik7CisKKyAgICAgICAgem9zLndyaXRlKHBheWxvYWQuZ2V0Qnl0ZXMoKSk7CisgICAgICAgIHpvcy5jbG9zZUFyY2hpdmVFbnRyeSgpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEZpbGVFbnRyeUZyb21GaWxlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGVbXSB0bXAgPSBjcmVhdGVUZW1wRGlyQW5kRmlsZSgpOworICAgICAgICBGaWxlIGFyY2hpdmUgPSBudWxsOworICAgICAgICBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtIHpvcyA9IG51bGw7CisgICAgICAgIFppcEZpbGUgemYgPSBudWxsOworICAgICAgICBGaWxlSW5wdXRTdHJlYW0gZmlzID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFyY2hpdmUgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKCJ0ZXN0LiIsICIuemlwIiwgdG1wWzBdKTsKKyAgICAgICAgICAgIGFyY2hpdmUuZGVsZXRlT25FeGl0KCk7CisgICAgICAgICAgICB6b3MgPSBuZXcgWmlwQXJjaGl2ZU91dHB1dFN0cmVhbShhcmNoaXZlKTsKKyAgICAgICAgICAgIGZpbmFsIFppcEFyY2hpdmVFbnRyeSBpbiA9IG5ldyBaaXBBcmNoaXZlRW50cnkodG1wWzFdLCAiZm9vIik7CisgICAgICAgICAgICB6b3MucHV0QXJjaGl2ZUVudHJ5KGluKTsKKyAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBiID0gbmV3IGJ5dGVbKGludCkgdG1wWzFdLmxlbmd0aCgpXTsKKyAgICAgICAgICAgIGZpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0odG1wWzFdKTsKKyAgICAgICAgICAgIHdoaWxlIChmaXMucmVhZChiKSA+IDApIHsKKyAgICAgICAgICAgICAgICB6b3Mud3JpdGUoYik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmaXMuY2xvc2UoKTsKKyAgICAgICAgICAgIGZpcyA9IG51bGw7CisgICAgICAgICAgICB6b3MuY2xvc2VBcmNoaXZlRW50cnkoKTsKKyAgICAgICAgICAgIHpvcy5jbG9zZSgpOworICAgICAgICAgICAgem9zID0gbnVsbDsKKyAgICAgICAgICAgIHpmID0gbmV3IFppcEZpbGUoYXJjaGl2ZSk7CisgICAgICAgICAgICBmaW5hbCBaaXBBcmNoaXZlRW50cnkgb3V0ID0gemYuZ2V0RW50cnkoImZvbyIpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChvdXQpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJmb28iLCBvdXQuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyh0bXBbMV0ubGVuZ3RoKCksIG91dC5nZXRTaXplKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHRtcFsxXS5sYXN0TW9kaWZpZWQoKSAvIDIwMDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgb3V0LmdldExhc3RNb2RpZmllZERhdGUoKS5nZXRUaW1lKCkgLyAyMDAwKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKG91dC5pc0RpcmVjdG9yeSgpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIFppcEZpbGUuY2xvc2VRdWlldGx5KHpmKTsKKyAgICAgICAgICAgIGlmICh6b3MgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHpvcy5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdHJ5SGFyZFRvRGVsZXRlKGFyY2hpdmUpOworICAgICAgICAgICAgaWYgKGZpcyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgZmlzLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnlIYXJkVG9EZWxldGUodG1wWzFdKTsKKyAgICAgICAgICAgIHJtZGlyKHRtcFswXSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RFeHBsaWNpdEZpbGVFbnRyeSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlW10gdG1wID0gY3JlYXRlVGVtcERpckFuZEZpbGUoKTsKKyAgICAgICAgRmlsZSBhcmNoaXZlID0gbnVsbDsKKyAgICAgICAgWmlwQXJjaGl2ZU91dHB1dFN0cmVhbSB6b3MgPSBudWxsOworICAgICAgICBaaXBGaWxlIHpmID0gbnVsbDsKKyAgICAgICAgRmlsZUlucHV0U3RyZWFtIGZpcyA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhcmNoaXZlID0gRmlsZS5jcmVhdGVUZW1wRmlsZSgidGVzdC4iLCAiLnppcCIsIHRtcFswXSk7CisgICAgICAgICAgICBhcmNoaXZlLmRlbGV0ZU9uRXhpdCgpOworICAgICAgICAgICAgem9zID0gbmV3IFppcEFyY2hpdmVPdXRwdXRTdHJlYW0oYXJjaGl2ZSk7CisgICAgICAgICAgICBmaW5hbCBaaXBBcmNoaXZlRW50cnkgaW4gPSBuZXcgWmlwQXJjaGl2ZUVudHJ5KCJmb28iKTsKKyAgICAgICAgICAgIGluLnNldFRpbWUodG1wWzFdLmxhc3RNb2RpZmllZCgpKTsKKyAgICAgICAgICAgIGluLnNldFNpemUodG1wWzFdLmxlbmd0aCgpKTsKKyAgICAgICAgICAgIHpvcy5wdXRBcmNoaXZlRW50cnkoaW4pOworICAgICAgICAgICAgZmluYWwgYnl0ZVtdIGIgPSBuZXcgYnl0ZVsoaW50KSB0bXBbMV0ubGVuZ3RoKCldOworICAgICAgICAgICAgZmlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbSh0bXBbMV0pOworICAgICAgICAgICAgd2hpbGUgKGZpcy5yZWFkKGIpID4gMCkgeworICAgICAgICAgICAgICAgIHpvcy53cml0ZShiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZpcy5jbG9zZSgpOworICAgICAgICAgICAgZmlzID0gbnVsbDsKKyAgICAgICAgICAgIHpvcy5jbG9zZUFyY2hpdmVFbnRyeSgpOworICAgICAgICAgICAgem9zLmNsb3NlKCk7CisgICAgICAgICAgICB6b3MgPSBudWxsOworICAgICAgICAgICAgemYgPSBuZXcgWmlwRmlsZShhcmNoaXZlKTsKKyAgICAgICAgICAgIGZpbmFsIFppcEFyY2hpdmVFbnRyeSBvdXQgPSB6Zi5nZXRFbnRyeSgiZm9vIik7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKG91dCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImZvbyIsIG91dC5nZXROYW1lKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHRtcFsxXS5sZW5ndGgoKSwgb3V0LmdldFNpemUoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHModG1wWzFdLmxhc3RNb2RpZmllZCgpIC8gMjAwMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICBvdXQuZ2V0TGFzdE1vZGlmaWVkRGF0ZSgpLmdldFRpbWUoKSAvIDIwMDApOworICAgICAgICAgICAgYXNzZXJ0RmFsc2Uob3V0LmlzRGlyZWN0b3J5KCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgWmlwRmlsZS5jbG9zZVF1aWV0bHkoemYpOworICAgICAgICAgICAgaWYgKHpvcyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgem9zLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnlIYXJkVG9EZWxldGUoYXJjaGl2ZSk7CisgICAgICAgICAgICBpZiAoZmlzICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBmaXMuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRyeUhhcmRUb0RlbGV0ZSh0bXBbMV0pOworICAgICAgICAgICAgcm1kaXIodG1wWzBdKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgaW5wdXRTdHJlYW1TdGF0aXN0aWNzT2ZaaXBCb21iRXhjZWwoKSB0aHJvd3MgSU9FeGNlcHRpb24sIEFyY2hpdmVFeGNlcHRpb24geworICAgICAgICBNYXA8U3RyaW5nLCBMaXN0PExvbmc+PiBleHBlY3RlZCA9IG5ldyBIYXNoTWFwPFN0cmluZywgTGlzdDxMb25nPj4oKSB7eworICAgICAgICAgICAgcHV0KCJbQ29udGVudF9UeXBlc10ueG1sIiwgQXJyYXlzLmFzTGlzdCg4MzkwMDM2TCwgODYwMEwpKTsKKyAgICAgICAgICAgIHB1dCgieGwvd29ya3NoZWV0cy9zaGVldDEueG1sIiwgQXJyYXlzLmFzTGlzdCgxMzQ4TCwgNTA4TCkpOworICAgICAgICB9fTsKKyAgICAgICAgdGVzdElucHV0U3RyZWFtU3RhdGlzdGljcygiemlwYm9tYi54bHN4IiwgZXhwZWN0ZWQpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgaW5wdXRTdHJlYW1TdGF0aXN0aWNzRm9ySW1wbG9kZWRFbnRyeSgpIHRocm93cyBJT0V4Y2VwdGlvbiwgQXJjaGl2ZUV4Y2VwdGlvbiB7CisgICAgICAgIE1hcDxTdHJpbmcsIExpc3Q8TG9uZz4+IGV4cGVjdGVkID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBMaXN0PExvbmc+PigpIHt7CisgICAgICAgICAgICBwdXQoIkxJQ0VOU0UuVFhUIiwgQXJyYXlzLmFzTGlzdCgxMTU2MEwsIDQxMzFMKSk7CisgICAgICAgIH19OworICAgICAgICB0ZXN0SW5wdXRTdHJlYW1TdGF0aXN0aWNzKCJpbXBsb2RpbmctOEtkaWN0LTN0cmVlcy56aXAiLCBleHBlY3RlZCk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBpbnB1dFN0cmVhbVN0YXRpc3RpY3NGb3JTaHJ1bmtFbnRyeSgpIHRocm93cyBJT0V4Y2VwdGlvbiwgQXJjaGl2ZUV4Y2VwdGlvbiB7CisgICAgICAgIE1hcDxTdHJpbmcsIExpc3Q8TG9uZz4+IGV4cGVjdGVkID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBMaXN0PExvbmc+PigpIHt7CisgICAgICAgICAgICBwdXQoIlRFU1QxLlhNTCIsIEFycmF5cy5hc0xpc3QoNzZMLCA2NkwpKTsKKyAgICAgICAgICAgIHB1dCgiVEVTVDIuWE1MIiwgQXJyYXlzLmFzTGlzdCg4MUwsIDc2TCkpOworICAgICAgICB9fTsKKyAgICAgICAgdGVzdElucHV0U3RyZWFtU3RhdGlzdGljcygiU0hSVU5LLlpJUCIsIGV4cGVjdGVkKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIGlucHV0U3RyZWFtU3RhdGlzdGljc0ZvclN0b3JlZEVudHJ5KCkgdGhyb3dzIElPRXhjZXB0aW9uLCBBcmNoaXZlRXhjZXB0aW9uIHsKKyAgICAgICAgTWFwPFN0cmluZywgTGlzdDxMb25nPj4gZXhwZWN0ZWQgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIExpc3Q8TG9uZz4+KCkge3sKKyAgICAgICAgICAgIHB1dCgidGVzdC50eHQiLCBBcnJheXMuYXNMaXN0KDVMLCA1TCkpOworICAgICAgICB9fTsKKyAgICAgICAgdGVzdElucHV0U3RyZWFtU3RhdGlzdGljcygiQ09NUFJFU1MtMjY0LnppcCIsIGV4cGVjdGVkKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIGlucHV0U3RyZWFtU3RhdGlzdGljc0ZvckJ6aXAyRW50cnkoKSB0aHJvd3MgSU9FeGNlcHRpb24sIEFyY2hpdmVFeGNlcHRpb24geworICAgICAgICBNYXA8U3RyaW5nLCBMaXN0PExvbmc+PiBleHBlY3RlZCA9IG5ldyBIYXNoTWFwPFN0cmluZywgTGlzdDxMb25nPj4oKSB7eworICAgICAgICAgICAgcHV0KCJsb3RzLW9mLWFzIiwgQXJyYXlzLmFzTGlzdCg0MkwsIDM5TCkpOworICAgICAgICB9fTsKKyAgICAgICAgdGVzdElucHV0U3RyZWFtU3RhdGlzdGljcygiYnppcDItemlwLnppcCIsIGV4cGVjdGVkKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIGlucHV0U3RyZWFtU3RhdGlzdGljc0ZvckRlZmxhdGU2NEVudHJ5KCkgdGhyb3dzIElPRXhjZXB0aW9uLCBBcmNoaXZlRXhjZXB0aW9uIHsKKyAgICAgICAgTWFwPFN0cmluZywgTGlzdDxMb25nPj4gZXhwZWN0ZWQgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIExpc3Q8TG9uZz4+KCkge3sKKyAgICAgICAgICAgIHB1dCgiaW5wdXQyIiwgQXJyYXlzLmFzTGlzdCgzMDcyTCwgMjExMUwpKTsKKyAgICAgICAgfX07CisgICAgICAgIHRlc3RJbnB1dFN0cmVhbVN0YXRpc3RpY3MoIkNPTVBSRVNTLTM4MC9DT01QUkVTUy0zODAuemlwIiwgZXhwZWN0ZWQpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0SW5wdXRTdHJlYW1TdGF0aXN0aWNzKFN0cmluZyBmaWxlTmFtZSwgTWFwPFN0cmluZywgTGlzdDxMb25nPj4gZXhwZWN0ZWRTdGF0aXN0aWNzKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIEFyY2hpdmVFeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlIGlucHV0ID0gZ2V0RmlsZShmaWxlTmFtZSk7CisKKyAgICAgICAgZmluYWwgTWFwPFN0cmluZyxMaXN0PExpc3Q8TG9uZz4+PiBhY3R1YWxTdGF0aXN0aWNzID0gbmV3IEhhc2hNYXA8PigpOworCisgICAgICAgIC8vIHN0cmVhbSBhY2Nlc3MKKyAgICAgICAgdHJ5IChmaW5hbCBGaWxlSW5wdXRTdHJlYW0gZmlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShpbnB1dCk7CisgICAgICAgICAgICBmaW5hbCBBcmNoaXZlSW5wdXRTdHJlYW0gaW4gPSBuZXcgQXJjaGl2ZVN0cmVhbUZhY3RvcnkoKS5jcmVhdGVBcmNoaXZlSW5wdXRTdHJlYW0oInppcCIsIGZpcykpIHsKKyAgICAgICAgICAgIGZvciAoQXJjaGl2ZUVudHJ5IGVudHJ5OyAoZW50cnkgPSBpbi5nZXROZXh0RW50cnkoKSkgIT0gbnVsbDsgKSB7CisgICAgICAgICAgICAgICAgcmVhZFN0cmVhbShpbiwgZW50cnksIGFjdHVhbFN0YXRpc3RpY3MpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gZmlsZSBhY2Nlc3MKKyAgICAgICAgdHJ5IChmaW5hbCBaaXBGaWxlIHpmID0gbmV3IFppcEZpbGUoaW5wdXQpKSB7CisgICAgICAgICAgICBmaW5hbCBFbnVtZXJhdGlvbjxaaXBBcmNoaXZlRW50cnk+IGVudHJpZXMgPSB6Zi5nZXRFbnRyaWVzKCk7CisgICAgICAgICAgICB3aGlsZSAoZW50cmllcy5oYXNNb3JlRWxlbWVudHMoKSkgeworICAgICAgICAgICAgICAgIGZpbmFsIFppcEFyY2hpdmVFbnRyeSB6YWUgPSBlbnRyaWVzLm5leHRFbGVtZW50KCk7CisgICAgICAgICAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBpbiA9IHpmLmdldElucHV0U3RyZWFtKHphZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgcmVhZFN0cmVhbShpbiwgemFlLCBhY3R1YWxTdGF0aXN0aWNzKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyBjb21wYXJlIHN0YXRpc3RpY3Mgb2Ygc3RyZWFtIC8gZmlsZSBhY2Nlc3MKKyAgICAgICAgZm9yIChNYXAuRW50cnk8U3RyaW5nLExpc3Q8TGlzdDxMb25nPj4+IG1lIDogYWN0dWFsU3RhdGlzdGljcy5lbnRyeVNldCgpKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIk1pc21hdGNoIG9mIHN0YXRzIGZvcjogIiArIG1lLmdldEtleSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgIG1lLmdldFZhbHVlKCkuZ2V0KDApLCBtZS5nZXRWYWx1ZSgpLmdldCgxKSk7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKE1hcC5FbnRyeTxTdHJpbmcsIExpc3Q8TG9uZz4+IG1lIDogZXhwZWN0ZWRTdGF0aXN0aWNzLmVudHJ5U2V0KCkpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiTWlzbWF0Y2ggb2Ygc3RhdHMgd2l0aCBleHBlY3RlZCB2YWx1ZSBmb3I6ICIgKyBtZS5nZXRLZXkoKSwKKyAgICAgICAgICAgICAgICBtZS5nZXRWYWx1ZSgpLCBhY3R1YWxTdGF0aXN0aWNzLmdldChtZS5nZXRLZXkoKSkuZ2V0KDApKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByZWFkU3RyZWFtKGZpbmFsIElucHV0U3RyZWFtIGluLCBmaW5hbCBBcmNoaXZlRW50cnkgZW50cnksIGZpbmFsIE1hcDxTdHJpbmcsTGlzdDxMaXN0PExvbmc+Pj4gbWFwKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBieXRlW10gYnVmID0gbmV3IGJ5dGVbNDA5Nl07CisgICAgICAgIGZpbmFsIElucHV0U3RyZWFtU3RhdGlzdGljcyBzdGF0cyA9IChJbnB1dFN0cmVhbVN0YXRpc3RpY3MpIGluOworICAgICAgICB3aGlsZSAoaW4ucmVhZChidWYpICE9IC0xKTsKKworICAgICAgICBmaW5hbCBTdHJpbmcgbmFtZSA9IGVudHJ5LmdldE5hbWUoKTsKKyAgICAgICAgZmluYWwgTGlzdDxMaXN0PExvbmc+PiBsOworICAgICAgICBpZiAobWFwLmNvbnRhaW5zS2V5KG5hbWUpKSB7CisgICAgICAgICAgICBsID0gbWFwLmdldChuYW1lKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIG1hcC5wdXQobmFtZSwgbCA9IG5ldyBBcnJheUxpc3Q8PigpKTsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIGxvbmcgdCA9IHN0YXRzLmdldFVuY29tcHJlc3NlZENvdW50KCk7CisgICAgICAgIGZpbmFsIGxvbmcgYiA9IHN0YXRzLmdldENvbXByZXNzZWRDb3VudCgpOworICAgICAgICBsLmFkZChBcnJheXMuYXNMaXN0KHQsIGIpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvYXIvQXJBcmNoaXZlSW5wdXRTdHJlYW1UZXN0LmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvYXIvQXJBcmNoaXZlSW5wdXRTdHJlYW1UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTY2NWZmOQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9hci9BckFyY2hpdmVJbnB1dFN0cmVhbVRlc3QuamF2YQpAQCAtMCwwICsxLDEwMiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICoKKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuYXI7CisKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC4qOworCitpbXBvcnQgamF2YS5pby5CdWZmZXJlZElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLkFic3RyYWN0VGVzdENhc2U7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5BcmNoaXZlRW50cnk7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLkFyY2hpdmVVdGlsczsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuSU9VdGlsczsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworcHVibGljIGNsYXNzIEFyQXJjaGl2ZUlucHV0U3RyZWFtVGVzdCBleHRlbmRzIEFic3RyYWN0VGVzdENhc2UgeworCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVhZExvbmdOYW1lc0dOVSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBjaGVja0xvbmdOYW1lRW50cnkoImxvbmdmaWxlX2dudS5hciIpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFJlYWRMb25nTmFtZXNCU0QoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tMb25nTmFtZUVudHJ5KCJsb25nZmlsZV9ic2QuYXIiKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY2hlY2tMb25nTmFtZUVudHJ5KGZpbmFsIFN0cmluZyBhcmNoaXZlKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IChmaW5hbCBGaWxlSW5wdXRTdHJlYW0gZmlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShnZXRGaWxlKGFyY2hpdmUpKTsKKyAgICAgICAgICAgICAgICBmaW5hbCBBckFyY2hpdmVJbnB1dFN0cmVhbSBzID0gbmV3IEFyQXJjaGl2ZUlucHV0U3RyZWFtKG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKGZpcykpKSB7CisgICAgICAgICAgICBBcmNoaXZlRW50cnkgZSA9IHMuZ2V0TmV4dEVudHJ5KCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoInRoaXNfaXNfYV9sb25nX2ZpbGVfbmFtZS50eHQiLCBlLmdldE5hbWUoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMTQsIGUuZ2V0U2l6ZSgpKTsKKyAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBoZWxsbyA9IG5ldyBieXRlWzE0XTsKKyAgICAgICAgICAgIHMucmVhZChoZWxsbyk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkhlbGxvLCB3b3JsZCFcbiIsIEFyY2hpdmVVdGlscy50b0FzY2lpU3RyaW5nKGhlbGxvKSk7CisgICAgICAgICAgICBlID0gcy5nZXROZXh0RW50cnkoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygidGhpc19pc19hX2xvbmdfZmlsZV9uYW1lX2FzX3dlbGwudHh0IiwgZS5nZXROYW1lKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDQsIGUuZ2V0U2l6ZSgpKTsKKyAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBieWUgPSBuZXcgYnl0ZVs0XTsKKyAgICAgICAgICAgIHMucmVhZChieWUpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJCeWVcbiIsIEFyY2hpdmVVdGlscy50b0FzY2lpU3RyaW5nKGJ5ZSkpOworICAgICAgICAgICAgYXNzZXJ0TnVsbChzLmdldE5leHRFbnRyeSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgc2luZ2xlQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgKEZpbGVJbnB1dFN0cmVhbSBpbiA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oZ2V0RmlsZSgiYmxhLmFyIikpOworICAgICAgICAgICAgIEFyQXJjaGl2ZUlucHV0U3RyZWFtIGFyY2hpdmUgPSBuZXcgQXJBcmNoaXZlSW5wdXRTdHJlYW0oaW4pKSB7CisgICAgICAgICAgICBBcmNoaXZlRW50cnkgZSA9IGFyY2hpdmUuZ2V0TmV4dEVudHJ5KCk7CisgICAgICAgICAgICBJT1V0aWxzLnRvQnl0ZUFycmF5KGFyY2hpdmUpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBhcmNoaXZlLnJlYWQoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIGFyY2hpdmUucmVhZCgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgbXVsdGlCeXRlUmVhZENvbnNpc3RlbnRseVJldHVybnNNaW51c09uZUF0RW9mKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBidWYgPSBuZXcgYnl0ZVsyXTsKKyAgICAgICAgdHJ5IChGaWxlSW5wdXRTdHJlYW0gaW4gPSBuZXcgRmlsZUlucHV0U3RyZWFtKGdldEZpbGUoImJsYS5hciIpKTsKKyAgICAgICAgICAgICBBckFyY2hpdmVJbnB1dFN0cmVhbSBhcmNoaXZlID0gbmV3IEFyQXJjaGl2ZUlucHV0U3RyZWFtKGluKSkgeworICAgICAgICAgICAgQXJjaGl2ZUVudHJ5IGUgPSBhcmNoaXZlLmdldE5leHRFbnRyeSgpOworICAgICAgICAgICAgSU9VdGlscy50b0J5dGVBcnJheShhcmNoaXZlKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygtMSwgYXJjaGl2ZS5yZWFkKGJ1ZikpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBhcmNoaXZlLnJlYWQoYnVmKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdChleHBlY3RlZD1JbGxlZ2FsU3RhdGVFeGNlcHRpb24uY2xhc3MpCisgICAgcHVibGljIHZvaWQgY2FudFJlYWRXaXRob3V0T3BlbmluZ0FuRW50cnkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IChGaWxlSW5wdXRTdHJlYW0gaW4gPSBuZXcgRmlsZUlucHV0U3RyZWFtKGdldEZpbGUoImJsYS5hciIpKTsKKyAgICAgICAgICAgICBBckFyY2hpdmVJbnB1dFN0cmVhbSBhcmNoaXZlID0gbmV3IEFyQXJjaGl2ZUlucHV0U3RyZWFtKGluKSkgeworICAgICAgICAgICAgYXJjaGl2ZS5yZWFkKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdChleHBlY3RlZD1JbGxlZ2FsU3RhdGVFeGNlcHRpb24uY2xhc3MpCisgICAgcHVibGljIHZvaWQgY2FudFJlYWRBZnRlckNsb3NlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSAoRmlsZUlucHV0U3RyZWFtIGluID0gbmV3IEZpbGVJbnB1dFN0cmVhbShnZXRGaWxlKCJibGEuYXIiKSk7CisgICAgICAgICAgICAgQXJBcmNoaXZlSW5wdXRTdHJlYW0gYXJjaGl2ZSA9IG5ldyBBckFyY2hpdmVJbnB1dFN0cmVhbShpbikpIHsKKyAgICAgICAgICAgIGFyY2hpdmUuY2xvc2UoKTsKKyAgICAgICAgICAgIGFyY2hpdmUucmVhZCgpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2FyL0FyQXJjaGl2ZU91dHB1dFN0cmVhbVRlc3QuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9hci9BckFyY2hpdmVPdXRwdXRTdHJlYW1UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGMzMDlhYQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9hci9BckFyY2hpdmVPdXRwdXRTdHJlYW1UZXN0LmphdmEKQEAgLTAsMCArMSw2NCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICoKKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuYXI7CisKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC4qOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuQWJzdHJhY3RUZXN0Q2FzZTsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworcHVibGljIGNsYXNzIEFyQXJjaGl2ZU91dHB1dFN0cmVhbVRlc3QgZXh0ZW5kcyBBYnN0cmFjdFRlc3RDYXNlIHsKKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdExvbmdGaWxlTmFtZXNDYXVzZUV4Y2VwdGlvbkJ5RGVmYXVsdCgpIHsKKyAgICAgICAgdHJ5IChBckFyY2hpdmVPdXRwdXRTdHJlYW0gb3MgPSBuZXcgQXJBcmNoaXZlT3V0cHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKSkpIHsKKyAgICAgICAgICAgIGZpbmFsIEFyQXJjaGl2ZUVudHJ5IGFlID0gbmV3IEFyQXJjaGl2ZUVudHJ5KCJ0aGlzX2lzX2FfbG9uZ19uYW1lLnR4dCIsIDApOworICAgICAgICAgICAgb3MucHV0QXJjaGl2ZUVudHJ5KGFlKTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIGFuIGV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChmaW5hbCBJT0V4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShleC5nZXRNZXNzYWdlKCkuc3RhcnRzV2l0aCgiZmlsZW5hbWUgdG9vIGxvbmciKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RMb25nRmlsZU5hbWVzV29ya1VzaW5nQlNERGlhbGVjdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlW10gZGYgPSBjcmVhdGVUZW1wRGlyQW5kRmlsZSgpOworICAgICAgICB0cnkgKEZpbGVPdXRwdXRTdHJlYW0gZm9zID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0oZGZbMV0pOworICAgICAgICAgICAgICAgIEFyQXJjaGl2ZU91dHB1dFN0cmVhbSBvcyA9IG5ldyBBckFyY2hpdmVPdXRwdXRTdHJlYW0oZm9zKSkgeworICAgICAgICAgICAgb3Muc2V0TG9uZ0ZpbGVNb2RlKEFyQXJjaGl2ZU91dHB1dFN0cmVhbS5MT05HRklMRV9CU0QpOworICAgICAgICAgICAgZmluYWwgQXJBcmNoaXZlRW50cnkgYWUgPSBuZXcgQXJBcmNoaXZlRW50cnkoInRoaXNfaXNfYV9sb25nX25hbWUudHh0IiwgMTQpOworICAgICAgICAgICAgb3MucHV0QXJjaGl2ZUVudHJ5KGFlKTsKKyAgICAgICAgICAgIG9zLndyaXRlKG5ldyBieXRlW10geyAnSCcsICdlJywgJ2wnLCAnbCcsICdvJywgJywnLCAnICcsICd3JywgJ28nLCAncicsICdsJywgJ2QnLCAnIScsICdcbicgfSk7CisgICAgICAgICAgICBvcy5jbG9zZUFyY2hpdmVFbnRyeSgpOworCisgICAgICAgICAgICBmaW5hbCBMaXN0PFN0cmluZz4gZXhwZWN0ZWQgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKyAgICAgICAgICAgIGV4cGVjdGVkLmFkZCgidGhpc19pc19hX2xvbmdfbmFtZS50eHQiKTsKKyAgICAgICAgICAgIGNoZWNrQXJjaGl2ZUNvbnRlbnQoZGZbMV0sIGV4cGVjdGVkKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHJtZGlyKGRmWzBdKTsKKyAgICAgICAgfQorICAgIH0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvYXJqL0FyakFyY2hpdmVJbnB1dFN0cmVhbVRlc3QuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9hcmovQXJqQXJjaGl2ZUlucHV0U3RyZWFtVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjcwYThiMWYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvYXJqL0FyakFyY2hpdmVJbnB1dFN0cmVhbVRlc3QuamF2YQpAQCAtMCwwICsxLDExMCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5hcmo7CisKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC4qOworCitpbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLkNhbGVuZGFyOworaW1wb3J0IGphdmEudXRpbC5UaW1lWm9uZTsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5BYnN0cmFjdFRlc3RDYXNlOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZUVudHJ5OworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5JT1V0aWxzOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworCitwdWJsaWMgY2xhc3MgQXJqQXJjaGl2ZUlucHV0U3RyZWFtVGVzdCBleHRlbmRzIEFic3RyYWN0VGVzdENhc2UgeworCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QXJqVW5hcmNoaXZlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFN0cmluZ0J1aWxkZXIgZXhwZWN0ZWQgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICBleHBlY3RlZC5hcHBlbmQoInRlc3QxLnhtbDw/eG1sIHZlcnNpb249XCIxLjBcIj8+XG4iKTsKKyAgICAgICAgZXhwZWN0ZWQuYXBwZW5kKCI8ZW1wdHkvPnRlc3QyLnhtbDw/eG1sIHZlcnNpb249XCIxLjBcIj8+XG4iKTsKKyAgICAgICAgZXhwZWN0ZWQuYXBwZW5kKCI8ZW1wdHkvPlxuIik7CisKKworICAgICAgICBmaW5hbCBBcmpBcmNoaXZlSW5wdXRTdHJlYW0gaW4gPSBuZXcgQXJqQXJjaGl2ZUlucHV0U3RyZWFtKG5ldyBGaWxlSW5wdXRTdHJlYW0oZ2V0RmlsZSgiYmxhLmFyaiIpKSk7CisgICAgICAgIEFyakFyY2hpdmVFbnRyeSBlbnRyeTsKKworICAgICAgICBmaW5hbCBTdHJpbmdCdWlsZGVyIHJlc3VsdCA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgIHdoaWxlICgoZW50cnkgPSBpbi5nZXROZXh0RW50cnkoKSkgIT0gbnVsbCkgeworICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChlbnRyeS5nZXROYW1lKCkpOworICAgICAgICAgICAgaW50IHRtcDsKKyAgICAgICAgICAgIHdoaWxlICgodG1wID0gaW4ucmVhZCgpKSAhPSAtMSkgeworICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoKGNoYXIpIHRtcCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRGYWxzZShlbnRyeS5pc0RpcmVjdG9yeSgpKTsKKyAgICAgICAgfQorICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICBhc3NlcnRFcXVhbHMocmVzdWx0LnRvU3RyaW5nKCksIGV4cGVjdGVkLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFJlYWRpbmdPZkF0dHJpYnV0ZXNEb3NWZXJzaW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEFyakFyY2hpdmVJbnB1dFN0cmVhbSBpbiA9IG5ldyBBcmpBcmNoaXZlSW5wdXRTdHJlYW0obmV3IEZpbGVJbnB1dFN0cmVhbShnZXRGaWxlKCJibGEuYXJqIikpKTsKKyAgICAgICAgZmluYWwgQXJqQXJjaGl2ZUVudHJ5IGVudHJ5ID0gaW4uZ2V0TmV4dEVudHJ5KCk7CisgICAgICAgIGFzc2VydEVxdWFscygidGVzdDEueG1sIiwgZW50cnkuZ2V0TmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDMwLCBlbnRyeS5nZXRTaXplKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgZW50cnkuZ2V0VW5peE1vZGUoKSk7CisgICAgICAgIGZpbmFsIENhbGVuZGFyIGNhbCA9IENhbGVuZGFyLmdldEluc3RhbmNlKCk7CisgICAgICAgIGNhbC5zZXQoMjAwOCwgOSwgNiwgMjMsIDUwLCA1Mik7CisgICAgICAgIGNhbC5zZXQoQ2FsZW5kYXIuTUlMTElTRUNPTkQsIDApOworICAgICAgICBhc3NlcnRFcXVhbHMoY2FsLmdldFRpbWUoKSwgZW50cnkuZ2V0TGFzdE1vZGlmaWVkRGF0ZSgpKTsKKyAgICAgICAgaW4uY2xvc2UoKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RSZWFkaW5nT2ZBdHRyaWJ1dGVzVW5peFZlcnNpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgQXJqQXJjaGl2ZUlucHV0U3RyZWFtIGluID0gbmV3IEFyakFyY2hpdmVJbnB1dFN0cmVhbShuZXcgRmlsZUlucHV0U3RyZWFtKGdldEZpbGUoImJsYS51bml4LmFyaiIpKSk7CisgICAgICAgIGZpbmFsIEFyakFyY2hpdmVFbnRyeSBlbnRyeSA9IGluLmdldE5leHRFbnRyeSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoInRlc3QxLnhtbCIsIGVudHJ5LmdldE5hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygzMCwgZW50cnkuZ2V0U2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDA2NjQsIGVudHJ5LmdldFVuaXhNb2RlKCkgJiAwNzc3NyAvKiBVbml4U3RhdC5QRVJNX01BU0sgKi8pOworICAgICAgICBmaW5hbCBDYWxlbmRhciBjYWwgPSBDYWxlbmRhci5nZXRJbnN0YW5jZShUaW1lWm9uZS5nZXRUaW1lWm9uZSgiR01UKzAwMDAiKSk7CisgICAgICAgIGNhbC5zZXQoMjAwOCwgOSwgNiwgMjEsIDUwLCA1Mik7CisgICAgICAgIGNhbC5zZXQoQ2FsZW5kYXIuTUlMTElTRUNPTkQsIDApOworICAgICAgICBhc3NlcnRFcXVhbHMoY2FsLmdldFRpbWUoKSwgZW50cnkuZ2V0TGFzdE1vZGlmaWVkRGF0ZSgpKTsKKyAgICAgICAgaW4uY2xvc2UoKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHNpbmdsZUJ5dGVSZWFkQ29uc2lzdGVudGx5UmV0dXJuc01pbnVzT25lQXRFb2YoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IChGaWxlSW5wdXRTdHJlYW0gaW4gPSBuZXcgRmlsZUlucHV0U3RyZWFtKGdldEZpbGUoImJsYS5hcmoiKSk7CisgICAgICAgICAgICAgQXJqQXJjaGl2ZUlucHV0U3RyZWFtIGFyY2hpdmUgPSBuZXcgQXJqQXJjaGl2ZUlucHV0U3RyZWFtKGluKSkgeworICAgICAgICAgICAgQXJjaGl2ZUVudHJ5IGUgPSBhcmNoaXZlLmdldE5leHRFbnRyeSgpOworICAgICAgICAgICAgSU9VdGlscy50b0J5dGVBcnJheShhcmNoaXZlKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygtMSwgYXJjaGl2ZS5yZWFkKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBhcmNoaXZlLnJlYWQoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIG11bHRpQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBieXRlW10gYnVmID0gbmV3IGJ5dGVbMl07CisgICAgICAgIHRyeSAoRmlsZUlucHV0U3RyZWFtIGluID0gbmV3IEZpbGVJbnB1dFN0cmVhbShnZXRGaWxlKCJibGEuYXJqIikpOworICAgICAgICAgICAgIEFyakFyY2hpdmVJbnB1dFN0cmVhbSBhcmNoaXZlID0gbmV3IEFyakFyY2hpdmVJbnB1dFN0cmVhbShpbikpIHsKKyAgICAgICAgICAgIEFyY2hpdmVFbnRyeSBlID0gYXJjaGl2ZS5nZXROZXh0RW50cnkoKTsKKyAgICAgICAgICAgIElPVXRpbHMudG9CeXRlQXJyYXkoYXJjaGl2ZSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIGFyY2hpdmUucmVhZChidWYpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygtMSwgYXJjaGl2ZS5yZWFkKGJ1ZikpOworICAgICAgICB9CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvYXJqL0NvdmVyYWdlVGVzdC5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2Fyai9Db3ZlcmFnZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42ZGQ5ZjcwCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2Fyai9Db3ZlcmFnZVRlc3QuamF2YQpAQCAtMCwwICsxLDQ2IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5hcmo7CisKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnROb3ROdWxsOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5hcmouQXJqQXJjaGl2ZUVudHJ5Lkhvc3RPczsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworcHVibGljIGNsYXNzIENvdmVyYWdlVGVzdCB7CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RIb3N0T3NJbnN0YW5jZSgpIHsKKyAgICAgICAgSG9zdE9zIGhvc3RPcyA9IG5ldyBIb3N0T3MoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChob3N0T3MpOworICAgIH0KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RIZWFkZXJJbnN0YW5jZXMoKSB7CisgICAgICAgIGFzc2VydE5vdE51bGwobmV3IExvY2FsRmlsZUhlYWRlci5GaWxlVHlwZXMoKSk7CisgICAgICAgIGFzc2VydE5vdE51bGwobmV3IExvY2FsRmlsZUhlYWRlci5NZXRob2RzKCkpOworICAgICAgICBhc3NlcnROb3ROdWxsKG5ldyBMb2NhbEZpbGVIZWFkZXIuRmxhZ3MoKSk7CisgICAgICAgIGFzc2VydE5vdE51bGwobmV3IE1haW5IZWFkZXIuRmxhZ3MoKSk7CisgICAgfQorICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdENhbGxMRkhUb1N0cmluZygpIHsKKyAgICAgICAgTG9jYWxGaWxlSGVhZGVyIGxmaCA9IG5ldyBMb2NhbEZpbGVIZWFkZXIoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChsZmgudG9TdHJpbmcoKSk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvY3Bpby9DcGlvQXJjaGl2ZUlucHV0U3RyZWFtVGVzdC5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2NwaW8vQ3Bpb0FyY2hpdmVJbnB1dFN0cmVhbVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NWE5Zjc1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2NwaW8vQ3Bpb0FyY2hpdmVJbnB1dFN0cmVhbVRlc3QuamF2YQpAQCAtMCwwICsxLDExMCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuY3BpbzsKKworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0Lio7CisKK2ltcG9ydCBqYXZhLmlvLkZpbGVJbnB1dFN0cmVhbTsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5BYnN0cmFjdFRlc3RDYXNlOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZUVudHJ5OworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5JT1V0aWxzOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworCitwdWJsaWMgY2xhc3MgQ3Bpb0FyY2hpdmVJbnB1dFN0cmVhbVRlc3QgZXh0ZW5kcyBBYnN0cmFjdFRlc3RDYXNlIHsKKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdENwaW9VbmFyY2hpdmUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgU3RyaW5nQnVpbGRlciBleHBlY3RlZCA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgIGV4cGVjdGVkLmFwcGVuZCgiLi90ZXN0MS54bWw8P3htbCB2ZXJzaW9uPVwiMS4wXCI/PlxuIik7CisgICAgICAgIGV4cGVjdGVkLmFwcGVuZCgiPGVtcHR5Lz4uL3Rlc3QyLnhtbDw/eG1sIHZlcnNpb249XCIxLjBcIj8+XG4iKTsKKyAgICAgICAgZXhwZWN0ZWQuYXBwZW5kKCI8ZW1wdHkvPlxuIik7CisKKworICAgICAgICBmaW5hbCBDcGlvQXJjaGl2ZUlucHV0U3RyZWFtIGluID0gbmV3IENwaW9BcmNoaXZlSW5wdXRTdHJlYW0obmV3IEZpbGVJbnB1dFN0cmVhbShnZXRGaWxlKCJibGEuY3BpbyIpKSk7CisgICAgICAgIENwaW9BcmNoaXZlRW50cnkgZW50cnk7CisKKyAgICAgICAgZmluYWwgU3RyaW5nQnVpbGRlciByZXN1bHQgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICB3aGlsZSAoKGVudHJ5ID0gKENwaW9BcmNoaXZlRW50cnkpIGluLmdldE5leHRFbnRyeSgpKSAhPSBudWxsKSB7CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKGVudHJ5LmdldE5hbWUoKSk7CisgICAgICAgICAgICBpbnQgdG1wOworICAgICAgICAgICAgd2hpbGUgKCh0bXAgPSBpbi5yZWFkKCkpICE9IC0xKSB7CisgICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgoY2hhcikgdG1wKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICBhc3NlcnRFcXVhbHMocmVzdWx0LnRvU3RyaW5nKCksIGV4cGVjdGVkLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdENwaW9VbmFyY2hpdmVDcmVhdGVkQnlSZWRsaW5lUnBtKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIENwaW9BcmNoaXZlSW5wdXRTdHJlYW0gaW4gPQorICAgICAgICAgICAgbmV3IENwaW9BcmNoaXZlSW5wdXRTdHJlYW0obmV3IEZpbGVJbnB1dFN0cmVhbShnZXRGaWxlKCJyZWRsaW5lLmNwaW8iKSkpOworICAgICAgICBDcGlvQXJjaGl2ZUVudHJ5IGVudHJ5PSBudWxsOworCisgICAgICAgIGludCBjb3VudCA9IDA7CisgICAgICAgIHdoaWxlICgoZW50cnkgPSAoQ3Bpb0FyY2hpdmVFbnRyeSkgaW4uZ2V0TmV4dEVudHJ5KCkpICE9IG51bGwpIHsKKyAgICAgICAgICAgIGNvdW50Kys7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGVudHJ5KTsKKyAgICAgICAgfQorICAgICAgICBpbi5jbG9zZSgpOworCisgICAgICAgIGFzc2VydEVxdWFscyhjb3VudCwgMSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q3Bpb1VuYXJjaGl2ZU11bHRpYnl0ZUNoYXJOYW1lKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIENwaW9BcmNoaXZlSW5wdXRTdHJlYW0gaW4gPQorICAgICAgICAgICAgbmV3IENwaW9BcmNoaXZlSW5wdXRTdHJlYW0obmV3IEZpbGVJbnB1dFN0cmVhbShnZXRGaWxlKCJDT01QUkVTUy00NTkuY3BpbyIpKSwgIlVURi04Iik7CisgICAgICAgIENwaW9BcmNoaXZlRW50cnkgZW50cnk9IG51bGw7CisKKyAgICAgICAgaW50IGNvdW50ID0gMDsKKyAgICAgICAgd2hpbGUgKChlbnRyeSA9IChDcGlvQXJjaGl2ZUVudHJ5KSBpbi5nZXROZXh0RW50cnkoKSkgIT0gbnVsbCkgeworICAgICAgICAgICAgY291bnQrKzsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoZW50cnkpOworICAgICAgICB9CisgICAgICAgIGluLmNsb3NlKCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIGNvdW50KTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHNpbmdsZUJ5dGVSZWFkQ29uc2lzdGVudGx5UmV0dXJuc01pbnVzT25lQXRFb2YoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IChGaWxlSW5wdXRTdHJlYW0gaW4gPSBuZXcgRmlsZUlucHV0U3RyZWFtKGdldEZpbGUoImJsYS5jcGlvIikpOworICAgICAgICAgICAgIENwaW9BcmNoaXZlSW5wdXRTdHJlYW0gYXJjaGl2ZSA9IG5ldyBDcGlvQXJjaGl2ZUlucHV0U3RyZWFtKGluKSkgeworICAgICAgICAgICAgQXJjaGl2ZUVudHJ5IGUgPSBhcmNoaXZlLmdldE5leHRFbnRyeSgpOworICAgICAgICAgICAgSU9VdGlscy50b0J5dGVBcnJheShhcmNoaXZlKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygtMSwgYXJjaGl2ZS5yZWFkKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBhcmNoaXZlLnJlYWQoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIG11bHRpQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBieXRlW10gYnVmID0gbmV3IGJ5dGVbMl07CisgICAgICAgIHRyeSAoRmlsZUlucHV0U3RyZWFtIGluID0gbmV3IEZpbGVJbnB1dFN0cmVhbShnZXRGaWxlKCJibGEuY3BpbyIpKTsKKyAgICAgICAgICAgICBDcGlvQXJjaGl2ZUlucHV0U3RyZWFtIGFyY2hpdmUgPSBuZXcgQ3Bpb0FyY2hpdmVJbnB1dFN0cmVhbShpbikpIHsKKyAgICAgICAgICAgIEFyY2hpdmVFbnRyeSBlID0gYXJjaGl2ZS5nZXROZXh0RW50cnkoKTsKKyAgICAgICAgICAgIElPVXRpbHMudG9CeXRlQXJyYXkoYXJjaGl2ZSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIGFyY2hpdmUucmVhZChidWYpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygtMSwgYXJjaGl2ZS5yZWFkKGJ1ZikpOworICAgICAgICB9CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvY3Bpby9DcGlvQXJjaGl2ZU91dHB1dFN0cmVhbVRlc3QuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9jcGlvL0NwaW9BcmNoaXZlT3V0cHV0U3RyZWFtVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJhODM3NzEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvY3Bpby9DcGlvQXJjaGl2ZU91dHB1dFN0cmVhbVRlc3QuamF2YQpAQCAtMCwwICsxLDcxIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5jcGlvOworCitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuKjsKKworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5BYnN0cmFjdFRlc3RDYXNlOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5JT1V0aWxzOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworCitwdWJsaWMgY2xhc3MgQ3Bpb0FyY2hpdmVPdXRwdXRTdHJlYW1UZXN0IGV4dGVuZHMgQWJzdHJhY3RUZXN0Q2FzZSB7CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RXcml0ZU9sZEJpbmFyeSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlIGYgPSBnZXRGaWxlKCJ0ZXN0MS54bWwiKTsKKyAgICAgICAgZmluYWwgRmlsZSBvdXRwdXQgPSBuZXcgRmlsZShkaXIsICJ0ZXN0LmNwaW8iKTsKKyAgICAgICAgZmluYWwgRmlsZU91dHB1dFN0cmVhbSBvdXQgPSBuZXcgRmlsZU91dHB1dFN0cmVhbShvdXRwdXQpOworICAgICAgICBJbnB1dFN0cmVhbSBpbiA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmaW5hbCBDcGlvQXJjaGl2ZU91dHB1dFN0cmVhbSBvcyA9CisgICAgICAgICAgICAgICAgbmV3IENwaW9BcmNoaXZlT3V0cHV0U3RyZWFtKG91dCwgQ3Bpb0NvbnN0YW50cworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuRk9STUFUX09MRF9CSU5BUlkpOworICAgICAgICAgICAgb3MucHV0QXJjaGl2ZUVudHJ5KG5ldyBDcGlvQXJjaGl2ZUVudHJ5KENwaW9Db25zdGFudHMKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuRk9STUFUX09MRF9CSU5BUlksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiwgInRlc3QxLnhtbCIpKTsKKyAgICAgICAgICAgIElPVXRpbHMuY29weShpbiA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oZiksIG9zKTsKKyAgICAgICAgICAgIGluLmNsb3NlKCk7CisgICAgICAgICAgICBpbiA9IG51bGw7CisgICAgICAgICAgICBvcy5jbG9zZUFyY2hpdmVFbnRyeSgpOworICAgICAgICAgICAgb3MuY2xvc2UoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmIChpbiAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGluID0gbmV3IENwaW9BcmNoaXZlSW5wdXRTdHJlYW0obmV3IEZpbGVJbnB1dFN0cmVhbShvdXRwdXQpKTsKKyAgICAgICAgICAgIGZpbmFsIENwaW9BcmNoaXZlRW50cnkgZSA9ICgoQ3Bpb0FyY2hpdmVJbnB1dFN0cmVhbSkgaW4pCisgICAgICAgICAgICAgICAgLmdldE5leHRDUElPRW50cnkoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygidGVzdDEueG1sIiwgZS5nZXROYW1lKCkpOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgoKENwaW9BcmNoaXZlSW5wdXRTdHJlYW0pIGluKS5nZXROZXh0RW50cnkoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAoaW4gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGluLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2NwaW8vQ3Bpb0FyY2hpdmVUZXN0LmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvY3Bpby9DcGlvQXJjaGl2ZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wZGFjMDkwCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2NwaW8vQ3Bpb0FyY2hpdmVUZXN0LmphdmEKQEAgLTAsMCArMSw3NCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuY3BpbzsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuSU9VdGlsczsKK2ltcG9ydCBvcmcuanVuaXQuQXNzZXJ0OworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXIuUnVuV2l0aDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVycy5QYXJhbWV0ZXJpemVkLlBhcmFtZXRlcnM7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lcnMuUGFyYW1ldGVyaXplZDsKKworQFJ1bldpdGgoUGFyYW1ldGVyaXplZC5jbGFzcykKK3B1YmxpYyBjbGFzcyBDcGlvQXJjaGl2ZVRlc3QgeworCisgICAgQFBhcmFtZXRlcnMobmFtZSA9ICJ1c2luZyB7MH0iKQorICAgIHB1YmxpYyBzdGF0aWMgQ29sbGVjdGlvbjxPYmplY3RbXT4gZmFjdG9yeSgpIHsKKyAgICAgICAgcmV0dXJuIEFycmF5cy5hc0xpc3QobmV3IE9iamVjdFtdW10geworICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSAgeyBDcGlvQ29uc3RhbnRzLkZPUk1BVF9ORVcgfSwKKyAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10gIHsgQ3Bpb0NvbnN0YW50cy5GT1JNQVRfTkVXX0NSQyB9LAorICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSAgeyBDcGlvQ29uc3RhbnRzLkZPUk1BVF9PTERfQVNDSUkgfSwKKyAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10gIHsgQ3Bpb0NvbnN0YW50cy5GT1JNQVRfT0xEX0JJTkFSWSB9LAorICAgICAgICAgICAgfSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBmaW5hbCBzaG9ydCBmb3JtYXQ7CisKKyAgICBwdWJsaWMgQ3Bpb0FyY2hpdmVUZXN0KHNob3J0IGZvcm1hdCkgeworICAgICAgICB0aGlzLmZvcm1hdCA9IGZvcm1hdDsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHV0ZjE4Um91bmR0cmlwVGVzdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgKEJ5dGVBcnJheU91dHB1dFN0cmVhbSBiYW9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpKSB7CisgICAgICAgICAgICB0cnkgKENwaW9BcmNoaXZlT3V0cHV0U3RyZWFtIG9zID0gbmV3IENwaW9BcmNoaXZlT3V0cHV0U3RyZWFtKGJhb3MsIGZvcm1hdCwgQ3Bpb0NvbnN0YW50cy5CTE9DS19TSVpFLAorICAgICAgICAgICAgICAgICJVVEYtMTZMRSIpKSB7CisgICAgICAgICAgICAgICAgQ3Bpb0FyY2hpdmVFbnRyeSBlbnRyeSA9IG5ldyBDcGlvQXJjaGl2ZUVudHJ5KGZvcm1hdCwgIlRcdTAwZTRzdC50eHQiLCA0KTsKKyAgICAgICAgICAgICAgICBpZiAoZm9ybWF0ID09IENwaW9Db25zdGFudHMuRk9STUFUX05FV19DUkMpIHsKKyAgICAgICAgICAgICAgICAgICAgZW50cnkuc2V0Q2hrc3VtKDEwKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgb3MucHV0QXJjaGl2ZUVudHJ5KGVudHJ5KTsKKyAgICAgICAgICAgICAgICBvcy53cml0ZShuZXcgYnl0ZVtdIHsgMSwgMiwgMywgNCB9KTsKKyAgICAgICAgICAgICAgICBvcy5jbG9zZUFyY2hpdmVFbnRyeSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYmFvcy5jbG9zZSgpOworICAgICAgICAgICAgdHJ5IChCeXRlQXJyYXlJbnB1dFN0cmVhbSBiaW4gPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYmFvcy50b0J5dGVBcnJheSgpKTsKKyAgICAgICAgICAgICAgICAgQ3Bpb0FyY2hpdmVJbnB1dFN0cmVhbSBpbiA9IG5ldyBDcGlvQXJjaGl2ZUlucHV0U3RyZWFtKGJpbiwgIlVURi0xNkxFIikpIHsKKyAgICAgICAgICAgICAgICBDcGlvQXJjaGl2ZUVudHJ5IGVudHJ5ID0gKENwaW9BcmNoaXZlRW50cnkpIGluLmdldE5leHRFbnRyeSgpOworICAgICAgICAgICAgICAgIEFzc2VydC5hc3NlcnROb3ROdWxsKGVudHJ5KTsKKyAgICAgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKCJUXHUwMGU0c3QudHh0IiwgZW50cnkuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0QXJyYXlFcXVhbHMobmV3IGJ5dGVbXSB7IDEsIDIsIDMsIDQgfSwgSU9VdGlscy50b0J5dGVBcnJheShpbikpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2NwaW8vQ3Bpb1V0aWxUZXN0LmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvY3Bpby9DcGlvVXRpbFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41YjFlZGI1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2NwaW8vQ3Bpb1V0aWxUZXN0LmphdmEKQEAgLTAsMCArMSw4MyBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuY3BpbzsKKworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworCitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0QXJyYXlFcXVhbHM7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0RXF1YWxzOworCitwdWJsaWMgY2xhc3MgQ3Bpb1V0aWxUZXN0IHsKKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgb2xkQmluTWFnaWMyQnl0ZUFycmF5Tm90U3dhcHBlZCgpIHsKKyAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMobmV3IGJ5dGVbXSB7IChieXRlKSAweGM3LCAweDcxIH0sCisgICAgICAgICAgICAgICAgICAgICAgICAgIENwaW9VdGlsLmxvbmcyYnl0ZUFycmF5KENwaW9Db25zdGFudHMuTUFHSUNfT0xEX0JJTkFSWSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMiwgZmFsc2UpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIG9sZEJpbk1hZ2ljMkJ5dGVBcnJheVN3YXBwZWQoKSB7CisgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKG5ldyBieXRlW10geyAweDcxLCAoYnl0ZSkgMHhjNywgIH0sCisgICAgICAgICAgICAgICAgICAgICAgICAgIENwaW9VdGlsLmxvbmcyYnl0ZUFycmF5KENwaW9Db25zdGFudHMuTUFHSUNfT0xEX0JJTkFSWSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMiwgdHJ1ZSkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgb2xkQmluTWFnaWNGcm9tQnl0ZUFycmF5Tm90U3dhcHBlZCgpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKENwaW9Db25zdGFudHMuTUFHSUNfT0xEX0JJTkFSWSwKKyAgICAgICAgICAgICAgICAgICAgIENwaW9VdGlsLmJ5dGVBcnJheTJsb25nKG5ldyBieXRlW10geyAoYnl0ZSkgMHhjNywgMHg3MSB9LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIG9sZEJpbk1hZ2ljRnJvbUJ5dGVBcnJheVN3YXBwZWQoKSB7CisgICAgICAgIGFzc2VydEVxdWFscyhDcGlvQ29uc3RhbnRzLk1BR0lDX09MRF9CSU5BUlksCisgICAgICAgICAgICAgICAgICAgICBDcGlvVXRpbC5ieXRlQXJyYXkybG9uZyhuZXcgYnl0ZVtdIHsgMHg3MSwgKGJ5dGUpIDB4YzcgfSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUpKTsKKyAgICB9CisKKworICAgIEBUZXN0KGV4cGVjdGVkID0gVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24uY2xhc3MpCisgICAgcHVibGljIHZvaWQgdGVzdExvbmcyYnl0ZUFycmF5V2l0aFplcm9UaHJvd3NVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpIHsKKworICAgICAgICBDcGlvVXRpbC5sb25nMmJ5dGVBcnJheSgwTCwgMCwgZmFsc2UpOworCisgICAgfQorCisKKyAgICBAVGVzdChleHBlY3RlZCA9IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uLmNsYXNzKQorICAgIHB1YmxpYyB2b2lkIHRlc3RMb25nMmJ5dGVBcnJheVdpdGhQb3NpdGl2ZVRocm93c1Vuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCkgeworCisgICAgICAgIENwaW9VdGlsLmxvbmcyYnl0ZUFycmF5KDBMLCAxMDIxLCBmYWxzZSk7CisKKyAgICB9CisKKworICAgIEBUZXN0KGV4cGVjdGVkID0gVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24uY2xhc3MpCisgICAgcHVibGljIHZvaWQgdGVzdEJ5dGVBcnJheTJsb25nVGhyb3dzVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKSB7CisKKyAgICAgICAgYnl0ZVtdIGJ5dGVBcnJheSA9IG5ldyBieXRlWzFdOworCisgICAgICAgIENwaW9VdGlsLmJ5dGVBcnJheTJsb25nKGJ5dGVBcnJheSwgdHJ1ZSk7CisKKyAgICB9CisKKworfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9kdW1wL0R1bXBBcmNoaXZlRW50cnlUZXN0LmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvZHVtcC9EdW1wQXJjaGl2ZUVudHJ5VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhjYzhmZDIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvZHVtcC9EdW1wQXJjaGl2ZUVudHJ5VGVzdC5qYXZhCkBAIC0wLDAgKzEsNDQgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLmR1bXA7CisKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRFcXVhbHM7CisKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworcHVibGljIGNsYXNzIER1bXBBcmNoaXZlRW50cnlUZXN0IHsKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHB1YmxpY05hbWVBZGRzVHJhaWxpbmdTbGFzaEZvckRpcmVjdG9yaWVzKCkgeworICAgICAgICBmaW5hbCBEdW1wQXJjaGl2ZUVudHJ5IGVudCA9IG5ldyBEdW1wQXJjaGl2ZUVudHJ5KCJmb28iLCAiYmFyIiwgLTEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRHVtcEFyY2hpdmVFbnRyeS5UWVBFCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLkRJUkVDVE9SWSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYmFyIiwgZW50LmdldFNpbXBsZU5hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZm9vIiwgZW50LmdldE9yaWdpbmFsTmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmb28vIiwgZW50LmdldE5hbWUoKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBwdWJsaWNOYW1lUmVtb3Zlc0xlYWRpbmdEb3RTbGFzaCgpIHsKKyAgICAgICAgZmluYWwgRHVtcEFyY2hpdmVFbnRyeSBlbnQgPSBuZXcgRHVtcEFyY2hpdmVFbnRyeSgiLi9mb28iLCAiYmFyIik7CisgICAgICAgIGFzc2VydEVxdWFscygiYmFyIiwgZW50LmdldFNpbXBsZU5hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiLi9mb28iLCBlbnQuZ2V0T3JpZ2luYWxOYW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImZvbyIsIGVudC5nZXROYW1lKCkpOworICAgIH0KKworfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9kdW1wL0R1bXBBcmNoaXZlSW5wdXRTdHJlYW1UZXN0LmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvZHVtcC9EdW1wQXJjaGl2ZUlucHV0U3RyZWFtVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg5ZjZmMTUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvZHVtcC9EdW1wQXJjaGl2ZUlucHV0U3RyZWFtVGVzdC5qYXZhCkBAIC0wLDAgKzEsOTYgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLmR1bXA7CisKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC4qOworCitpbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5BYnN0cmFjdFRlc3RDYXNlOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZUVudHJ5OworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZUV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuSU9VdGlsczsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworcHVibGljIGNsYXNzIER1bXBBcmNoaXZlSW5wdXRTdHJlYW1UZXN0IGV4dGVuZHMgQWJzdHJhY3RUZXN0Q2FzZSB7CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3ROb3RBRHVtcEFyY2hpdmUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IChGaWxlSW5wdXRTdHJlYW0gaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGdldEZpbGUoImJsYS56aXAiKSkpIHsKKyAgICAgICAgICAgIG5ldyBEdW1wQXJjaGl2ZUlucHV0U3RyZWFtKGlzKS5jbG9zZSgpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgYW4gZXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIEFyY2hpdmVFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgICAgICBhc3NlcnRUcnVlKGV4LmdldENhdXNlKCkgaW5zdGFuY2VvZiBTaG9ydEZpbGVFeGNlcHRpb24pOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Tm90QUR1bXBBcmNoaXZlQnV0QmlnRW5vdWdoKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSAoRmlsZUlucHV0U3RyZWFtIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShnZXRGaWxlKCJ6aXA2NHN1cHBvcnQudGFyLmJ6MiIpKSkgeworICAgICAgICAgICAgbmV3IER1bXBBcmNoaXZlSW5wdXRTdHJlYW0oaXMpLmNsb3NlKCk7CisgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBhbiBleGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgQXJjaGl2ZUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgICAgIGFzc2VydFRydWUoZXguZ2V0Q2F1c2UoKSBpbnN0YW5jZW9mIFVucmVjb2duaXplZEZvcm1hdEV4Y2VwdGlvbik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RDb25zdW1lc0FyY2hpdmVDb21wbGV0ZWx5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIElucHV0U3RyZWFtIGlzID0gRHVtcEFyY2hpdmVJbnB1dFN0cmVhbVRlc3QuY2xhc3MKKyAgICAgICAgICAgIC5nZXRSZXNvdXJjZUFzU3RyZWFtKCIvYXJjaGl2ZV93aXRoX3RyYWlsZXIuZHVtcCIpOworICAgICAgICBmaW5hbCBEdW1wQXJjaGl2ZUlucHV0U3RyZWFtIGR1bXAgPSBuZXcgRHVtcEFyY2hpdmVJbnB1dFN0cmVhbShpcyk7CisgICAgICAgIHdoaWxlIChkdW1wLmdldE5leHREdW1wRW50cnkoKSAhPSBudWxsKSB7CisgICAgICAgICAgICAvLyBqdXN0IGNvbnN1bWUgdGhlIGFyY2hpdmUKKyAgICAgICAgfQorICAgICAgICBmaW5hbCBieXRlW10gZXhwZWN0ZWQgPSBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICdIJywgJ2UnLCAnbCcsICdsJywgJ28nLCAnLCcsICcgJywgJ3cnLCAnbycsICdyJywgJ2wnLCAnZCcsICchJywgJ1xuJworICAgICAgICB9OworICAgICAgICBmaW5hbCBieXRlW10gYWN0dWFsID0gbmV3IGJ5dGVbZXhwZWN0ZWQubGVuZ3RoXTsKKyAgICAgICAgaXMucmVhZChhY3R1YWwpOworICAgICAgICBhc3NlcnRBcnJheUVxdWFscyhleHBlY3RlZCwgYWN0dWFsKTsKKyAgICAgICAgZHVtcC5jbG9zZSgpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgc2luZ2xlQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgKEZpbGVJbnB1dFN0cmVhbSBpbiA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oZ2V0RmlsZSgiYmxhLmR1bXAiKSk7CisgICAgICAgICAgICAgRHVtcEFyY2hpdmVJbnB1dFN0cmVhbSBhcmNoaXZlID0gbmV3IER1bXBBcmNoaXZlSW5wdXRTdHJlYW0oaW4pKSB7CisgICAgICAgICAgICBBcmNoaXZlRW50cnkgZSA9IGFyY2hpdmUuZ2V0TmV4dEVudHJ5KCk7CisgICAgICAgICAgICBJT1V0aWxzLnRvQnl0ZUFycmF5KGFyY2hpdmUpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBhcmNoaXZlLnJlYWQoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIGFyY2hpdmUucmVhZCgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgbXVsdGlCeXRlUmVhZENvbnNpc3RlbnRseVJldHVybnNNaW51c09uZUF0RW9mKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBidWYgPSBuZXcgYnl0ZVsyXTsKKyAgICAgICAgdHJ5IChGaWxlSW5wdXRTdHJlYW0gaW4gPSBuZXcgRmlsZUlucHV0U3RyZWFtKGdldEZpbGUoImJsYS5kdW1wIikpOworICAgICAgICAgICAgIER1bXBBcmNoaXZlSW5wdXRTdHJlYW0gYXJjaGl2ZSA9IG5ldyBEdW1wQXJjaGl2ZUlucHV0U3RyZWFtKGluKSkgeworICAgICAgICAgICAgQXJjaGl2ZUVudHJ5IGUgPSBhcmNoaXZlLmdldE5leHRFbnRyeSgpOworICAgICAgICAgICAgSU9VdGlscy50b0J5dGVBcnJheShhcmNoaXZlKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygtMSwgYXJjaGl2ZS5yZWFkKGJ1ZikpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBhcmNoaXZlLnJlYWQoYnVmKSk7CisgICAgICAgIH0KKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9kdW1wL0R1bXBBcmNoaXZlVXRpbFRlc3QuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9kdW1wL0R1bXBBcmNoaXZlVXRpbFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yYWNlY2EzCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2R1bXAvRHVtcEFyY2hpdmVVdGlsVGVzdC5qYXZhCkBAIC0wLDAgKzEsNTEgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLmR1bXA7CisKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRFcXVhbHM7CisKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworcHVibGljIGNsYXNzIER1bXBBcmNoaXZlVXRpbFRlc3QgeworCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBjb252ZXJ0NjQoKSB7CisgICAgICAgIGFzc2VydEVxdWFscygweEFCQ0RFRjAxMjM0NTY3ODBMLAorICAgICAgICAgICAgICAgICAgICAgRHVtcEFyY2hpdmVVdGlsLmNvbnZlcnQ2NChuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpIDB4ODAsIDB4NjcsIDB4NDUsIDB4MjMsIDEsIChieXRlKSAweEVGLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgMHhDRCwgKGJ5dGUpIDB4QUIKKyAgICAgICAgICAgICAgICAgICAgICAgICB9LCAwKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBjb252ZXJ0MzIoKSB7CisgICAgICAgIGFzc2VydEVxdWFscygweEFCQ0RFRjAxLAorICAgICAgICAgICAgICAgICAgICAgRHVtcEFyY2hpdmVVdGlsLmNvbnZlcnQzMihuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMSwgKGJ5dGUpIDB4RUYsIChieXRlKSAweENELCAoYnl0ZSkgMHhBQgorICAgICAgICAgICAgICAgICAgICAgICAgIH0sIDApKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIGNvbnZlcnQxNigpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDB4QUJDRCwKKyAgICAgICAgICAgICAgICAgICAgIER1bXBBcmNoaXZlVXRpbC5jb252ZXJ0MTYobmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweENELCAoYnl0ZSkgMHhBQgorICAgICAgICAgICAgICAgICAgICAgICAgIH0sIDApKTsKKyAgICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2V4YW1wbGVzL0V4cGFuZGVyVGVzdC5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2V4YW1wbGVzL0V4cGFuZGVyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQxNGEyNzMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvZXhhbXBsZXMvRXhwYW5kZXJUZXN0LmphdmEKQEAgLTAsMCArMSwyMzMgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLmV4YW1wbGVzOworCitpbXBvcnQgamF2YS5pby5CdWZmZXJlZElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuRmlsZUNoYW5uZWw7CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuU2Vla2FibGVCeXRlQ2hhbm5lbDsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LlN0YW5kYXJkQ2hhcnNldHM7CitpbXBvcnQgamF2YS5uaW8uZmlsZS5GaWxlczsKK2ltcG9ydCBqYXZhLm5pby5maWxlLlN0YW5kYXJkT3Blbk9wdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLkFic3RyYWN0VGVzdENhc2U7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5BcmNoaXZlRW50cnk7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5BcmNoaXZlRXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZUlucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLkFyY2hpdmVTdHJlYW1GYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuU3RyZWFtaW5nTm90U3VwcG9ydGVkRXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuc2V2ZW56LlNldmVuWkZpbGU7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5zZXZlbnouU2V2ZW5aT3V0cHV0RmlsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcC5aaXBGaWxlOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5JT1V0aWxzOworaW1wb3J0IG9yZy5qdW5pdC5Bc3NlcnQ7CitpbXBvcnQgb3JnLmp1bml0LkFzc3VtZTsKK2ltcG9ydCBvcmcuanVuaXQuUnVsZTsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBvcmcuanVuaXQucnVsZXMuRXhwZWN0ZWRFeGNlcHRpb247CisKK3B1YmxpYyBjbGFzcyBFeHBhbmRlclRlc3QgZXh0ZW5kcyBBYnN0cmFjdFRlc3RDYXNlIHsKKworICAgIEBSdWxlCisgICAgcHVibGljIEV4cGVjdGVkRXhjZXB0aW9uIHRocm93biA9IEV4cGVjdGVkRXhjZXB0aW9uLm5vbmUoKTsKKworICAgIHByaXZhdGUgRmlsZSBhcmNoaXZlOworCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBzZXZlblpUd29GaWxlVmVyc2lvbigpIHRocm93cyBJT0V4Y2VwdGlvbiwgQXJjaGl2ZUV4Y2VwdGlvbiB7CisgICAgICAgIHNldHVwN3ooKTsKKyAgICAgICAgbmV3IEV4cGFuZGVyKCkuZXhwYW5kKCI3eiIsIGFyY2hpdmUsIHJlc3VsdERpcik7CisgICAgICAgIHZlcmlmeVRhcmdldERpcigpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgc2V2ZW5aVHdvRmlsZVZlcnNpb25XaXRoQXV0b0RldGVjdGlvbigpIHRocm93cyBJT0V4Y2VwdGlvbiwgQXJjaGl2ZUV4Y2VwdGlvbiB7CisgICAgICAgIHNldHVwN3ooKTsKKyAgICAgICAgbmV3IEV4cGFuZGVyKCkuZXhwYW5kKGFyY2hpdmUsIHJlc3VsdERpcik7CisgICAgICAgIHZlcmlmeVRhcmdldERpcigpOworICAgIH0KKworICAgIEBUZXN0KGV4cGVjdGVkID0gU3RyZWFtaW5nTm90U3VwcG9ydGVkRXhjZXB0aW9uLmNsYXNzKQorICAgIHB1YmxpYyB2b2lkIHNldmVuWklucHV0U3RyZWFtVmVyc2lvbigpIHRocm93cyBJT0V4Y2VwdGlvbiwgQXJjaGl2ZUV4Y2VwdGlvbiB7CisgICAgICAgIHNldHVwN3ooKTsKKyAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBpID0gbmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0oRmlsZXMubmV3SW5wdXRTdHJlYW0oYXJjaGl2ZS50b1BhdGgoKSkpKSB7CisgICAgICAgICAgICBuZXcgRXhwYW5kZXIoKS5leHBhbmQoIjd6IiwgaSwgcmVzdWx0RGlyKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0KGV4cGVjdGVkID0gU3RyZWFtaW5nTm90U3VwcG9ydGVkRXhjZXB0aW9uLmNsYXNzKQorICAgIHB1YmxpYyB2b2lkIHNldmVuWklucHV0U3RyZWFtVmVyc2lvbldpdGhBdXRvRGV0ZWN0aW9uKCkgdGhyb3dzIElPRXhjZXB0aW9uLCBBcmNoaXZlRXhjZXB0aW9uIHsKKyAgICAgICAgc2V0dXA3eigpOworICAgICAgICB0cnkgKElucHV0U3RyZWFtIGkgPSBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShGaWxlcy5uZXdJbnB1dFN0cmVhbShhcmNoaXZlLnRvUGF0aCgpKSkpIHsKKyAgICAgICAgICAgIG5ldyBFeHBhbmRlcigpLmV4cGFuZChpLCByZXN1bHREaXIpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBzZXZlblpDaGFubmVsVmVyc2lvbigpIHRocm93cyBJT0V4Y2VwdGlvbiwgQXJjaGl2ZUV4Y2VwdGlvbiB7CisgICAgICAgIHNldHVwN3ooKTsKKyAgICAgICAgdHJ5IChTZWVrYWJsZUJ5dGVDaGFubmVsIGMgPSBGaWxlQ2hhbm5lbC5vcGVuKGFyY2hpdmUudG9QYXRoKCksIFN0YW5kYXJkT3Blbk9wdGlvbi5SRUFEKSkgeworICAgICAgICAgICAgbmV3IEV4cGFuZGVyKCkuZXhwYW5kKCI3eiIsIGMsIHJlc3VsdERpcik7CisgICAgICAgIH0KKyAgICAgICAgdmVyaWZ5VGFyZ2V0RGlyKCk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBzZXZlblpGaWxlVmVyc2lvbigpIHRocm93cyBJT0V4Y2VwdGlvbiwgQXJjaGl2ZUV4Y2VwdGlvbiB7CisgICAgICAgIHNldHVwN3ooKTsKKyAgICAgICAgdHJ5IChTZXZlblpGaWxlIGYgPSBuZXcgU2V2ZW5aRmlsZShhcmNoaXZlKSkgeworICAgICAgICAgICAgbmV3IEV4cGFuZGVyKCkuZXhwYW5kKGYsIHJlc3VsdERpcik7CisgICAgICAgIH0KKyAgICAgICAgdmVyaWZ5VGFyZ2V0RGlyKCk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB6aXBGaWxlVmVyc2lvbigpIHRocm93cyBJT0V4Y2VwdGlvbiwgQXJjaGl2ZUV4Y2VwdGlvbiB7CisgICAgICAgIHNldHVwWmlwKCk7CisgICAgICAgIHRyeSAoWmlwRmlsZSBmID0gbmV3IFppcEZpbGUoYXJjaGl2ZSkpIHsKKyAgICAgICAgICAgIG5ldyBFeHBhbmRlcigpLmV4cGFuZChmLCByZXN1bHREaXIpOworICAgICAgICB9CisgICAgICAgIHZlcmlmeVRhcmdldERpcigpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgZmlsZUNhbnRFc2NhcGVWaWFBYnNvbHV0ZVBhdGgoKSB0aHJvd3MgSU9FeGNlcHRpb24sIEFyY2hpdmVFeGNlcHRpb24geworICAgICAgICBzZXR1cFppcCgiL3RtcC9mb28iKTsKKyAgICAgICAgdHJ5IChaaXBGaWxlIGYgPSBuZXcgWmlwRmlsZShhcmNoaXZlKSkgeworICAgICAgICAgICAgbmV3IEV4cGFuZGVyKCkuZXhwYW5kKGYsIHJlc3VsdERpcik7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0SGVsbG9Xb3JsZCgidG1wL2ZvbyIsICIxIik7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBmaWxlQ2FudEVzY2FwZURvdWJsZURvdFBhdGgoKSB0aHJvd3MgSU9FeGNlcHRpb24sIEFyY2hpdmVFeGNlcHRpb24geworICAgICAgICB0aHJvd24uZXhwZWN0KElPRXhjZXB0aW9uLmNsYXNzKTsKKyAgICAgICAgdGhyb3duLmV4cGVjdE1lc3NhZ2UoImV4cGFuZGluZyAuLi9mb28gd291bGQgY3JlYXRlIGZpbGUgb3V0c2lkZSBvZiIpOworICAgICAgICBzZXR1cFppcCgiLi4vZm9vIik7CisgICAgICAgIHRyeSAoWmlwRmlsZSBmID0gbmV3IFppcEZpbGUoYXJjaGl2ZSkpIHsKKyAgICAgICAgICAgIG5ldyBFeHBhbmRlcigpLmV4cGFuZChmLCByZXN1bHREaXIpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBmaWxlQ2FudEVzY2FwZURvdWJsZURvdFBhdGhXaXRoU2ltaWxhclNpYmxpbmcoKSB0aHJvd3MgSU9FeGNlcHRpb24sIEFyY2hpdmVFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgc2libGluZyA9IHJlc3VsdERpci5nZXROYW1lKCkgKyAieCI7CisgICAgICAgIEZpbGUgcyA9IG5ldyBGaWxlKHJlc3VsdERpci5nZXRQYXJlbnRGaWxlKCksIHNpYmxpbmcpOworICAgICAgICBBc3N1bWUuYXNzdW1lRmFsc2Uocy5leGlzdHMoKSk7CisgICAgICAgIHMubWtkaXJzKCk7CisgICAgICAgIEFzc3VtZS5hc3N1bWVUcnVlKHMuZXhpc3RzKCkpOworICAgICAgICBzLmRlbGV0ZU9uRXhpdCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGhyb3duLmV4cGVjdChJT0V4Y2VwdGlvbi5jbGFzcyk7CisgICAgICAgICAgICB0aHJvd24uZXhwZWN0TWVzc2FnZSgiZXhwYW5kaW5nIC4uLyIgKyBzaWJsaW5nICsgIi9hIHdvdWxkIGNyZWF0ZSBmaWxlIG91dHNpZGUgb2YiKTsKKyAgICAgICAgICAgIHNldHVwWmlwKCIuLi8iICsgc2libGluZyArICIvYSIpOworICAgICAgICAgICAgdHJ5IChaaXBGaWxlIGYgPSBuZXcgWmlwRmlsZShhcmNoaXZlKSkgeworICAgICAgICAgICAgICAgIG5ldyBFeHBhbmRlcigpLmV4cGFuZChmLCByZXN1bHREaXIpOworICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5SGFyZFRvRGVsZXRlKHMpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHNldHVwN3ooKSB0aHJvd3MgSU9FeGNlcHRpb24sIEFyY2hpdmVFeGNlcHRpb24geworICAgICAgICBhcmNoaXZlID0gbmV3IEZpbGUoZGlyLCAidGVzdC43eiIpOworICAgICAgICBGaWxlIGR1bW15ID0gbmV3IEZpbGUoZGlyLCAieCIpOworICAgICAgICB0cnkgKE91dHB1dFN0cmVhbSBvID0gRmlsZXMubmV3T3V0cHV0U3RyZWFtKGR1bW15LnRvUGF0aCgpKSkgeworICAgICAgICAgICAgby53cml0ZShuZXcgYnl0ZVsxNF0pOworICAgICAgICB9CisgICAgICAgIHRyeSAoU2V2ZW5aT3V0cHV0RmlsZSBhb3MgPSBuZXcgU2V2ZW5aT3V0cHV0RmlsZShhcmNoaXZlKSkgeworICAgICAgICAgICAgYW9zLnB1dEFyY2hpdmVFbnRyeShhb3MuY3JlYXRlQXJjaGl2ZUVudHJ5KGRpciwgImEiKSk7CisgICAgICAgICAgICBhb3MuY2xvc2VBcmNoaXZlRW50cnkoKTsKKyAgICAgICAgICAgIGFvcy5wdXRBcmNoaXZlRW50cnkoYW9zLmNyZWF0ZUFyY2hpdmVFbnRyeShkaXIsICJhL2IiKSk7CisgICAgICAgICAgICBhb3MuY2xvc2VBcmNoaXZlRW50cnkoKTsKKyAgICAgICAgICAgIGFvcy5wdXRBcmNoaXZlRW50cnkoYW9zLmNyZWF0ZUFyY2hpdmVFbnRyeShkaXIsICJhL2IvYyIpKTsKKyAgICAgICAgICAgIGFvcy5jbG9zZUFyY2hpdmVFbnRyeSgpOworICAgICAgICAgICAgYW9zLnB1dEFyY2hpdmVFbnRyeShhb3MuY3JlYXRlQXJjaGl2ZUVudHJ5KGR1bW15LCAiYS9iL2QudHh0IikpOworICAgICAgICAgICAgYW9zLndyaXRlKCJIZWxsbywgd29ybGQgMSIuZ2V0Qnl0ZXMoU3RhbmRhcmRDaGFyc2V0cy5VVEZfOCkpOworICAgICAgICAgICAgYW9zLmNsb3NlQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgICAgICBhb3MucHV0QXJjaGl2ZUVudHJ5KGFvcy5jcmVhdGVBcmNoaXZlRW50cnkoZHVtbXksICJhL2IvYy9lLnR4dCIpKTsKKyAgICAgICAgICAgIGFvcy53cml0ZSgiSGVsbG8sIHdvcmxkIDIiLmdldEJ5dGVzKFN0YW5kYXJkQ2hhcnNldHMuVVRGXzgpKTsKKyAgICAgICAgICAgIGFvcy5jbG9zZUFyY2hpdmVFbnRyeSgpOworICAgICAgICAgICAgYW9zLmZpbmlzaCgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHNldHVwWmlwKCkgdGhyb3dzIElPRXhjZXB0aW9uLCBBcmNoaXZlRXhjZXB0aW9uIHsKKyAgICAgICAgYXJjaGl2ZSA9IG5ldyBGaWxlKGRpciwgInRlc3QuemlwIik7CisgICAgICAgIEZpbGUgZHVtbXkgPSBuZXcgRmlsZShkaXIsICJ4Iik7CisgICAgICAgIHRyeSAoT3V0cHV0U3RyZWFtIG8gPSBGaWxlcy5uZXdPdXRwdXRTdHJlYW0oZHVtbXkudG9QYXRoKCkpKSB7CisgICAgICAgICAgICBvLndyaXRlKG5ldyBieXRlWzE0XSk7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IChBcmNoaXZlT3V0cHV0U3RyZWFtIGFvcyA9IG5ldyBBcmNoaXZlU3RyZWFtRmFjdG9yeSgpCisgICAgICAgICAgICAgLmNyZWF0ZUFyY2hpdmVPdXRwdXRTdHJlYW0oInppcCIsIEZpbGVzLm5ld091dHB1dFN0cmVhbShhcmNoaXZlLnRvUGF0aCgpKSkpIHsKKyAgICAgICAgICAgIGFvcy5wdXRBcmNoaXZlRW50cnkoYW9zLmNyZWF0ZUFyY2hpdmVFbnRyeShkaXIsICJhIikpOworICAgICAgICAgICAgYW9zLmNsb3NlQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgICAgICBhb3MucHV0QXJjaGl2ZUVudHJ5KGFvcy5jcmVhdGVBcmNoaXZlRW50cnkoZGlyLCAiYS9iIikpOworICAgICAgICAgICAgYW9zLmNsb3NlQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgICAgICBhb3MucHV0QXJjaGl2ZUVudHJ5KGFvcy5jcmVhdGVBcmNoaXZlRW50cnkoZGlyLCAiYS9iL2MiKSk7CisgICAgICAgICAgICBhb3MuY2xvc2VBcmNoaXZlRW50cnkoKTsKKyAgICAgICAgICAgIGFvcy5wdXRBcmNoaXZlRW50cnkoYW9zLmNyZWF0ZUFyY2hpdmVFbnRyeShkdW1teSwgImEvYi9kLnR4dCIpKTsKKyAgICAgICAgICAgIGFvcy53cml0ZSgiSGVsbG8sIHdvcmxkIDEiLmdldEJ5dGVzKFN0YW5kYXJkQ2hhcnNldHMuVVRGXzgpKTsKKyAgICAgICAgICAgIGFvcy5jbG9zZUFyY2hpdmVFbnRyeSgpOworICAgICAgICAgICAgYW9zLnB1dEFyY2hpdmVFbnRyeShhb3MuY3JlYXRlQXJjaGl2ZUVudHJ5KGR1bW15LCAiYS9iL2MvZS50eHQiKSk7CisgICAgICAgICAgICBhb3Mud3JpdGUoIkhlbGxvLCB3b3JsZCAyIi5nZXRCeXRlcyhTdGFuZGFyZENoYXJzZXRzLlVURl84KSk7CisgICAgICAgICAgICBhb3MuY2xvc2VBcmNoaXZlRW50cnkoKTsKKyAgICAgICAgICAgIGFvcy5maW5pc2goKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBzZXR1cFppcChTdHJpbmcgZW50cnkpIHRocm93cyBJT0V4Y2VwdGlvbiwgQXJjaGl2ZUV4Y2VwdGlvbiB7CisgICAgICAgIGFyY2hpdmUgPSBuZXcgRmlsZShkaXIsICJ0ZXN0LnppcCIpOworICAgICAgICBGaWxlIGR1bW15ID0gbmV3IEZpbGUoZGlyLCAieCIpOworICAgICAgICB0cnkgKE91dHB1dFN0cmVhbSBvID0gRmlsZXMubmV3T3V0cHV0U3RyZWFtKGR1bW15LnRvUGF0aCgpKSkgeworICAgICAgICAgICAgby53cml0ZShuZXcgYnl0ZVsxNF0pOworICAgICAgICB9CisgICAgICAgIHRyeSAoQXJjaGl2ZU91dHB1dFN0cmVhbSBhb3MgPSBuZXcgQXJjaGl2ZVN0cmVhbUZhY3RvcnkoKQorICAgICAgICAgICAgIC5jcmVhdGVBcmNoaXZlT3V0cHV0U3RyZWFtKCJ6aXAiLCBGaWxlcy5uZXdPdXRwdXRTdHJlYW0oYXJjaGl2ZS50b1BhdGgoKSkpKSB7CisgICAgICAgICAgICBhb3MucHV0QXJjaGl2ZUVudHJ5KGFvcy5jcmVhdGVBcmNoaXZlRW50cnkoZHVtbXksIGVudHJ5KSk7CisgICAgICAgICAgICBhb3Mud3JpdGUoIkhlbGxvLCB3b3JsZCAxIi5nZXRCeXRlcyhTdGFuZGFyZENoYXJzZXRzLlVURl84KSk7CisgICAgICAgICAgICBhb3MuY2xvc2VBcmNoaXZlRW50cnkoKTsKKyAgICAgICAgICAgIGFvcy5maW5pc2goKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB2ZXJpZnlUYXJnZXREaXIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBBc3NlcnQuYXNzZXJ0VHJ1ZSgiYSBoYXMgbm90IGJlZW4gY3JlYXRlZCIsIG5ldyBGaWxlKHJlc3VsdERpciwgImEiKS5pc0RpcmVjdG9yeSgpKTsKKyAgICAgICAgQXNzZXJ0LmFzc2VydFRydWUoImEvYiBoYXMgbm90IGJlZW4gY3JlYXRlZCIsIG5ldyBGaWxlKHJlc3VsdERpciwgImEvYiIpLmlzRGlyZWN0b3J5KCkpOworICAgICAgICBBc3NlcnQuYXNzZXJ0VHJ1ZSgiYS9iL2MgaGFzIG5vdCBiZWVuIGNyZWF0ZWQiLCBuZXcgRmlsZShyZXN1bHREaXIsICJhL2IvYyIpLmlzRGlyZWN0b3J5KCkpOworICAgICAgICBhc3NlcnRIZWxsb1dvcmxkKCJhL2IvZC50eHQiLCAiMSIpOworICAgICAgICBhc3NlcnRIZWxsb1dvcmxkKCJhL2IvYy9lLnR4dCIsICIyIik7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGFzc2VydEhlbGxvV29ybGQoU3RyaW5nIGZpbGVOYW1lLCBTdHJpbmcgc3VmZml4KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShmaWxlTmFtZSArICIgZG9lcyBub3QgZXhpc3QiLCBuZXcgRmlsZShyZXN1bHREaXIsIGZpbGVOYW1lKS5pc0ZpbGUoKSk7CisgICAgICAgIGJ5dGVbXSBleHBlY3RlZCA9ICgiSGVsbG8sIHdvcmxkICIgKyBzdWZmaXgpLmdldEJ5dGVzKFN0YW5kYXJkQ2hhcnNldHMuVVRGXzgpOworICAgICAgICB0cnkgKElucHV0U3RyZWFtIGlzID0gRmlsZXMubmV3SW5wdXRTdHJlYW0obmV3IEZpbGUocmVzdWx0RGlyLCBmaWxlTmFtZSkudG9QYXRoKCkpKSB7CisgICAgICAgICAgICBieXRlW10gYWN0dWFsID0gSU9VdGlscy50b0J5dGVBcnJheShpcyk7CisgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0QXJyYXlFcXVhbHMoZXhwZWN0ZWQsIGFjdHVhbCk7CisgICAgICAgIH0KKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9leGFtcGxlcy9QYXJhbWV0ZXJpemVkQXJjaGl2ZXJUZXN0LmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvZXhhbXBsZXMvUGFyYW1ldGVyaXplZEFyY2hpdmVyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIyNjc2MTAKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvZXhhbXBsZXMvUGFyYW1ldGVyaXplZEFyY2hpdmVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTUzIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5leGFtcGxlczsKKworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLkZpbGVDaGFubmVsOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLlNlZWthYmxlQnl0ZUNoYW5uZWw7CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5TdGFuZGFyZENoYXJzZXRzOworaW1wb3J0IGphdmEubmlvLmZpbGUuRmlsZXM7CitpbXBvcnQgamF2YS5uaW8uZmlsZS5TdGFuZGFyZE9wZW5PcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5BYnN0cmFjdFRlc3RDYXNlOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZUVudHJ5OworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZUV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLkFyY2hpdmVJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLkFyY2hpdmVPdXRwdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5BcmNoaXZlU3RyZWFtRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuSU9VdGlsczsKK2ltcG9ydCBvcmcuanVuaXQuQXNzZXJ0OworaW1wb3J0IG9yZy5qdW5pdC5CZWZvcmU7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lci5SdW5XaXRoOworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXJzLlBhcmFtZXRlcml6ZWQuUGFyYW1ldGVyczsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVycy5QYXJhbWV0ZXJpemVkOworCitAUnVuV2l0aChQYXJhbWV0ZXJpemVkLmNsYXNzKQorcHVibGljIGNsYXNzIFBhcmFtZXRlcml6ZWRBcmNoaXZlclRlc3QgZXh0ZW5kcyBBYnN0cmFjdFRlc3RDYXNlIHsKKworICAgIC8vIGNhbid0IHRlc3QgN3ogaGVyZSBhcyA3eiBjYW5ub3Qgd3JpdGUgdG8gbm9uLXNlZWthYmxlIHN0cmVhbXMKKyAgICAvLyBhbmQgcmVhZGluZyBsb2dpYyB3b3VsZCBiZSBkaWZmZXJlbnQgYXMgd2VsbCAtIHNlZQorICAgIC8vIFNldmVuWkFyY2hpdmVyVGVzdCBjbGFzcworICAgIEBQYXJhbWV0ZXJzKG5hbWUgPSAiZm9ybWF0PXswfSIpCisgICAgcHVibGljIHN0YXRpYyBDb2xsZWN0aW9uPE9iamVjdFtdPiBkYXRhKCkgeworICAgICAgICByZXR1cm4gQXJyYXlzLmFzTGlzdCgKKyAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7ICJ0YXIiIH0sCisgICAgICAgICAgICBuZXcgT2JqZWN0W10geyAiY3BpbyIgfSwKKyAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7ICJ6aXAiIH0KKyAgICAgICAgKTsKKyAgICB9CisKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBmb3JtYXQ7CisgICAgcHJpdmF0ZSBGaWxlIHRhcmdldDsKKworICAgIHB1YmxpYyBQYXJhbWV0ZXJpemVkQXJjaGl2ZXJUZXN0KFN0cmluZyBmb3JtYXQpIHsKKyAgICAgICAgdGhpcy5mb3JtYXQgPSBmb3JtYXQ7CisgICAgfQorCisgICAgQEJlZm9yZQorICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIEZpbGUgYyA9IG5ldyBGaWxlKGRpciwgImEvYi9jIik7CisgICAgICAgIGMubWtkaXJzKCk7CisgICAgICAgIHRyeSAoT3V0cHV0U3RyZWFtIG9zID0gRmlsZXMubmV3T3V0cHV0U3RyZWFtKG5ldyBGaWxlKGRpciwgImEvYi9kLnR4dCIpLnRvUGF0aCgpKSkgeworICAgICAgICAgICAgb3Mud3JpdGUoIkhlbGxvLCB3b3JsZCAxIi5nZXRCeXRlcyhTdGFuZGFyZENoYXJzZXRzLlVURl84KSk7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IChPdXRwdXRTdHJlYW0gb3MgPSBGaWxlcy5uZXdPdXRwdXRTdHJlYW0obmV3IEZpbGUoZGlyLCAiYS9iL2MvZS50eHQiKS50b1BhdGgoKSkpIHsKKyAgICAgICAgICAgIG9zLndyaXRlKCJIZWxsbywgd29ybGQgMiIuZ2V0Qnl0ZXMoU3RhbmRhcmRDaGFyc2V0cy5VVEZfOCkpOworICAgICAgICB9CisgICAgICAgIHRhcmdldCA9IG5ldyBGaWxlKHJlc3VsdERpciwgInRlc3QuIiArIGZvcm1hdCk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBmaWxlVmVyc2lvbigpIHRocm93cyBJT0V4Y2VwdGlvbiwgQXJjaGl2ZUV4Y2VwdGlvbiB7CisgICAgICAgIG5ldyBBcmNoaXZlcigpLmNyZWF0ZShmb3JtYXQsIHRhcmdldCwgZGlyKTsKKyAgICAgICAgdmVyaWZ5Q29udGVudCgpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgb3V0cHV0U3RyZWFtVmVyc2lvbigpIHRocm93cyBJT0V4Y2VwdGlvbiwgQXJjaGl2ZUV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSAoT3V0cHV0U3RyZWFtIG9zID0gRmlsZXMubmV3T3V0cHV0U3RyZWFtKHRhcmdldC50b1BhdGgoKSkpIHsKKyAgICAgICAgICAgIG5ldyBBcmNoaXZlcigpLmNyZWF0ZShmb3JtYXQsIG9zLCBkaXIpOworICAgICAgICB9CisgICAgICAgIHZlcmlmeUNvbnRlbnQoKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIGNoYW5uZWxWZXJzaW9uKCkgdGhyb3dzIElPRXhjZXB0aW9uLCBBcmNoaXZlRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IChTZWVrYWJsZUJ5dGVDaGFubmVsIGMgPSBGaWxlQ2hhbm5lbC5vcGVuKHRhcmdldC50b1BhdGgoKSwgU3RhbmRhcmRPcGVuT3B0aW9uLldSSVRFLAorICAgICAgICAgICAgU3RhbmRhcmRPcGVuT3B0aW9uLkNSRUFURSwgU3RhbmRhcmRPcGVuT3B0aW9uLlRSVU5DQVRFX0VYSVNUSU5HKSkgeworICAgICAgICAgICAgbmV3IEFyY2hpdmVyKCkuY3JlYXRlKGZvcm1hdCwgYywgZGlyKTsKKyAgICAgICAgfQorICAgICAgICB2ZXJpZnlDb250ZW50KCk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBhcmNoaXZlU3RyZWFtVmVyc2lvbigpIHRocm93cyBJT0V4Y2VwdGlvbiwgQXJjaGl2ZUV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSAoT3V0cHV0U3RyZWFtIG9zID0gRmlsZXMubmV3T3V0cHV0U3RyZWFtKHRhcmdldC50b1BhdGgoKSk7CisgICAgICAgICAgICAgQXJjaGl2ZU91dHB1dFN0cmVhbSBhb3MgPSBuZXcgQXJjaGl2ZVN0cmVhbUZhY3RvcnkoKS5jcmVhdGVBcmNoaXZlT3V0cHV0U3RyZWFtKGZvcm1hdCwgb3MpKSB7CisgICAgICAgICAgICBuZXcgQXJjaGl2ZXIoKS5jcmVhdGUoYW9zLCBkaXIpOworICAgICAgICB9CisgICAgICAgIHZlcmlmeUNvbnRlbnQoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdmVyaWZ5Q29udGVudCgpIHRocm93cyBJT0V4Y2VwdGlvbiwgQXJjaGl2ZUV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSAoSW5wdXRTdHJlYW0gaXMgPSBGaWxlcy5uZXdJbnB1dFN0cmVhbSh0YXJnZXQudG9QYXRoKCkpOworICAgICAgICAgICAgIEJ1ZmZlcmVkSW5wdXRTdHJlYW0gYmlzID0gbmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0oaXMpOworICAgICAgICAgICAgIEFyY2hpdmVJbnB1dFN0cmVhbSBhaXMgPSBuZXcgQXJjaGl2ZVN0cmVhbUZhY3RvcnkoKS5jcmVhdGVBcmNoaXZlSW5wdXRTdHJlYW0oZm9ybWF0LCBiaXMpKSB7CisgICAgICAgICAgICBhc3NlcnREaXIoImEiLCBhaXMuZ2V0TmV4dEVudHJ5KCkpOworICAgICAgICAgICAgYXNzZXJ0RGlyKCJhL2IiLCBhaXMuZ2V0TmV4dEVudHJ5KCkpOworICAgICAgICAgICAgQXJjaGl2ZUVudHJ5IG4gPSBhaXMuZ2V0TmV4dEVudHJ5KCk7CisgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0Tm90TnVsbChuKTsKKyAgICAgICAgICAgIC8vIEZpbGUubGlzdCBtYXkgcmV0dXJuIGEvYi9jIG9yIGEvYi9kLnR4dCBmaXJzdAorICAgICAgICAgICAgaWYgKG4uZ2V0TmFtZSgpLmVuZHNXaXRoKCIvIikpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnREaXIoImEvYi9jIiwgbik7CisgICAgICAgICAgICAgICAgYXNzZXJ0SGVsbG9Xb3JsZCgiYS9iL2MvZS50eHQiLCAiMiIsIGFpcy5nZXROZXh0RW50cnkoKSwgYWlzKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRIZWxsb1dvcmxkKCJhL2IvZC50eHQiLCAiMSIsIGFpcy5nZXROZXh0RW50cnkoKSwgYWlzKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0SGVsbG9Xb3JsZCgiYS9iL2QudHh0IiwgIjEiLCBuLCBhaXMpOworICAgICAgICAgICAgICAgIGFzc2VydERpcigiYS9iL2MiLCBhaXMuZ2V0TmV4dEVudHJ5KCkpOworICAgICAgICAgICAgICAgIGFzc2VydEhlbGxvV29ybGQoImEvYi9jL2UudHh0IiwgIjIiLCBhaXMuZ2V0TmV4dEVudHJ5KCksIGFpcyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYXNzZXJ0RGlyKFN0cmluZyBleHBlY3RlZE5hbWUsIEFyY2hpdmVFbnRyeSBlbnRyeSkgeworICAgICAgICBBc3NlcnQuYXNzZXJ0Tm90TnVsbChleHBlY3RlZE5hbWUgKyAiIGRvZXMgbm90IGV4aXN0cyIsIGVudHJ5KTsKKyAgICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyhleHBlY3RlZE5hbWUgKyAiLyIsIGVudHJ5LmdldE5hbWUoKSk7CisgICAgICAgIEFzc2VydC5hc3NlcnRUcnVlKGV4cGVjdGVkTmFtZSArICIgaXMgbm90IGEgZGlyZWN0b3J5IiwgZW50cnkuaXNEaXJlY3RvcnkoKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGFzc2VydEhlbGxvV29ybGQoU3RyaW5nIGV4cGVjdGVkTmFtZSwgU3RyaW5nIHN1ZmZpeCwgQXJjaGl2ZUVudHJ5IGVudHJ5LCBJbnB1dFN0cmVhbSBpcykKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgQXNzZXJ0LmFzc2VydE5vdE51bGwoZXhwZWN0ZWROYW1lICsgIiBkb2VzIG5vdCBleGlzdHMiLCBlbnRyeSk7CisgICAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoZXhwZWN0ZWROYW1lLCBlbnRyeS5nZXROYW1lKCkpOworICAgICAgICBBc3NlcnQuYXNzZXJ0RmFsc2UoZXhwZWN0ZWROYW1lICsgIiBpcyBhIGRpcmVjdG9yeSIsIGVudHJ5LmlzRGlyZWN0b3J5KCkpOworICAgICAgICBieXRlW10gZXhwZWN0ZWQgPSAoIkhlbGxvLCB3b3JsZCAiICsgc3VmZml4KS5nZXRCeXRlcyhTdGFuZGFyZENoYXJzZXRzLlVURl84KTsKKyAgICAgICAgYnl0ZVtdIGFjdHVhbCA9IElPVXRpbHMudG9CeXRlQXJyYXkoaXMpOworICAgICAgICBBc3NlcnQuYXNzZXJ0QXJyYXlFcXVhbHMoZXhwZWN0ZWQsIGFjdHVhbCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2V4YW1wbGVzL1BhcmFtZXRlcml6ZWRFeHBhbmRlclRlc3QuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9leGFtcGxlcy9QYXJhbWV0ZXJpemVkRXhwYW5kZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWQ2ZGE0YgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9leGFtcGxlcy9QYXJhbWV0ZXJpemVkRXhwYW5kZXJUZXN0LmphdmEKQEAgLTAsMCArMSwxNTcgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLmV4YW1wbGVzOworCitpbXBvcnQgamF2YS5pby5CdWZmZXJlZElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuRmlsZUNoYW5uZWw7CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuU2Vla2FibGVCeXRlQ2hhbm5lbDsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LlN0YW5kYXJkQ2hhcnNldHM7CitpbXBvcnQgamF2YS5uaW8uZmlsZS5GaWxlczsKK2ltcG9ydCBqYXZhLm5pby5maWxlLlN0YW5kYXJkT3Blbk9wdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLkFic3RyYWN0VGVzdENhc2U7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5BcmNoaXZlRW50cnk7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5BcmNoaXZlRXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZUlucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLkFyY2hpdmVTdHJlYW1GYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5JT1V0aWxzOworaW1wb3J0IG9yZy5qdW5pdC5Bc3NlcnQ7CitpbXBvcnQgb3JnLmp1bml0LkJlZm9yZTsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVyLlJ1bldpdGg7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lcnMuUGFyYW1ldGVyaXplZC5QYXJhbWV0ZXJzOworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXJzLlBhcmFtZXRlcml6ZWQ7CisKK0BSdW5XaXRoKFBhcmFtZXRlcml6ZWQuY2xhc3MpCitwdWJsaWMgY2xhc3MgUGFyYW1ldGVyaXplZEV4cGFuZGVyVGVzdCBleHRlbmRzIEFic3RyYWN0VGVzdENhc2UgeworCisgICAgLy8gN3ogYW5kIFpJUCB1c2luZyBaaXBGaWxlIGlzIGluIEV4cGFuZGVyVGVzdAorICAgIEBQYXJhbWV0ZXJzKG5hbWUgPSAiZm9ybWF0PXswfSIpCisgICAgcHVibGljIHN0YXRpYyBDb2xsZWN0aW9uPE9iamVjdFtdPiBkYXRhKCkgeworICAgICAgICByZXR1cm4gQXJyYXlzLmFzTGlzdCgKKyAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7ICJ0YXIiIH0sCisgICAgICAgICAgICBuZXcgT2JqZWN0W10geyAiY3BpbyIgfSwKKyAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7ICJ6aXAiIH0KKyAgICAgICAgKTsKKyAgICB9CisKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBmb3JtYXQ7CisgICAgcHJpdmF0ZSBGaWxlIGFyY2hpdmU7CisKKyAgICBwdWJsaWMgUGFyYW1ldGVyaXplZEV4cGFuZGVyVGVzdChTdHJpbmcgZm9ybWF0KSB7CisgICAgICAgIHRoaXMuZm9ybWF0ID0gZm9ybWF0OworICAgIH0KKworICAgIEBCZWZvcmUKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgICAgICBhcmNoaXZlID0gbmV3IEZpbGUoZGlyLCAidGVzdC4iICsgZm9ybWF0KTsKKyAgICAgICAgRmlsZSBkdW1teSA9IG5ldyBGaWxlKGRpciwgIngiKTsKKyAgICAgICAgdHJ5IChPdXRwdXRTdHJlYW0gbyA9IEZpbGVzLm5ld091dHB1dFN0cmVhbShkdW1teS50b1BhdGgoKSkpIHsKKyAgICAgICAgICAgIG8ud3JpdGUobmV3IGJ5dGVbMTRdKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgKEFyY2hpdmVPdXRwdXRTdHJlYW0gYW9zID0gbmV3IEFyY2hpdmVTdHJlYW1GYWN0b3J5KCkKKyAgICAgICAgICAgICAuY3JlYXRlQXJjaGl2ZU91dHB1dFN0cmVhbShmb3JtYXQsIEZpbGVzLm5ld091dHB1dFN0cmVhbShhcmNoaXZlLnRvUGF0aCgpKSkpIHsKKyAgICAgICAgICAgIGFvcy5wdXRBcmNoaXZlRW50cnkoYW9zLmNyZWF0ZUFyY2hpdmVFbnRyeShkaXIsICJhIikpOworICAgICAgICAgICAgYW9zLmNsb3NlQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgICAgICBhb3MucHV0QXJjaGl2ZUVudHJ5KGFvcy5jcmVhdGVBcmNoaXZlRW50cnkoZGlyLCAiYS9iIikpOworICAgICAgICAgICAgYW9zLmNsb3NlQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgICAgICBhb3MucHV0QXJjaGl2ZUVudHJ5KGFvcy5jcmVhdGVBcmNoaXZlRW50cnkoZGlyLCAiYS9iL2MiKSk7CisgICAgICAgICAgICBhb3MuY2xvc2VBcmNoaXZlRW50cnkoKTsKKyAgICAgICAgICAgIGFvcy5wdXRBcmNoaXZlRW50cnkoYW9zLmNyZWF0ZUFyY2hpdmVFbnRyeShkdW1teSwgImEvYi9kLnR4dCIpKTsKKyAgICAgICAgICAgIGFvcy53cml0ZSgiSGVsbG8sIHdvcmxkIDEiLmdldEJ5dGVzKFN0YW5kYXJkQ2hhcnNldHMuVVRGXzgpKTsKKyAgICAgICAgICAgIGFvcy5jbG9zZUFyY2hpdmVFbnRyeSgpOworICAgICAgICAgICAgYW9zLnB1dEFyY2hpdmVFbnRyeShhb3MuY3JlYXRlQXJjaGl2ZUVudHJ5KGR1bW15LCAiYS9iL2MvZS50eHQiKSk7CisgICAgICAgICAgICBhb3Mud3JpdGUoIkhlbGxvLCB3b3JsZCAyIi5nZXRCeXRlcyhTdGFuZGFyZENoYXJzZXRzLlVURl84KSk7CisgICAgICAgICAgICBhb3MuY2xvc2VBcmNoaXZlRW50cnkoKTsKKyAgICAgICAgICAgIGFvcy5maW5pc2goKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgZmlsZVZlcnNpb24oKSB0aHJvd3MgSU9FeGNlcHRpb24sIEFyY2hpdmVFeGNlcHRpb24geworICAgICAgICBuZXcgRXhwYW5kZXIoKS5leHBhbmQoZm9ybWF0LCBhcmNoaXZlLCByZXN1bHREaXIpOworICAgICAgICB2ZXJpZnlUYXJnZXREaXIoKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIGZpbGVWZXJzaW9uV2l0aEF1dG9EZXRlY3Rpb24oKSB0aHJvd3MgSU9FeGNlcHRpb24sIEFyY2hpdmVFeGNlcHRpb24geworICAgICAgICBuZXcgRXhwYW5kZXIoKS5leHBhbmQoYXJjaGl2ZSwgcmVzdWx0RGlyKTsKKyAgICAgICAgdmVyaWZ5VGFyZ2V0RGlyKCk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBpbnB1dFN0cmVhbVZlcnNpb24oKSB0aHJvd3MgSU9FeGNlcHRpb24sIEFyY2hpdmVFeGNlcHRpb24geworICAgICAgICB0cnkgKElucHV0U3RyZWFtIGkgPSBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShGaWxlcy5uZXdJbnB1dFN0cmVhbShhcmNoaXZlLnRvUGF0aCgpKSkpIHsKKyAgICAgICAgICAgIG5ldyBFeHBhbmRlcigpLmV4cGFuZChmb3JtYXQsIGksIHJlc3VsdERpcik7CisgICAgICAgIH0KKyAgICAgICAgdmVyaWZ5VGFyZ2V0RGlyKCk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBpbnB1dFN0cmVhbVZlcnNpb25XaXRoQXV0b0RldGVjdGlvbigpIHRocm93cyBJT0V4Y2VwdGlvbiwgQXJjaGl2ZUV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSAoSW5wdXRTdHJlYW0gaSA9IG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKEZpbGVzLm5ld0lucHV0U3RyZWFtKGFyY2hpdmUudG9QYXRoKCkpKSkgeworICAgICAgICAgICAgbmV3IEV4cGFuZGVyKCkuZXhwYW5kKGksIHJlc3VsdERpcik7CisgICAgICAgIH0KKyAgICAgICAgdmVyaWZ5VGFyZ2V0RGlyKCk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBjaGFubmVsVmVyc2lvbigpIHRocm93cyBJT0V4Y2VwdGlvbiwgQXJjaGl2ZUV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSAoU2Vla2FibGVCeXRlQ2hhbm5lbCBjID0gRmlsZUNoYW5uZWwub3BlbihhcmNoaXZlLnRvUGF0aCgpLCBTdGFuZGFyZE9wZW5PcHRpb24uUkVBRCkpIHsKKyAgICAgICAgICAgIG5ldyBFeHBhbmRlcigpLmV4cGFuZChmb3JtYXQsIGMsIHJlc3VsdERpcik7CisgICAgICAgIH0KKyAgICAgICAgdmVyaWZ5VGFyZ2V0RGlyKCk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBhcmNoaXZlSW5wdXRTdHJlYW1WZXJzaW9uKCkgdGhyb3dzIElPRXhjZXB0aW9uLCBBcmNoaXZlRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBpID0gbmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0oRmlsZXMubmV3SW5wdXRTdHJlYW0oYXJjaGl2ZS50b1BhdGgoKSkpOworICAgICAgICAgICAgIEFyY2hpdmVJbnB1dFN0cmVhbSBhaXMgPSBuZXcgQXJjaGl2ZVN0cmVhbUZhY3RvcnkoKS5jcmVhdGVBcmNoaXZlSW5wdXRTdHJlYW0oZm9ybWF0LCBpKSkgeworICAgICAgICAgICAgbmV3IEV4cGFuZGVyKCkuZXhwYW5kKGFpcywgcmVzdWx0RGlyKTsKKyAgICAgICAgfQorICAgICAgICB2ZXJpZnlUYXJnZXREaXIoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdmVyaWZ5VGFyZ2V0RGlyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgQXNzZXJ0LmFzc2VydFRydWUoImEgaGFzIG5vdCBiZWVuIGNyZWF0ZWQiLCBuZXcgRmlsZShyZXN1bHREaXIsICJhIikuaXNEaXJlY3RvcnkoKSk7CisgICAgICAgIEFzc2VydC5hc3NlcnRUcnVlKCJhL2IgaGFzIG5vdCBiZWVuIGNyZWF0ZWQiLCBuZXcgRmlsZShyZXN1bHREaXIsICJhL2IiKS5pc0RpcmVjdG9yeSgpKTsKKyAgICAgICAgQXNzZXJ0LmFzc2VydFRydWUoImEvYi9jIGhhcyBub3QgYmVlbiBjcmVhdGVkIiwgbmV3IEZpbGUocmVzdWx0RGlyLCAiYS9iL2MiKS5pc0RpcmVjdG9yeSgpKTsKKyAgICAgICAgYXNzZXJ0SGVsbG9Xb3JsZCgiYS9iL2QudHh0IiwgIjEiKTsKKyAgICAgICAgYXNzZXJ0SGVsbG9Xb3JsZCgiYS9iL2MvZS50eHQiLCAiMiIpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhc3NlcnRIZWxsb1dvcmxkKFN0cmluZyBmaWxlTmFtZSwgU3RyaW5nIHN1ZmZpeCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgQXNzZXJ0LmFzc2VydFRydWUoZmlsZU5hbWUgKyAiIGRvZXMgbm90IGV4aXN0IiwgbmV3IEZpbGUocmVzdWx0RGlyLCBmaWxlTmFtZSkuaXNGaWxlKCkpOworICAgICAgICBieXRlW10gZXhwZWN0ZWQgPSAoIkhlbGxvLCB3b3JsZCAiICsgc3VmZml4KS5nZXRCeXRlcyhTdGFuZGFyZENoYXJzZXRzLlVURl84KTsKKyAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBpcyA9IEZpbGVzLm5ld0lucHV0U3RyZWFtKG5ldyBGaWxlKHJlc3VsdERpciwgZmlsZU5hbWUpLnRvUGF0aCgpKSkgeworICAgICAgICAgICAgYnl0ZVtdIGFjdHVhbCA9IElPVXRpbHMudG9CeXRlQXJyYXkoaXMpOworICAgICAgICAgICAgQXNzZXJ0LmFzc2VydEFycmF5RXF1YWxzKGV4cGVjdGVkLCBhY3R1YWwpOworICAgICAgICB9CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvZXhhbXBsZXMvU2V2ZW5aQXJjaGl2ZXJUZXN0LmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvZXhhbXBsZXMvU2V2ZW5aQXJjaGl2ZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjM1Yzg5OQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9leGFtcGxlcy9TZXZlblpBcmNoaXZlclRlc3QuamF2YQpAQCAtMCwwICsxLDEyNCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuZXhhbXBsZXM7CisKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5GaWxlQ2hhbm5lbDsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5TZWVrYWJsZUJ5dGVDaGFubmVsOworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuU3RhbmRhcmRDaGFyc2V0czsKK2ltcG9ydCBqYXZhLm5pby5maWxlLkZpbGVzOworaW1wb3J0IGphdmEubmlvLmZpbGUuU3RhbmRhcmRPcGVuT3B0aW9uOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLkFic3RyYWN0VGVzdENhc2U7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5BcmNoaXZlRW50cnk7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5BcmNoaXZlRXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuU3RyZWFtaW5nTm90U3VwcG9ydGVkRXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuc2V2ZW56LlNldmVuWkZpbGU7CitpbXBvcnQgb3JnLmp1bml0LkFzc2VydDsKK2ltcG9ydCBvcmcuanVuaXQuQmVmb3JlOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworCitwdWJsaWMgY2xhc3MgU2V2ZW5aQXJjaGl2ZXJUZXN0IGV4dGVuZHMgQWJzdHJhY3RUZXN0Q2FzZSB7CisgICAgcHJpdmF0ZSBGaWxlIHRhcmdldDsKKworICAgIEBCZWZvcmUKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgICAgICBGaWxlIGMgPSBuZXcgRmlsZShkaXIsICJhL2IvYyIpOworICAgICAgICBjLm1rZGlycygpOworICAgICAgICB0cnkgKE91dHB1dFN0cmVhbSBvcyA9IEZpbGVzLm5ld091dHB1dFN0cmVhbShuZXcgRmlsZShkaXIsICJhL2IvZC50eHQiKS50b1BhdGgoKSkpIHsKKyAgICAgICAgICAgIG9zLndyaXRlKCJIZWxsbywgd29ybGQgMSIuZ2V0Qnl0ZXMoU3RhbmRhcmRDaGFyc2V0cy5VVEZfOCkpOworICAgICAgICB9CisgICAgICAgIHRyeSAoT3V0cHV0U3RyZWFtIG9zID0gRmlsZXMubmV3T3V0cHV0U3RyZWFtKG5ldyBGaWxlKGRpciwgImEvYi9jL2UudHh0IikudG9QYXRoKCkpKSB7CisgICAgICAgICAgICBvcy53cml0ZSgiSGVsbG8sIHdvcmxkIDIiLmdldEJ5dGVzKFN0YW5kYXJkQ2hhcnNldHMuVVRGXzgpKTsKKyAgICAgICAgfQorICAgICAgICB0YXJnZXQgPSBuZXcgRmlsZShyZXN1bHREaXIsICJ0ZXN0Ljd6Iik7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBmaWxlVmVyc2lvbigpIHRocm93cyBJT0V4Y2VwdGlvbiwgQXJjaGl2ZUV4Y2VwdGlvbiB7CisgICAgICAgIG5ldyBBcmNoaXZlcigpLmNyZWF0ZSgiN3oiLCB0YXJnZXQsIGRpcik7CisgICAgICAgIHZlcmlmeUNvbnRlbnQoKTsKKyAgICB9CisKKyAgICBAVGVzdChleHBlY3RlZCA9IFN0cmVhbWluZ05vdFN1cHBvcnRlZEV4Y2VwdGlvbi5jbGFzcykKKyAgICBwdWJsaWMgdm9pZCBvdXRwdXRTdHJlYW1WZXJzaW9uKCkgdGhyb3dzIElPRXhjZXB0aW9uLCBBcmNoaXZlRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IChPdXRwdXRTdHJlYW0gb3MgPSBGaWxlcy5uZXdPdXRwdXRTdHJlYW0odGFyZ2V0LnRvUGF0aCgpKSkgeworICAgICAgICAgICAgbmV3IEFyY2hpdmVyKCkuY3JlYXRlKCI3eiIsIG9zLCBkaXIpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBjaGFubmVsVmVyc2lvbigpIHRocm93cyBJT0V4Y2VwdGlvbiwgQXJjaGl2ZUV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSAoU2Vla2FibGVCeXRlQ2hhbm5lbCBjID0gRmlsZUNoYW5uZWwub3Blbih0YXJnZXQudG9QYXRoKCksIFN0YW5kYXJkT3Blbk9wdGlvbi5XUklURSwKKyAgICAgICAgICAgIFN0YW5kYXJkT3Blbk9wdGlvbi5DUkVBVEUsIFN0YW5kYXJkT3Blbk9wdGlvbi5UUlVOQ0FURV9FWElTVElORykpIHsKKyAgICAgICAgICAgIG5ldyBBcmNoaXZlcigpLmNyZWF0ZSgiN3oiLCBjLCBkaXIpOworICAgICAgICB9CisgICAgICAgIHZlcmlmeUNvbnRlbnQoKTsKKyAgICB9CisKKyAgICAvLyBub3QgcmVhbGx5IGEgN3ogdGVzdCBidXQgSSBkaWRuJ3QgZmVlbCBsaWtlIGFkZGluZyBhIG5ldyB0ZXN0IGp1c3QgZm9yIHRoaXMKKyAgICBAVGVzdChleHBlY3RlZCA9IEFyY2hpdmVFeGNlcHRpb24uY2xhc3MpCisgICAgcHVibGljIHZvaWQgdW5rbm93bkZvcm1hdCgpIHRocm93cyBJT0V4Y2VwdGlvbiwgQXJjaGl2ZUV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSAoU2Vla2FibGVCeXRlQ2hhbm5lbCBjID0gRmlsZUNoYW5uZWwub3Blbih0YXJnZXQudG9QYXRoKCksIFN0YW5kYXJkT3Blbk9wdGlvbi5XUklURSwKKyAgICAgICAgICAgIFN0YW5kYXJkT3Blbk9wdGlvbi5DUkVBVEUsIFN0YW5kYXJkT3Blbk9wdGlvbi5UUlVOQ0FURV9FWElTVElORykpIHsKKyAgICAgICAgICAgIG5ldyBBcmNoaXZlcigpLmNyZWF0ZSgidW5rbm93biBmb3JtYXQiLCBjLCBkaXIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHZlcmlmeUNvbnRlbnQoKSB0aHJvd3MgSU9FeGNlcHRpb24sIEFyY2hpdmVFeGNlcHRpb24geworICAgICAgICB0cnkgKFNldmVuWkZpbGUgeiA9IG5ldyBTZXZlblpGaWxlKHRhcmdldCkpIHsKKyAgICAgICAgICAgIGFzc2VydERpcigiYSIsIHouZ2V0TmV4dEVudHJ5KCkpOworICAgICAgICAgICAgYXNzZXJ0RGlyKCJhL2IiLCB6LmdldE5leHRFbnRyeSgpKTsKKyAgICAgICAgICAgIEFyY2hpdmVFbnRyeSBuID0gei5nZXROZXh0RW50cnkoKTsKKyAgICAgICAgICAgIEFzc2VydC5hc3NlcnROb3ROdWxsKG4pOworICAgICAgICAgICAgLy8gRmlsZS5saXN0IG1heSByZXR1cm4gYS9iL2Mgb3IgYS9iL2QudHh0IGZpcnN0CisgICAgICAgICAgICBpZiAobi5nZXROYW1lKCkuZW5kc1dpdGgoIi8iKSkgeworICAgICAgICAgICAgICAgIGFzc2VydERpcigiYS9iL2MiLCBuKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRIZWxsb1dvcmxkKCJhL2IvYy9lLnR4dCIsICIyIiwgei5nZXROZXh0RW50cnkoKSwgeik7CisgICAgICAgICAgICAgICAgYXNzZXJ0SGVsbG9Xb3JsZCgiYS9iL2QudHh0IiwgIjEiLCB6LmdldE5leHRFbnRyeSgpLCB6KTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0SGVsbG9Xb3JsZCgiYS9iL2QudHh0IiwgIjEiLCBuLCB6KTsKKyAgICAgICAgICAgICAgICBhc3NlcnREaXIoImEvYi9jIiwgei5nZXROZXh0RW50cnkoKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0SGVsbG9Xb3JsZCgiYS9iL2MvZS50eHQiLCAiMiIsIHouZ2V0TmV4dEVudHJ5KCksIHopOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGFzc2VydERpcihTdHJpbmcgZXhwZWN0ZWROYW1lLCBBcmNoaXZlRW50cnkgZW50cnkpIHsKKyAgICAgICAgQXNzZXJ0LmFzc2VydE5vdE51bGwoZXhwZWN0ZWROYW1lICsgIiBkb2VzIG5vdCBleGlzdHMiLCBlbnRyeSk7CisgICAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoZXhwZWN0ZWROYW1lICsgIi8iLCBlbnRyeS5nZXROYW1lKCkpOworICAgICAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShleHBlY3RlZE5hbWUgKyAiIGlzIG5vdCBhIGRpcmVjdG9yeSIsIGVudHJ5LmlzRGlyZWN0b3J5KCkpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhc3NlcnRIZWxsb1dvcmxkKFN0cmluZyBleHBlY3RlZE5hbWUsIFN0cmluZyBzdWZmaXgsIEFyY2hpdmVFbnRyeSBlbnRyeSwgU2V2ZW5aRmlsZSB6KQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBBc3NlcnQuYXNzZXJ0Tm90TnVsbChleHBlY3RlZE5hbWUgKyAiIGRvZXMgbm90IGV4aXN0cyIsIGVudHJ5KTsKKyAgICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyhleHBlY3RlZE5hbWUsIGVudHJ5LmdldE5hbWUoKSk7CisgICAgICAgIEFzc2VydC5hc3NlcnRGYWxzZShleHBlY3RlZE5hbWUgKyAiIGlzIGEgZGlyZWN0b3J5IiwgZW50cnkuaXNEaXJlY3RvcnkoKSk7CisgICAgICAgIGJ5dGVbXSBleHBlY3RlZCA9ICgiSGVsbG8sIHdvcmxkICIgKyBzdWZmaXgpLmdldEJ5dGVzKFN0YW5kYXJkQ2hhcnNldHMuVVRGXzgpOworICAgICAgICBieXRlW10gYWN0dWFsID0gbmV3IGJ5dGVbZXhwZWN0ZWQubGVuZ3RoXTsKKyAgICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyhhY3R1YWwubGVuZ3RoLCB6LnJlYWQoYWN0dWFsKSk7CisgICAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoLTEsIHoucmVhZCgpKTsKKyAgICAgICAgQXNzZXJ0LmFzc2VydEFycmF5RXF1YWxzKGV4cGVjdGVkLCBhY3R1YWwpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9qYXIvSmFyQXJjaGl2ZU91dHB1dFN0cmVhbVRlc3QuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9qYXIvSmFyQXJjaGl2ZU91dHB1dFN0cmVhbVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zMDA4Mzk1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2phci9KYXJBcmNoaXZlT3V0cHV0U3RyZWFtVGVzdC5qYXZhCkBAIC0wLDAgKzEsNzUgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLmphcjsKKworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0Lio7CisKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuQWJzdHJhY3RUZXN0Q2FzZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcC5KYXJNYXJrZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXAuWmlwQXJjaGl2ZUVudHJ5OworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwLlppcEV4dHJhRmllbGQ7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXAuWmlwRmlsZTsKKworcHVibGljIGNsYXNzIEphckFyY2hpdmVPdXRwdXRTdHJlYW1UZXN0IHsKKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEphck1hcmtlcigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGUgdGVzdEFyY2hpdmUgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKCJqYXItYW9zdGVzdCIsICIuamFyIik7CisgICAgICAgIHRlc3RBcmNoaXZlLmRlbGV0ZU9uRXhpdCgpOworICAgICAgICBKYXJBcmNoaXZlT3V0cHV0U3RyZWFtIG91dCA9IG51bGw7CisgICAgICAgIFppcEZpbGUgemYgPSBudWxsOworICAgICAgICB0cnkgeworCisgICAgICAgICAgICBvdXQgPSBuZXcgSmFyQXJjaGl2ZU91dHB1dFN0cmVhbShuZXcgRmlsZU91dHB1dFN0cmVhbSh0ZXN0QXJjaGl2ZSkpOworICAgICAgICAgICAgb3V0LnB1dEFyY2hpdmVFbnRyeShuZXcgWmlwQXJjaGl2ZUVudHJ5KCJmb28vIikpOworICAgICAgICAgICAgb3V0LmNsb3NlQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgICAgICBvdXQucHV0QXJjaGl2ZUVudHJ5KG5ldyBaaXBBcmNoaXZlRW50cnkoImJhci8iKSk7CisgICAgICAgICAgICBvdXQuY2xvc2VBcmNoaXZlRW50cnkoKTsKKyAgICAgICAgICAgIG91dC5maW5pc2goKTsKKyAgICAgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICAgICAgb3V0ID0gbnVsbDsKKworICAgICAgICAgICAgemYgPSBuZXcgWmlwRmlsZSh0ZXN0QXJjaGl2ZSk7CisgICAgICAgICAgICBaaXBBcmNoaXZlRW50cnkgemUgPSB6Zi5nZXRFbnRyeSgiZm9vLyIpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCh6ZSk7CisgICAgICAgICAgICBaaXBFeHRyYUZpZWxkW10gZmVzID0gemUuZ2V0RXh0cmFGaWVsZHMoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCBmZXMubGVuZ3RoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoZmVzWzBdIGluc3RhbmNlb2YgSmFyTWFya2VyKTsKKworICAgICAgICAgICAgemUgPSB6Zi5nZXRFbnRyeSgiYmFyLyIpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCh6ZSk7CisgICAgICAgICAgICBmZXMgPSB6ZS5nZXRFeHRyYUZpZWxkcygpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGZlcy5sZW5ndGgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKG91dCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgb3V0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoZmluYWwgSU9FeGNlcHRpb24gZSkgeyAvKiBzd2FsbG93ICovIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIFppcEZpbGUuY2xvc2VRdWlldGx5KHpmKTsKKyAgICAgICAgICAgIEFic3RyYWN0VGVzdENhc2UudHJ5SGFyZFRvRGVsZXRlKHRlc3RBcmNoaXZlKTsKKyAgICAgICAgfQorICAgIH0KKworfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9qYXIvSmFyTWFya2VyVGVzdC5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL2phci9KYXJNYXJrZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTA3YTgxNAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9qYXIvSmFyTWFya2VyVGVzdC5qYXZhCkBAIC0wLDAgKzEsMzkgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLmphcjsKKworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmZhaWw7CisKK2ltcG9ydCBqYXZhLnV0aWwuemlwLlppcEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcC5KYXJNYXJrZXI7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CisKK3B1YmxpYyBjbGFzcyBKYXJNYXJrZXJUZXN0IHsKKworICAgIEBUZXN0IHB1YmxpYyB2b2lkIHRlc3RKYXJNYXJrZXJMZW5ndGhDaGVjaygpIHsKKyAgICAgICAgSmFyTWFya2VyIGphck1hcmtlciA9IEphck1hcmtlci5nZXRJbnN0YW5jZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgamFyTWFya2VyLnBhcnNlRnJvbUxvY2FsRmlsZURhdGEobnVsbCwwLDEpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIGhhdmUgdGhyb3duIGV4Y2VwdGlvbiBkdWUgdG8gbGVuZ3RoIG9mIDEiKTsKKyAgICAgICAgfSBjYXRjaCAoWmlwRXhjZXB0aW9uIGUpIHsKKworICAgICAgICB9CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvbWVtb3J5L01lbW9yeUFyY2hpdmVFbnRyeS5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL21lbW9yeS9NZW1vcnlBcmNoaXZlRW50cnkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NmVmYjA5Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL21lbW9yeS9NZW1vcnlBcmNoaXZlRW50cnkuamF2YQpAQCAtMCwwICsxLDU0IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5tZW1vcnk7CisKK2ltcG9ydCBqYXZhLnV0aWwuRGF0ZTsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZUVudHJ5OworCitwdWJsaWMgZmluYWwgY2xhc3MgTWVtb3J5QXJjaGl2ZUVudHJ5IGltcGxlbWVudHMgQXJjaGl2ZUVudHJ5IHsKKworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIG5hbWU7CisKKyAgICBwdWJsaWMgTWVtb3J5QXJjaGl2ZUVudHJ5KGZpbmFsIFN0cmluZyBwTmFtZSkgeworICAgICAgICBuYW1lID0gcE5hbWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgeworICAgICAgICByZXR1cm4gbmFtZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgbG9uZyBnZXRTaXplKCkgeworICAgICAgICAvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIG1ldGhvZCBzdHViCisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGlzRGlyZWN0b3J5KCkgeworICAgICAgICAvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIG1ldGhvZCBzdHViCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRGF0ZSBnZXRMYXN0TW9kaWZpZWREYXRlKCkgeworICAgICAgICByZXR1cm4gbmV3IERhdGUoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvbWVtb3J5L01lbW9yeUFyY2hpdmVJbnB1dFN0cmVhbS5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL21lbW9yeS9NZW1vcnlBcmNoaXZlSW5wdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hM2I4MzQ3Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL21lbW9yeS9NZW1vcnlBcmNoaXZlSW5wdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDYyIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5tZW1vcnk7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5BcmNoaXZlRW50cnk7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5BcmNoaXZlSW5wdXRTdHJlYW07CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBNZW1vcnlBcmNoaXZlSW5wdXRTdHJlYW0gZXh0ZW5kcyBBcmNoaXZlSW5wdXRTdHJlYW0geworCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmdbXSBmaWxlbmFtZXM7CisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmdbXSBjb250ZW50OworICAgIHByaXZhdGUgaW50IHA7CisKKyAgICBwdWJsaWMgTWVtb3J5QXJjaGl2ZUlucHV0U3RyZWFtKCBmaW5hbCBTdHJpbmdbXVtdIHBGaWxlcyApIHsKKyAgICAgICAgZmlsZW5hbWVzID0gbmV3IFN0cmluZ1twRmlsZXMubGVuZ3RoXTsKKyAgICAgICAgY29udGVudCA9IG5ldyBTdHJpbmdbcEZpbGVzLmxlbmd0aF07CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwRmlsZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGZpbmFsIFN0cmluZ1tdIG5hbWVBbmRDb250ZW50ID0gcEZpbGVzW2ldOworICAgICAgICAgICAgZmlsZW5hbWVzW2ldID0gbmFtZUFuZENvbnRlbnRbMF07CisgICAgICAgICAgICBjb250ZW50W2ldID0gbmFtZUFuZENvbnRlbnRbMV07CisgICAgICAgIH0KKyAgICAgICAgcCA9IDA7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEFyY2hpdmVFbnRyeSBnZXROZXh0RW50cnkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAocCA+PSBmaWxlbmFtZXMubGVuZ3RoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBuZXcgTWVtb3J5QXJjaGl2ZUVudHJ5KGZpbGVuYW1lc1twXSk7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyByZWFkU3RyaW5nKCkgeworICAgICAgICByZXR1cm4gY29udGVudFtwKytdOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL21lbW9yeS9NZW1vcnlBcmNoaXZlVGVzdENhc2UuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9tZW1vcnkvTWVtb3J5QXJjaGl2ZVRlc3RDYXNlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjM4Njc1ZAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9tZW1vcnkvTWVtb3J5QXJjaGl2ZVRlc3RDYXNlLmphdmEKQEAgLTAsMCArMSw1NyBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMubWVtb3J5OworCitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuKjsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZUVudHJ5OworCitwdWJsaWMgZmluYWwgY2xhc3MgTWVtb3J5QXJjaGl2ZVRlc3RDYXNlIHsKKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFJlYWRpbmcoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCisgICAgICAgIGZpbmFsIE1lbW9yeUFyY2hpdmVJbnB1dFN0cmVhbSBpcyA9IG5ldyBNZW1vcnlBcmNoaXZlSW5wdXRTdHJlYW0obmV3IFN0cmluZ1tdW10geworICAgICAgICAgICAgICAgIHsgInRlc3QxIiwgICAgICJjb250ZW50MSIgfSwKKyAgICAgICAgICAgICAgICB7ICJ0ZXN0MiIsICAgICAiY29udGVudDIiIH0sCisgICAgICAgICAgICAgICAgfSk7CisKKyAgICAgICAgZmluYWwgQXJjaGl2ZUVudHJ5IGVudHJ5MSA9IGlzLmdldE5leHRFbnRyeSgpOworICAgICAgICBhc3NlcnROb3ROdWxsKGVudHJ5MSk7CisgICAgICAgIGFzc2VydEVxdWFscygidGVzdDEiLCBlbnRyeTEuZ2V0TmFtZSgpKTsKKyAgICAgICAgZmluYWwgU3RyaW5nIGNvbnRlbnQxID0gaXMucmVhZFN0cmluZygpOworICAgICAgICBhc3NlcnRFcXVhbHMoImNvbnRlbnQxIiwgY29udGVudDEpOworCisgICAgICAgIGZpbmFsIEFyY2hpdmVFbnRyeSBlbnRyeTIgPSBpcy5nZXROZXh0RW50cnkoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChlbnRyeTIpOworICAgICAgICBhc3NlcnRFcXVhbHMoInRlc3QyIiwgZW50cnkyLmdldE5hbWUoKSk7CisgICAgICAgIGZpbmFsIFN0cmluZyBjb250ZW50MiA9IGlzLnJlYWRTdHJpbmcoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJjb250ZW50MiIsIGNvbnRlbnQyKTsKKworICAgICAgICBmaW5hbCBBcmNoaXZlRW50cnkgZW50cnkzID0gaXMuZ2V0TmV4dEVudHJ5KCk7CisgICAgICAgIGFzc2VydE51bGwoZW50cnkzKTsKKworICAgICAgICBpcy5jbG9zZSgpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3NldmVuei9BRVMyNTZTSEEyNTZEZWNvZGVyVGVzdC5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3NldmVuei9BRVMyNTZTSEEyNTZEZWNvZGVyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIzYjY4YjEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvc2V2ZW56L0FFUzI1NlNIQTI1NkRlY29kZXJUZXN0LmphdmEKQEAgLTAsMCArMSw2NCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuc2V2ZW56OworCitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CisKK2ltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW07CisKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC4qOworCisKKy8qKgorICogVW5pdCB0ZXN0cyBmb3IgY2xhc3Mge0BsaW5rIEFFUzI1NlNIQTI1NkRlY29kZXJ9LgorICoKKyAqIEBkYXRlIDI2LjA2LjIwMTcKKyAqIEBzZWUgQUVTMjU2U0hBMjU2RGVjb2RlcgorICoqLworcHVibGljIGNsYXNzIEFFUzI1NlNIQTI1NkRlY29kZXJUZXN0IHsKKworCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGVjb2RlV2l0aE5vbkVtcHR5U3RyaW5nKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKworICAgICAgICBBRVMyNTZTSEEyNTZEZWNvZGVyIGFFUzI1NlNIQTI1NkRlY29kZXIgPSBuZXcgQUVTMjU2U0hBMjU2RGVjb2RlcigpOworICAgICAgICBCdWZmZXJlZElucHV0U3RyZWFtIGJ1ZmZlcmVkSW5wdXRTdHJlYW0gPSBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShudWxsLCAzMTM4KTsKKyAgICAgICAgQ29kZXIgY29kZXIgPSBuZXcgQ29kZXIoKTsKKyAgICAgICAgYnl0ZVtdIGJ5dGVBcnJheSA9IG5ldyBieXRlWzhdOworICAgICAgICBieXRlQXJyYXlbMV0gPSAoYnl0ZSkgKC03Mik7CisgICAgICAgIGNvZGVyLnByb3BlcnRpZXMgPSBieXRlQXJyYXk7CisgICAgICAgIElucHV0U3RyZWFtIGlucHV0U3RyZWFtID0gYUVTMjU2U0hBMjU2RGVjb2Rlci5kZWNvZGUoIngiLCBidWZmZXJlZElucHV0U3RyZWFtLCAzMTM4LCBjb2RlciwgY29kZXIucHJvcGVydGllcyk7CisKKyAgICAgICAgT2JqZWN0SW5wdXRTdHJlYW0gb2JqZWN0SW5wdXRTdHJlYW0gPSBudWxsOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvYmplY3RJbnB1dFN0cmVhbSA9IG5ldyBPYmplY3RJbnB1dFN0cmVhbShpbnB1dFN0cmVhbSk7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RpbmcgZXhjZXB0aW9uOiBJT0V4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoKFRocm93YWJsZSBlKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlNhbHQgc2l6ZSArIElWIHNpemUgdG9vIGxvbmcgaW4geCIsZS5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnNldmVuei5BRVMyNTZTSEEyNTZEZWNvZGVyJDEiLCBlLmdldFN0YWNrVHJhY2UoKVswXS5nZXRDbGFzc05hbWUoKSk7CisgICAgICAgIH0KKworICAgIH0KKworCit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvc2V2ZW56L0NvdmVyYWdlVGVzdC5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3NldmVuei9Db3ZlcmFnZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40YmZlM2M1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3NldmVuei9Db3ZlcmFnZVRlc3QuamF2YQpAQCAtMCwwICsxLDQyIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5zZXZlbno7CisKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnROb3ROdWxsOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmZhaWw7CisKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworcHVibGljIGNsYXNzIENvdmVyYWdlVGVzdCB7CisKKyAgICBAVGVzdCBwdWJsaWMgdm9pZCB0ZXN0TmlkSW5zdGFuY2UoKSB7CisgICAgICAgIGFzc2VydE5vdE51bGwobmV3IE5JRCgpKTsKKyAgICB9CisKKyAgICBAVGVzdCBwdWJsaWMgdm9pZCB0ZXN0Q0xJSW5zdGFuY2UoKSB7CisgICAgICAgIENMSSBmb28gPSBuZXcgQ0xJKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoZm9vKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENMSS5tYWluKG5ldyBTdHJpbmdbXXsiL2Rldi9udWxsL25vdC10aGVyZSJ9KTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZG4ndCBiZSBhYmxlIHRvIGxpc3QgY29udGVudHMgb2YgIGEgZmlsZSB0aGF0IGlzbid0IHRoZXJlIik7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBpZ25vcmVkKSB7CisKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9zZXZlbnovRm9sZGVyVGVzdC5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3NldmVuei9Gb2xkZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTE1MGI4OQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9zZXZlbnovRm9sZGVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsODggQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnNldmVuejsKKworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworCitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0RXF1YWxzOworCisKKy8qKgorICogVW5pdCB0ZXN0cyBmb3IgY2xhc3Mge0BsaW5rIEZvbGRlcn0uCisgKgorICogQGRhdGUgMjYuMDYuMjAxNworICogQHNlZSBGb2xkZXIKKyAqKi8KK3B1YmxpYyBjbGFzcyBGb2xkZXJUZXN0IHsKKworCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0VW5wYWNrU2l6ZUZvckNvZGVyT25lKCkgeworCisgICAgICAgIEZvbGRlciBmb2xkZXIgPSBuZXcgRm9sZGVyKCk7CisgICAgICAgIENvZGVyW10gY29kZXJBcnJheSA9IG5ldyBDb2Rlcls1XTsKKyAgICAgICAgQ29kZXIgY29kZXIgPSBuZXcgQ29kZXIoKTsKKyAgICAgICAgZm9sZGVyLmNvZGVycyA9IGNvZGVyQXJyYXk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDBMLCBmb2xkZXIuZ2V0VW5wYWNrU2l6ZUZvckNvZGVyKGNvZGVyKSk7CisKKyAgICB9CisKKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEdldFVucGFja1NpemVPbmUoKSB7CisKKyAgICAgICAgRm9sZGVyIGZvbGRlciA9IG5ldyBGb2xkZXIoKTsKKyAgICAgICAgZm9sZGVyLnRvdGFsT3V0cHV0U3RyZWFtcyA9IDI2Nkw7CisgICAgICAgIEJpbmRQYWlyW10gYmluZFBhaXJBcnJheSA9IG5ldyBCaW5kUGFpclsxXTsKKyAgICAgICAgQmluZFBhaXIgYmluZFBhaXIgPSBuZXcgQmluZFBhaXIoKTsKKyAgICAgICAgYmluZFBhaXJBcnJheVswXSA9IGJpbmRQYWlyOworICAgICAgICBmb2xkZXIuYmluZFBhaXJzID0gYmluZFBhaXJBcnJheTsKKyAgICAgICAgZm9sZGVyLnRvdGFsT3V0cHV0U3RyZWFtcyA9IDFMOworCisgICAgICAgIGFzc2VydEVxdWFscygwTCwgZm9sZGVyLmdldFVucGFja1NpemUoKSk7CisKKyAgICB9CisKKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEdldFVucGFja1NpemVUd28oKSB7CisKKyAgICAgICAgRm9sZGVyIGZvbGRlciA9IG5ldyBGb2xkZXIoKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoMEwsIGZvbGRlci5nZXRVbnBhY2tTaXplKCkpOworCisgICAgfQorCisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RGaW5kQmluZFBhaXJGb3JJblN0cmVhbSgpIHsKKworICAgICAgICBGb2xkZXIgZm9sZGVyID0gbmV3IEZvbGRlcigpOworICAgICAgICBCaW5kUGFpcltdIGJpbmRQYWlyQXJyYXkgPSBuZXcgQmluZFBhaXJbMV07CisgICAgICAgIEJpbmRQYWlyIGJpbmRQYWlyID0gbmV3IEJpbmRQYWlyKCk7CisgICAgICAgIGJpbmRQYWlyQXJyYXlbMF0gPSBiaW5kUGFpcjsKKyAgICAgICAgZm9sZGVyLmJpbmRQYWlycyA9IGJpbmRQYWlyQXJyYXk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGZvbGRlci5maW5kQmluZFBhaXJGb3JJblN0cmVhbSgwKSk7CisKKyAgICB9CisKKworfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9zZXZlbnovU2V2ZW5aQXJjaGl2ZUVudHJ5VGVzdC5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3NldmVuei9TZXZlblpBcmNoaXZlRW50cnlUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGFmNjE4NgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9zZXZlbnovU2V2ZW5aQXJjaGl2ZUVudHJ5VGVzdC5qYXZhCkBAIC0wLDAgKzEsMzkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5zZXZlbno7CisKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworcHVibGljIGNsYXNzIFNldmVuWkFyY2hpdmVFbnRyeVRlc3QgeworCisgICAgQFRlc3QoZXhwZWN0ZWQ9VW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24uY2xhc3MpCisgICAgcHVibGljIHZvaWQgc2hvdWxkVGhyb3dJZk5vTGFzdE1vZGlmaWVkRGF0ZUlzU2V0KCkgeworICAgICAgICBuZXcgU2V2ZW5aQXJjaGl2ZUVudHJ5KCkuZ2V0TGFzdE1vZGlmaWVkRGF0ZSgpOworICAgIH0KKworICAgIEBUZXN0KGV4cGVjdGVkPVVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uLmNsYXNzKQorICAgIHB1YmxpYyB2b2lkIHNob3VsZFRocm93SWZOb0NyZWF0aW9uRGF0ZUlzU2V0KCkgeworICAgICAgICBuZXcgU2V2ZW5aQXJjaGl2ZUVudHJ5KCkuZ2V0Q3JlYXRpb25EYXRlKCk7CisgICAgfQorCisgICAgQFRlc3QoZXhwZWN0ZWQ9VW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24uY2xhc3MpCisgICAgcHVibGljIHZvaWQgc2hvdWxkVGhyb3dJZk5vQWNjZXNzRGF0ZUlzU2V0KCkgeworICAgICAgICBuZXcgU2V2ZW5aQXJjaGl2ZUVudHJ5KCkuZ2V0QWNjZXNzRGF0ZSgpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3NldmVuei9TZXZlblpGaWxlVGVzdC5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3NldmVuei9TZXZlblpGaWxlVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc3NmFkNGQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvc2V2ZW56L1NldmVuWkZpbGVUZXN0LmphdmEKQEAgLTAsMCArMSwzNDYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5zZXZlbno7CisKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC4qOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuUmFuZG9tOworCitpbXBvcnQgamF2YXguY3J5cHRvLkNpcGhlcjsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5BYnN0cmFjdFRlc3RDYXNlOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5QYXNzd29yZFJlcXVpcmVkRXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5JT1V0aWxzOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5TZWVrYWJsZUluTWVtb3J5Qnl0ZUNoYW5uZWw7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CisKK3B1YmxpYyBjbGFzcyBTZXZlblpGaWxlVGVzdCBleHRlbmRzIEFic3RyYWN0VGVzdENhc2UgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBURVNUMl9DT05URU5UID0gIjw/eG1sIHZlcnNpb24gPSAnMS4wJz8+XHJcbjwhRE9DVFlQRSIKKyAgICAgICAgKyAiIGNvbm5lY3Rpb25zPlxyXG48bWVpbnhtbD5cclxuXHQ8bGVlciAvPlxyXG48L21laW54bWw+XG4iOworCisgICAgLy8gaHR0cHM6Ly9pc3N1ZXMuYXBhY2hlLm9yZy9qaXJhL2Jyb3dzZS9DT01QUkVTUy0zMjAKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RSYW5kb21seVNraXBwaW5nRW50cmllcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBSZWFkIHNlcXVlbnRpYWwgcmVmZXJlbmNlLgorICAgICAgICBmaW5hbCBNYXA8U3RyaW5nLCBieXRlW10+IGVudHJpZXNCeU5hbWUgPSBuZXcgSGFzaE1hcDw+KCk7CisgICAgICAgIFNldmVuWkZpbGUgYXJjaGl2ZSA9IG5ldyBTZXZlblpGaWxlKGdldEZpbGUoIkNPTVBSRVNTLTMyMC9Db3B5Ljd6IikpOworICAgICAgICBTZXZlblpBcmNoaXZlRW50cnkgZW50cnk7CisgICAgICAgIHdoaWxlICgoZW50cnkgPSBhcmNoaXZlLmdldE5leHRFbnRyeSgpKSAhPSBudWxsKSB7CisgICAgICAgICAgICBpZiAoZW50cnkuaGFzU3RyZWFtKCkpIHsKKyAgICAgICAgICAgICAgICBlbnRyaWVzQnlOYW1lLnB1dChlbnRyeS5nZXROYW1lKCksIHJlYWRGdWxseShhcmNoaXZlKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgYXJjaGl2ZS5jbG9zZSgpOworCisgICAgICAgIGZpbmFsIFN0cmluZ1tdIHZhcmlhbnRzID0geworICAgICAgICAgICAgIkJaaXAyLXNvbGlkLjd6IiwKKyAgICAgICAgICAgICJCWmlwMi43eiIsCisgICAgICAgICAgICAiQ29weS1zb2xpZC43eiIsCisgICAgICAgICAgICAiQ29weS43eiIsCisgICAgICAgICAgICAiRGVmbGF0ZS1zb2xpZC43eiIsCisgICAgICAgICAgICAiRGVmbGF0ZS43eiIsCisgICAgICAgICAgICAiTFpNQS1zb2xpZC43eiIsCisgICAgICAgICAgICAiTFpNQS43eiIsCisgICAgICAgICAgICAiTFpNQTItc29saWQuN3oiLAorICAgICAgICAgICAgIkxaTUEyLjd6IiwKKyAgICAgICAgICAgIC8vIFRPRE86IHVuc3VwcG9ydGVkIGNvbXByZXNzaW9uIG1ldGhvZC4KKyAgICAgICAgICAgIC8vICJQUE1kLXNvbGlkLjd6IiwKKyAgICAgICAgICAgIC8vICJQUE1kLjd6IiwKKyAgICAgICAgfTsKKworICAgICAgICAvLyBUT0RPOiB1c2UgcmFuZG9taXplZHRlc3RpbmcgZm9yIHByZWRpY3RhYmxlLCBidXQgZGlmZmVyZW50LCByYW5kb21uZXNzLgorICAgICAgICBmaW5hbCBSYW5kb20gcm5kID0gbmV3IFJhbmRvbSgweGRlYWRiZWVmKTsKKyAgICAgICAgZm9yIChmaW5hbCBTdHJpbmcgZmlsZU5hbWUgOiB2YXJpYW50cykgeworICAgICAgICAgICAgYXJjaGl2ZSA9IG5ldyBTZXZlblpGaWxlKGdldEZpbGUoIkNPTVBSRVNTLTMyMC8iICsgZmlsZU5hbWUpKTsKKworICAgICAgICAgICAgd2hpbGUgKChlbnRyeSA9IGFyY2hpdmUuZ2V0TmV4dEVudHJ5KCkpICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAvLyBTb21ldGltZXMgc2tpcCByZWFkaW5nIGVudHJpZXMuCisgICAgICAgICAgICAgICAgaWYgKHJuZC5uZXh0Qm9vbGVhbigpKSB7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGlmIChlbnRyeS5oYXNTdHJlYW0oKSkgeworICAgICAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKGVudHJpZXNCeU5hbWUuY29udGFpbnNLZXkoZW50cnkuZ2V0TmFtZSgpKSk7CisgICAgICAgICAgICAgICAgICAgIGZpbmFsIGJ5dGUgW10gY29udGVudCA9IHJlYWRGdWxseShhcmNoaXZlKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiQ29udGVudCBtaXNtYXRjaCBvbjogIiArIGZpbGVOYW1lICsgIiEiICsgZW50cnkuZ2V0TmFtZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFycmF5cy5lcXVhbHMoY29udGVudCwgZW50cmllc0J5TmFtZS5nZXQoZW50cnkuZ2V0TmFtZSgpKSkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgYXJjaGl2ZS5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBieXRlW10gcmVhZEZ1bGx5KGZpbmFsIFNldmVuWkZpbGUgYXJjaGl2ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgYnl0ZSBbXSBidWYgPSBuZXcgYnl0ZSBbMTAyNF07CisgICAgICAgIGZpbmFsIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBiYW9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICBmb3IgKGludCBsZW4gPSAwOyAobGVuID0gYXJjaGl2ZS5yZWFkKGJ1ZikpID4gMDspIHsKKyAgICAgICAgICAgIGJhb3Mud3JpdGUoYnVmLCAwLCBsZW4pOworICAgICAgICB9CisgICAgICAgIHJldHVybiBiYW9zLnRvQnl0ZUFycmF5KCk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QWxsRW1wdHlGaWxlc0FyY2hpdmUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IChTZXZlblpGaWxlIGFyY2hpdmUgPSBuZXcgU2V2ZW5aRmlsZShnZXRGaWxlKCI3ei1lbXB0eS1taGMtb2ZmLjd6IikpKSB7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGFyY2hpdmUuZ2V0TmV4dEVudHJ5KCkpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SGVsbG9Xb3JsZEhlYWRlckNvbXByZXNzaW9uT2ZmQ29weSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBjaGVja0hlbGxvV29ybGQoIjd6LWhlbGxvLW1oYy1vZmYtY29weS43eiIpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEhlbGxvV29ybGRIZWFkZXJDb21wcmVzc2lvbk9mZkxaTUEyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrSGVsbG9Xb3JsZCgiN3otaGVsbG8tbWhjLW9mZi1sem1hMi43eiIpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdDd6VW5hcmNoaXZlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3Q3elVuYXJjaGl2ZShnZXRGaWxlKCJibGEuN3oiKSwgU2V2ZW5aTWV0aG9kLkxaTUEpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdDd6RGVmbGF0ZVVuYXJjaGl2ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0N3pVbmFyY2hpdmUoZ2V0RmlsZSgiYmxhLmRlZmxhdGUuN3oiKSwgU2V2ZW5aTWV0aG9kLkRFRkxBVEUpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdDd6RGVmbGF0ZTY0VW5hcmNoaXZlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3Q3elVuYXJjaGl2ZShnZXRGaWxlKCJibGEuZGVmbGF0ZTY0Ljd6IiksIFNldmVuWk1ldGhvZC5ERUZMQVRFNjQpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdDd6RGVjcnlwdFVuYXJjaGl2ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBpZiAoaXNTdHJvbmdDcnlwdG9BdmFpbGFibGUoKSkgeworICAgICAgICAgICAgdGVzdDd6VW5hcmNoaXZlKGdldEZpbGUoImJsYS5lbmNyeXB0ZWQuN3oiKSwgU2V2ZW5aTWV0aG9kLkxaTUEsIC8vIHN0YWNrIExaTUEgKyBBRVMKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZm9vIi5nZXRCeXRlcygiVVRGLTE2TEUiKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3Q3ekRlY3J5cHRVbmFyY2hpdmVVc2luZ0NoYXJBcnJheVBhc3N3b3JkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChpc1N0cm9uZ0NyeXB0b0F2YWlsYWJsZSgpKSB7CisgICAgICAgICAgICB0ZXN0N3pVbmFyY2hpdmUoZ2V0RmlsZSgiYmxhLmVuY3J5cHRlZC43eiIpLCBTZXZlblpNZXRob2QuTFpNQSwgLy8gc3RhY2sgTFpNQSArIEFFUworICAgICAgICAgICAgICAgICAgICAgICAgICAgICJmb28iLnRvQ2hhckFycmF5KCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3Q3elVuYXJjaGl2ZShmaW5hbCBGaWxlIGYsIGZpbmFsIFNldmVuWk1ldGhvZCBtKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdDd6VW5hcmNoaXZlKGYsIG0sIChjaGFyW10pIG51bGwpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEVuY3J5cHRlZEFyY2hpdmVSZXF1aXJlc1Bhc3N3b3JkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgU2V2ZW5aRmlsZShnZXRGaWxlKCJibGEuZW5jcnlwdGVkLjd6IikpLmNsb3NlKCk7CisgICAgICAgICAgICBmYWlsKCJzaG91bGRuJ3QgZGVjcnlwdCB3aXRob3V0IGEgcGFzc3dvcmQiKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgUGFzc3dvcmRSZXF1aXJlZEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgZmluYWwgU3RyaW5nIG1zZyA9IGV4LmdldE1lc3NhZ2UoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlNob3VsZCBzdGFydCB3aXRoIHdoaW5pbmcgYWJvdXQgYmVpbmcgdW5hYmxlIHRvIGRlY3J5cHQiLAorICAgICAgICAgICAgICAgICAgICAgICBtc2cuc3RhcnRzV2l0aCgiQ2Fubm90IHJlYWQgZW5jcnlwdGVkIGNvbnRlbnQgZnJvbSAiKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJTaG91bGQgZmluaXNoIHRoZSBzZW50ZW5jZSBwcm9wZXJseSIsCisgICAgICAgICAgICAgICAgICAgICAgIG1zZy5lbmRzV2l0aCgiIHdpdGhvdXQgYSBwYXNzd29yZC4iKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJTaG91bGQgY29udGFpbiBhcmNoaXZlJ3MgbmFtZSIsCisgICAgICAgICAgICAgICAgICAgICAgIG1zZy5jb250YWlucygiYmxhLmVuY3J5cHRlZC43eiIpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgImh0dHBzOi8vaXNzdWVzLmFwYWNoZS5vcmcvamlyYS9icm93c2UvQ09NUFJFU1MtMjU2IgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdENvbXByZXNzZWRIZWFkZXJXaXRoTm9uRGVmYXVsdERpY3Rpb25hcnlTaXplKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSAoU2V2ZW5aRmlsZSBzZXZlblpGaWxlID0gbmV3IFNldmVuWkZpbGUoZ2V0RmlsZSgiQ09NUFJFU1MtMjU2Ljd6IikpKSB7CisgICAgICAgICAgICBpbnQgY291bnQgPSAwOworICAgICAgICAgICAgd2hpbGUgKHNldmVuWkZpbGUuZ2V0TmV4dEVudHJ5KCkgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGNvdW50Kys7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoNDQ2LCBjb3VudCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RTaWduYXR1cmVDaGVjaygpIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZShTZXZlblpGaWxlLm1hdGNoZXMoU2V2ZW5aRmlsZS5zZXZlblpTaWduYXR1cmUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNldmVuWkZpbGUuc2V2ZW5aU2lnbmF0dXJlLmxlbmd0aCkpOworICAgICAgICBhc3NlcnRUcnVlKFNldmVuWkZpbGUubWF0Y2hlcyhTZXZlblpGaWxlLnNldmVuWlNpZ25hdHVyZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2V2ZW5aRmlsZS5zZXZlblpTaWduYXR1cmUubGVuZ3RoICsgMSkpOworICAgICAgICBhc3NlcnRGYWxzZShTZXZlblpGaWxlLm1hdGNoZXMoU2V2ZW5aRmlsZS5zZXZlblpTaWduYXR1cmUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNldmVuWkZpbGUuc2V2ZW5aU2lnbmF0dXJlLmxlbmd0aCAtIDEpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoU2V2ZW5aRmlsZS5tYXRjaGVzKG5ldyBieXRlW10geyAxLCAyLCAzLCA0LCA1LCA2IH0sIDYpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShTZXZlblpGaWxlLm1hdGNoZXMobmV3IGJ5dGVbXSB7ICc3JywgJ3onLCAoYnl0ZSkgMHhCQywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweEFGLCAweDI3LCAweDFDfSwgNikpOworICAgICAgICBhc3NlcnRGYWxzZShTZXZlblpGaWxlLm1hdGNoZXMobmV3IGJ5dGVbXSB7ICc3JywgJ3onLCAoYnl0ZSkgMHhCQywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgMHhBRiwgMHgyNywgMHgxRH0sIDYpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RSZWFkaW5nQmFja0xaTUEyRGljdFNpemUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgRmlsZSBvdXRwdXQgPSBuZXcgRmlsZShkaXIsICJsem1hMi1kaWN0c2l6ZS43eiIpOworICAgICAgICB0cnkgKFNldmVuWk91dHB1dEZpbGUgb3V0QXJjaGl2ZSA9IG5ldyBTZXZlblpPdXRwdXRGaWxlKG91dHB1dCkpIHsKKyAgICAgICAgICAgIG91dEFyY2hpdmUuc2V0Q29udGVudE1ldGhvZHMoQXJyYXlzLmFzTGlzdChuZXcgU2V2ZW5aTWV0aG9kQ29uZmlndXJhdGlvbihTZXZlblpNZXRob2QuTFpNQTIsIDEgPDwgMjApKSk7CisgICAgICAgICAgICBmaW5hbCBTZXZlblpBcmNoaXZlRW50cnkgZW50cnkgPSBuZXcgU2V2ZW5aQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgICAgICBlbnRyeS5zZXROYW1lKCJmb28udHh0Iik7CisgICAgICAgICAgICBvdXRBcmNoaXZlLnB1dEFyY2hpdmVFbnRyeShlbnRyeSk7CisgICAgICAgICAgICBvdXRBcmNoaXZlLndyaXRlKG5ldyBieXRlW10geyAnQScgfSk7CisgICAgICAgICAgICBvdXRBcmNoaXZlLmNsb3NlQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgKFNldmVuWkZpbGUgYXJjaGl2ZSA9IG5ldyBTZXZlblpGaWxlKG91dHB1dCkpIHsKKyAgICAgICAgICAgIGZpbmFsIFNldmVuWkFyY2hpdmVFbnRyeSBlbnRyeSA9IGFyY2hpdmUuZ2V0TmV4dEVudHJ5KCk7CisgICAgICAgICAgICBmaW5hbCBTZXZlblpNZXRob2RDb25maWd1cmF0aW9uIG0gPSBlbnRyeS5nZXRDb250ZW50TWV0aG9kcygpLml0ZXJhdG9yKCkubmV4dCgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKFNldmVuWk1ldGhvZC5MWk1BMiwgbS5nZXRNZXRob2QoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMSA8PCAyMCwgbS5nZXRPcHRpb25zKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVhZGluZ0JhY2tEZWx0YURpc3RhbmNlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGUgb3V0cHV0ID0gbmV3IEZpbGUoZGlyLCAiZGVsdGEtZGlzdGFuY2UuN3oiKTsKKyAgICAgICAgdHJ5IChTZXZlblpPdXRwdXRGaWxlIG91dEFyY2hpdmUgPSBuZXcgU2V2ZW5aT3V0cHV0RmlsZShvdXRwdXQpKSB7CisgICAgICAgICAgICBvdXRBcmNoaXZlLnNldENvbnRlbnRNZXRob2RzKEFycmF5cy5hc0xpc3QobmV3IFNldmVuWk1ldGhvZENvbmZpZ3VyYXRpb24oU2V2ZW5aTWV0aG9kLkRFTFRBX0ZJTFRFUiwgMzIpLAorICAgICAgICAgICAgICAgICAgICBuZXcgU2V2ZW5aTWV0aG9kQ29uZmlndXJhdGlvbihTZXZlblpNZXRob2QuTFpNQTIpKSk7CisgICAgICAgICAgICBmaW5hbCBTZXZlblpBcmNoaXZlRW50cnkgZW50cnkgPSBuZXcgU2V2ZW5aQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgICAgICBlbnRyeS5zZXROYW1lKCJmb28udHh0Iik7CisgICAgICAgICAgICBvdXRBcmNoaXZlLnB1dEFyY2hpdmVFbnRyeShlbnRyeSk7CisgICAgICAgICAgICBvdXRBcmNoaXZlLndyaXRlKG5ldyBieXRlW10geyAnQScgfSk7CisgICAgICAgICAgICBvdXRBcmNoaXZlLmNsb3NlQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgKFNldmVuWkZpbGUgYXJjaGl2ZSA9IG5ldyBTZXZlblpGaWxlKG91dHB1dCkpIHsKKyAgICAgICAgICAgIGZpbmFsIFNldmVuWkFyY2hpdmVFbnRyeSBlbnRyeSA9IGFyY2hpdmUuZ2V0TmV4dEVudHJ5KCk7CisgICAgICAgICAgICBmaW5hbCBTZXZlblpNZXRob2RDb25maWd1cmF0aW9uIG0gPSBlbnRyeS5nZXRDb250ZW50TWV0aG9kcygpLml0ZXJhdG9yKCkubmV4dCgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKFNldmVuWk1ldGhvZC5ERUxUQV9GSUxURVIsIG0uZ2V0TWV0aG9kKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDMyLCBtLmdldE9wdGlvbnMoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIGdldEVudHJpZXNPZlVuYXJjaGl2ZVRlc3QoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0cnkgKFNldmVuWkZpbGUgc2V2ZW5aRmlsZSA9IG5ldyBTZXZlblpGaWxlKGdldEZpbGUoImJsYS43eiIpKSkgeworICAgICAgICAgICAgZmluYWwgSXRlcmFibGU8U2V2ZW5aQXJjaGl2ZUVudHJ5PiBlbnRyaWVzID0gc2V2ZW5aRmlsZS5nZXRFbnRyaWVzKCk7CisgICAgICAgICAgICBmaW5hbCBJdGVyYXRvcjxTZXZlblpBcmNoaXZlRW50cnk+IGl0ZXIgPSBlbnRyaWVzLml0ZXJhdG9yKCk7CisgICAgICAgICAgICBTZXZlblpBcmNoaXZlRW50cnkgZW50cnkgPSBpdGVyLm5leHQoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygidGVzdDEueG1sIiwgZW50cnkuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIGVudHJ5ID0gaXRlci5uZXh0KCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoInRlc3QyLnhtbCIsIGVudHJ5LmdldE5hbWUoKSk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShpdGVyLmhhc05leHQoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIGdldEVudHJpZXNPZlVuYXJjaGl2ZUluTWVtb3J5VGVzdCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBkYXRhID0gbnVsbDsKKyAgICAgICAgdHJ5IChGaWxlSW5wdXRTdHJlYW0gZmlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShnZXRGaWxlKCJibGEuN3oiKSkpIHsKKyAgICAgICAgICAgIGRhdGEgPSBJT1V0aWxzLnRvQnl0ZUFycmF5KGZpcyk7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IChTZXZlblpGaWxlIHNldmVuWkZpbGUgPSBuZXcgU2V2ZW5aRmlsZShuZXcgU2Vla2FibGVJbk1lbW9yeUJ5dGVDaGFubmVsKGRhdGEpKSkgeworICAgICAgICAgICAgZmluYWwgSXRlcmFibGU8U2V2ZW5aQXJjaGl2ZUVudHJ5PiBlbnRyaWVzID0gc2V2ZW5aRmlsZS5nZXRFbnRyaWVzKCk7CisgICAgICAgICAgICBmaW5hbCBJdGVyYXRvcjxTZXZlblpBcmNoaXZlRW50cnk+IGl0ZXIgPSBlbnRyaWVzLml0ZXJhdG9yKCk7CisgICAgICAgICAgICBTZXZlblpBcmNoaXZlRW50cnkgZW50cnkgPSBpdGVyLm5leHQoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygidGVzdDEueG1sIiwgZW50cnkuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIGVudHJ5ID0gaXRlci5uZXh0KCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoInRlc3QyLnhtbCIsIGVudHJ5LmdldE5hbWUoKSk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShpdGVyLmhhc05leHQoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlICJodHRwczovL2lzc3Vlcy5hcGFjaGUub3JnL2ppcmEvYnJvd3NlL0NPTVBSRVNTLTM0OCIKKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHJlYWRFbnRyaWVzT2ZTaXplMCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRyeSAoU2V2ZW5aRmlsZSBzZXZlblpGaWxlID0gbmV3IFNldmVuWkZpbGUoZ2V0RmlsZSgiQ09NUFJFU1MtMzQ4Ljd6IikpKSB7CisgICAgICAgICAgICBpbnQgZW50cmllcyA9IDA7CisgICAgICAgICAgICBTZXZlblpBcmNoaXZlRW50cnkgZW50cnkgPSBzZXZlblpGaWxlLmdldE5leHRFbnRyeSgpOworICAgICAgICAgICAgd2hpbGUgKGVudHJ5ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBlbnRyaWVzKys7CisgICAgICAgICAgICAgICAgZmluYWwgaW50IGIgPSBzZXZlblpGaWxlLnJlYWQoKTsKKyAgICAgICAgICAgICAgICBpZiAoIjIudHh0Ii5lcXVhbHMoZW50cnkuZ2V0TmFtZSgpKSB8fCAiNS50eHQiLmVxdWFscyhlbnRyeS5nZXROYW1lKCkpKSB7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygtMSwgYik7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0Tm90RXF1YWxzKC0xLCBiKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZW50cnkgPSBzZXZlblpGaWxlLmdldE5leHRFbnRyeSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDUsIGVudHJpZXMpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3Q3elVuYXJjaGl2ZShmaW5hbCBGaWxlIGYsIGZpbmFsIFNldmVuWk1ldGhvZCBtLCBmaW5hbCBieXRlW10gcGFzc3dvcmQpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgKFNldmVuWkZpbGUgc2V2ZW5aRmlsZSA9IG5ldyBTZXZlblpGaWxlKGYsIHBhc3N3b3JkKSkgeworICAgICAgICAgICAgdGVzdDd6VW5hcmNoaXZlKHNldmVuWkZpbGUsIG0pOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3Q3elVuYXJjaGl2ZShmaW5hbCBGaWxlIGYsIGZpbmFsIFNldmVuWk1ldGhvZCBtLCBmaW5hbCBjaGFyW10gcGFzc3dvcmQpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgKFNldmVuWkZpbGUgc2V2ZW5aRmlsZSA9IG5ldyBTZXZlblpGaWxlKGYsIHBhc3N3b3JkKSkgeworICAgICAgICAgICAgdGVzdDd6VW5hcmNoaXZlKHNldmVuWkZpbGUsIG0pOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3Q3elVuYXJjaGl2ZShTZXZlblpGaWxlIHNldmVuWkZpbGUsIGZpbmFsIFNldmVuWk1ldGhvZCBtKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU2V2ZW5aQXJjaGl2ZUVudHJ5IGVudHJ5ID0gc2V2ZW5aRmlsZS5nZXROZXh0RW50cnkoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0ZXN0MS54bWwiLCBlbnRyeS5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobSwgZW50cnkuZ2V0Q29udGVudE1ldGhvZHMoKS5pdGVyYXRvcigpLm5leHQoKS5nZXRNZXRob2QoKSk7CisgICAgICAgIGVudHJ5ID0gc2V2ZW5aRmlsZS5nZXROZXh0RW50cnkoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0ZXN0Mi54bWwiLCBlbnRyeS5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobSwgZW50cnkuZ2V0Q29udGVudE1ldGhvZHMoKS5pdGVyYXRvcigpLm5leHQoKS5nZXRNZXRob2QoKSk7CisgICAgICAgIGZpbmFsIGJ5dGVbXSBjb250ZW50cyA9IG5ldyBieXRlWyhpbnQpIGVudHJ5LmdldFNpemUoKV07CisgICAgICAgIGludCBvZmYgPSAwOworICAgICAgICB3aGlsZSAoKG9mZiA8IGNvbnRlbnRzLmxlbmd0aCkpIHsKKyAgICAgICAgICAgIGZpbmFsIGludCBieXRlc1JlYWQgPSBzZXZlblpGaWxlLnJlYWQoY29udGVudHMsIG9mZiwgY29udGVudHMubGVuZ3RoIC0gb2ZmKTsKKyAgICAgICAgICAgIGFzc2VydCAoYnl0ZXNSZWFkID49IDApOworICAgICAgICAgICAgb2ZmICs9IGJ5dGVzUmVhZDsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoVEVTVDJfQ09OVEVOVCwgbmV3IFN0cmluZyhjb250ZW50cywgIlVURi04IikpOworICAgICAgICBhc3NlcnROdWxsKHNldmVuWkZpbGUuZ2V0TmV4dEVudHJ5KCkpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBjaGVja0hlbGxvV29ybGQoZmluYWwgU3RyaW5nIGZpbGVuYW1lKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IChTZXZlblpGaWxlIHNldmVuWkZpbGUgPSBuZXcgU2V2ZW5aRmlsZShnZXRGaWxlKGZpbGVuYW1lKSkpIHsKKyAgICAgICAgICAgIGZpbmFsIFNldmVuWkFyY2hpdmVFbnRyeSBlbnRyeSA9IHNldmVuWkZpbGUuZ2V0TmV4dEVudHJ5KCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkhlbGxvIHdvcmxkLnR4dCIsIGVudHJ5LmdldE5hbWUoKSk7CisgICAgICAgICAgICBmaW5hbCBieXRlW10gY29udGVudHMgPSBuZXcgYnl0ZVsoaW50KSBlbnRyeS5nZXRTaXplKCldOworICAgICAgICAgICAgaW50IG9mZiA9IDA7CisgICAgICAgICAgICB3aGlsZSAoKG9mZiA8IGNvbnRlbnRzLmxlbmd0aCkpIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBpbnQgYnl0ZXNSZWFkID0gc2V2ZW5aRmlsZS5yZWFkKGNvbnRlbnRzLCBvZmYsIGNvbnRlbnRzLmxlbmd0aCAtIG9mZik7CisgICAgICAgICAgICAgICAgYXNzZXJ0IChieXRlc1JlYWQgPj0gMCk7CisgICAgICAgICAgICAgICAgb2ZmICs9IGJ5dGVzUmVhZDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSGVsbG8sIHdvcmxkIVxuIiwgbmV3IFN0cmluZyhjb250ZW50cywgIlVURi04IikpOworICAgICAgICAgICAgYXNzZXJ0TnVsbChzZXZlblpGaWxlLmdldE5leHRFbnRyeSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNTdHJvbmdDcnlwdG9BdmFpbGFibGUoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIENpcGhlci5nZXRNYXhBbGxvd2VkS2V5TGVuZ3RoKCJBRVMvRUNCL1BLQ1M1UGFkZGluZyIpID49IDI1NjsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvc2V2ZW56L1NldmVuWk1ldGhvZENvbmZpZ3VyYXRpb25UZXN0LmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvc2V2ZW56L1NldmVuWk1ldGhvZENvbmZpZ3VyYXRpb25UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjBmY2NiZAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9zZXZlbnovU2V2ZW5aTWV0aG9kQ29uZmlndXJhdGlvblRlc3QuamF2YQpAQCAtMCwwICsxLDgwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuc2V2ZW56OworCitpbXBvcnQgb3JnLmp1bml0LkFzc2VydDsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBvcmcudHVrYWFuaS54ei5MWk1BMk9wdGlvbnM7CisKK3B1YmxpYyBjbGFzcyBTZXZlblpNZXRob2RDb25maWd1cmF0aW9uVGVzdCB7CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHNob3VsZEFsbG93TnVsbE9wdGlvbnMoKSB7CisgICAgICAgIEFzc2VydC5hc3NlcnROdWxsKG5ldyBTZXZlblpNZXRob2RDb25maWd1cmF0aW9uKFNldmVuWk1ldGhvZC5MWk1BMiwgbnVsbCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgLmdldE9wdGlvbnMoKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBzaG91bGRBbGxvd0xaTUEyT3B0aW9uc0ZvckxaTUEoKSB7CisgICAgICAgIEFzc2VydC5hc3NlcnROb3ROdWxsKG5ldyBTZXZlblpNZXRob2RDb25maWd1cmF0aW9uKFNldmVuWk1ldGhvZC5MWk1BLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgTFpNQTJPcHRpb25zKCkpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRPcHRpb25zKCkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgc2hvdWxkQWxsb3dOdW1iZXJGb3JMWk1BKCkgeworICAgICAgICBBc3NlcnQuYXNzZXJ0Tm90TnVsbChuZXcgU2V2ZW5aTWV0aG9kQ29uZmlndXJhdGlvbihTZXZlblpNZXRob2QuTFpNQSwgNDIpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRPcHRpb25zKCkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgc2hvdWxkQWxsb3dMWk1BMk9wdGlvbnNGb3JMWk1BMigpIHsKKyAgICAgICAgQXNzZXJ0LmFzc2VydE5vdE51bGwobmV3IFNldmVuWk1ldGhvZENvbmZpZ3VyYXRpb24oU2V2ZW5aTWV0aG9kLkxaTUEyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgTFpNQTJPcHRpb25zKCkpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRPcHRpb25zKCkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgc2hvdWxkQWxsb3dOdW1iZXJGb3JMWk1BMigpIHsKKyAgICAgICAgQXNzZXJ0LmFzc2VydE5vdE51bGwobmV3IFNldmVuWk1ldGhvZENvbmZpZ3VyYXRpb24oU2V2ZW5aTWV0aG9kLkxaTUEyLCA0MikKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmdldE9wdGlvbnMoKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBzaG91bGRBbGxvd051bWJlckZvckJ6aXAyKCkgeworICAgICAgICBBc3NlcnQuYXNzZXJ0Tm90TnVsbChuZXcgU2V2ZW5aTWV0aG9kQ29uZmlndXJhdGlvbihTZXZlblpNZXRob2QuQlpJUDIsIDQyKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0T3B0aW9ucygpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHNob3VsZEFsbG93TnVtYmVyRm9yRGVmbGF0ZSgpIHsKKyAgICAgICAgQXNzZXJ0LmFzc2VydE5vdE51bGwobmV3IFNldmVuWk1ldGhvZENvbmZpZ3VyYXRpb24oU2V2ZW5aTWV0aG9kLkRFRkxBVEUsIDQyKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0T3B0aW9ucygpKTsKKyAgICB9CisKKyAgICBAVGVzdChleHBlY3RlZCA9IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi5jbGFzcykKKyAgICBwdWJsaWMgdm9pZCBzaG91bGROb3RBbGxvd1N0cmluZ09wdGlvbnNGb3JMWk1BKCkgeworICAgICAgICBuZXcgU2V2ZW5aTWV0aG9kQ29uZmlndXJhdGlvbihTZXZlblpNZXRob2QuTFpNQSwgIiIpOworICAgIH0KKworICAgIEBUZXN0KGV4cGVjdGVkID0gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLmNsYXNzKQorICAgIHB1YmxpYyB2b2lkIHNob3VsZE5vdEFsbG93U3RyaW5nT3B0aW9uc0ZvckxaTUEyKCkgeworICAgICAgICBuZXcgU2V2ZW5aTWV0aG9kQ29uZmlndXJhdGlvbihTZXZlblpNZXRob2QuTFpNQTIsICIiKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9zZXZlbnovU2V2ZW5aTmF0aXZlSGVhcFRlc3QuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9zZXZlbnovU2V2ZW5aTmF0aXZlSGVhcFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kNTU2ODE5Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3NldmVuei9TZXZlblpOYXRpdmVIZWFwVGVzdC5qYXZhCkBAIC0wLDAgKzEsMjY3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuc2V2ZW56OworCitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VHJ1ZTsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljLkF0b21pY0Jvb2xlYW47CitpbXBvcnQgamF2YS51dGlsLnppcC5EYXRhRm9ybWF0RXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC56aXAuRGVmbGF0ZXI7CitpbXBvcnQgamF2YS51dGlsLnppcC5JbmZsYXRlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuQWJzdHJhY3RUZXN0Q2FzZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnNldmVuei5Db2RlcnMuRGVmbGF0ZURlY29kZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5zZXZlbnouQ29kZXJzLkRlZmxhdGVEZWNvZGVyLkRlZmxhdGVEZWNvZGVySW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5zZXZlbnouQ29kZXJzLkRlZmxhdGVEZWNvZGVyLkRlZmxhdGVEZWNvZGVyT3V0cHV0U3RyZWFtOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworCitwdWJsaWMgY2xhc3MgU2V2ZW5aTmF0aXZlSGVhcFRlc3QgZXh0ZW5kcyBBYnN0cmFjdFRlc3RDYXNlIHsKKworCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW5kRGVmbGF0ZXJPbkNsb3NlU3RyZWFtKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIENvZGVycy5EZWZsYXRlRGVjb2RlciBkZWZsYXRlRGVjb2RlciA9IG5ldyBEZWZsYXRlRGVjb2RlcigpOworCisgICAgICAgIGZpbmFsIERlZmxhdGVEZWNvZGVyT3V0cHV0U3RyZWFtIG91dHB1dFN0cmVhbSA9CisgICAgICAgICAgICAoRGVmbGF0ZURlY29kZXJPdXRwdXRTdHJlYW0pIGRlZmxhdGVEZWNvZGVyLmVuY29kZShuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCksIDkpOworICAgICAgICBEZWxlZ2F0aW5nRGVmbGF0ZXIgZGVsZWdhdGluZ0RlZmxhdGVyID0gbmV3IERlbGVnYXRpbmdEZWZsYXRlcihvdXRwdXRTdHJlYW0uZGVmbGF0ZXIpOworICAgICAgICBvdXRwdXRTdHJlYW0uZGVmbGF0ZXIgPSBkZWxlZ2F0aW5nRGVmbGF0ZXI7CisgICAgICAgIG91dHB1dFN0cmVhbS5jbG9zZSgpOworICAgICAgICBhc3NlcnRUcnVlKGRlbGVnYXRpbmdEZWZsYXRlci5pc0VuZGVkLmdldCgpKTsKKworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEVuZEluZmxhdGVyT25DbG9zZVN0cmVhbSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBDb2RlcnMuRGVmbGF0ZURlY29kZXIgZGVmbGF0ZURlY29kZXIgPSBuZXcgRGVmbGF0ZURlY29kZXIoKTsKKyAgICAgICAgZmluYWwgRGVmbGF0ZURlY29kZXJJbnB1dFN0cmVhbSBpbnB1dFN0cmVhbSA9CisgICAgICAgICAgICAoRGVmbGF0ZURlY29kZXJJbnB1dFN0cmVhbSkgZGVmbGF0ZURlY29kZXIuZGVjb2RlKCJkdW1teSIsbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKG5ldyBieXRlWzBdKSwwLG51bGwsbnVsbCk7CisgICAgICAgIERlbGVnYXRpbmdJbmZsYXRlciBkZWxlZ2F0aW5nSW5mbGF0ZXIgPSBuZXcgRGVsZWdhdGluZ0luZmxhdGVyKGlucHV0U3RyZWFtLmluZmxhdGVyKTsKKyAgICAgICAgaW5wdXRTdHJlYW0uaW5mbGF0ZXIgPSBkZWxlZ2F0aW5nSW5mbGF0ZXI7CisgICAgICAgIGlucHV0U3RyZWFtLmNsb3NlKCk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShkZWxlZ2F0aW5nSW5mbGF0ZXIuaXNFbmRlZC5nZXQoKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBjbGFzcyBEZWxlZ2F0aW5nSW5mbGF0ZXIgZXh0ZW5kcyBJbmZsYXRlciB7CisKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBJbmZsYXRlciBpbmZsYXRlcjsKKworICAgICAgICBwdWJsaWMgRGVsZWdhdGluZ0luZmxhdGVyKEluZmxhdGVyIGluZmxhdGVyKSB7CisgICAgICAgICAgICB0aGlzLmluZmxhdGVyID0gaW5mbGF0ZXI7CisgICAgICAgIH0KKyAgICAgICAgQXRvbWljQm9vbGVhbiBpc0VuZGVkID0gbmV3IEF0b21pY0Jvb2xlYW4oKTsKKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgZW5kKCkgeworICAgICAgICAgICAgaXNFbmRlZC5zZXQodHJ1ZSk7CisgICAgICAgICAgICBpbmZsYXRlci5lbmQoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBzZXRJbnB1dChieXRlW10gYiwgaW50IG9mZiwgaW50IGxlbikgeworICAgICAgICAgICAgaW5mbGF0ZXIuc2V0SW5wdXQoYiwgb2ZmLCBsZW4pOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIHNldElucHV0KGJ5dGVbXSBiKSB7CisgICAgICAgICAgICBpbmZsYXRlci5zZXRJbnB1dChiKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBzZXREaWN0aW9uYXJ5KGJ5dGVbXSBiLCBpbnQgb2ZmLCBpbnQgbGVuKSB7CisgICAgICAgICAgICBpbmZsYXRlci5zZXREaWN0aW9uYXJ5KGIsIG9mZiwgbGVuKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBzZXREaWN0aW9uYXJ5KGJ5dGVbXSBiKSB7CisgICAgICAgICAgICBpbmZsYXRlci5zZXREaWN0aW9uYXJ5KGIpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBpbnQgZ2V0UmVtYWluaW5nKCkgeworICAgICAgICAgICAgcmV0dXJuIGluZmxhdGVyLmdldFJlbWFpbmluZygpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBib29sZWFuIG5lZWRzSW5wdXQoKSB7CisgICAgICAgICAgICByZXR1cm4gaW5mbGF0ZXIubmVlZHNJbnB1dCgpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBib29sZWFuIG5lZWRzRGljdGlvbmFyeSgpIHsKKyAgICAgICAgICAgIHJldHVybiBpbmZsYXRlci5uZWVkc0RpY3Rpb25hcnkoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgYm9vbGVhbiBmaW5pc2hlZCgpIHsKKyAgICAgICAgICAgIHJldHVybiBpbmZsYXRlci5maW5pc2hlZCgpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBpbnQgaW5mbGF0ZShieXRlW10gYiwgaW50IG9mZiwgaW50IGxlbikgdGhyb3dzIERhdGFGb3JtYXRFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIGluZmxhdGVyLmluZmxhdGUoYiwgb2ZmLCBsZW4pOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBpbnQgaW5mbGF0ZShieXRlW10gYikgdGhyb3dzIERhdGFGb3JtYXRFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIGluZmxhdGVyLmluZmxhdGUoYik7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGludCBnZXRBZGxlcigpIHsKKyAgICAgICAgICAgIHJldHVybiBpbmZsYXRlci5nZXRBZGxlcigpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBpbnQgZ2V0VG90YWxJbigpIHsKKyAgICAgICAgICAgIHJldHVybiBpbmZsYXRlci5nZXRUb3RhbEluKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGxvbmcgZ2V0Qnl0ZXNSZWFkKCkgeworICAgICAgICAgICAgcmV0dXJuIGluZmxhdGVyLmdldEJ5dGVzUmVhZCgpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBpbnQgZ2V0VG90YWxPdXQoKSB7CisgICAgICAgICAgICByZXR1cm4gaW5mbGF0ZXIuZ2V0VG90YWxPdXQoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgbG9uZyBnZXRCeXRlc1dyaXR0ZW4oKSB7CisgICAgICAgICAgICByZXR1cm4gaW5mbGF0ZXIuZ2V0Qnl0ZXNXcml0dGVuKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgcmVzZXQoKSB7CisgICAgICAgICAgICBpbmZsYXRlci5yZXNldCgpOworICAgICAgICB9CisKKyAgICB9CisKKyAgICBwcml2YXRlIGNsYXNzIERlbGVnYXRpbmdEZWZsYXRlciBleHRlbmRzIERlZmxhdGVyIHsKKworICAgICAgICBwcml2YXRlIGZpbmFsIERlZmxhdGVyIGRlZmxhdGVyOworCisgICAgICAgIHB1YmxpYyBEZWxlZ2F0aW5nRGVmbGF0ZXIoRGVmbGF0ZXIgZGVmbGF0ZXIpIHsKKyAgICAgICAgICAgIHRoaXMuZGVmbGF0ZXIgPSBkZWZsYXRlcjsKKyAgICAgICAgfQorCisgICAgICAgIEF0b21pY0Jvb2xlYW4gaXNFbmRlZCA9IG5ldyBBdG9taWNCb29sZWFuKCk7CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIGVuZCgpIHsKKyAgICAgICAgICAgIGlzRW5kZWQuc2V0KHRydWUpOworICAgICAgICAgICAgZGVmbGF0ZXIuZW5kKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgc2V0SW5wdXQoYnl0ZVtdIGIsIGludCBvZmYsIGludCBsZW4pIHsKKyAgICAgICAgICAgIGRlZmxhdGVyLnNldElucHV0KGIsIG9mZiwgbGVuKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBzZXRJbnB1dChieXRlW10gYikgeworICAgICAgICAgICAgZGVmbGF0ZXIuc2V0SW5wdXQoYik7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgc2V0RGljdGlvbmFyeShieXRlW10gYiwgaW50IG9mZiwgaW50IGxlbikgeworICAgICAgICAgICAgZGVmbGF0ZXIuc2V0RGljdGlvbmFyeShiLCBvZmYsIGxlbik7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgc2V0RGljdGlvbmFyeShieXRlW10gYikgeworICAgICAgICAgICAgZGVmbGF0ZXIuc2V0RGljdGlvbmFyeShiKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBzZXRTdHJhdGVneShpbnQgc3RyYXRlZ3kpIHsKKyAgICAgICAgICAgIGRlZmxhdGVyLnNldFN0cmF0ZWd5KHN0cmF0ZWd5KTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBzZXRMZXZlbChpbnQgbGV2ZWwpIHsKKyAgICAgICAgICAgIGRlZmxhdGVyLnNldExldmVsKGxldmVsKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgYm9vbGVhbiBuZWVkc0lucHV0KCkgeworICAgICAgICAgICAgcmV0dXJuIGRlZmxhdGVyLm5lZWRzSW5wdXQoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBmaW5pc2goKSB7CisgICAgICAgICAgICBkZWZsYXRlci5maW5pc2goKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgYm9vbGVhbiBmaW5pc2hlZCgpIHsKKyAgICAgICAgICAgIHJldHVybiBkZWZsYXRlci5maW5pc2hlZCgpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBpbnQgZGVmbGF0ZShieXRlW10gYiwgaW50IG9mZiwgaW50IGxlbikgeworICAgICAgICAgICAgcmV0dXJuIGRlZmxhdGVyLmRlZmxhdGUoYiwgb2ZmLCBsZW4pOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBpbnQgZGVmbGF0ZShieXRlW10gYikgeworICAgICAgICAgICAgcmV0dXJuIGRlZmxhdGVyLmRlZmxhdGUoYik7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGludCBkZWZsYXRlKGJ5dGVbXSBiLCBpbnQgb2ZmLCBpbnQgbGVuLCBpbnQgZmx1c2gpIHsKKyAgICAgICAgICAgIHJldHVybiBkZWZsYXRlci5kZWZsYXRlKGIsIG9mZiwgbGVuLCBmbHVzaCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGludCBnZXRBZGxlcigpIHsKKyAgICAgICAgICAgIHJldHVybiBkZWZsYXRlci5nZXRBZGxlcigpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBpbnQgZ2V0VG90YWxJbigpIHsKKyAgICAgICAgICAgIHJldHVybiBkZWZsYXRlci5nZXRUb3RhbEluKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGxvbmcgZ2V0Qnl0ZXNSZWFkKCkgeworICAgICAgICAgICAgcmV0dXJuIGRlZmxhdGVyLmdldEJ5dGVzUmVhZCgpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBpbnQgZ2V0VG90YWxPdXQoKSB7CisgICAgICAgICAgICByZXR1cm4gZGVmbGF0ZXIuZ2V0VG90YWxPdXQoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgbG9uZyBnZXRCeXRlc1dyaXR0ZW4oKSB7CisgICAgICAgICAgICByZXR1cm4gZGVmbGF0ZXIuZ2V0Qnl0ZXNXcml0dGVuKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgcmVzZXQoKSB7CisgICAgICAgICAgICBkZWZsYXRlci5yZXNldCgpOworICAgICAgICB9CisKKworICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9zZXZlbnovU2V2ZW5aT3V0cHV0RmlsZVRlc3QuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy9zZXZlbnovU2V2ZW5aT3V0cHV0RmlsZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43MTM5ZWMzCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3NldmVuei9TZXZlblpPdXRwdXRGaWxlVGVzdC5qYXZhCkBAIC0wLDAgKzEsNTIyIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuc2V2ZW56OworCitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuKjsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQ2FsZW5kYXI7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5EYXRlOworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuQWJzdHJhY3RUZXN0Q2FzZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuU2Vla2FibGVJbk1lbW9yeUJ5dGVDaGFubmVsOworaW1wb3J0IG9yZy50dWthYW5pLnh6LkxaTUEyT3B0aW9uczsKKworcHVibGljIGNsYXNzIFNldmVuWk91dHB1dEZpbGVUZXN0IGV4dGVuZHMgQWJzdHJhY3RUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIFhaX0JDSl9JU19CVUdHWTsKKworICAgIHN0YXRpYyB7CisgICAgICAgIGZpbmFsIFN0cmluZyB2ZXJzaW9uID0gb3JnLnR1a2FhbmkueHouWFouY2xhc3MuZ2V0UGFja2FnZSgpLmdldEltcGxlbWVudGF0aW9uVmVyc2lvbigpOworCisgICAgICAgIFhaX0JDSl9JU19CVUdHWT0gdmVyc2lvbiAhPSBudWxsICYmIHZlcnNpb24uZXF1YWxzKCIxLjQiKTsKKyAgICAgICAgaWYgKFhaX0JDSl9JU19CVUdHWSkgeworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJYWiB2ZXJzaW9uIGlzICIgKyB2ZXJzaW9uICsgIiAtIHNraXBwaW5nIEJDSiB0ZXN0cyIpOworICAgICAgICB9CisgICAgfQorICAgIHByaXZhdGUgRmlsZSBvdXRwdXQ7CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBpZiAob3V0cHV0ICE9IG51bGwgJiYgIW91dHB1dC5kZWxldGUoKSkgeworICAgICAgICAgICAgb3V0cHV0LmRlbGV0ZU9uRXhpdCgpOworICAgICAgICB9CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGlyZWN0b3JpZXNBbmRFbXB0eUZpbGVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIG91dHB1dCA9IG5ldyBGaWxlKGRpciwgImVtcHRpZXMuN3oiKTsKKworICAgICAgICBmaW5hbCBEYXRlIGFjY2Vzc0RhdGUgPSBuZXcgRGF0ZSgpOworICAgICAgICBmaW5hbCBDYWxlbmRhciBjYWwgPSBDYWxlbmRhci5nZXRJbnN0YW5jZSgpOworICAgICAgICBjYWwuYWRkKENhbGVuZGFyLkhPVVIsIC0xKTsKKyAgICAgICAgZmluYWwgRGF0ZSBjcmVhdGlvbkRhdGUgPSBjYWwuZ2V0VGltZSgpOworCisgICAgICAgIHRyeSAoU2V2ZW5aT3V0cHV0RmlsZSBvdXRBcmNoaXZlID0gbmV3IFNldmVuWk91dHB1dEZpbGUob3V0cHV0KSkgeworICAgICAgICAgICAgU2V2ZW5aQXJjaGl2ZUVudHJ5IGVudHJ5ID0gb3V0QXJjaGl2ZS5jcmVhdGVBcmNoaXZlRW50cnkoZGlyLCAiZm9vLyIpOworICAgICAgICAgICAgb3V0QXJjaGl2ZS5wdXRBcmNoaXZlRW50cnkoZW50cnkpOworICAgICAgICAgICAgb3V0QXJjaGl2ZS5jbG9zZUFyY2hpdmVFbnRyeSgpOworCisgICAgICAgICAgICBlbnRyeSA9IG5ldyBTZXZlblpBcmNoaXZlRW50cnkoKTsKKyAgICAgICAgICAgIGVudHJ5LnNldE5hbWUoImZvby9iYXIiKTsKKyAgICAgICAgICAgIGVudHJ5LnNldENyZWF0aW9uRGF0ZShjcmVhdGlvbkRhdGUpOworICAgICAgICAgICAgZW50cnkuc2V0QWNjZXNzRGF0ZShhY2Nlc3NEYXRlKTsKKyAgICAgICAgICAgIG91dEFyY2hpdmUucHV0QXJjaGl2ZUVudHJ5KGVudHJ5KTsKKyAgICAgICAgICAgIG91dEFyY2hpdmUud3JpdGUobmV3IGJ5dGVbMF0pOworICAgICAgICAgICAgb3V0QXJjaGl2ZS5jbG9zZUFyY2hpdmVFbnRyeSgpOworCisgICAgICAgICAgICBlbnRyeSA9IG5ldyBTZXZlblpBcmNoaXZlRW50cnkoKTsKKyAgICAgICAgICAgIGVudHJ5LnNldE5hbWUoInh5enp5Iik7CisgICAgICAgICAgICBvdXRBcmNoaXZlLnB1dEFyY2hpdmVFbnRyeShlbnRyeSk7CisgICAgICAgICAgICBvdXRBcmNoaXZlLndyaXRlKDApOworICAgICAgICAgICAgb3V0QXJjaGl2ZS5jbG9zZUFyY2hpdmVFbnRyeSgpOworCisgICAgICAgICAgICBlbnRyeSA9IG91dEFyY2hpdmUuY3JlYXRlQXJjaGl2ZUVudHJ5KGRpciwgImJhei8iKTsKKyAgICAgICAgICAgIGVudHJ5LnNldEFudGlJdGVtKHRydWUpOworICAgICAgICAgICAgb3V0QXJjaGl2ZS5wdXRBcmNoaXZlRW50cnkoZW50cnkpOworICAgICAgICAgICAgb3V0QXJjaGl2ZS5jbG9zZUFyY2hpdmVFbnRyeSgpOworCisgICAgICAgICAgICBlbnRyeSA9IG5ldyBTZXZlblpBcmNoaXZlRW50cnkoKTsKKyAgICAgICAgICAgIGVudHJ5LnNldE5hbWUoImRhZGEiKTsKKyAgICAgICAgICAgIGVudHJ5LnNldEhhc1dpbmRvd3NBdHRyaWJ1dGVzKHRydWUpOworICAgICAgICAgICAgZW50cnkuc2V0V2luZG93c0F0dHJpYnV0ZXMoMTcpOworICAgICAgICAgICAgb3V0QXJjaGl2ZS5wdXRBcmNoaXZlRW50cnkoZW50cnkpOworICAgICAgICAgICAgb3V0QXJjaGl2ZS53cml0ZSg1KTsKKyAgICAgICAgICAgIG91dEFyY2hpdmUud3JpdGUoNDIpOworICAgICAgICAgICAgb3V0QXJjaGl2ZS5jbG9zZUFyY2hpdmVFbnRyeSgpOworCisgICAgICAgICAgICBvdXRBcmNoaXZlLmZpbmlzaCgpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IChTZXZlblpGaWxlIGFyY2hpdmUgPSBuZXcgU2V2ZW5aRmlsZShvdXRwdXQpKSB7CisgICAgICAgICAgICBTZXZlblpBcmNoaXZlRW50cnkgZW50cnkgPSBhcmNoaXZlLmdldE5leHRFbnRyeSgpOworICAgICAgICAgICAgYXNzZXJ0IChlbnRyeSAhPSBudWxsKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZm9vLyIsIGVudHJ5LmdldE5hbWUoKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKGVudHJ5LmlzRGlyZWN0b3J5KCkpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoZW50cnkuaXNBbnRpSXRlbSgpKTsKKworICAgICAgICAgICAgZW50cnkgPSBhcmNoaXZlLmdldE5leHRFbnRyeSgpOworICAgICAgICAgICAgYXNzZXJ0IChlbnRyeSAhPSBudWxsKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZm9vL2JhciIsIGVudHJ5LmdldE5hbWUoKSk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShlbnRyeS5pc0RpcmVjdG9yeSgpKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGVudHJ5LmlzQW50aUl0ZW0oKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMCwgZW50cnkuZ2V0U2l6ZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGVudHJ5LmdldEhhc0xhc3RNb2RpZmllZERhdGUoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoYWNjZXNzRGF0ZSwgZW50cnkuZ2V0QWNjZXNzRGF0ZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhjcmVhdGlvbkRhdGUsIGVudHJ5LmdldENyZWF0aW9uRGF0ZSgpKTsKKworICAgICAgICAgICAgZW50cnkgPSBhcmNoaXZlLmdldE5leHRFbnRyeSgpOworICAgICAgICAgICAgYXNzZXJ0IChlbnRyeSAhPSBudWxsKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygieHl6enkiLCBlbnRyeS5nZXROYW1lKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGVudHJ5LmdldFNpemUoKSk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShlbnRyeS5nZXRIYXNBY2Nlc3NEYXRlKCkpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoZW50cnkuZ2V0SGFzQ3JlYXRpb25EYXRlKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGFyY2hpdmUucmVhZCgpKTsKKworICAgICAgICAgICAgZW50cnkgPSBhcmNoaXZlLmdldE5leHRFbnRyeSgpOworICAgICAgICAgICAgYXNzZXJ0IChlbnRyeSAhPSBudWxsKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiYmF6LyIsIGVudHJ5LmdldE5hbWUoKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKGVudHJ5LmlzRGlyZWN0b3J5KCkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShlbnRyeS5pc0FudGlJdGVtKCkpOworCisgICAgICAgICAgICBlbnRyeSA9IGFyY2hpdmUuZ2V0TmV4dEVudHJ5KCk7CisgICAgICAgICAgICBhc3NlcnQgKGVudHJ5ICE9IG51bGwpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJkYWRhIiwgZW50cnkuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygyLCBlbnRyeS5nZXRTaXplKCkpOworICAgICAgICAgICAgZmluYWwgYnl0ZVtdIGNvbnRlbnQgPSBuZXcgYnl0ZVsyXTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygyLCBhcmNoaXZlLnJlYWQoY29udGVudCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDUsIGNvbnRlbnRbMF0pOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDQyLCBjb250ZW50WzFdKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygxNywgZW50cnkuZ2V0V2luZG93c0F0dHJpYnV0ZXMoKSk7CisKKyAgICAgICAgICAgIGFzc2VydCAoYXJjaGl2ZS5nZXROZXh0RW50cnkoKSA9PSBudWxsKTsKKyAgICAgICAgfQorCisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGlyZWN0b3JpZXNPbmx5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIG91dHB1dCA9IG5ldyBGaWxlKGRpciwgImRpcnMuN3oiKTsKKyAgICAgICAgdHJ5IChTZXZlblpPdXRwdXRGaWxlIG91dEFyY2hpdmUgPSBuZXcgU2V2ZW5aT3V0cHV0RmlsZShvdXRwdXQpKSB7CisgICAgICAgICAgICBmaW5hbCBTZXZlblpBcmNoaXZlRW50cnkgZW50cnkgPSBuZXcgU2V2ZW5aQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgICAgICBlbnRyeS5zZXROYW1lKCJmb28vIik7CisgICAgICAgICAgICBlbnRyeS5zZXREaXJlY3RvcnkodHJ1ZSk7CisgICAgICAgICAgICBvdXRBcmNoaXZlLnB1dEFyY2hpdmVFbnRyeShlbnRyeSk7CisgICAgICAgICAgICBvdXRBcmNoaXZlLmNsb3NlQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgKFNldmVuWkZpbGUgYXJjaGl2ZSA9IG5ldyBTZXZlblpGaWxlKG91dHB1dCkpIHsKKyAgICAgICAgICAgIGZpbmFsIFNldmVuWkFyY2hpdmVFbnRyeSBlbnRyeSA9IGFyY2hpdmUuZ2V0TmV4dEVudHJ5KCk7CisgICAgICAgICAgICBhc3NlcnQgKGVudHJ5ICE9IG51bGwpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJmb28vIiwgZW50cnkuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoZW50cnkuaXNEaXJlY3RvcnkoKSk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShlbnRyeS5pc0FudGlJdGVtKCkpOworCisgICAgICAgICAgICBhc3NlcnQgKGFyY2hpdmUuZ2V0TmV4dEVudHJ5KCkgPT0gbnVsbCk7CisgICAgICAgIH0KKworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdENhbnRGaW5pc2hUd2ljZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBvdXRwdXQgPSBuZXcgRmlsZShkaXIsICJmaW5pc2guN3oiKTsKKyAgICAgICAgdHJ5IChTZXZlblpPdXRwdXRGaWxlIG91dEFyY2hpdmUgPSBuZXcgU2V2ZW5aT3V0cHV0RmlsZShvdXRwdXQpKSB7CisgICAgICAgICAgICBvdXRBcmNoaXZlLmZpbmlzaCgpOworICAgICAgICAgICAgb3V0QXJjaGl2ZS5maW5pc2goKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZG4ndCBiZSBhYmxlIHRvIGNhbGwgZmluaXNoIHR3aWNlIik7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIElPRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlRoaXMgYXJjaGl2ZSBoYXMgYWxyZWFkeSBiZWVuIGZpbmlzaGVkIiwgZXguZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFNpeEVtcHR5RmlsZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdENvbXByZXNzMjUyKDYsIDApOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFNpeEZpbGVzU29tZU5vdEVtcHR5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RDb21wcmVzczI1Mig2LCAyKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RTZXZlbkVtcHR5RmlsZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdENvbXByZXNzMjUyKDcsIDApOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFNldmVuRmlsZXNTb21lTm90RW1wdHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdENvbXByZXNzMjUyKDcsIDIpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEVpZ2h0RW1wdHlGaWxlcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0Q29tcHJlc3MyNTIoOCwgMCk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RWlnaHRGaWxlc1NvbWVOb3RFbXB0eSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0Q29tcHJlc3MyNTIoOCwgMik7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TmluZUVtcHR5RmlsZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdENvbXByZXNzMjUyKDksIDApOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdE5pbmVGaWxlc1NvbWVOb3RFbXB0eSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0Q29tcHJlc3MyNTIoOSwgMik7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VHdlbnR5TmluZUVtcHR5RmlsZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdENvbXByZXNzMjUyKDI5LCAwKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RUd2VudHlOaW5lRmlsZXNTb21lTm90RW1wdHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdENvbXByZXNzMjUyKDI5LCA3KTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RDb3B5Um91bmR0cmlwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RSb3VuZFRyaXAoU2V2ZW5aTWV0aG9kLkNPUFkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEJ6aXAyUm91bmR0cmlwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RSb3VuZFRyaXAoU2V2ZW5aTWV0aG9kLkJaSVAyKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RMem1hMlJvdW5kdHJpcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0Um91bmRUcmlwKFNldmVuWk1ldGhvZC5MWk1BMik7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGVmbGF0ZVJvdW5kdHJpcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0Um91bmRUcmlwKFNldmVuWk1ldGhvZC5ERUZMQVRFKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RCQ0pYODZSb3VuZHRyaXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKFhaX0JDSl9JU19CVUdHWSkgeyByZXR1cm47IH0KKyAgICAgICAgdGVzdEZpbHRlclJvdW5kVHJpcChuZXcgU2V2ZW5aTWV0aG9kQ29uZmlndXJhdGlvbihTZXZlblpNZXRob2QuQkNKX1g4Nl9GSUxURVIpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RCQ0pBUk1Sb3VuZHRyaXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKFhaX0JDSl9JU19CVUdHWSkgeyByZXR1cm47IH0KKyAgICAgICAgdGVzdEZpbHRlclJvdW5kVHJpcChuZXcgU2V2ZW5aTWV0aG9kQ29uZmlndXJhdGlvbihTZXZlblpNZXRob2QuQkNKX0FSTV9GSUxURVIpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RCQ0pBUk1UaHVtYlJvdW5kdHJpcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBpZiAoWFpfQkNKX0lTX0JVR0dZKSB7IHJldHVybjsgfQorICAgICAgICB0ZXN0RmlsdGVyUm91bmRUcmlwKG5ldyBTZXZlblpNZXRob2RDb25maWd1cmF0aW9uKFNldmVuWk1ldGhvZC5CQ0pfQVJNX1RIVU1CX0ZJTFRFUikpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEJDSklBNjRSb3VuZHRyaXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKFhaX0JDSl9JU19CVUdHWSkgeyByZXR1cm47IH0KKyAgICAgICAgdGVzdEZpbHRlclJvdW5kVHJpcChuZXcgU2V2ZW5aTWV0aG9kQ29uZmlndXJhdGlvbihTZXZlblpNZXRob2QuQkNKX0lBNjRfRklMVEVSKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QkNKUFBDUm91bmR0cmlwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChYWl9CQ0pfSVNfQlVHR1kpIHsgcmV0dXJuOyB9CisgICAgICAgIHRlc3RGaWx0ZXJSb3VuZFRyaXAobmV3IFNldmVuWk1ldGhvZENvbmZpZ3VyYXRpb24oU2V2ZW5aTWV0aG9kLkJDSl9QUENfRklMVEVSKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QkNKU3BhcmNSb3VuZHRyaXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKFhaX0JDSl9JU19CVUdHWSkgeyByZXR1cm47IH0KKyAgICAgICAgdGVzdEZpbHRlclJvdW5kVHJpcChuZXcgU2V2ZW5aTWV0aG9kQ29uZmlndXJhdGlvbihTZXZlblpNZXRob2QuQkNKX1NQQVJDX0ZJTFRFUikpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdERlbHRhUm91bmR0cmlwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RGaWx0ZXJSb3VuZFRyaXAobmV3IFNldmVuWk1ldGhvZENvbmZpZ3VyYXRpb24oU2V2ZW5aTWV0aG9kLkRFTFRBX0ZJTFRFUikpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFN0YWNrT2ZDb250ZW50Q29tcHJlc3Npb25zKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIG91dHB1dCA9IG5ldyBGaWxlKGRpciwgIm11bHRpcGxlLW1ldGhvZHMuN3oiKTsKKyAgICAgICAgZmluYWwgQXJyYXlMaXN0PFNldmVuWk1ldGhvZENvbmZpZ3VyYXRpb24+IG1ldGhvZHMgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKyAgICAgICAgbWV0aG9kcy5hZGQobmV3IFNldmVuWk1ldGhvZENvbmZpZ3VyYXRpb24oU2V2ZW5aTWV0aG9kLkxaTUEyKSk7CisgICAgICAgIG1ldGhvZHMuYWRkKG5ldyBTZXZlblpNZXRob2RDb25maWd1cmF0aW9uKFNldmVuWk1ldGhvZC5DT1BZKSk7CisgICAgICAgIG1ldGhvZHMuYWRkKG5ldyBTZXZlblpNZXRob2RDb25maWd1cmF0aW9uKFNldmVuWk1ldGhvZC5ERUZMQVRFKSk7CisgICAgICAgIG1ldGhvZHMuYWRkKG5ldyBTZXZlblpNZXRob2RDb25maWd1cmF0aW9uKFNldmVuWk1ldGhvZC5CWklQMikpOworICAgICAgICBjcmVhdGVBbmRSZWFkQmFjayhvdXRwdXQsIG1ldGhvZHMpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFN0YWNrT2ZDb250ZW50Q29tcHJlc3Npb25zSW5NZW1vcnkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgQXJyYXlMaXN0PFNldmVuWk1ldGhvZENvbmZpZ3VyYXRpb24+IG1ldGhvZHMgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKyAgICAgICAgbWV0aG9kcy5hZGQobmV3IFNldmVuWk1ldGhvZENvbmZpZ3VyYXRpb24oU2V2ZW5aTWV0aG9kLkxaTUEyKSk7CisgICAgICAgIG1ldGhvZHMuYWRkKG5ldyBTZXZlblpNZXRob2RDb25maWd1cmF0aW9uKFNldmVuWk1ldGhvZC5DT1BZKSk7CisgICAgICAgIG1ldGhvZHMuYWRkKG5ldyBTZXZlblpNZXRob2RDb25maWd1cmF0aW9uKFNldmVuWk1ldGhvZC5ERUZMQVRFKSk7CisgICAgICAgIG1ldGhvZHMuYWRkKG5ldyBTZXZlblpNZXRob2RDb25maWd1cmF0aW9uKFNldmVuWk1ldGhvZC5CWklQMikpOworICAgICAgICBjcmVhdGVBbmRSZWFkQmFjayhuZXcgU2Vla2FibGVJbk1lbW9yeUJ5dGVDaGFubmVsKCksIG1ldGhvZHMpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdERlZmxhdGVXaXRoQ29uZmlndXJhdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBvdXRwdXQgPSBuZXcgRmlsZShkaXIsICJkZWZsYXRlLW9wdGlvbnMuN3oiKTsKKyAgICAgICAgLy8gRGVmbGF0ZXIuQkVTVF9TUEVFRAorICAgICAgICBjcmVhdGVBbmRSZWFkQmFjayhvdXRwdXQsIENvbGxlY3Rpb25zCisgICAgICAgICAgICAgICAgICAgICAgICAgIC5zaW5nbGV0b25MaXN0KG5ldyBTZXZlblpNZXRob2RDb25maWd1cmF0aW9uKFNldmVuWk1ldGhvZC5ERUZMQVRFLCAxKSkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEJ6aXAyV2l0aENvbmZpZ3VyYXRpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgb3V0cHV0ID0gbmV3IEZpbGUoZGlyLCAiYnppcDItb3B0aW9ucy43eiIpOworICAgICAgICAvLyA0MDBrIGJsb2NrIHNpemUKKyAgICAgICAgY3JlYXRlQW5kUmVhZEJhY2sob3V0cHV0LCBDb2xsZWN0aW9ucworICAgICAgICAgICAgICAgICAgICAgICAgICAuc2luZ2xldG9uTGlzdChuZXcgU2V2ZW5aTWV0aG9kQ29uZmlndXJhdGlvbihTZXZlblpNZXRob2QuQlpJUDIsIDQpKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0THptYVdpdGhJbnRDb25maWd1cmF0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIG91dHB1dCA9IG5ldyBGaWxlKGRpciwgImx6bWEtb3B0aW9ucy43eiIpOworICAgICAgICAvLyAxIE1CIGRpY3Rpb25hcnkKKyAgICAgICAgY3JlYXRlQW5kUmVhZEJhY2sob3V0cHV0LCBDb2xsZWN0aW9ucworICAgICAgICAgICAgICAgICAgICAgICAgICAuc2luZ2xldG9uTGlzdChuZXcgU2V2ZW5aTWV0aG9kQ29uZmlndXJhdGlvbihTZXZlblpNZXRob2QuTFpNQSwgMSA8PCAyMCkpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RMem1hV2l0aE9wdGlvbnNDb25maWd1cmF0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIG91dHB1dCA9IG5ldyBGaWxlKGRpciwgImx6bWEtb3B0aW9uczIuN3oiKTsKKyAgICAgICAgZmluYWwgTFpNQTJPcHRpb25zIG9wdHMgPSBuZXcgTFpNQTJPcHRpb25zKDEpOworICAgICAgICBjcmVhdGVBbmRSZWFkQmFjayhvdXRwdXQsIENvbGxlY3Rpb25zCisgICAgICAgICAgICAgICAgICAgICAgICAgIC5zaW5nbGV0b25MaXN0KG5ldyBTZXZlblpNZXRob2RDb25maWd1cmF0aW9uKFNldmVuWk1ldGhvZC5MWk1BLCBvcHRzKSkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEx6bWEyV2l0aEludENvbmZpZ3VyYXRpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgb3V0cHV0ID0gbmV3IEZpbGUoZGlyLCAibHptYTItb3B0aW9ucy43eiIpOworICAgICAgICAvLyAxIE1CIGRpY3Rpb25hcnkKKyAgICAgICAgY3JlYXRlQW5kUmVhZEJhY2sob3V0cHV0LCBDb2xsZWN0aW9ucworICAgICAgICAgICAgICAgICAgICAgICAgICAuc2luZ2xldG9uTGlzdChuZXcgU2V2ZW5aTWV0aG9kQ29uZmlndXJhdGlvbihTZXZlblpNZXRob2QuTFpNQTIsIDEgPDwgMjApKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0THptYTJXaXRoT3B0aW9uc0NvbmZpZ3VyYXRpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgb3V0cHV0ID0gbmV3IEZpbGUoZGlyLCAibHptYTItb3B0aW9uczIuN3oiKTsKKyAgICAgICAgZmluYWwgTFpNQTJPcHRpb25zIG9wdHMgPSBuZXcgTFpNQTJPcHRpb25zKDEpOworICAgICAgICBjcmVhdGVBbmRSZWFkQmFjayhvdXRwdXQsIENvbGxlY3Rpb25zCisgICAgICAgICAgICAgICAgICAgICAgICAgIC5zaW5nbGV0b25MaXN0KG5ldyBTZXZlblpNZXRob2RDb25maWd1cmF0aW9uKFNldmVuWk1ldGhvZC5MWk1BMiwgb3B0cykpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RBcmNoaXZlV2l0aE1peGVkTWV0aG9kcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBvdXRwdXQgPSBuZXcgRmlsZShkaXIsICJtaXhlZC1tZXRob2RzLjd6Iik7CisgICAgICAgIHRyeSAoU2V2ZW5aT3V0cHV0RmlsZSBvdXRBcmNoaXZlID0gbmV3IFNldmVuWk91dHB1dEZpbGUob3V0cHV0KSkgeworICAgICAgICAgICAgYWRkRmlsZShvdXRBcmNoaXZlLCAwLCB0cnVlKTsKKyAgICAgICAgICAgIGFkZEZpbGUob3V0QXJjaGl2ZSwgMSwgdHJ1ZSwgQXJyYXlzLmFzTGlzdChuZXcgU2V2ZW5aTWV0aG9kQ29uZmlndXJhdGlvbihTZXZlblpNZXRob2QuQlpJUDIpKSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgKFNldmVuWkZpbGUgYXJjaGl2ZSA9IG5ldyBTZXZlblpGaWxlKG91dHB1dCkpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhCb29sZWFuLlRSVUUsCisgICAgICAgICAgICAgICAgICAgIHZlcmlmeUZpbGUoYXJjaGl2ZSwgMCwgQXJyYXlzLmFzTGlzdChuZXcgU2V2ZW5aTWV0aG9kQ29uZmlndXJhdGlvbihTZXZlblpNZXRob2QuTFpNQTIpKSkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKEJvb2xlYW4uVFJVRSwKKyAgICAgICAgICAgICAgICAgICAgdmVyaWZ5RmlsZShhcmNoaXZlLCAxLCBBcnJheXMuYXNMaXN0KG5ldyBTZXZlblpNZXRob2RDb25maWd1cmF0aW9uKFNldmVuWk1ldGhvZC5CWklQMikpKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdGVzdENvbXByZXNzMjUyKGZpbmFsIGludCBudW1iZXJPZkZpbGVzLCBmaW5hbCBpbnQgbnVtYmVyT2ZOb25FbXB0eUZpbGVzKQorICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgaW50IG5vbkVtcHR5TW9kdWx1cyA9IG51bWJlck9mTm9uRW1wdHlGaWxlcyAhPSAwCisgICAgICAgICAgICA/IG51bWJlck9mRmlsZXMgLyBudW1iZXJPZk5vbkVtcHR5RmlsZXMKKyAgICAgICAgICAgIDogbnVtYmVyT2ZGaWxlcyArIDE7CisgICAgICAgIGludCBub25FbXB0eUZpbGVzQWRkZWQgPSAwOworICAgICAgICBvdXRwdXQgPSBuZXcgRmlsZShkaXIsICJDT01QUkVTUzI1Mi0iICsgbnVtYmVyT2ZGaWxlcyArICItIiArIG51bWJlck9mTm9uRW1wdHlGaWxlcyArICIuN3oiKTsKKyAgICAgICAgdHJ5IChTZXZlblpPdXRwdXRGaWxlIGFyY2hpdmUgPSBuZXcgU2V2ZW5aT3V0cHV0RmlsZShvdXRwdXQpKSB7CisgICAgICAgICAgICBhZGREaXIoYXJjaGl2ZSk7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bWJlck9mRmlsZXM7IGkrKykgeworICAgICAgICAgICAgICAgIGFkZEZpbGUoYXJjaGl2ZSwgaSwKKyAgICAgICAgICAgICAgICAgICAgICAgIChpICsgMSkgJSBub25FbXB0eU1vZHVsdXMgPT0gMCAmJiBub25FbXB0eUZpbGVzQWRkZWQrKyA8IG51bWJlck9mTm9uRW1wdHlGaWxlcyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgdmVyaWZ5Q29tcHJlc3MyNTIob3V0cHV0LCBudW1iZXJPZkZpbGVzLCBudW1iZXJPZk5vbkVtcHR5RmlsZXMpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB2ZXJpZnlDb21wcmVzczI1MihmaW5hbCBGaWxlIG91dHB1dCwgZmluYWwgaW50IG51bWJlck9mRmlsZXMsIGZpbmFsIGludCBudW1iZXJPZk5vbkVtcHR5RmlsZXMpCisgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBpbnQgZmlsZXNGb3VuZCA9IDA7CisgICAgICAgIGludCBub25FbXB0eUZpbGVzRm91bmQgPSAwOworICAgICAgICB0cnkgKFNldmVuWkZpbGUgYXJjaGl2ZSA9IG5ldyBTZXZlblpGaWxlKG91dHB1dCkpIHsKKyAgICAgICAgICAgIHZlcmlmeURpcihhcmNoaXZlKTsKKyAgICAgICAgICAgIEJvb2xlYW4gYiA9IHZlcmlmeUZpbGUoYXJjaGl2ZSwgZmlsZXNGb3VuZCsrKTsKKyAgICAgICAgICAgIHdoaWxlIChiICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBpZiAoQm9vbGVhbi5UUlVFLmVxdWFscyhiKSkgeworICAgICAgICAgICAgICAgICAgICBub25FbXB0eUZpbGVzRm91bmQrKzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYiA9IHZlcmlmeUZpbGUoYXJjaGl2ZSwgZmlsZXNGb3VuZCsrKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMobnVtYmVyT2ZGaWxlcyArIDEsIGZpbGVzRm91bmQpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVtYmVyT2ZOb25FbXB0eUZpbGVzLCBub25FbXB0eUZpbGVzRm91bmQpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhZGREaXIoZmluYWwgU2V2ZW5aT3V0cHV0RmlsZSBhcmNoaXZlKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgU2V2ZW5aQXJjaGl2ZUVudHJ5IGVudHJ5ID0gYXJjaGl2ZS5jcmVhdGVBcmNoaXZlRW50cnkoZGlyLCAiZm9vLyIpOworICAgICAgICBhcmNoaXZlLnB1dEFyY2hpdmVFbnRyeShlbnRyeSk7CisgICAgICAgIGFyY2hpdmUuY2xvc2VBcmNoaXZlRW50cnkoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdmVyaWZ5RGlyKGZpbmFsIFNldmVuWkZpbGUgYXJjaGl2ZSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFNldmVuWkFyY2hpdmVFbnRyeSBlbnRyeSA9IGFyY2hpdmUuZ2V0TmV4dEVudHJ5KCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoZW50cnkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImZvby8iLCBlbnRyeS5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnRUcnVlKGVudHJ5LmlzRGlyZWN0b3J5KCkpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhZGRGaWxlKGZpbmFsIFNldmVuWk91dHB1dEZpbGUgYXJjaGl2ZSwgZmluYWwgaW50IGluZGV4LCBmaW5hbCBib29sZWFuIG5vbkVtcHR5KQorICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYWRkRmlsZShhcmNoaXZlLCBpbmRleCwgbm9uRW1wdHksIG51bGwpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhZGRGaWxlKGZpbmFsIFNldmVuWk91dHB1dEZpbGUgYXJjaGl2ZSwgZmluYWwgaW50IGluZGV4LCBmaW5hbCBib29sZWFuIG5vbkVtcHR5LCBmaW5hbCBJdGVyYWJsZTxTZXZlblpNZXRob2RDb25maWd1cmF0aW9uPiBtZXRob2RzKQorICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgU2V2ZW5aQXJjaGl2ZUVudHJ5IGVudHJ5ID0gbmV3IFNldmVuWkFyY2hpdmVFbnRyeSgpOworICAgICAgICBlbnRyeS5zZXROYW1lKCJmb28vIiArIGluZGV4ICsgIi50eHQiKTsKKyAgICAgICAgZW50cnkuc2V0Q29udGVudE1ldGhvZHMobWV0aG9kcyk7CisgICAgICAgIGFyY2hpdmUucHV0QXJjaGl2ZUVudHJ5KGVudHJ5KTsKKyAgICAgICAgYXJjaGl2ZS53cml0ZShub25FbXB0eSA/IG5ldyBieXRlW10geyAnQScgfSA6IG5ldyBieXRlWzBdKTsKKyAgICAgICAgYXJjaGl2ZS5jbG9zZUFyY2hpdmVFbnRyeSgpOworICAgIH0KKworICAgIHByaXZhdGUgQm9vbGVhbiB2ZXJpZnlGaWxlKGZpbmFsIFNldmVuWkZpbGUgYXJjaGl2ZSwgZmluYWwgaW50IGluZGV4KSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHZlcmlmeUZpbGUoYXJjaGl2ZSwgaW5kZXgsIG51bGwpOworICAgIH0KKworICAgIHByaXZhdGUgQm9vbGVhbiB2ZXJpZnlGaWxlKGZpbmFsIFNldmVuWkZpbGUgYXJjaGl2ZSwgZmluYWwgaW50IGluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEl0ZXJhYmxlPFNldmVuWk1ldGhvZENvbmZpZ3VyYXRpb24+IG1ldGhvZHMpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBTZXZlblpBcmNoaXZlRW50cnkgZW50cnkgPSBhcmNoaXZlLmdldE5leHRFbnRyeSgpOworICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmb28vIiArIGluZGV4ICsgIi50eHQiLCBlbnRyeS5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoZmFsc2UsIGVudHJ5LmlzRGlyZWN0b3J5KCkpOworICAgICAgICBpZiAoZW50cnkuZ2V0U2l6ZSgpID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiBCb29sZWFuLkZBTFNFOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygxLCBlbnRyeS5nZXRTaXplKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoJ0EnLCBhcmNoaXZlLnJlYWQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygtMSwgYXJjaGl2ZS5yZWFkKCkpOworICAgICAgICBpZiAobWV0aG9kcyAhPSBudWxsKSB7CisgICAgICAgICAgICBhc3NlcnRDb250ZW50TWV0aG9kc0VxdWFscyhtZXRob2RzLCBlbnRyeS5nZXRDb250ZW50TWV0aG9kcygpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gQm9vbGVhbi5UUlVFOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0Um91bmRUcmlwKGZpbmFsIFNldmVuWk1ldGhvZCBtZXRob2QpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBvdXRwdXQgPSBuZXcgRmlsZShkaXIsIG1ldGhvZCArICItcm91bmR0cmlwLjd6Iik7CisgICAgICAgIGZpbmFsIEFycmF5TGlzdDxTZXZlblpNZXRob2RDb25maWd1cmF0aW9uPiBtZXRob2RzID0gbmV3IEFycmF5TGlzdDw+KCk7CisgICAgICAgIG1ldGhvZHMuYWRkKG5ldyBTZXZlblpNZXRob2RDb25maWd1cmF0aW9uKG1ldGhvZCkpOworICAgICAgICBjcmVhdGVBbmRSZWFkQmFjayhvdXRwdXQsIG1ldGhvZHMpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0RmlsdGVyUm91bmRUcmlwKGZpbmFsIFNldmVuWk1ldGhvZENvbmZpZ3VyYXRpb24gbWV0aG9kKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgb3V0cHV0ID0gbmV3IEZpbGUoZGlyLCBtZXRob2QuZ2V0TWV0aG9kKCkgKyAiLXJvdW5kdHJpcC43eiIpOworICAgICAgICBmaW5hbCBBcnJheUxpc3Q8U2V2ZW5aTWV0aG9kQ29uZmlndXJhdGlvbj4gbWV0aG9kcyA9IG5ldyBBcnJheUxpc3Q8PigpOworICAgICAgICBtZXRob2RzLmFkZChtZXRob2QpOworICAgICAgICBtZXRob2RzLmFkZChuZXcgU2V2ZW5aTWV0aG9kQ29uZmlndXJhdGlvbihTZXZlblpNZXRob2QuTFpNQTIpKTsKKyAgICAgICAgY3JlYXRlQW5kUmVhZEJhY2sob3V0cHV0LCBtZXRob2RzKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY3JlYXRlQW5kUmVhZEJhY2soZmluYWwgRmlsZSBvdXRwdXQsIGZpbmFsIEl0ZXJhYmxlPFNldmVuWk1ldGhvZENvbmZpZ3VyYXRpb24+IG1ldGhvZHMpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBTZXZlblpPdXRwdXRGaWxlIG91dEFyY2hpdmUgPSBuZXcgU2V2ZW5aT3V0cHV0RmlsZShvdXRwdXQpOworICAgICAgICBvdXRBcmNoaXZlLnNldENvbnRlbnRNZXRob2RzKG1ldGhvZHMpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYWRkRmlsZShvdXRBcmNoaXZlLCAwLCB0cnVlKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIG91dEFyY2hpdmUuY2xvc2UoKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSAoU2V2ZW5aRmlsZSBhcmNoaXZlID0gbmV3IFNldmVuWkZpbGUob3V0cHV0KSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKEJvb2xlYW4uVFJVRSwgdmVyaWZ5RmlsZShhcmNoaXZlLCAwLCBtZXRob2RzKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY3JlYXRlQW5kUmVhZEJhY2soZmluYWwgU2Vla2FibGVJbk1lbW9yeUJ5dGVDaGFubmVsIG91dHB1dCwgZmluYWwgSXRlcmFibGU8U2V2ZW5aTWV0aG9kQ29uZmlndXJhdGlvbj4gbWV0aG9kcykgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFNldmVuWk91dHB1dEZpbGUgb3V0QXJjaGl2ZSA9IG5ldyBTZXZlblpPdXRwdXRGaWxlKG91dHB1dCk7CisgICAgICAgIG91dEFyY2hpdmUuc2V0Q29udGVudE1ldGhvZHMobWV0aG9kcyk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhZGRGaWxlKG91dEFyY2hpdmUsIDAsIHRydWUpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgb3V0QXJjaGl2ZS5jbG9zZSgpOworICAgICAgICB9CisgICAgICAgIHRyeSAoU2V2ZW5aRmlsZSBhcmNoaXZlID0KKyAgICAgICAgICAgICBuZXcgU2V2ZW5aRmlsZShuZXcgU2Vla2FibGVJbk1lbW9yeUJ5dGVDaGFubmVsKG91dHB1dC5hcnJheSgpKSwgImluIG1lbW9yeSIpKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoQm9vbGVhbi5UUlVFLCB2ZXJpZnlGaWxlKGFyY2hpdmUsIDAsIG1ldGhvZHMpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgYXNzZXJ0Q29udGVudE1ldGhvZHNFcXVhbHMoZmluYWwgSXRlcmFibGU8PyBleHRlbmRzIFNldmVuWk1ldGhvZENvbmZpZ3VyYXRpb24+IGV4cGVjdGVkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgSXRlcmFibGU8PyBleHRlbmRzIFNldmVuWk1ldGhvZENvbmZpZ3VyYXRpb24+IGFjdHVhbCkgeworICAgICAgICBhc3NlcnROb3ROdWxsKGFjdHVhbCk7CisgICAgICAgIGZpbmFsIEl0ZXJhdG9yPD8gZXh0ZW5kcyBTZXZlblpNZXRob2RDb25maWd1cmF0aW9uPiBleHBlY3RlZEl0ZXIgPSBleHBlY3RlZC5pdGVyYXRvcigpOworICAgICAgICBmaW5hbCBJdGVyYXRvcjw/IGV4dGVuZHMgU2V2ZW5aTWV0aG9kQ29uZmlndXJhdGlvbj4gYWN0dWFsSXRlciA9IGFjdHVhbC5pdGVyYXRvcigpOworICAgICAgICB3aGlsZSAoZXhwZWN0ZWRJdGVyLmhhc05leHQoKSkgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShhY3R1YWxJdGVyLmhhc05leHQoKSk7CisgICAgICAgICAgICBmaW5hbCBTZXZlblpNZXRob2RDb25maWd1cmF0aW9uIGV4cENvbmZpZyA9IGV4cGVjdGVkSXRlci5uZXh0KCk7CisgICAgICAgICAgICBmaW5hbCBTZXZlblpNZXRob2RDb25maWd1cmF0aW9uIGFjdENvbmZpZyA9IGFjdHVhbEl0ZXIubmV4dCgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cENvbmZpZy5nZXRNZXRob2QoKSwgYWN0Q29uZmlnLmdldE1ldGhvZCgpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRGYWxzZShhY3R1YWxJdGVyLmhhc05leHQoKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3Rhci9CaWdGaWxlc0lULmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvdGFyL0JpZ0ZpbGVzSVQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xNGNmZTY0Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3Rhci9CaWdGaWxlc0lULmphdmEKQEAgLTAsMCArMSwxMTIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnRhcjsKKworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEVxdWFsczsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnROb3ROdWxsOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydE51bGw7CisKK2ltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuUmFuZG9tOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLmd6aXAuR3ppcENvbXByZXNzb3JJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworcHVibGljIGNsYXNzIEJpZ0ZpbGVzSVQgeworCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCByZWFkRmlsZUJpZ2dlclRoYW44R0J5dGVTdGFyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHJlYWRGaWxlQmlnZ2VyVGhhbjhHQnl0ZSgiLzguc3Rhci50YXIuZ3oiKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHJlYWRGaWxlQmlnZ2VyVGhhbjhHQnl0ZVBvc2l4KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHJlYWRGaWxlQmlnZ2VyVGhhbjhHQnl0ZSgiLzgucG9zaXgudGFyLmd6Iik7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCByZWFkRmlsZUhlYWRlcnNPZkFyY2hpdmVCaWdnZXJUaGFuOEdCeXRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIElucHV0U3RyZWFtIGluID0gbnVsbDsKKyAgICAgICAgR3ppcENvbXByZXNzb3JJbnB1dFN0cmVhbSBnemluID0gbnVsbDsKKyAgICAgICAgVGFyQXJjaGl2ZUlucHV0U3RyZWFtIHRpbiA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbiA9IG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKEJpZ0ZpbGVzSVQuY2xhc3MKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmdldFJlc291cmNlQXNTdHJlYW0oIi84LnBvc2l4LnRhci5neiIpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7CisgICAgICAgICAgICBnemluID0gbmV3IEd6aXBDb21wcmVzc29ySW5wdXRTdHJlYW0oaW4pOworICAgICAgICAgICAgdGluID0gbmV3IFRhckFyY2hpdmVJbnB1dFN0cmVhbShnemluKTsKKyAgICAgICAgICAgIGZpbmFsIFRhckFyY2hpdmVFbnRyeSBlID0gdGluLmdldE5leHRUYXJFbnRyeSgpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChlKTsKKyAgICAgICAgICAgIGFzc2VydE51bGwodGluLmdldE5leHRUYXJFbnRyeSgpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmICh0aW4gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRpbi5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGd6aW4gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGd6aW4uY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChpbiAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByZWFkRmlsZUJpZ2dlclRoYW44R0J5dGUoZmluYWwgU3RyaW5nIG5hbWUpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBJbnB1dFN0cmVhbSBpbiA9IG51bGw7CisgICAgICAgIEd6aXBDb21wcmVzc29ySW5wdXRTdHJlYW0gZ3ppbiA9IG51bGw7CisgICAgICAgIFRhckFyY2hpdmVJbnB1dFN0cmVhbSB0aW4gPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW4gPSBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShCaWdGaWxlc0lULmNsYXNzCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRSZXNvdXJjZUFzU3RyZWFtKG5hbWUpKTsKKyAgICAgICAgICAgIGd6aW4gPSBuZXcgR3ppcENvbXByZXNzb3JJbnB1dFN0cmVhbShpbik7CisgICAgICAgICAgICB0aW4gPSBuZXcgVGFyQXJjaGl2ZUlucHV0U3RyZWFtKGd6aW4pOworICAgICAgICAgICAgZmluYWwgVGFyQXJjaGl2ZUVudHJ5IGUgPSB0aW4uZ2V0TmV4dFRhckVudHJ5KCk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGUpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDgyMDBsICogMTAyNCAqIDEwMjQsIGUuZ2V0U2l6ZSgpKTsKKworICAgICAgICAgICAgbG9uZyByZWFkID0gMDsKKyAgICAgICAgICAgIGZpbmFsIFJhbmRvbSByID0gbmV3IFJhbmRvbShTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSk7CisgICAgICAgICAgICBpbnQgcmVhZE5vdzsKKyAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBidWYgPSBuZXcgYnl0ZVsxMDI0ICogMTAyNF07CisgICAgICAgICAgICB3aGlsZSAoKHJlYWROb3cgPSB0aW4ucmVhZChidWYsIDAsIGJ1Zi5sZW5ndGgpKSA+IDApIHsKKyAgICAgICAgICAgICAgICAvLyB0ZXN0aW5nIGFsbCBieXRlcyBmb3IgYSB2YWx1ZSBvZiAwIGlzIGdvaW5nIHRvIHRha2UKKyAgICAgICAgICAgICAgICAvLyB0b28gbG9uZywganVzdCBwaWNrIGEgZmV3IG9uZXMgcmFuZG9tbHkKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwMDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBpZHggPSByLm5leHRJbnQocmVhZE5vdyk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygidGVzdGluZyBieXRlICIgKyAocmVhZCArIGlkeCksIDAsIGJ1ZltpZHhdKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmVhZCArPSByZWFkTm93OworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDgyMDBsICogMTAyNCAqIDEwMjQsIHJlYWQpOworICAgICAgICAgICAgYXNzZXJ0TnVsbCh0aW4uZ2V0TmV4dFRhckVudHJ5KCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKHRpbiAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGluLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoZ3ppbiAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgZ3ppbi5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGluICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvdGFyL1NwYXJzZUZpbGVzVGVzdC5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3Rhci9TcGFyc2VGaWxlc1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NmFjMjI3Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3Rhci9TcGFyc2VGaWxlc1Rlc3QuamF2YQpAQCAtMCwwICsxLDc1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy50YXI7CisKK2ltcG9ydCBzdGF0aWMgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLkFic3RyYWN0VGVzdENhc2UuZ2V0RmlsZTsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC4qOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworCisKK3B1YmxpYyBjbGFzcyBTcGFyc2VGaWxlc1Rlc3QgeworCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0T2xkR05VKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIGZpbmFsIEZpbGUgZmlsZSA9IGdldEZpbGUoIm9sZGdudV9zcGFyc2UudGFyIik7CisgICAgICAgIFRhckFyY2hpdmVJbnB1dFN0cmVhbSB0aW4gPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGluID0gbmV3IFRhckFyY2hpdmVJbnB1dFN0cmVhbShuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGUpKTsKKyAgICAgICAgICAgIGZpbmFsIFRhckFyY2hpdmVFbnRyeSBhZSA9IHRpbi5nZXROZXh0VGFyRW50cnkoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygic3BhcnNlZmlsZSIsIGFlLmdldE5hbWUoKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKGFlLmlzT2xkR05VU3BhcnNlKCkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShhZS5pc0dOVVNwYXJzZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGFlLmlzUGF4R05VU3BhcnNlKCkpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2UodGluLmNhblJlYWRFbnRyeURhdGEoYWUpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmICh0aW4gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRpbi5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UGF4R05VKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIGZpbmFsIEZpbGUgZmlsZSA9IGdldEZpbGUoInBheF9nbnVfc3BhcnNlLnRhciIpOworICAgICAgICBUYXJBcmNoaXZlSW5wdXRTdHJlYW0gdGluID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRpbiA9IG5ldyBUYXJBcmNoaXZlSW5wdXRTdHJlYW0obmV3IEZpbGVJbnB1dFN0cmVhbShmaWxlKSk7CisgICAgICAgICAgICBhc3NlcnRQYXhHTlVFbnRyeSh0aW4sICIwLjAiKTsKKyAgICAgICAgICAgIGFzc2VydFBheEdOVUVudHJ5KHRpbiwgIjAuMSIpOworICAgICAgICAgICAgYXNzZXJ0UGF4R05VRW50cnkodGluLCAiMS4wIik7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAodGluICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aW4uY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhc3NlcnRQYXhHTlVFbnRyeShmaW5hbCBUYXJBcmNoaXZlSW5wdXRTdHJlYW0gdGluLCBmaW5hbCBTdHJpbmcgc3VmZml4KSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgZmluYWwgVGFyQXJjaGl2ZUVudHJ5IGFlID0gdGluLmdldE5leHRUYXJFbnRyeSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoInNwYXJzZWZpbGUtIiArIHN1ZmZpeCwgYWUuZ2V0TmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShhZS5pc0dOVVNwYXJzZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShhZS5pc1BheEdOVVNwYXJzZSgpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoYWUuaXNPbGRHTlVTcGFyc2UoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKHRpbi5jYW5SZWFkRW50cnlEYXRhKGFlKSk7CisgICAgfQorfQorCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvdGFyL1RhckFyY2hpdmVFbnRyeVRlc3QuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy90YXIvVGFyQXJjaGl2ZUVudHJ5VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjcwM2QzYTQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvdGFyL1RhckFyY2hpdmVFbnRyeVRlc3QuamF2YQpAQCAtMCwwICsxLDIxNiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICoKKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMudGFyOworCitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0RXF1YWxzOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydE5vdEVxdWFsczsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnROb3ROdWxsOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydE51bGw7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VHJ1ZTsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5mYWlsOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzdW1lLmFzc3VtZVRydWU7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtUmVhZGVyOworaW1wb3J0IGphdmEuaW8uUmVhZGVyOworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLkFic3RyYWN0VGVzdENhc2U7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CisKK3B1YmxpYyBjbGFzcyBUYXJBcmNoaXZlRW50cnlUZXN0IGltcGxlbWVudHMgVGFyQ29uc3RhbnRzIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBPUyA9CisgICAgICAgIFN5c3RlbS5nZXRQcm9wZXJ0eSgib3MubmFtZSIpLnRvTG93ZXJDYXNlKExvY2FsZS5FTkdMSVNIKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUk9PVCA9CisgICAgICAgIE9TLnN0YXJ0c1dpdGgoIndpbmRvd3MiKSB8fCBPUy5zdGFydHNXaXRoKCJuZXR3YXJlIikgPyAiQzpcXCIgOiAiLyI7CisKKyAgICAvKioKKyAgICAgKiBKSVJBIGlzc3VlIFNBTkRCT1gtMjg0CisgICAgICoKKyAgICAgKiBAc2VlICJodHRwczovL2lzc3Vlcy5hcGFjaGUub3JnL2ppcmEvYnJvd3NlL1NBTkRCT1gtMjg0IgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEZpbGVTeXN0ZW1Sb290KCkgeworICAgICAgICBmaW5hbCBUYXJBcmNoaXZlRW50cnkgdCA9IG5ldyBUYXJBcmNoaXZlRW50cnkobmV3IEZpbGUoUk9PVCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIi8iLCB0LmdldE5hbWUoKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VGFyRmlsZVdpdGhGU1Jvb3QoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlIGYgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKCJ0YWV0ZXN0IiwgIi50YXIiKTsKKyAgICAgICAgZi5kZWxldGVPbkV4aXQoKTsKKyAgICAgICAgVGFyQXJjaGl2ZU91dHB1dFN0cmVhbSB0b3V0ID0gbnVsbDsKKyAgICAgICAgVGFyQXJjaGl2ZUlucHV0U3RyZWFtIHRpbiA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0b3V0ID0gbmV3IFRhckFyY2hpdmVPdXRwdXRTdHJlYW0obmV3IEZpbGVPdXRwdXRTdHJlYW0oZikpOworICAgICAgICAgICAgVGFyQXJjaGl2ZUVudHJ5IHQgPSBuZXcgVGFyQXJjaGl2ZUVudHJ5KG5ldyBGaWxlKFJPT1QpKTsKKyAgICAgICAgICAgIHRvdXQucHV0QXJjaGl2ZUVudHJ5KHQpOworICAgICAgICAgICAgdG91dC5jbG9zZUFyY2hpdmVFbnRyeSgpOworICAgICAgICAgICAgdCA9IG5ldyBUYXJBcmNoaXZlRW50cnkobmV3IEZpbGUobmV3IEZpbGUoUk9PVCksICJmb28udHh0IikpOworICAgICAgICAgICAgdC5zZXRTaXplKDYpOworICAgICAgICAgICAgdG91dC5wdXRBcmNoaXZlRW50cnkodCk7CisgICAgICAgICAgICB0b3V0LndyaXRlKG5ldyBieXRlW10geydoJywgJ2UnLCAnbCcsICdsJywgJ28nLCAnICd9KTsKKyAgICAgICAgICAgIHRvdXQuY2xvc2VBcmNoaXZlRW50cnkoKTsKKyAgICAgICAgICAgIHQgPSBuZXcgVGFyQXJjaGl2ZUVudHJ5KG5ldyBGaWxlKG5ldyBGaWxlKFJPT1QpLCAiYmFyLnR4dCIpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0QWJzb2x1dGVQYXRoKCkpOworICAgICAgICAgICAgdC5zZXRTaXplKDUpOworICAgICAgICAgICAgdG91dC5wdXRBcmNoaXZlRW50cnkodCk7CisgICAgICAgICAgICB0b3V0LndyaXRlKG5ldyBieXRlW10geyd3JywgJ28nLCAncicsICdsJywgJ2QnfSk7CisgICAgICAgICAgICB0b3V0LmNsb3NlQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgICAgICB0ID0gbmV3IFRhckFyY2hpdmVFbnRyeSgiZHVtbXkiKTsKKyAgICAgICAgICAgIHQuc2V0TmFtZShuZXcgRmlsZShuZXcgRmlsZShST09UKSwgImJhei50eHQiKS5nZXRBYnNvbHV0ZVBhdGgoKSk7CisgICAgICAgICAgICB0LnNldFNpemUoMSk7CisgICAgICAgICAgICB0b3V0LnB1dEFyY2hpdmVFbnRyeSh0KTsKKyAgICAgICAgICAgIHRvdXQud3JpdGUobmV3IGJ5dGVbXSB7JyEnfSk7CisgICAgICAgICAgICB0b3V0LmNsb3NlQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgICAgICB0b3V0LmNsb3NlKCk7CisgICAgICAgICAgICB0b3V0ID0gbnVsbDsKKworICAgICAgICAgICAgdGluID0gbmV3IFRhckFyY2hpdmVJbnB1dFN0cmVhbShuZXcgRmlsZUlucHV0U3RyZWFtKGYpKTsKKyAgICAgICAgICAgIC8vdGluLnNldERlYnVnKHRydWUpOworICAgICAgICAgICAgdCA9IHRpbi5nZXROZXh0VGFyRW50cnkoKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwodCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIi8iLCB0LmdldE5hbWUoKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKHQuaXNDaGVja1N1bU9LKCkpOworICAgICAgICAgICAgdCA9IHRpbi5nZXROZXh0VGFyRW50cnkoKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwodCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImZvby50eHQiLCB0LmdldE5hbWUoKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKHQuaXNDaGVja1N1bU9LKCkpOworICAgICAgICAgICAgdCA9IHRpbi5nZXROZXh0VGFyRW50cnkoKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwodCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImJhci50eHQiLCB0LmdldE5hbWUoKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKHQuaXNDaGVja1N1bU9LKCkpOworICAgICAgICAgICAgdCA9IHRpbi5nZXROZXh0VGFyRW50cnkoKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwodCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImJhei50eHQiLCB0LmdldE5hbWUoKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKHQuaXNDaGVja1N1bU9LKCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKHRpbiAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGluLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAodG91dCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgdG91dC5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgQWJzdHJhY3RUZXN0Q2FzZS50cnlIYXJkVG9EZWxldGUoZik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RNYXhGaWxlU2l6ZSgpeworICAgICAgICBmaW5hbCBUYXJBcmNoaXZlRW50cnkgdCA9IG5ldyBUYXJBcmNoaXZlRW50cnkoIiIpOworICAgICAgICB0LnNldFNpemUoMCk7CisgICAgICAgIHQuc2V0U2l6ZSgxKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHQuc2V0U2l6ZSgtMSk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgaGF2ZSBnZW5lcmF0ZWQgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHQuc2V0U2l6ZSgwNzc3Nzc3Nzc3NzdMKTsKKyAgICAgICAgdC5zZXRTaXplKDAxMDAwMDAwMDAwMDBMKTsKKyAgICB9CisKKyAgICBAVGVzdCBwdWJsaWMgdm9pZCB0ZXN0RXh0cmFQYXhIZWFkZXJzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgVGFyQXJjaGl2ZU91dHB1dFN0cmVhbSB0b3MgPSBuZXcgVGFyQXJjaGl2ZU91dHB1dFN0cmVhbShib3MpOworCisgICAgICAgIFRhckFyY2hpdmVFbnRyeSBlbnRyeSA9IG5ldyBUYXJBcmNoaXZlRW50cnkoIi4vd2Vhc2VscyIpOworICAgICAgICBlbnRyeS5hZGRQYXhIZWFkZXIoIkFQQUNIRS5tdXN0ZWxpZGEiLCJ0cnVlIik7CisgICAgICAgIGVudHJ5LmFkZFBheEhlYWRlcigiU0NISUxZLnhhdHRyLnVzZXIub3JnLmFwYWNoZS53ZWFzZWxzIiwibWF4aW11bSB3ZWFzZWxzIik7CisgICAgICAgIGVudHJ5LmFkZFBheEhlYWRlcigic2l6ZSIsIjEiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJleHRyYSBoZWFkZXIgY291bnQiLDIsZW50cnkuZ2V0RXh0cmFQYXhIZWFkZXJzKCkuc2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBUEFDSEUubXVzdGVsaWRhIiwidHJ1ZSIsCisgICAgICAgICAgICBlbnRyeS5nZXRFeHRyYVBheEhlYWRlcigiQVBBQ0hFLm11c3RlbGlkYSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTQ0hJTFkueGF0dHIudXNlci5vcmcuYXBhY2hlLndlYXNlbHMiLCJtYXhpbXVtIHdlYXNlbHMiLAorICAgICAgICAgICAgZW50cnkuZ2V0RXh0cmFQYXhIZWFkZXIoIlNDSElMWS54YXR0ci51c2VyLm9yZy5hcGFjaGUud2Vhc2VscyIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJzaXplIixlbnRyeS5nZXRTaXplKCksMSk7CisKKyAgICAgICAgdG9zLnB1dEFyY2hpdmVFbnRyeShlbnRyeSk7CisgICAgICAgIHRvcy53cml0ZSgnVycpOworICAgICAgICB0b3MuY2xvc2VBcmNoaXZlRW50cnkoKTsKKyAgICAgICAgdG9zLmNsb3NlKCk7CisgICAgICAgIGFzc2VydE5vdEVxdWFscygic2hvdWxkIGhhdmUgZXh0cmEgaGVhZGVycyBiZWZvcmUgY2xlYXIiLDAsZW50cnkuZ2V0RXh0cmFQYXhIZWFkZXJzKCkuc2l6ZSgpKTsKKyAgICAgICAgZW50cnkuY2xlYXJFeHRyYVBheEhlYWRlcnMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJleHRyYSBoZWFkZXJzIHNob3VsZCBiZSBlbXB0eSBhZnRlciBjbGVhciIsMCxlbnRyeS5nZXRFeHRyYVBheEhlYWRlcnMoKS5zaXplKCkpOworICAgICAgICBUYXJBcmNoaXZlSW5wdXRTdHJlYW0gdGlzID0gbmV3IFRhckFyY2hpdmVJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYm9zLnRvQnl0ZUFycmF5KCkpKTsKKyAgICAgICAgZW50cnkgPSB0aXMuZ2V0TmV4dFRhckVudHJ5KCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoImNvdWxkbid0IGdldCBlbnRyeSIsZW50cnkpOworCisgICAgICAgIGFzc2VydEVxdWFscygiZXh0cmEgaGVhZGVyIGNvdW50IiwyLGVudHJ5LmdldEV4dHJhUGF4SGVhZGVycygpLnNpemUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiQVBBQ0hFLm11c3RlbGlkYSIsInRydWUiLAorICAgICAgICAgICAgZW50cnkuZ2V0RXh0cmFQYXhIZWFkZXIoIkFQQUNIRS5tdXN0ZWxpZGEiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygidXNlci5vcmcuYXBhY2hlLndlYXNlbHMiLCJtYXhpbXVtIHdlYXNlbHMiLAorICAgICAgICAgICAgZW50cnkuZ2V0RXh0cmFQYXhIZWFkZXIoIlNDSElMWS54YXR0ci51c2VyLm9yZy5hcGFjaGUud2Vhc2VscyIpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoJ1cnLHRpcy5yZWFkKCkpOworICAgICAgICBhc3NlcnRUcnVlKCJzaG91bGQgYmUgYXQgZW5kIG9mIGVudHJ5Iix0aXMucmVhZCgpIDwwKTsKKworICAgICAgICBhc3NlcnROdWxsKCJzaG91bGQgYmUgYXQgZW5kIG9mIGZpbGUiLHRpcy5nZXROZXh0VGFyRW50cnkoKSk7CisgICAgICAgIHRpcy5jbG9zZSgpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdExpbmtGbGFnQ29uc3RydWN0b3IoKSB7CisgICAgICAgIGZpbmFsIFRhckFyY2hpdmVFbnRyeSB0ID0gbmV3IFRhckFyY2hpdmVFbnRyeSgiL2ZvbyIsIExGX0dOVVRZUEVfTE9OR05BTUUpOworICAgICAgICBhc3NlcnRHbnVNYWdpYyh0KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmb28iLCB0LmdldE5hbWUoKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TGlua0ZsYWdDb25zdHJ1Y3RvcldpdGhGaWxlRmxhZygpIHsKKyAgICAgICAgZmluYWwgVGFyQXJjaGl2ZUVudHJ5IHQgPSBuZXcgVGFyQXJjaGl2ZUVudHJ5KCIvZm9vIiwgTEZfTk9STUFMKTsKKyAgICAgICAgYXNzZXJ0UG9zaXhNYWdpYyh0KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmb28iLCB0LmdldE5hbWUoKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TGlua0ZsYWdDb25zdHJ1Y3RvcldpdGhQcmVzZXJ2ZSgpIHsKKyAgICAgICAgZmluYWwgVGFyQXJjaGl2ZUVudHJ5IHQgPSBuZXcgVGFyQXJjaGl2ZUVudHJ5KCIvZm9vIiwgTEZfR05VVFlQRV9MT05HTkFNRSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUpOworICAgICAgICBhc3NlcnRHbnVNYWdpYyh0KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIvZm9vIiwgdC5nZXROYW1lKCkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgcHJlc2VydmVzRHJpdmVTcGVjT25XaW5kb3dzQW5kTmV0d2FyZUlmQXNrZWRUbygpIHsKKyAgICAgICAgYXNzdW1lVHJ1ZSgiQzpcXCIuZXF1YWxzKFJPT1QpKTsKKyAgICAgICAgVGFyQXJjaGl2ZUVudHJ5IHQgPSBuZXcgVGFyQXJjaGl2ZUVudHJ5KFJPT1QgKyAiZm9vLnR4dCIsIHRydWUpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkM6L2Zvby50eHQiLCB0LmdldE5hbWUoKSk7CisgICAgICAgIHQgPSBuZXcgVGFyQXJjaGl2ZUVudHJ5KFJPT1QgKyAiZm9vLnR4dCIsIExGX0dOVVRZUEVfTE9OR05BTUUsIHRydWUpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkM6L2Zvby50eHQiLCB0LmdldE5hbWUoKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGFzc2VydEdudU1hZ2ljKGZpbmFsIFRhckFyY2hpdmVFbnRyeSB0KSB7CisgICAgICAgIGFzc2VydEVxdWFscyhNQUdJQ19HTlUgKyBWRVJTSU9OX0dOVV9TUEFDRSwgcmVhZE1hZ2ljKHQpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYXNzZXJ0UG9zaXhNYWdpYyhmaW5hbCBUYXJBcmNoaXZlRW50cnkgdCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoTUFHSUNfUE9TSVggKyBWRVJTSU9OX1BPU0lYLCByZWFkTWFnaWModCkpOworICAgIH0KKworICAgIHByaXZhdGUgU3RyaW5nIHJlYWRNYWdpYyhmaW5hbCBUYXJBcmNoaXZlRW50cnkgdCkgeworICAgICAgICBmaW5hbCBieXRlW10gYnVmID0gbmV3IGJ5dGVbNTEyXTsKKyAgICAgICAgdC53cml0ZUVudHJ5SGVhZGVyKGJ1Zik7CisgICAgICAgIHJldHVybiBuZXcgU3RyaW5nKGJ1ZiwgTUFHSUNfT0ZGU0VULCBNQUdJQ0xFTiArIFZFUlNJT05MRU4pOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy90YXIvVGFyQXJjaGl2ZUlucHV0U3RyZWFtVGVzdC5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3Rhci9UYXJBcmNoaXZlSW5wdXRTdHJlYW1UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjdkY2IwNgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy90YXIvVGFyQXJjaGl2ZUlucHV0U3RyZWFtVGVzdC5qYXZhCkBAIC0wLDAgKzEsMzgxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy50YXI7CisKK2ltcG9ydCBzdGF0aWMgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLkFic3RyYWN0VGVzdENhc2UuZ2V0RmlsZTsKK2ltcG9ydCBzdGF0aWMgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLkFic3RyYWN0VGVzdENhc2UubWtkaXI7CitpbXBvcnQgc3RhdGljIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5BYnN0cmFjdFRlc3RDYXNlLnJtZGlyOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEFycmF5RXF1YWxzOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEVxdWFsczsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRGYWxzZTsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnROdWxsOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydFRydWU7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuZmFpbDsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLkNhbGVuZGFyOworaW1wb3J0IGphdmEudXRpbC5EYXRlOworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLlRpbWVab25lOworaW1wb3J0IGphdmEudXRpbC56aXAuR1pJUElucHV0U3RyZWFtOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5BcmNoaXZlRW50cnk7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLkNoYXJzZXROYW1lczsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuSU9VdGlsczsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworcHVibGljIGNsYXNzIFRhckFyY2hpdmVJbnB1dFN0cmVhbVRlc3QgeworCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCByZWFkU2ltcGxlUGF4SGVhZGVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIElucHV0U3RyZWFtIGlzID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKG5ldyBieXRlWzFdKTsKKyAgICAgICAgZmluYWwgVGFyQXJjaGl2ZUlucHV0U3RyZWFtIHRhaXMgPSBuZXcgVGFyQXJjaGl2ZUlucHV0U3RyZWFtKGlzKTsKKyAgICAgICAgZmluYWwgTWFwPFN0cmluZywgU3RyaW5nPiBoZWFkZXJzID0gdGFpcworICAgICAgICAgICAgLnBhcnNlUGF4SGVhZGVycyhuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oIjMwIGF0aW1lPTEzMjE3MTE3NzUuOTcyMDU5NDYzXG4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0Qnl0ZXMoQ2hhcnNldE5hbWVzLlVURl84KSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgaGVhZGVycy5zaXplKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjEzMjE3MTE3NzUuOTcyMDU5NDYzIiwgaGVhZGVycy5nZXQoImF0aW1lIikpOworICAgICAgICB0YWlzLmNsb3NlKCk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBzZWNvbmRFbnRyeVdpbnNXaGVuUGF4SGVhZGVyQ29udGFpbnNEdXBsaWNhdGVLZXkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgSW5wdXRTdHJlYW0gaXMgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0obmV3IGJ5dGVbMV0pOworICAgICAgICBmaW5hbCBUYXJBcmNoaXZlSW5wdXRTdHJlYW0gdGFpcyA9IG5ldyBUYXJBcmNoaXZlSW5wdXRTdHJlYW0oaXMpOworICAgICAgICBmaW5hbCBNYXA8U3RyaW5nLCBTdHJpbmc+IGhlYWRlcnMgPSB0YWlzCisgICAgICAgICAgICAucGFyc2VQYXhIZWFkZXJzKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbSgiMTEgZm9vPWJhclxuMTEgZm9vPWJhelxuIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmdldEJ5dGVzKENoYXJzZXROYW1lcy5VVEZfOCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGhlYWRlcnMuc2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJiYXoiLCBoZWFkZXJzLmdldCgiZm9vIikpOworICAgICAgICB0YWlzLmNsb3NlKCk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBwYXhIZWFkZXJFbnRyeVdpdGhFbXB0eVZhbHVlUmVtb3Zlc0tleSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBJbnB1dFN0cmVhbSBpcyA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShuZXcgYnl0ZVsxXSk7CisgICAgICAgIGZpbmFsIFRhckFyY2hpdmVJbnB1dFN0cmVhbSB0YWlzID0gbmV3IFRhckFyY2hpdmVJbnB1dFN0cmVhbShpcyk7CisgICAgICAgIGZpbmFsIE1hcDxTdHJpbmcsIFN0cmluZz4gaGVhZGVycyA9IHRhaXMKKyAgICAgICAgICAgIC5wYXJzZVBheEhlYWRlcnMobmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKCIxMSBmb289YmFyXG43IGZvbz1cbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRCeXRlcyhDaGFyc2V0TmFtZXMuVVRGXzgpKSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBoZWFkZXJzLnNpemUoKSk7CisgICAgICAgIHRhaXMuY2xvc2UoKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHJlYWRQYXhIZWFkZXJXaXRoRW1iZWRkZWROZXdsaW5lKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIElucHV0U3RyZWFtIGlzID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKG5ldyBieXRlWzFdKTsKKyAgICAgICAgZmluYWwgVGFyQXJjaGl2ZUlucHV0U3RyZWFtIHRhaXMgPSBuZXcgVGFyQXJjaGl2ZUlucHV0U3RyZWFtKGlzKTsKKyAgICAgICAgZmluYWwgTWFwPFN0cmluZywgU3RyaW5nPiBoZWFkZXJzID0gdGFpcworICAgICAgICAgICAgLnBhcnNlUGF4SGVhZGVycyhuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oIjI4IGNvbW1lbnQ9bGluZTFcbmxpbmUyXG5hbmQzXG4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0Qnl0ZXMoQ2hhcnNldE5hbWVzLlVURl84KSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgaGVhZGVycy5zaXplKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImxpbmUxXG5saW5lMlxuYW5kMyIsIGhlYWRlcnMuZ2V0KCJjb21tZW50IikpOworICAgICAgICB0YWlzLmNsb3NlKCk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCByZWFkTm9uQXNjaWlQYXhIZWFkZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgU3RyaW5nIGFlID0gIlx1MDBlNCI7CisgICAgICAgIGZpbmFsIFN0cmluZyBsaW5lID0gIjExIHBhdGg9IisgYWUgKyAiXG4iOworICAgICAgICBhc3NlcnRFcXVhbHMoMTEsIGxpbmUuZ2V0Qnl0ZXMoQ2hhcnNldE5hbWVzLlVURl84KS5sZW5ndGgpOworICAgICAgICBmaW5hbCBJbnB1dFN0cmVhbSBpcyA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShuZXcgYnl0ZVsxXSk7CisgICAgICAgIGZpbmFsIFRhckFyY2hpdmVJbnB1dFN0cmVhbSB0YWlzID0gbmV3IFRhckFyY2hpdmVJbnB1dFN0cmVhbShpcyk7CisgICAgICAgIGZpbmFsIE1hcDxTdHJpbmcsIFN0cmluZz4gaGVhZGVycyA9IHRhaXMKKyAgICAgICAgICAgIC5wYXJzZVBheEhlYWRlcnMobmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGxpbmUuZ2V0Qnl0ZXMoQ2hhcnNldE5hbWVzLlVURl84KSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgaGVhZGVycy5zaXplKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoYWUsIGhlYWRlcnMuZ2V0KCJwYXRoIikpOworICAgICAgICB0YWlzLmNsb3NlKCk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB3b3JrYXJvdW5kRm9yQnJva2VuVGltZUhlYWRlcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBUYXJBcmNoaXZlSW5wdXRTdHJlYW0gaW4gPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW4gPSBuZXcgVGFyQXJjaGl2ZUlucHV0U3RyZWFtKG5ldyBGaWxlSW5wdXRTdHJlYW0oZ2V0RmlsZSgic2ltcGxlLWFpeC1uYXRpdmUtdGFyLnRhciIpKSk7CisgICAgICAgICAgICBUYXJBcmNoaXZlRW50cnkgdGFlID0gaW4uZ2V0TmV4dFRhckVudHJ5KCk7CisgICAgICAgICAgICB0YWUgPSBpbi5nZXROZXh0VGFyRW50cnkoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygic2FtcGxlL2xpbmstdG8tdHh0LWZpbGUubG5rIiwgdGFlLmdldE5hbWUoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMobmV3IERhdGUoMCksIHRhZS5nZXRMYXN0TW9kaWZpZWREYXRlKCkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSh0YWUuaXNTeW1ib2xpY0xpbmsoKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKHRhZS5pc0NoZWNrU3VtT0soKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAoaW4gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGluLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIGRhdGVQcmlvclRvRXBvY2hJbkdOVUZvcm1hdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBkYXRlUHJpb3JUb0Vwb2NoKCJwcmVlcG9jaC1zdGFyLnRhciIpOworICAgIH0KKworCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBkYXRlUHJpb3JUb0Vwb2NoSW5QQVhGb3JtYXQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZGF0ZVByaW9yVG9FcG9jaCgicHJlZXBvY2gtcG9zaXgudGFyIik7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGRhdGVQcmlvclRvRXBvY2goZmluYWwgU3RyaW5nIGFyY2hpdmUpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBUYXJBcmNoaXZlSW5wdXRTdHJlYW0gaW4gPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW4gPSBuZXcgVGFyQXJjaGl2ZUlucHV0U3RyZWFtKG5ldyBGaWxlSW5wdXRTdHJlYW0oZ2V0RmlsZShhcmNoaXZlKSkpOworICAgICAgICAgICAgZmluYWwgVGFyQXJjaGl2ZUVudHJ5IHRhZSA9IGluLmdldE5leHRUYXJFbnRyeSgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJmb28iLCB0YWUuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIGZpbmFsIENhbGVuZGFyIGNhbCA9IENhbGVuZGFyLmdldEluc3RhbmNlKFRpbWVab25lLmdldFRpbWVab25lKCJHTVQiKSk7CisgICAgICAgICAgICBjYWwuc2V0KDE5NjksIDExLCAzMSwgMjMsIDU5LCA1OSk7CisgICAgICAgICAgICBjYWwuc2V0KENhbGVuZGFyLk1JTExJU0VDT05ELCAwKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhjYWwuZ2V0VGltZSgpLCB0YWUuZ2V0TGFzdE1vZGlmaWVkRGF0ZSgpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUodGFlLmlzQ2hlY2tTdW1PSygpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmIChpbiAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdENvbXByZXNzMTk3KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSAoVGFyQXJjaGl2ZUlucHV0U3RyZWFtIHRhciA9IGdldFRlc3RTdHJlYW0oIi9DT01QUkVTUy0xOTcudGFyIikpIHsKKyAgICAgICAgICAgIFRhckFyY2hpdmVFbnRyeSBlbnRyeSA9IHRhci5nZXROZXh0VGFyRW50cnkoKTsKKyAgICAgICAgICAgIHdoaWxlIChlbnRyeSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgZW50cnkgPSB0YXIuZ2V0TmV4dFRhckVudHJ5KCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkNPTVBSRVNTLTE5NzogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgc2hvdWxkVXNlU3BlY2lmaWVkRW5jb2RpbmdXaGVuUmVhZGluZ0dOVUxvbmdOYW1lcygpCisgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICBmaW5hbCBTdHJpbmcgZW5jb2RpbmcgPSBDaGFyc2V0TmFtZXMuVVRGXzE2OworICAgICAgICBmaW5hbCBTdHJpbmcgbmFtZSA9ICIxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5IgorICAgICAgICAgICAgKyAiMDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkiCisgICAgICAgICAgICArICIwMTIzNDU2Nzg5MFx1MDBlNCI7CisgICAgICAgIGZpbmFsIFRhckFyY2hpdmVPdXRwdXRTdHJlYW0gdG9zID0KKyAgICAgICAgICAgIG5ldyBUYXJBcmNoaXZlT3V0cHV0U3RyZWFtKGJvcywgZW5jb2RpbmcpOworICAgICAgICB0b3Muc2V0TG9uZ0ZpbGVNb2RlKFRhckFyY2hpdmVPdXRwdXRTdHJlYW0uTE9OR0ZJTEVfR05VKTsKKyAgICAgICAgVGFyQXJjaGl2ZUVudHJ5IHQgPSBuZXcgVGFyQXJjaGl2ZUVudHJ5KG5hbWUpOworICAgICAgICB0LnNldFNpemUoMSk7CisgICAgICAgIHRvcy5wdXRBcmNoaXZlRW50cnkodCk7CisgICAgICAgIHRvcy53cml0ZSgzMCk7CisgICAgICAgIHRvcy5jbG9zZUFyY2hpdmVFbnRyeSgpOworICAgICAgICB0b3MuY2xvc2UoKTsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGRhdGEgPSBib3MudG9CeXRlQXJyYXkoKTsKKyAgICAgICAgZmluYWwgQnl0ZUFycmF5SW5wdXRTdHJlYW0gYmlzID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGRhdGEpOworICAgICAgICBmaW5hbCBUYXJBcmNoaXZlSW5wdXRTdHJlYW0gdGlzID0KKyAgICAgICAgICAgIG5ldyBUYXJBcmNoaXZlSW5wdXRTdHJlYW0oYmlzLCBlbmNvZGluZyk7CisgICAgICAgIHQgPSB0aXMuZ2V0TmV4dFRhckVudHJ5KCk7CisgICAgICAgIGFzc2VydEVxdWFscyhuYW1lLCB0LmdldE5hbWUoKSk7CisgICAgICAgIHRpcy5jbG9zZSgpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgc2hvdWxkQ29uc3VtZUFyY2hpdmVDb21wbGV0ZWx5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIElucHV0U3RyZWFtIGlzID0gVGFyQXJjaGl2ZUlucHV0U3RyZWFtVGVzdC5jbGFzcworICAgICAgICAgICAgLmdldFJlc291cmNlQXNTdHJlYW0oIi9hcmNoaXZlX3dpdGhfdHJhaWxlci50YXIiKTsKKyAgICAgICAgZmluYWwgVGFyQXJjaGl2ZUlucHV0U3RyZWFtIHRhciA9IG5ldyBUYXJBcmNoaXZlSW5wdXRTdHJlYW0oaXMpOworICAgICAgICB3aGlsZSAodGFyLmdldE5leHRUYXJFbnRyeSgpICE9IG51bGwpIHsKKyAgICAgICAgICAgIC8vIGp1c3QgY29uc3VtZSB0aGUgYXJjaGl2ZQorICAgICAgICB9CisgICAgICAgIGZpbmFsIGJ5dGVbXSBleHBlY3RlZCA9IG5ldyBieXRlW10geworICAgICAgICAgICAgJ0gnLCAnZScsICdsJywgJ2wnLCAnbycsICcsJywgJyAnLCAndycsICdvJywgJ3InLCAnbCcsICdkJywgJyEnLCAnXG4nCisgICAgICAgIH07CisgICAgICAgIGZpbmFsIGJ5dGVbXSBhY3R1YWwgPSBuZXcgYnl0ZVtleHBlY3RlZC5sZW5ndGhdOworICAgICAgICBpcy5yZWFkKGFjdHVhbCk7CisgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKGV4cGVjdGVkLCBhY3R1YWwpOworICAgICAgICB0YXIuY2xvc2UoKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHJlYWRzQXJjaGl2ZUNvbXBsZXRlbHlfQ09NUFJFU1MyNDUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBpcyA9IFRhckFyY2hpdmVJbnB1dFN0cmVhbVRlc3QuY2xhc3MKKyAgICAgICAgICAgICAgICAuZ2V0UmVzb3VyY2VBc1N0cmVhbSgiL0NPTVBSRVNTLTI0NS50YXIuZ3oiKSkgeworICAgICAgICAgICAgZmluYWwgSW5wdXRTdHJlYW0gZ2luID0gbmV3IEdaSVBJbnB1dFN0cmVhbShpcyk7CisgICAgICAgICAgICBmaW5hbCBUYXJBcmNoaXZlSW5wdXRTdHJlYW0gdGFyID0gbmV3IFRhckFyY2hpdmVJbnB1dFN0cmVhbShnaW4pOworICAgICAgICAgICAgaW50IGNvdW50ID0gMDsKKyAgICAgICAgICAgIFRhckFyY2hpdmVFbnRyeSBlbnRyeSA9IHRhci5nZXROZXh0VGFyRW50cnkoKTsKKyAgICAgICAgICAgIHdoaWxlIChlbnRyeSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgY291bnQrKzsKKyAgICAgICAgICAgICAgICBlbnRyeSA9IHRhci5nZXROZXh0VGFyRW50cnkoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydEVxdWFscygzMSwgY291bnQpOworICAgICAgICAgICAgdGFyLmNsb3NlKCk7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkNPTVBSRVNTLTI0NTogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0KGV4cGVjdGVkID0gSU9FeGNlcHRpb24uY2xhc3MpCisgICAgcHVibGljIHZvaWQgc2hvdWxkVGhyb3dBbkV4Y2VwdGlvbk9uVHJ1bmNhdGVkRW50cmllcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlIGRpciA9IG1rZGlyKCJDT01QUkVTUy0yNzkiKTsKKyAgICAgICAgZmluYWwgVGFyQXJjaGl2ZUlucHV0U3RyZWFtIGlzID0gZ2V0VGVzdFN0cmVhbSgiL0NPTVBSRVNTLTI3OS50YXIiKTsKKyAgICAgICAgRmlsZU91dHB1dFN0cmVhbSBvdXQgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgVGFyQXJjaGl2ZUVudHJ5IGVudHJ5ID0gaXMuZ2V0TmV4dFRhckVudHJ5KCk7CisgICAgICAgICAgICBpbnQgY291bnQgPSAwOworICAgICAgICAgICAgd2hpbGUgKGVudHJ5ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBvdXQgPSBuZXcgRmlsZU91dHB1dFN0cmVhbShuZXcgRmlsZShkaXIsIFN0cmluZy52YWx1ZU9mKGNvdW50KSkpOworICAgICAgICAgICAgICAgIElPVXRpbHMuY29weShpcywgb3V0KTsKKyAgICAgICAgICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICBvdXQgPSBudWxsOworICAgICAgICAgICAgICAgIGNvdW50Kys7CisgICAgICAgICAgICAgICAgZW50cnkgPSBpcy5nZXROZXh0VGFyRW50cnkoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlzLmNsb3NlKCk7CisgICAgICAgICAgICBpZiAob3V0ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJtZGlyKGRpcik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHNob3VsZFJlYWRCaWdHaWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgZmluYWwgVGFyQXJjaGl2ZU91dHB1dFN0cmVhbSB0b3MgPSBuZXcgVGFyQXJjaGl2ZU91dHB1dFN0cmVhbShib3MpOworICAgICAgICB0b3Muc2V0QmlnTnVtYmVyTW9kZShUYXJBcmNoaXZlT3V0cHV0U3RyZWFtLkJJR05VTUJFUl9QT1NJWCk7CisgICAgICAgIFRhckFyY2hpdmVFbnRyeSB0ID0gbmV3IFRhckFyY2hpdmVFbnRyeSgibmFtZSIpOworICAgICAgICB0LnNldEdyb3VwSWQoNDI5NDk2NzI5NGwpOworICAgICAgICB0LnNldFNpemUoMSk7CisgICAgICAgIHRvcy5wdXRBcmNoaXZlRW50cnkodCk7CisgICAgICAgIHRvcy53cml0ZSgzMCk7CisgICAgICAgIHRvcy5jbG9zZUFyY2hpdmVFbnRyeSgpOworICAgICAgICB0b3MuY2xvc2UoKTsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGRhdGEgPSBib3MudG9CeXRlQXJyYXkoKTsKKyAgICAgICAgZmluYWwgQnl0ZUFycmF5SW5wdXRTdHJlYW0gYmlzID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGRhdGEpOworICAgICAgICBmaW5hbCBUYXJBcmNoaXZlSW5wdXRTdHJlYW0gdGlzID0KKyAgICAgICAgICAgIG5ldyBUYXJBcmNoaXZlSW5wdXRTdHJlYW0oYmlzKTsKKyAgICAgICAgdCA9IHRpcy5nZXROZXh0VGFyRW50cnkoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDQyOTQ5NjcyOTRsLCB0LmdldExvbmdHcm91cElkKCkpOworICAgICAgICB0aXMuY2xvc2UoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAbGluayAiaHR0cHM6Ly9pc3N1ZXMuYXBhY2hlLm9yZy9qaXJhL2Jyb3dzZS9DT01QUkVTUy0zMjQiCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBzaG91bGRSZWFkR05VTG9uZ05hbWVFbnRyeVdpdGhXcm9uZ05hbWUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IChUYXJBcmNoaXZlSW5wdXRTdHJlYW0gaXMgPSBnZXRUZXN0U3RyZWFtKCIvQ09NUFJFU1MtMzI0LnRhciIpKSB7CisgICAgICAgICAgICBmaW5hbCBUYXJBcmNoaXZlRW50cnkgZW50cnkgPSBpcy5nZXROZXh0VGFyRW50cnkoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MCIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIjEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MC50eHQiLAorICAgICAgICAgICAgICAgICAgICBlbnRyeS5nZXROYW1lKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQGxpbmsgImh0dHBzOi8vaXNzdWVzLmFwYWNoZS5vcmcvamlyYS9icm93c2UvQ09NUFJFU1MtMzU1IgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgc3Vydml2ZXNCbGFua0xpbmVzSW5QYXhIZWFkZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IChUYXJBcmNoaXZlSW5wdXRTdHJlYW0gaXMgPSBnZXRUZXN0U3RyZWFtKCIvQ09NUFJFU1MtMzU1LnRhciIpKSB7CisgICAgICAgICAgICBmaW5hbCBUYXJBcmNoaXZlRW50cnkgZW50cnkgPSBpcy5nZXROZXh0VGFyRW50cnkoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygicGFja2FnZS9wYWNrYWdlLmpzb24iLCBlbnRyeS5nZXROYW1lKCkpOworICAgICAgICAgICAgYXNzZXJ0TnVsbChpcy5nZXROZXh0VGFyRW50cnkoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAbGluayAiaHR0cHM6Ly9pc3N1ZXMuYXBhY2hlLm9yZy9qaXJhL2Jyb3dzZS9DT01QUkVTUy0zNTYiCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBzdXJ2aXZlc1BheEhlYWRlcldpdGhOYW1lRW5kaW5nSW5TbGFzaCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgKFRhckFyY2hpdmVJbnB1dFN0cmVhbSBpcyA9IGdldFRlc3RTdHJlYW0oIi9DT01QUkVTUy0zNTYudGFyIikpIHsKKyAgICAgICAgICAgIGZpbmFsIFRhckFyY2hpdmVFbnRyeSBlbnRyeSA9IGlzLmdldE5leHRUYXJFbnRyeSgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJwYWNrYWdlL3BhY2thZ2UuanNvbiIsIGVudHJ5LmdldE5hbWUoKSk7CisgICAgICAgICAgICBhc3NlcnROdWxsKGlzLmdldE5leHRUYXJFbnRyeSgpKTsKKyAgICAgICAgfQorICAgIH0KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRBbmRTZXRPZlBheEVudHJ5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSAoVGFyQXJjaGl2ZUlucHV0U3RyZWFtIGlzID0gZ2V0VGVzdFN0cmVhbSgiL0NPTVBSRVNTLTM1Ni50YXIiKSkgeworICAgICAgICAgICAgZmluYWwgVGFyQXJjaGl2ZUVudHJ5IGVudHJ5ID0gaXMuZ2V0TmV4dFRhckVudHJ5KCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoInBhY2thZ2UvcGFja2FnZS5qc29uIiwgZW50cnkuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhpcy5nZXRDdXJyZW50RW50cnkoKSxlbnRyeSk7CisgICAgICAgICAgICBUYXJBcmNoaXZlRW50cnkgd2Vhc2VsRW50cnkgPSBuZXcgVGFyQXJjaGl2ZUVudHJ5KGVudHJ5LmdldE5hbWUoKSk7CisgICAgICAgICAgICB3ZWFzZWxFbnRyeS5zZXRTaXplKGVudHJ5LmdldFNpemUoKSk7CisgICAgICAgICAgICBpcy5zZXRDdXJyZW50RW50cnkod2Vhc2VsRW50cnkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGVudHJ5LGlzLmdldEN1cnJlbnRFbnRyeSgpKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGVudHJ5ID09IGlzLmdldEN1cnJlbnRFbnRyeSgpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUod2Vhc2VsRW50cnkgPT0gaXMuZ2V0Q3VycmVudEVudHJ5KCkpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgIGlzLnNldEN1cnJlbnRFbnRyeShudWxsKTsKKyAgICAgICAgICAgICAgIGlzLnJlYWQoKTsKKyAgICAgICAgICAgICAgIGZhaWwoInNob3VsZCBhYm9ydCBiZWNhdXNlIGN1cnJlbnQgZW50cnkgaXMgbnVsbGVkIik7CisgICAgICAgICAgICB9ICBjYXRjaChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgICAgICB9CisgICAgICAgICAgICBpcy5zZXRDdXJyZW50RW50cnkoZW50cnkpOworICAgICAgICAgICAgaXMucmVhZCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQGxpbmsgImh0dHBzOi8vaXNzdWVzLmFwYWNoZS5vcmcvamlyYS9icm93c2UvQ09NUFJFU1MtNDE3IgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgc2tpcHNEZXZOdW1iZXJzV2hlbkVudHJ5SXNOb0RldmljZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgKFRhckFyY2hpdmVJbnB1dFN0cmVhbSBpcyA9IGdldFRlc3RTdHJlYW0oIi9DT01QUkVTUy00MTcudGFyIikpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygidGVzdDEueG1sIiwgaXMuZ2V0TmV4dFRhckVudHJ5KCkuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygidGVzdDIueG1sIiwgaXMuZ2V0TmV4dFRhckVudHJ5KCkuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIGFzc2VydE51bGwoaXMuZ2V0TmV4dFRhckVudHJ5KCkpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBzaW5nbGVCeXRlUmVhZENvbnNpc3RlbnRseVJldHVybnNNaW51c09uZUF0RW9mKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSAoRmlsZUlucHV0U3RyZWFtIGluID0gbmV3IEZpbGVJbnB1dFN0cmVhbShnZXRGaWxlKCJibGEudGFyIikpOworICAgICAgICAgICAgIFRhckFyY2hpdmVJbnB1dFN0cmVhbSBhcmNoaXZlID0gbmV3IFRhckFyY2hpdmVJbnB1dFN0cmVhbShpbikpIHsKKyAgICAgICAgICAgIEFyY2hpdmVFbnRyeSBlID0gYXJjaGl2ZS5nZXROZXh0RW50cnkoKTsKKyAgICAgICAgICAgIElPVXRpbHMudG9CeXRlQXJyYXkoYXJjaGl2ZSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIGFyY2hpdmUucmVhZCgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygtMSwgYXJjaGl2ZS5yZWFkKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBtdWx0aUJ5dGVSZWFkQ29uc2lzdGVudGx5UmV0dXJuc01pbnVzT25lQXRFb2YoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGJ1ZiA9IG5ldyBieXRlWzJdOworICAgICAgICB0cnkgKEZpbGVJbnB1dFN0cmVhbSBpbiA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oZ2V0RmlsZSgiYmxhLnRhciIpKTsKKyAgICAgICAgICAgICBUYXJBcmNoaXZlSW5wdXRTdHJlYW0gYXJjaGl2ZSA9IG5ldyBUYXJBcmNoaXZlSW5wdXRTdHJlYW0oaW4pKSB7CisgICAgICAgICAgICBBcmNoaXZlRW50cnkgZSA9IGFyY2hpdmUuZ2V0TmV4dEVudHJ5KCk7CisgICAgICAgICAgICBJT1V0aWxzLnRvQnl0ZUFycmF5KGFyY2hpdmUpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBhcmNoaXZlLnJlYWQoYnVmKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIGFyY2hpdmUucmVhZChidWYpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgVGFyQXJjaGl2ZUlucHV0U3RyZWFtIGdldFRlc3RTdHJlYW0oZmluYWwgU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBUYXJBcmNoaXZlSW5wdXRTdHJlYW0oCisgICAgICAgICAgICAgICAgVGFyQXJjaGl2ZUlucHV0U3RyZWFtVGVzdC5jbGFzcy5nZXRSZXNvdXJjZUFzU3RyZWFtKG5hbWUpKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy90YXIvVGFyQXJjaGl2ZU91dHB1dFN0cmVhbVRlc3QuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy90YXIvVGFyQXJjaGl2ZU91dHB1dFN0cmVhbVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zYmRmZTlkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3Rhci9UYXJBcmNoaXZlT3V0cHV0U3RyZWFtVGVzdC5qYXZhCkBAIC0wLDAgKzEsNzk3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy50YXI7CisKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRFcXVhbHM7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0RmFsc2U7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0Tm90TnVsbDsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnROdWxsOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydFRydWU7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuZmFpbDsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbVJlYWRlcjsKK2ltcG9ydCBqYXZhLmlvLlJlYWRlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk1lc3NhZ2VEaWdlc3Q7CitpbXBvcnQgamF2YS51dGlsLkNhbGVuZGFyOworaW1wb3J0IGphdmEudXRpbC5EYXRlOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLlRpbWVab25lOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5BYnN0cmFjdFRlc3RDYXNlOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZUVudHJ5OworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLkFyY2hpdmVTdHJlYW1GYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5DaGFyc2V0TmFtZXM7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLklPVXRpbHM7CitpbXBvcnQgb3JnLmp1bml0LkFzc2VydDsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworcHVibGljIGNsYXNzIFRhckFyY2hpdmVPdXRwdXRTdHJlYW1UZXN0IGV4dGVuZHMgQWJzdHJhY3RUZXN0Q2FzZSB7CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RDb3VudCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlIGYgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKCJjb21tb25zLWNvbXByZXNzLXRhcmNvdW50IiwgIi50YXIiKTsKKyAgICAgICAgZi5kZWxldGVPbkV4aXQoKTsKKyAgICAgICAgZmluYWwgRmlsZU91dHB1dFN0cmVhbSBmb3MgPSBuZXcgRmlsZU91dHB1dFN0cmVhbShmKTsKKworICAgICAgICBmaW5hbCBBcmNoaXZlT3V0cHV0U3RyZWFtIHRhck91dCA9IG5ldyBBcmNoaXZlU3RyZWFtRmFjdG9yeSgpCisgICAgICAgICAgICAuY3JlYXRlQXJjaGl2ZU91dHB1dFN0cmVhbShBcmNoaXZlU3RyZWFtRmFjdG9yeS5UQVIsIGZvcyk7CisKKyAgICAgICAgZmluYWwgRmlsZSBmaWxlMSA9IGdldEZpbGUoInRlc3QxLnhtbCIpOworICAgICAgICBmaW5hbCBUYXJBcmNoaXZlRW50cnkgc0VudHJ5ID0gbmV3IFRhckFyY2hpdmVFbnRyeShmaWxlMSwgZmlsZTEuZ2V0TmFtZSgpKTsKKyAgICAgICAgdGFyT3V0LnB1dEFyY2hpdmVFbnRyeShzRW50cnkpOworCisgICAgICAgIGZpbmFsIEZpbGVJbnB1dFN0cmVhbSBpbiA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oZmlsZTEpOworICAgICAgICBmaW5hbCBieXRlW10gYnVmID0gbmV3IGJ5dGVbODE5Ml07CisKKyAgICAgICAgaW50IHJlYWQgPSAwOworICAgICAgICB3aGlsZSAoKHJlYWQgPSBpbi5yZWFkKGJ1ZikpID4gMCkgeworICAgICAgICAgICAgdGFyT3V0LndyaXRlKGJ1ZiwgMCwgcmVhZCk7CisgICAgICAgIH0KKworICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICB0YXJPdXQuY2xvc2VBcmNoaXZlRW50cnkoKTsKKyAgICAgICAgdGFyT3V0LmNsb3NlKCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGYubGVuZ3RoKCksIHRhck91dC5nZXRCeXRlc1dyaXR0ZW4oKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWF4RmlsZVNpemVFcnJvcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBUYXJBcmNoaXZlRW50cnkgdCA9IG5ldyBUYXJBcmNoaXZlRW50cnkoImZvbyIpOworICAgICAgICB0LnNldFNpemUoMDc3Nzc3Nzc3Nzc3TCk7CisgICAgICAgIFRhckFyY2hpdmVPdXRwdXRTdHJlYW0gdG9zID0KKyAgICAgICAgICAgIG5ldyBUYXJBcmNoaXZlT3V0cHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKSk7CisgICAgICAgIHRvcy5wdXRBcmNoaXZlRW50cnkodCk7CisgICAgICAgIHQuc2V0U2l6ZSgwMTAwMDAwMDAwMDAwTCk7CisgICAgICAgIHRvcyA9IG5ldyBUYXJBcmNoaXZlT3V0cHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0b3MucHV0QXJjaGl2ZUVudHJ5KHQpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIGhhdmUgZ2VuZXJhdGVkIFJ1bnRpbWVFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgUnVudGltZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QmlnTnVtYmVyU3Rhck1vZGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgVGFyQXJjaGl2ZUVudHJ5IHQgPSBuZXcgVGFyQXJjaGl2ZUVudHJ5KCJmb28iKTsKKyAgICAgICAgdC5zZXRTaXplKDAxMDAwMDAwMDAwMDBMKTsKKyAgICAgICAgZmluYWwgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgZmluYWwgVGFyQXJjaGl2ZU91dHB1dFN0cmVhbSB0b3MgPSBuZXcgVGFyQXJjaGl2ZU91dHB1dFN0cmVhbShib3MpOworICAgICAgICB0b3Muc2V0QmlnTnVtYmVyTW9kZShUYXJBcmNoaXZlT3V0cHV0U3RyZWFtLkJJR05VTUJFUl9TVEFSKTsKKyAgICAgICAgdG9zLnB1dEFyY2hpdmVFbnRyeSh0KTsKKyAgICAgICAgLy8gbWFrZSBzdXJlIGhlYWRlciBpcyB3cml0dGVuIHRvIGJ5dGUgYXJyYXkKKyAgICAgICAgdG9zLndyaXRlKG5ldyBieXRlWzEwICogMTAyNF0pOworICAgICAgICBmaW5hbCBieXRlW10gZGF0YSA9IGJvcy50b0J5dGVBcnJheSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoMHg4MCwKKyAgICAgICAgICAgIGRhdGFbVGFyQ29uc3RhbnRzLk5BTUVMRU4KKyAgICAgICAgICAgICAgICArIFRhckNvbnN0YW50cy5NT0RFTEVOCisgICAgICAgICAgICAgICAgKyBUYXJDb25zdGFudHMuVUlETEVOCisgICAgICAgICAgICAgICAgKyBUYXJDb25zdGFudHMuR0lETEVOXSAmIDB4ODApOworICAgICAgICBmaW5hbCBUYXJBcmNoaXZlSW5wdXRTdHJlYW0gdGluID0KKyAgICAgICAgICAgIG5ldyBUYXJBcmNoaXZlSW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGRhdGEpKTsKKyAgICAgICAgZmluYWwgVGFyQXJjaGl2ZUVudHJ5IGUgPSB0aW4uZ2V0TmV4dFRhckVudHJ5KCk7CisgICAgICAgIGFzc2VydEVxdWFscygwMTAwMDAwMDAwMDAwTCwgZS5nZXRTaXplKCkpOworICAgICAgICB0aW4uY2xvc2UoKTsKKyAgICAgICAgLy8gZ2VuZXJhdGVzIElPRSBiZWNhdXNlIG9mIHVuY2xvc2VkIGVudHJpZXMuCisgICAgICAgIC8vIEhvd2V2ZXIgd2UgZG9uJ3QgcmVhbGx5IHdhbnQgdG8gY3JlYXRlIHN1Y2ggbGFyZ2UgZW50cmllcy4KKyAgICAgICAgY2xvc2VRdWlldGx5KHRvcyk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QmlnTnVtYmVyUG9zaXhNb2RlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFRhckFyY2hpdmVFbnRyeSB0ID0gbmV3IFRhckFyY2hpdmVFbnRyeSgiZm9vIik7CisgICAgICAgIHQuc2V0U2l6ZSgwMTAwMDAwMDAwMDAwTCk7CisgICAgICAgIGZpbmFsIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBib3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIGZpbmFsIFRhckFyY2hpdmVPdXRwdXRTdHJlYW0gdG9zID0gbmV3IFRhckFyY2hpdmVPdXRwdXRTdHJlYW0oYm9zKTsKKyAgICAgICAgdG9zLnNldEJpZ051bWJlck1vZGUoVGFyQXJjaGl2ZU91dHB1dFN0cmVhbS5CSUdOVU1CRVJfUE9TSVgpOworICAgICAgICB0b3MucHV0QXJjaGl2ZUVudHJ5KHQpOworICAgICAgICAvLyBtYWtlIHN1cmUgaGVhZGVyIGlzIHdyaXR0ZW4gdG8gYnl0ZSBhcnJheQorICAgICAgICB0b3Mud3JpdGUobmV3IGJ5dGVbMTAgKiAxMDI0XSk7CisgICAgICAgIGZpbmFsIGJ5dGVbXSBkYXRhID0gYm9zLnRvQnl0ZUFycmF5KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiMDAwMDAwMDAwMDAgIiwKKyAgICAgICAgICAgIG5ldyBTdHJpbmcoZGF0YSwKKyAgICAgICAgICAgICAgICAxMDI0ICsgVGFyQ29uc3RhbnRzLk5BTUVMRU4KKyAgICAgICAgICAgICAgICAgICAgKyBUYXJDb25zdGFudHMuTU9ERUxFTgorICAgICAgICAgICAgICAgICAgICArIFRhckNvbnN0YW50cy5VSURMRU4KKyAgICAgICAgICAgICAgICAgICAgKyBUYXJDb25zdGFudHMuR0lETEVOLCAxMiwKKyAgICAgICAgICAgICAgICBDaGFyc2V0TmFtZXMuVVRGXzgpKTsKKyAgICAgICAgZmluYWwgVGFyQXJjaGl2ZUlucHV0U3RyZWFtIHRpbiA9CisgICAgICAgICAgICBuZXcgVGFyQXJjaGl2ZUlucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShkYXRhKSk7CisgICAgICAgIGZpbmFsIFRhckFyY2hpdmVFbnRyeSBlID0gdGluLmdldE5leHRUYXJFbnRyeSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoMDEwMDAwMDAwMDAwMEwsIGUuZ2V0U2l6ZSgpKTsKKyAgICAgICAgdGluLmNsb3NlKCk7CisgICAgICAgIC8vIGdlbmVyYXRlcyBJT0UgYmVjYXVzZSBvZiB1bmNsb3NlZCBlbnRyaWVzLgorICAgICAgICAvLyBIb3dldmVyIHdlIGRvbid0IHJlYWxseSB3YW50IHRvIGNyZWF0ZSBzdWNoIGxhcmdlIGVudHJpZXMuCisgICAgICAgIGNsb3NlUXVpZXRseSh0b3MpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFdyaXRlU2ltcGxlUGF4SGVhZGVycygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBNYXA8U3RyaW5nLCBTdHJpbmc+IG0gPSBuZXcgSGFzaE1hcDw+KCk7CisgICAgICAgIG0ucHV0KCJhIiwgImIiKTsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGRhdGEgPSB3cml0ZVBheEhlYWRlcihtKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIwMDAwMDAwMDAwNiAiLAorICAgICAgICAgICAgbmV3IFN0cmluZyhkYXRhLCBUYXJDb25zdGFudHMuTkFNRUxFTgorICAgICAgICAgICAgICAgICsgVGFyQ29uc3RhbnRzLk1PREVMRU4KKyAgICAgICAgICAgICAgICArIFRhckNvbnN0YW50cy5VSURMRU4KKyAgICAgICAgICAgICAgICArIFRhckNvbnN0YW50cy5HSURMRU4sIDEyLAorICAgICAgICAgICAgICAgIENoYXJzZXROYW1lcy5VVEZfOCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjYgYT1iXG4iLCBuZXcgU3RyaW5nKGRhdGEsIDUxMiwgNiwgQ2hhcnNldE5hbWVzLlVURl84KSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UGF4SGVhZGVyc1dpdGhMZW5ndGg5OSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBNYXA8U3RyaW5nLCBTdHJpbmc+IG0gPSBuZXcgSGFzaE1hcDw+KCk7CisgICAgICAgIG0ucHV0KCJhIiwKKyAgICAgICAgICAgICIwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5IgorICAgICAgICAgICAgICAgICsgIjAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5IgorICAgICAgICAgICAgICAgICsgIjAxMiIpOworICAgICAgICBmaW5hbCBieXRlW10gZGF0YSA9IHdyaXRlUGF4SGVhZGVyKG0pOworICAgICAgICBhc3NlcnRFcXVhbHMoIjAwMDAwMDAwMTQzICIsCisgICAgICAgICAgICBuZXcgU3RyaW5nKGRhdGEsIFRhckNvbnN0YW50cy5OQU1FTEVOCisgICAgICAgICAgICAgICAgKyBUYXJDb25zdGFudHMuTU9ERUxFTgorICAgICAgICAgICAgICAgICsgVGFyQ29uc3RhbnRzLlVJRExFTgorICAgICAgICAgICAgICAgICsgVGFyQ29uc3RhbnRzLkdJRExFTiwgMTIsCisgICAgICAgICAgICAgICAgQ2hhcnNldE5hbWVzLlVURl84KSk7CisgICAgICAgIGFzc2VydEVxdWFscygiOTkgYT0wMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5IgorICAgICAgICAgICAgKyAiMDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkiCisgICAgICAgICAgICArICIwMTJcbiIsIG5ldyBTdHJpbmcoZGF0YSwgNTEyLCA5OSwgQ2hhcnNldE5hbWVzLlVURl84KSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UGF4SGVhZGVyc1dpdGhMZW5ndGgxMDEoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgTWFwPFN0cmluZywgU3RyaW5nPiBtID0gbmV3IEhhc2hNYXA8PigpOworICAgICAgICBtLnB1dCgiYSIsCisgICAgICAgICAgICAiMDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OSIKKyAgICAgICAgICAgICAgICArICIwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OSIKKyAgICAgICAgICAgICAgICArICIwMTIzIik7CisgICAgICAgIGZpbmFsIGJ5dGVbXSBkYXRhID0gd3JpdGVQYXhIZWFkZXIobSk7CisgICAgICAgIGFzc2VydEVxdWFscygiMDAwMDAwMDAxNDUgIiwKKyAgICAgICAgICAgIG5ldyBTdHJpbmcoZGF0YSwgVGFyQ29uc3RhbnRzLk5BTUVMRU4KKyAgICAgICAgICAgICAgICArIFRhckNvbnN0YW50cy5NT0RFTEVOCisgICAgICAgICAgICAgICAgKyBUYXJDb25zdGFudHMuVUlETEVOCisgICAgICAgICAgICAgICAgKyBUYXJDb25zdGFudHMuR0lETEVOLCAxMiwKKyAgICAgICAgICAgICAgICBDaGFyc2V0TmFtZXMuVVRGXzgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIxMDEgYT0wMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5IgorICAgICAgICAgICAgKyAiMDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkiCisgICAgICAgICAgICArICIwMTIzXG4iLCBuZXcgU3RyaW5nKGRhdGEsIDUxMiwgMTAxLCBDaGFyc2V0TmFtZXMuVVRGXzgpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIGJ5dGVbXSB3cml0ZVBheEhlYWRlcihmaW5hbCBNYXA8U3RyaW5nLCBTdHJpbmc+IG0pIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICBmaW5hbCBUYXJBcmNoaXZlT3V0cHV0U3RyZWFtIHRvcyA9IG5ldyBUYXJBcmNoaXZlT3V0cHV0U3RyZWFtKGJvcywgIkFTQ0lJIik7CisgICAgICAgIHRvcy53cml0ZVBheEhlYWRlcnMobmV3IFRhckFyY2hpdmVFbnRyeSgieCIpLCAiZm9vIiwgbSk7CisKKyAgICAgICAgLy8gYWRkIGEgZHVtbXkgZW50cnkgc28gZGF0YSBnZXRzIHdyaXR0ZW4KKyAgICAgICAgZmluYWwgVGFyQXJjaGl2ZUVudHJ5IHQgPSBuZXcgVGFyQXJjaGl2ZUVudHJ5KCJmb28iKTsKKyAgICAgICAgdC5zZXRTaXplKDEwICogMTAyNCk7CisgICAgICAgIHRvcy5wdXRBcmNoaXZlRW50cnkodCk7CisgICAgICAgIHRvcy53cml0ZShuZXcgYnl0ZVsxMCAqIDEwMjRdKTsKKyAgICAgICAgdG9zLmNsb3NlQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgIHRvcy5jbG9zZSgpOworCisgICAgICAgIHJldHVybiBib3MudG9CeXRlQXJyYXkoKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RXcml0ZUxvbmdGaWxlTmFtZVBvc2l4TW9kZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBTdHJpbmcgbiA9ICIwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OSIKKyAgICAgICAgICAgICsgIjAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5IgorICAgICAgICAgICAgKyAiMDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkiOworICAgICAgICBmaW5hbCBUYXJBcmNoaXZlRW50cnkgdCA9CisgICAgICAgICAgICBuZXcgVGFyQXJjaGl2ZUVudHJ5KG4pOworICAgICAgICB0LnNldFNpemUoMTAgKiAxMDI0KTsKKyAgICAgICAgZmluYWwgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgZmluYWwgVGFyQXJjaGl2ZU91dHB1dFN0cmVhbSB0b3MgPSBuZXcgVGFyQXJjaGl2ZU91dHB1dFN0cmVhbShib3MsICJBU0NJSSIpOworICAgICAgICB0b3Muc2V0TG9uZ0ZpbGVNb2RlKFRhckFyY2hpdmVPdXRwdXRTdHJlYW0uTE9OR0ZJTEVfUE9TSVgpOworICAgICAgICB0b3MucHV0QXJjaGl2ZUVudHJ5KHQpOworICAgICAgICB0b3Mud3JpdGUobmV3IGJ5dGVbMTAgKiAxMDI0XSk7CisgICAgICAgIHRvcy5jbG9zZUFyY2hpdmVFbnRyeSgpOworICAgICAgICBmaW5hbCBieXRlW10gZGF0YSA9IGJvcy50b0J5dGVBcnJheSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjE2MCBwYXRoPSIgKyBuICsgIlxuIiwKKyAgICAgICAgICAgIG5ldyBTdHJpbmcoZGF0YSwgNTEyLCAxNjAsIENoYXJzZXROYW1lcy5VVEZfOCkpOworICAgICAgICBmaW5hbCBUYXJBcmNoaXZlSW5wdXRTdHJlYW0gdGluID0KKyAgICAgICAgICAgIG5ldyBUYXJBcmNoaXZlSW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGRhdGEpKTsKKyAgICAgICAgZmluYWwgVGFyQXJjaGl2ZUVudHJ5IGUgPSB0aW4uZ2V0TmV4dFRhckVudHJ5KCk7CisgICAgICAgIGFzc2VydEVxdWFscyhuLCBlLmdldE5hbWUoKSk7CisgICAgICAgIHRpbi5jbG9zZSgpOworICAgICAgICB0b3MuY2xvc2UoKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RPbGRFbnRyeVN0YXJNb2RlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFRhckFyY2hpdmVFbnRyeSB0ID0gbmV3IFRhckFyY2hpdmVFbnRyeSgiZm9vIik7CisgICAgICAgIHQuc2V0U2l6ZShJbnRlZ2VyLk1BWF9WQUxVRSk7CisgICAgICAgIHQuc2V0TW9kVGltZSgtMTAwMCk7CisgICAgICAgIGZpbmFsIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBib3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIGZpbmFsIFRhckFyY2hpdmVPdXRwdXRTdHJlYW0gdG9zID0gbmV3IFRhckFyY2hpdmVPdXRwdXRTdHJlYW0oYm9zKTsKKyAgICAgICAgdG9zLnNldEJpZ051bWJlck1vZGUoVGFyQXJjaGl2ZU91dHB1dFN0cmVhbS5CSUdOVU1CRVJfU1RBUik7CisgICAgICAgIHRvcy5wdXRBcmNoaXZlRW50cnkodCk7CisgICAgICAgIC8vIG1ha2Ugc3VyZSBoZWFkZXIgaXMgd3JpdHRlbiB0byBieXRlIGFycmF5CisgICAgICAgIHRvcy53cml0ZShuZXcgYnl0ZVsxMCAqIDEwMjRdKTsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGRhdGEgPSBib3MudG9CeXRlQXJyYXkoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChieXRlKSAweGZmLAorICAgICAgICAgICAgZGF0YVtUYXJDb25zdGFudHMuTkFNRUxFTgorICAgICAgICAgICAgICAgICsgVGFyQ29uc3RhbnRzLk1PREVMRU4KKyAgICAgICAgICAgICAgICArIFRhckNvbnN0YW50cy5VSURMRU4KKyAgICAgICAgICAgICAgICArIFRhckNvbnN0YW50cy5HSURMRU4KKyAgICAgICAgICAgICAgICArIFRhckNvbnN0YW50cy5TSVpFTEVOXSk7CisgICAgICAgIGZpbmFsIFRhckFyY2hpdmVJbnB1dFN0cmVhbSB0aW4gPQorICAgICAgICAgICAgbmV3IFRhckFyY2hpdmVJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oZGF0YSkpOworICAgICAgICBmaW5hbCBUYXJBcmNoaXZlRW50cnkgZSA9IHRpbi5nZXROZXh0VGFyRW50cnkoKTsKKyAgICAgICAgZmluYWwgQ2FsZW5kYXIgY2FsID0gQ2FsZW5kYXIuZ2V0SW5zdGFuY2UoVGltZVpvbmUuZ2V0VGltZVpvbmUoIkdNVCIpKTsKKyAgICAgICAgY2FsLnNldCgxOTY5LCAxMSwgMzEsIDIzLCA1OSwgNTkpOworICAgICAgICBjYWwuc2V0KENhbGVuZGFyLk1JTExJU0VDT05ELCAwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGNhbC5nZXRUaW1lKCksIGUuZ2V0TGFzdE1vZGlmaWVkRGF0ZSgpKTsKKyAgICAgICAgdGluLmNsb3NlKCk7CisgICAgICAgIC8vIGdlbmVyYXRlcyBJT0UgYmVjYXVzZSBvZiB1bmNsb3NlZCBlbnRyaWVzLgorICAgICAgICAvLyBIb3dldmVyIHdlIGRvbid0IHJlYWxseSB3YW50IHRvIGNyZWF0ZSBzdWNoIGxhcmdlIGVudHJpZXMuCisgICAgICAgIGNsb3NlUXVpZXRseSh0b3MpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdE9sZEVudHJ5UG9zaXhNb2RlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFRhckFyY2hpdmVFbnRyeSB0ID0gbmV3IFRhckFyY2hpdmVFbnRyeSgiZm9vIik7CisgICAgICAgIHQuc2V0U2l6ZShJbnRlZ2VyLk1BWF9WQUxVRSk7CisgICAgICAgIHQuc2V0TW9kVGltZSgtMTAwMCk7CisgICAgICAgIGZpbmFsIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBib3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIGZpbmFsIFRhckFyY2hpdmVPdXRwdXRTdHJlYW0gdG9zID0gbmV3IFRhckFyY2hpdmVPdXRwdXRTdHJlYW0oYm9zKTsKKyAgICAgICAgdG9zLnNldEJpZ051bWJlck1vZGUoVGFyQXJjaGl2ZU91dHB1dFN0cmVhbS5CSUdOVU1CRVJfUE9TSVgpOworICAgICAgICB0b3MucHV0QXJjaGl2ZUVudHJ5KHQpOworICAgICAgICAvLyBtYWtlIHN1cmUgaGVhZGVyIGlzIHdyaXR0ZW4gdG8gYnl0ZSBhcnJheQorICAgICAgICB0b3Mud3JpdGUobmV3IGJ5dGVbMTAgKiAxMDI0XSk7CisgICAgICAgIGZpbmFsIGJ5dGVbXSBkYXRhID0gYm9zLnRvQnl0ZUFycmF5KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiMDAwMDAwMDAwMDAgIiwKKyAgICAgICAgICAgIG5ldyBTdHJpbmcoZGF0YSwKKyAgICAgICAgICAgICAgICAxMDI0ICsgVGFyQ29uc3RhbnRzLk5BTUVMRU4KKyAgICAgICAgICAgICAgICAgICAgKyBUYXJDb25zdGFudHMuTU9ERUxFTgorICAgICAgICAgICAgICAgICAgICArIFRhckNvbnN0YW50cy5VSURMRU4KKyAgICAgICAgICAgICAgICAgICAgKyBUYXJDb25zdGFudHMuR0lETEVOCisgICAgICAgICAgICAgICAgICAgICsgVGFyQ29uc3RhbnRzLlNJWkVMRU4sIDEyLAorICAgICAgICAgICAgICAgIENoYXJzZXROYW1lcy5VVEZfOCkpOworICAgICAgICBmaW5hbCBUYXJBcmNoaXZlSW5wdXRTdHJlYW0gdGluID0KKyAgICAgICAgICAgIG5ldyBUYXJBcmNoaXZlSW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGRhdGEpKTsKKyAgICAgICAgZmluYWwgVGFyQXJjaGl2ZUVudHJ5IGUgPSB0aW4uZ2V0TmV4dFRhckVudHJ5KCk7CisgICAgICAgIGZpbmFsIENhbGVuZGFyIGNhbCA9IENhbGVuZGFyLmdldEluc3RhbmNlKFRpbWVab25lLmdldFRpbWVab25lKCJHTVQiKSk7CisgICAgICAgIGNhbC5zZXQoMTk2OSwgMTEsIDMxLCAyMywgNTksIDU5KTsKKyAgICAgICAgY2FsLnNldChDYWxlbmRhci5NSUxMSVNFQ09ORCwgMCk7CisgICAgICAgIGFzc2VydEVxdWFscyhjYWwuZ2V0VGltZSgpLCBlLmdldExhc3RNb2RpZmllZERhdGUoKSk7CisgICAgICAgIHRpbi5jbG9zZSgpOworICAgICAgICAvLyBnZW5lcmF0ZXMgSU9FIGJlY2F1c2Ugb2YgdW5jbG9zZWQgZW50cmllcy4KKyAgICAgICAgLy8gSG93ZXZlciB3ZSBkb24ndCByZWFsbHkgd2FudCB0byBjcmVhdGUgc3VjaCBsYXJnZSBlbnRyaWVzLgorICAgICAgICBjbG9zZVF1aWV0bHkodG9zKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RPbGRFbnRyeUVycm9yKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFRhckFyY2hpdmVFbnRyeSB0ID0gbmV3IFRhckFyY2hpdmVFbnRyeSgiZm9vIik7CisgICAgICAgIHQuc2V0U2l6ZShJbnRlZ2VyLk1BWF9WQUxVRSk7CisgICAgICAgIHQuc2V0TW9kVGltZSgtMTAwMCk7CisgICAgICAgIGZpbmFsIFRhckFyY2hpdmVPdXRwdXRTdHJlYW0gdG9zID0KKyAgICAgICAgICAgIG5ldyBUYXJBcmNoaXZlT3V0cHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0b3MucHV0QXJjaGl2ZUVudHJ5KHQpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIGhhdmUgZ2VuZXJhdGVkIFJ1bnRpbWVFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgUnVudGltZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRvcy5jbG9zZSgpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFdyaXRlTm9uQXNjaWlQYXRoTmFtZVBheEhlYWRlcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBTdHJpbmcgbiA9ICJcdTAwZTQiOworICAgICAgICBmaW5hbCBUYXJBcmNoaXZlRW50cnkgdCA9IG5ldyBUYXJBcmNoaXZlRW50cnkobik7CisgICAgICAgIHQuc2V0U2l6ZSgxMCAqIDEwMjQpOworICAgICAgICBmaW5hbCBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICBmaW5hbCBUYXJBcmNoaXZlT3V0cHV0U3RyZWFtIHRvcyA9IG5ldyBUYXJBcmNoaXZlT3V0cHV0U3RyZWFtKGJvcyk7CisgICAgICAgIHRvcy5zZXRBZGRQYXhIZWFkZXJzRm9yTm9uQXNjaWlOYW1lcyh0cnVlKTsKKyAgICAgICAgdG9zLnB1dEFyY2hpdmVFbnRyeSh0KTsKKyAgICAgICAgdG9zLndyaXRlKG5ldyBieXRlWzEwICogMTAyNF0pOworICAgICAgICB0b3MuY2xvc2VBcmNoaXZlRW50cnkoKTsKKyAgICAgICAgdG9zLmNsb3NlKCk7CisgICAgICAgIGZpbmFsIGJ5dGVbXSBkYXRhID0gYm9zLnRvQnl0ZUFycmF5KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiMTEgcGF0aD0iICsgbiArICJcbiIsCisgICAgICAgICAgICBuZXcgU3RyaW5nKGRhdGEsIDUxMiwgMTEsIENoYXJzZXROYW1lcy5VVEZfOCkpOworICAgICAgICBmaW5hbCBUYXJBcmNoaXZlSW5wdXRTdHJlYW0gdGluID0KKyAgICAgICAgICAgIG5ldyBUYXJBcmNoaXZlSW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGRhdGEpKTsKKyAgICAgICAgZmluYWwgVGFyQXJjaGl2ZUVudHJ5IGUgPSB0aW4uZ2V0TmV4dFRhckVudHJ5KCk7CisgICAgICAgIGFzc2VydEVxdWFscyhuLCBlLmdldE5hbWUoKSk7CisgICAgICAgIHRpbi5jbG9zZSgpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFdyaXRlTm9uQXNjaWlMaW5rUGF0aE5hbWVQYXhIZWFkZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgU3RyaW5nIG4gPSAiXHUwMGU0IjsKKyAgICAgICAgZmluYWwgVGFyQXJjaGl2ZUVudHJ5IHQgPSBuZXcgVGFyQXJjaGl2ZUVudHJ5KCJhIiwgVGFyQ29uc3RhbnRzLkxGX0xJTkspOworICAgICAgICB0LnNldFNpemUoMTAgKiAxMDI0KTsKKyAgICAgICAgdC5zZXRMaW5rTmFtZShuKTsKKyAgICAgICAgZmluYWwgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgZmluYWwgVGFyQXJjaGl2ZU91dHB1dFN0cmVhbSB0b3MgPSBuZXcgVGFyQXJjaGl2ZU91dHB1dFN0cmVhbShib3MpOworICAgICAgICB0b3Muc2V0QWRkUGF4SGVhZGVyc0Zvck5vbkFzY2lpTmFtZXModHJ1ZSk7CisgICAgICAgIHRvcy5wdXRBcmNoaXZlRW50cnkodCk7CisgICAgICAgIHRvcy53cml0ZShuZXcgYnl0ZVsxMCAqIDEwMjRdKTsKKyAgICAgICAgdG9zLmNsb3NlQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgIHRvcy5jbG9zZSgpOworICAgICAgICBmaW5hbCBieXRlW10gZGF0YSA9IGJvcy50b0J5dGVBcnJheSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjE1IGxpbmtwYXRoPSIgKyBuICsgIlxuIiwKKyAgICAgICAgICAgIG5ldyBTdHJpbmcoZGF0YSwgNTEyLCAxNSwgQ2hhcnNldE5hbWVzLlVURl84KSk7CisgICAgICAgIGZpbmFsIFRhckFyY2hpdmVJbnB1dFN0cmVhbSB0aW4gPQorICAgICAgICAgICAgbmV3IFRhckFyY2hpdmVJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oZGF0YSkpOworICAgICAgICBmaW5hbCBUYXJBcmNoaXZlRW50cnkgZSA9IHRpbi5nZXROZXh0VGFyRW50cnkoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG4sIGUuZ2V0TGlua05hbWUoKSk7CisgICAgICAgIHRpbi5jbG9zZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgImh0dHBzOi8vaXNzdWVzLmFwYWNoZS5vcmcvamlyYS9icm93c2UvQ09NUFJFU1MtMjAwIgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFJvdW5kdHJpcFdpdGg2N0NoYXJGaWxlTmFtZUdudSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0Um91bmR0cmlwV2l0aDY3Q2hhckZpbGVOYW1lKFRhckFyY2hpdmVPdXRwdXRTdHJlYW0uTE9OR0ZJTEVfR05VKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlICJodHRwczovL2lzc3Vlcy5hcGFjaGUub3JnL2ppcmEvYnJvd3NlL0NPTVBSRVNTLTIwMCIKKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RSb3VuZHRyaXBXaXRoNjdDaGFyRmlsZU5hbWVQb3NpeCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0Um91bmR0cmlwV2l0aDY3Q2hhckZpbGVOYW1lKFRhckFyY2hpdmVPdXRwdXRTdHJlYW0uTE9OR0ZJTEVfUE9TSVgpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0Um91bmR0cmlwV2l0aDY3Q2hhckZpbGVOYW1lKGZpbmFsIGludCBtb2RlKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgU3RyaW5nIG4gPSAiQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBIgorICAgICAgICAgICAgKyAiQUFBQUFBQSI7CisgICAgICAgIGFzc2VydEVxdWFscyg2Nywgbi5sZW5ndGgoKSk7CisgICAgICAgIGZpbmFsIFRhckFyY2hpdmVFbnRyeSB0ID0gbmV3IFRhckFyY2hpdmVFbnRyeShuKTsKKyAgICAgICAgdC5zZXRTaXplKDEwICogMTAyNCk7CisgICAgICAgIGZpbmFsIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBib3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIGZpbmFsIFRhckFyY2hpdmVPdXRwdXRTdHJlYW0gdG9zID0gbmV3IFRhckFyY2hpdmVPdXRwdXRTdHJlYW0oYm9zLCAiQVNDSUkiKTsKKyAgICAgICAgdG9zLnNldExvbmdGaWxlTW9kZShtb2RlKTsKKyAgICAgICAgdG9zLnB1dEFyY2hpdmVFbnRyeSh0KTsKKyAgICAgICAgdG9zLndyaXRlKG5ldyBieXRlWzEwICogMTAyNF0pOworICAgICAgICB0b3MuY2xvc2VBcmNoaXZlRW50cnkoKTsKKyAgICAgICAgdG9zLmNsb3NlKCk7CisgICAgICAgIGZpbmFsIGJ5dGVbXSBkYXRhID0gYm9zLnRvQnl0ZUFycmF5KCk7CisgICAgICAgIGZpbmFsIFRhckFyY2hpdmVJbnB1dFN0cmVhbSB0aW4gPQorICAgICAgICAgICAgbmV3IFRhckFyY2hpdmVJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oZGF0YSkpOworICAgICAgICBmaW5hbCBUYXJBcmNoaXZlRW50cnkgZSA9IHRpbi5nZXROZXh0VGFyRW50cnkoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG4sIGUuZ2V0TmFtZSgpKTsKKyAgICAgICAgdGluLmNsb3NlKCk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0V3JpdGVMb25nRGlyZWN0b3J5TmFtZUVycm9yTW9kZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBTdHJpbmcgbiA9ICIwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OSIKKyAgICAgICAgICAgICsgIjAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5IgorICAgICAgICAgICAgKyAiMDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkvIjsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmluYWwgVGFyQXJjaGl2ZUVudHJ5IHQgPSBuZXcgVGFyQXJjaGl2ZUVudHJ5KG4pOworICAgICAgICAgICAgZmluYWwgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgICAgIGZpbmFsIFRhckFyY2hpdmVPdXRwdXRTdHJlYW0gdG9zID0gbmV3IFRhckFyY2hpdmVPdXRwdXRTdHJlYW0oYm9zLCAiQVNDSUkiKTsKKyAgICAgICAgICAgIHRvcy5zZXRMb25nRmlsZU1vZGUoVGFyQXJjaGl2ZU91dHB1dFN0cmVhbS5MT05HRklMRV9FUlJPUik7CisgICAgICAgICAgICB0b3MucHV0QXJjaGl2ZUVudHJ5KHQpOworICAgICAgICAgICAgdG9zLmNsb3NlQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgICAgICB0b3MuY2xvc2UoKTsKKworICAgICAgICAgICAgZmFpbCgiVHJ1bmNhdGVkIG5hbWUgZGlkbid0IHRocm93IGFuIGV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChmaW5hbCBSdW50aW1lRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RXcml0ZUxvbmdEaXJlY3RvcnlOYW1lVHJ1bmNhdGVNb2RlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFN0cmluZyBuID0gIjAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5IgorICAgICAgICAgICAgKyAiMDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkiCisgICAgICAgICAgICArICIwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OS8iOworICAgICAgICBmaW5hbCBUYXJBcmNoaXZlRW50cnkgdCA9IG5ldyBUYXJBcmNoaXZlRW50cnkobik7CisgICAgICAgIGZpbmFsIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBib3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIGZpbmFsIFRhckFyY2hpdmVPdXRwdXRTdHJlYW0gdG9zID0gbmV3IFRhckFyY2hpdmVPdXRwdXRTdHJlYW0oYm9zLCAiQVNDSUkiKTsKKyAgICAgICAgdG9zLnNldExvbmdGaWxlTW9kZShUYXJBcmNoaXZlT3V0cHV0U3RyZWFtLkxPTkdGSUxFX1RSVU5DQVRFKTsKKyAgICAgICAgdG9zLnB1dEFyY2hpdmVFbnRyeSh0KTsKKyAgICAgICAgdG9zLmNsb3NlQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgIHRvcy5jbG9zZSgpOworICAgICAgICBmaW5hbCBieXRlW10gZGF0YSA9IGJvcy50b0J5dGVBcnJheSgpOworICAgICAgICBmaW5hbCBUYXJBcmNoaXZlSW5wdXRTdHJlYW0gdGluID0KKyAgICAgICAgICAgIG5ldyBUYXJBcmNoaXZlSW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGRhdGEpKTsKKyAgICAgICAgZmluYWwgVGFyQXJjaGl2ZUVudHJ5IGUgPSB0aW4uZ2V0TmV4dFRhckVudHJ5KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiRW50cnkgbmFtZSIsIG4uc3Vic3RyaW5nKDAsIFRhckNvbnN0YW50cy5OQU1FTEVOKSArICIvIiwgZS5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnRUcnVlKCJUaGUgZW50cnkgaXMgbm90IGEgZGlyZWN0b3J5IiwgZS5pc0RpcmVjdG9yeSgpKTsKKyAgICAgICAgdGluLmNsb3NlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSAiaHR0cHM6Ly9pc3N1ZXMuYXBhY2hlLm9yZy9qaXJhL2Jyb3dzZS9DT01QUkVTUy0yMDMiCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0V3JpdGVMb25nRGlyZWN0b3J5TmFtZUdudU1vZGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdFdyaXRlTG9uZ0RpcmVjdG9yeU5hbWUoVGFyQXJjaGl2ZU91dHB1dFN0cmVhbS5MT05HRklMRV9HTlUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgImh0dHBzOi8vaXNzdWVzLmFwYWNoZS5vcmcvamlyYS9icm93c2UvQ09NUFJFU1MtMjAzIgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFdyaXRlTG9uZ0RpcmVjdG9yeU5hbWVQb3NpeE1vZGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdFdyaXRlTG9uZ0RpcmVjdG9yeU5hbWUoVGFyQXJjaGl2ZU91dHB1dFN0cmVhbS5MT05HRklMRV9QT1NJWCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RXcml0ZUxvbmdEaXJlY3RvcnlOYW1lKGZpbmFsIGludCBtb2RlKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgU3RyaW5nIG4gPSAiMDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkiCisgICAgICAgICAgICArICIwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OSIKKyAgICAgICAgICAgICsgIjAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5LyI7CisgICAgICAgIGZpbmFsIFRhckFyY2hpdmVFbnRyeSB0ID0gbmV3IFRhckFyY2hpdmVFbnRyeShuKTsKKyAgICAgICAgZmluYWwgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgZmluYWwgVGFyQXJjaGl2ZU91dHB1dFN0cmVhbSB0b3MgPSBuZXcgVGFyQXJjaGl2ZU91dHB1dFN0cmVhbShib3MsICJBU0NJSSIpOworICAgICAgICB0b3Muc2V0TG9uZ0ZpbGVNb2RlKG1vZGUpOworICAgICAgICB0b3MucHV0QXJjaGl2ZUVudHJ5KHQpOworICAgICAgICB0b3MuY2xvc2VBcmNoaXZlRW50cnkoKTsKKyAgICAgICAgdG9zLmNsb3NlKCk7CisgICAgICAgIGZpbmFsIGJ5dGVbXSBkYXRhID0gYm9zLnRvQnl0ZUFycmF5KCk7CisgICAgICAgIGZpbmFsIFRhckFyY2hpdmVJbnB1dFN0cmVhbSB0aW4gPQorICAgICAgICAgICAgbmV3IFRhckFyY2hpdmVJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oZGF0YSkpOworICAgICAgICBmaW5hbCBUYXJBcmNoaXZlRW50cnkgZSA9IHRpbi5nZXROZXh0VGFyRW50cnkoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG4sIGUuZ2V0TmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShlLmlzRGlyZWN0b3J5KCkpOworICAgICAgICB0aW4uY2xvc2UoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlICJodHRwczovL2lzc3Vlcy5hcGFjaGUub3JnL2ppcmEvYnJvd3NlL0NPTVBSRVNTLTIwMyIKKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RXcml0ZU5vbkFzY2lpRGlyZWN0b3J5TmFtZVBvc2l4TW9kZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBTdHJpbmcgbiA9ICJmXHUwMGY2XHUwMGY2LyI7CisgICAgICAgIGZpbmFsIFRhckFyY2hpdmVFbnRyeSB0ID0gbmV3IFRhckFyY2hpdmVFbnRyeShuKTsKKyAgICAgICAgZmluYWwgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgZmluYWwgVGFyQXJjaGl2ZU91dHB1dFN0cmVhbSB0b3MgPSBuZXcgVGFyQXJjaGl2ZU91dHB1dFN0cmVhbShib3MpOworICAgICAgICB0b3Muc2V0QWRkUGF4SGVhZGVyc0Zvck5vbkFzY2lpTmFtZXModHJ1ZSk7CisgICAgICAgIHRvcy5wdXRBcmNoaXZlRW50cnkodCk7CisgICAgICAgIHRvcy5jbG9zZUFyY2hpdmVFbnRyeSgpOworICAgICAgICB0b3MuY2xvc2UoKTsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGRhdGEgPSBib3MudG9CeXRlQXJyYXkoKTsKKyAgICAgICAgZmluYWwgVGFyQXJjaGl2ZUlucHV0U3RyZWFtIHRpbiA9CisgICAgICAgICAgICBuZXcgVGFyQXJjaGl2ZUlucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShkYXRhKSk7CisgICAgICAgIGZpbmFsIFRhckFyY2hpdmVFbnRyeSBlID0gdGluLmdldE5leHRUYXJFbnRyeSgpOworICAgICAgICBhc3NlcnRFcXVhbHMobiwgZS5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnRUcnVlKGUuaXNEaXJlY3RvcnkoKSk7CisgICAgICAgIHRpbi5jbG9zZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgImh0dHBzOi8vaXNzdWVzLmFwYWNoZS5vcmcvamlyYS9icm93c2UvQ09NUFJFU1MtMjY1IgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFdyaXRlTm9uQXNjaWlOYW1lV2l0aFVuZm9ydHVuYXRlTmFtZVBvc2l4TW9kZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBTdHJpbmcgbiA9ICJmXHUwMGY2XHUwMGY2XHUwMGRjIjsKKyAgICAgICAgZmluYWwgVGFyQXJjaGl2ZUVudHJ5IHQgPSBuZXcgVGFyQXJjaGl2ZUVudHJ5KG4pOworICAgICAgICBmaW5hbCBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICBmaW5hbCBUYXJBcmNoaXZlT3V0cHV0U3RyZWFtIHRvcyA9IG5ldyBUYXJBcmNoaXZlT3V0cHV0U3RyZWFtKGJvcyk7CisgICAgICAgIHRvcy5zZXRBZGRQYXhIZWFkZXJzRm9yTm9uQXNjaWlOYW1lcyh0cnVlKTsKKyAgICAgICAgdG9zLnB1dEFyY2hpdmVFbnRyeSh0KTsKKyAgICAgICAgdG9zLmNsb3NlQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgIHRvcy5jbG9zZSgpOworICAgICAgICBmaW5hbCBieXRlW10gZGF0YSA9IGJvcy50b0J5dGVBcnJheSgpOworICAgICAgICBmaW5hbCBUYXJBcmNoaXZlSW5wdXRTdHJlYW0gdGluID0KKyAgICAgICAgICAgIG5ldyBUYXJBcmNoaXZlSW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGRhdGEpKTsKKyAgICAgICAgZmluYWwgVGFyQXJjaGl2ZUVudHJ5IGUgPSB0aW4uZ2V0TmV4dFRhckVudHJ5KCk7CisgICAgICAgIGFzc2VydEVxdWFscyhuLCBlLmdldE5hbWUoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGUuaXNEaXJlY3RvcnkoKSk7CisgICAgICAgIHRpbi5jbG9zZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgImh0dHBzOi8vaXNzdWVzLmFwYWNoZS5vcmcvamlyYS9icm93c2UvQ09NUFJFU1MtMjM3IgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFdyaXRlTG9uZ0xpbmtOYW1lRXJyb3JNb2RlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFN0cmluZyBsaW5rbmFtZSA9ICIwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OSIKKyAgICAgICAgICAgICsgIjAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5IgorICAgICAgICAgICAgKyAiMDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkvdGVzdCI7CisgICAgICAgIGZpbmFsIFRhckFyY2hpdmVFbnRyeSBlbnRyeSA9IG5ldyBUYXJBcmNoaXZlRW50cnkoInRlc3QiLCBUYXJDb25zdGFudHMuTEZfU1lNTElOSyk7CisgICAgICAgIGVudHJ5LnNldExpbmtOYW1lKGxpbmtuYW1lKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmluYWwgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgICAgIGZpbmFsIFRhckFyY2hpdmVPdXRwdXRTdHJlYW0gdG9zID0gbmV3IFRhckFyY2hpdmVPdXRwdXRTdHJlYW0oYm9zLCAiQVNDSUkiKTsKKyAgICAgICAgICAgIHRvcy5zZXRMb25nRmlsZU1vZGUoVGFyQXJjaGl2ZU91dHB1dFN0cmVhbS5MT05HRklMRV9FUlJPUik7CisgICAgICAgICAgICB0b3MucHV0QXJjaGl2ZUVudHJ5KGVudHJ5KTsKKyAgICAgICAgICAgIHRvcy5jbG9zZUFyY2hpdmVFbnRyeSgpOworICAgICAgICAgICAgdG9zLmNsb3NlKCk7CisKKyAgICAgICAgICAgIGZhaWwoIlRydW5jYXRlZCBsaW5rIG5hbWUgZGlkbid0IHRocm93IGFuIGV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChmaW5hbCBSdW50aW1lRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RXcml0ZUxvbmdMaW5rTmFtZVRydW5jYXRlTW9kZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBTdHJpbmcgbGlua25hbWUgPSAiMDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkiCisgICAgICAgICAgICArICIwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OSIKKyAgICAgICAgICAgICsgIjAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5LyI7CisgICAgICAgIGZpbmFsIFRhckFyY2hpdmVFbnRyeSBlbnRyeSA9IG5ldyBUYXJBcmNoaXZlRW50cnkoInRlc3QiLCBUYXJDb25zdGFudHMuTEZfU1lNTElOSyk7CisgICAgICAgIGVudHJ5LnNldExpbmtOYW1lKGxpbmtuYW1lKTsKKworICAgICAgICBmaW5hbCBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICBmaW5hbCBUYXJBcmNoaXZlT3V0cHV0U3RyZWFtIHRvcyA9IG5ldyBUYXJBcmNoaXZlT3V0cHV0U3RyZWFtKGJvcywgIkFTQ0lJIik7CisgICAgICAgIHRvcy5zZXRMb25nRmlsZU1vZGUoVGFyQXJjaGl2ZU91dHB1dFN0cmVhbS5MT05HRklMRV9UUlVOQ0FURSk7CisgICAgICAgIHRvcy5wdXRBcmNoaXZlRW50cnkoZW50cnkpOworICAgICAgICB0b3MuY2xvc2VBcmNoaXZlRW50cnkoKTsKKyAgICAgICAgdG9zLmNsb3NlKCk7CisKKyAgICAgICAgZmluYWwgYnl0ZVtdIGRhdGEgPSBib3MudG9CeXRlQXJyYXkoKTsKKyAgICAgICAgZmluYWwgVGFyQXJjaGl2ZUlucHV0U3RyZWFtIHRpbiA9IG5ldyBUYXJBcmNoaXZlSW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGRhdGEpKTsKKyAgICAgICAgZmluYWwgVGFyQXJjaGl2ZUVudHJ5IGUgPSB0aW4uZ2V0TmV4dFRhckVudHJ5KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiTGluayBuYW1lIiwgbGlua25hbWUuc3Vic3RyaW5nKDAsIFRhckNvbnN0YW50cy5OQU1FTEVOKSwgZS5nZXRMaW5rTmFtZSgpKTsKKyAgICAgICAgdGluLmNsb3NlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSAiaHR0cHM6Ly9pc3N1ZXMuYXBhY2hlLm9yZy9qaXJhL2Jyb3dzZS9DT01QUkVTUy0yMzciCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0V3JpdGVMb25nTGlua05hbWVHbnVNb2RlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RXcml0ZUxvbmdMaW5rTmFtZShUYXJBcmNoaXZlT3V0cHV0U3RyZWFtLkxPTkdGSUxFX0dOVSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSAiaHR0cHM6Ly9pc3N1ZXMuYXBhY2hlLm9yZy9qaXJhL2Jyb3dzZS9DT01QUkVTUy0yMzciCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0V3JpdGVMb25nTGlua05hbWVQb3NpeE1vZGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdFdyaXRlTG9uZ0xpbmtOYW1lKFRhckFyY2hpdmVPdXRwdXRTdHJlYW0uTE9OR0ZJTEVfUE9TSVgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgImh0dHBzOi8vaXNzdWVzLmFwYWNoZS5vcmcvamlyYS9icm93c2UvQ09NUFJFU1MtMjM3IgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCB0ZXN0V3JpdGVMb25nTGlua05hbWUoZmluYWwgaW50IG1vZGUpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBTdHJpbmcgbGlua25hbWUgPSAiMDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkiCisgICAgICAgICAgICArICIwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OSIKKyAgICAgICAgICAgICsgIjAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5L3Rlc3QiOworICAgICAgICBmaW5hbCBUYXJBcmNoaXZlRW50cnkgZW50cnkgPSBuZXcgVGFyQXJjaGl2ZUVudHJ5KCJ0ZXN0IiwgVGFyQ29uc3RhbnRzLkxGX1NZTUxJTkspOworICAgICAgICBlbnRyeS5zZXRMaW5rTmFtZShsaW5rbmFtZSk7CisKKyAgICAgICAgZmluYWwgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgZmluYWwgVGFyQXJjaGl2ZU91dHB1dFN0cmVhbSB0b3MgPSBuZXcgVGFyQXJjaGl2ZU91dHB1dFN0cmVhbShib3MsICJBU0NJSSIpOworICAgICAgICB0b3Muc2V0TG9uZ0ZpbGVNb2RlKG1vZGUpOworICAgICAgICB0b3MucHV0QXJjaGl2ZUVudHJ5KGVudHJ5KTsKKyAgICAgICAgdG9zLmNsb3NlQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgIHRvcy5jbG9zZSgpOworCisgICAgICAgIGZpbmFsIGJ5dGVbXSBkYXRhID0gYm9zLnRvQnl0ZUFycmF5KCk7CisgICAgICAgIGZpbmFsIFRhckFyY2hpdmVJbnB1dFN0cmVhbSB0aW4gPSBuZXcgVGFyQXJjaGl2ZUlucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShkYXRhKSk7CisgICAgICAgIGZpbmFsIFRhckFyY2hpdmVFbnRyeSBlID0gdGluLmdldE5leHRUYXJFbnRyeSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkVudHJ5IG5hbWUiLCAidGVzdCIsIGUuZ2V0TmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJMaW5rIG5hbWUiLCBsaW5rbmFtZSwgZS5nZXRMaW5rTmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIGVudHJ5IGlzIG5vdCBhIHN5bWJvbGljIGxpbmsiLCBlLmlzU3ltYm9saWNMaW5rKCkpOworICAgICAgICB0aW4uY2xvc2UoKTsKKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKQorICAgIEBUZXN0IHB1YmxpYyB2b2lkIHRlc3RSZWNvcmRTaXplKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFRhckFyY2hpdmVPdXRwdXRTdHJlYW0gdG9zID0KKyAgICAgICAgICAgICAgICBuZXcgVGFyQXJjaGl2ZU91dHB1dFN0cmVhbShuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCksNTEyLDUxMSk7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgaGF2ZSByZWplY3RlZCByZWNvcmRTaXplIG9mIDUxMSIpOworICAgICAgICB9IGNhdGNoKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZDsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgVGFyQXJjaGl2ZU91dHB1dFN0cmVhbSB0b3MgPQorICAgICAgICAgICAgICAgIG5ldyBUYXJBcmNoaXZlT3V0cHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKSw1MTIsNTExLG51bGwpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIGhhdmUgcmVqZWN0ZWQgcmVjb3JkU2l6ZSBvZiA1MTEiKTsKKyAgICAgICAgfSBjYXRjaChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQ7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IChUYXJBcmNoaXZlT3V0cHV0U3RyZWFtIHRvcyA9IG5ldyBUYXJBcmNoaXZlT3V0cHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKSwKKyAgICAgICAgICAgIDUxMiwgNTEyKSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJyZWNvcmRTaXplIiw1MTIsdG9zLmdldFJlY29yZFNpemUoKSk7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IChUYXJBcmNoaXZlT3V0cHV0U3RyZWFtIHRvcyA9IG5ldyBUYXJBcmNoaXZlT3V0cHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKSwKKyAgICAgICAgICAgIDUxMiwgNTEyLCBudWxsKSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJyZWNvcmRTaXplIiw1MTIsdG9zLmdldFJlY29yZFNpemUoKSk7CisgICAgICAgIH0KKyAgICB9CisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QmxvY2tTaXplcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgZmlsZU5hbWUgPSAiL3Rlc3QxLnhtbCI7CisgICAgICAgIGJ5dGVbXSBjb250ZW50cyA9IGdldFJlc291cmNlQ29udGVudHMoZmlsZU5hbWUpOworICAgICAgICB0ZXN0UGFkZGluZyhUYXJDb25zdGFudHMuREVGQVVMVF9CTEtTSVpFLCBmaWxlTmFtZSwgY29udGVudHMpOyAvLyBVU1RBUiAvIHByZS1wYXgKKyAgICAgICAgdGVzdFBhZGRpbmcoNTEyMCwgZmlsZU5hbWUsIGNvbnRlbnRzKTsgLy8gUEFYIGRlZmF1bHQKKyAgICAgICAgdGVzdFBhZGRpbmcoMTw8MTUsIGZpbGVOYW1lLCBjb250ZW50cyk7IC8vUEFYIG1heAorICAgICAgICB0ZXN0UGFkZGluZygtMiwgZmlsZU5hbWUsIGNvbnRlbnRzKTsgICAgLy8gZG9uJ3Qgc3BlY2lmeSBhIGJsb2NrIHNpemUgLT4gdXNlIG1pbmltdW0gbGVuZ3RoCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0ZXN0UGFkZGluZyg1MTEsIGZpbGVOYW1lLCBjb250ZW50cyk7ICAgIC8vIGRvbid0IHNwZWNpZnkgYSBibG9jayBzaXplIC0+IHVzZSBtaW5pbXVtIGxlbmd0aAorICAgICAgICAgICAgZmFpbCgic2hvdWxkIGhhdmUgdGhyb3duIGFuIGlsbGVnYWwgYXJndW1lbnQgZXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRlc3RQYWRkaW5nKDAsIGZpbGVOYW1lLCBjb250ZW50cyk7ICAgIC8vIGRvbid0IHNwZWNpZnkgYSBibG9jayBzaXplIC0+IHVzZSBtaW5pbXVtIGxlbmd0aAorICAgICAgICAgICAgZmFpbCgic2hvdWxkIGhhdmUgdGhyb3duIGFuIGlsbGVnYWwgYXJndW1lbnQgZXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgLy8gdGVzdCB3aXRoICJjb250ZW50IiB0aGF0IGlzIGFuIGV4YWN0IG11bHRpcGxlIG9mIHJlY29yZCBsZW5ndGgKKyAgICAgICAgY29udGVudHMgPSBuZXcgYnl0ZVsyMDQ4XTsKKyAgICAgICAgamF2YS51dGlsLkFycmF5cy5maWxsKGNvbnRlbnRzLCAoYnl0ZSkgNDIpOworICAgICAgICB0ZXN0UGFkZGluZyhUYXJDb25zdGFudHMuREVGQVVMVF9CTEtTSVpFLCBmaWxlTmFtZSwgY29udGVudHMpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0UGFkZGluZyhpbnQgYmxvY2tTaXplLCBTdHJpbmcgZmlsZU5hbWUsIGJ5dGVbXSBjb250ZW50cykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgRmlsZSBmID0gRmlsZS5jcmVhdGVUZW1wRmlsZSgiY29tbW9ucy1jb21wcmVzcy1wYWRkaW5nIiwgIi50YXIiKTsKKyAgICAgICAgZi5kZWxldGVPbkV4aXQoKTsKKyAgICAgICAgZmluYWwgRmlsZU91dHB1dFN0cmVhbSBmb3MgPSBuZXcgRmlsZU91dHB1dFN0cmVhbShmKTsKKyAgICAgICAgZmluYWwgVGFyQXJjaGl2ZU91dHB1dFN0cmVhbSB0b3M7CisgICAgICAgIGlmIChibG9ja1NpemUgIT0gLTIpIHsKKyAgICAgICAgICAgIHRvcyA9IG5ldyBUYXJBcmNoaXZlT3V0cHV0U3RyZWFtKGZvcywgYmxvY2tTaXplKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGJsb2NrU2l6ZSA9IDUxMjsKKyAgICAgICAgICAgIHRvcyA9IG5ldyBUYXJBcmNoaXZlT3V0cHV0U3RyZWFtKGZvcyk7CisgICAgICAgIH0KKyAgICAgICAgVGFyQXJjaGl2ZUVudHJ5IHNFbnRyeTsKKyAgICAgICAgc0VudHJ5ID0gbmV3IFRhckFyY2hpdmVFbnRyeShmaWxlTmFtZSk7CisgICAgICAgIHNFbnRyeS5zZXRTaXplKGNvbnRlbnRzLmxlbmd0aCk7CisgICAgICAgIHRvcy5wdXRBcmNoaXZlRW50cnkoc0VudHJ5KTsKKyAgICAgICAgdG9zLndyaXRlKGNvbnRlbnRzKTsKKyAgICAgICAgdG9zLmNsb3NlQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgIHRvcy5jbG9zZSgpOworICAgICAgICBpbnQgZmlsZVJlY29yZHNTaXplID0gKGludCkgTWF0aC5jZWlsKChkb3VibGUpIGNvbnRlbnRzLmxlbmd0aCAvIDUxMikgKiA1MTI7CisgICAgICAgIGZpbmFsIGludCBoZWFkZXJTaXplID0gNTEyOworICAgICAgICBmaW5hbCBpbnQgZW5kT2ZBcmNoaXZlU2l6ZSA9IDEwMjQ7CisgICAgICAgIGludCB1bnBhZGRlZFNpemUgPSBoZWFkZXJTaXplICsgZmlsZVJlY29yZHNTaXplICsgZW5kT2ZBcmNoaXZlU2l6ZTsKKyAgICAgICAgaW50IHBhZGRlZFNpemUgPSAoaW50KSBNYXRoLmNlaWwoKGRvdWJsZSl1bnBhZGRlZFNpemUvYmxvY2tTaXplKSpibG9ja1NpemU7CisgICAgICAgIGFzc2VydEVxdWFscyhwYWRkZWRTaXplLCBmLmxlbmd0aCgpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIGJ5dGVbXSBnZXRSZXNvdXJjZUNvbnRlbnRzKFN0cmluZyBuYW1lKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm9zOworICAgICAgICB0cnkgKElucHV0U3RyZWFtIHJlc291cmNlQXNTdHJlYW0gPSBnZXRDbGFzcygpLmdldFJlc291cmNlQXNTdHJlYW0obmFtZSkpIHsKKyAgICAgICAgICAgIGJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgICAgIElPVXRpbHMuY29weShyZXNvdXJjZUFzU3RyZWFtLCBib3MpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBib3MudG9CeXRlQXJyYXkoKTsKKyAgICB9CisgICAgQFRlc3QgcHVibGljIHZvaWQgdGVzdFB1dEdsb2JhbFBheEhlYWRlckVudHJ5KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgVGFyQXJjaGl2ZU91dHB1dFN0cmVhbSB0b3MgPSBuZXcgVGFyQXJjaGl2ZU91dHB1dFN0cmVhbShib3MpOworICAgICAgICBpbnQgcGlkID0gNzM7CisgICAgICAgIGludCBnbG9iQ291bnQgPSAxOworICAgICAgICBieXRlIGxmUGF4R2xvYmFsRXh0ZW5kZWRIZWFkZXIgPSBUYXJDb25zdGFudHMuTEZfUEFYX0dMT0JBTF9FWFRFTkRFRF9IRUFERVI7CisgICAgICAgIFRhckFyY2hpdmVFbnRyeSBnbG9iYWxIZWFkZXIgPSBuZXcgVGFyQXJjaGl2ZUVudHJ5KCIvdG1wL0dsb2JhbEhlYWQuIiArIHBpZCArICIuIiArIGdsb2JDb3VudCwKKyAgICAgICAgICAgIGxmUGF4R2xvYmFsRXh0ZW5kZWRIZWFkZXIpOworICAgICAgICBnbG9iYWxIZWFkZXIuYWRkUGF4SGVhZGVyKCJTQ0hJTExZLnhhdHRyLnVzZXIub3JnLmFwYWNoZS53ZWFzZWxzIiwiZ2xvYmFsLXdlYXNlbHMiKTsKKyAgICAgICAgdG9zLnB1dEFyY2hpdmVFbnRyeShnbG9iYWxIZWFkZXIpOworICAgICAgICBUYXJBcmNoaXZlRW50cnkgZW50cnkgPSBuZXcgVGFyQXJjaGl2ZUVudHJ5KCJtZXNzYWdlIik7CisgICAgICAgIFN0cmluZyB4ID0gIklmIGF0IGZpcnN0IHlvdSBkb24ndCBzdWNjZWVkLCBnaXZlIHVwIjsKKyAgICAgICAgZW50cnkuc2V0U2l6ZSh4Lmxlbmd0aCgpKTsKKyAgICAgICAgdG9zLnB1dEFyY2hpdmVFbnRyeShlbnRyeSk7CisgICAgICAgIHRvcy53cml0ZSh4LmdldEJ5dGVzKCkpOworICAgICAgICB0b3MuY2xvc2VBcmNoaXZlRW50cnkoKTsKKyAgICAgICAgZW50cnkgPSBuZXcgVGFyQXJjaGl2ZUVudHJ5KCJjb3VudGVyLW1lc3NhZ2UiKTsKKyAgICAgICAgU3RyaW5nIHkgPSAiTm90aGluZyBzdWNjZWVkcyBsaWtlIGV4Y2VzcyI7CisgICAgICAgIGVudHJ5LnNldFNpemUoeS5sZW5ndGgoKSk7CisgICAgICAgIGVudHJ5LmFkZFBheEhlYWRlcigiU0NISUxMWS54YXR0ci51c2VyLm9yZy5hcGFjaGUud2Vhc2Vscy5zcGVjaWVzIiwidW5rbm93biIpOworICAgICAgICB0b3MucHV0QXJjaGl2ZUVudHJ5KGVudHJ5KTsKKyAgICAgICAgdG9zLndyaXRlKHkuZ2V0Qnl0ZXMoKSk7CisgICAgICAgIHRvcy5jbG9zZUFyY2hpdmVFbnRyeSgpOworICAgICAgICB0b3MuY2xvc2UoKTsKKyAgICAgICAgVGFyQXJjaGl2ZUlucHV0U3RyZWFtIGluID0gbmV3IFRhckFyY2hpdmVJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYm9zLnRvQnl0ZUFycmF5KCkpKTsKKyAgICAgICAgVGFyQXJjaGl2ZUVudHJ5IGVudHJ5SW4gPSBpbi5nZXROZXh0VGFyRW50cnkoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChlbnRyeUluKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJtZXNzYWdlIixlbnRyeUluLmdldE5hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZ2xvYmFsLXdlYXNlbHMiLGVudHJ5SW4uZ2V0RXh0cmFQYXhIZWFkZXIoIlNDSElMTFkueGF0dHIudXNlci5vcmcuYXBhY2hlLndlYXNlbHMiKSk7CisgICAgICAgIFJlYWRlciByZWFkZXIgPSBuZXcgSW5wdXRTdHJlYW1SZWFkZXIoaW4pOworICAgICAgICBmb3IoaW50IGk9MDtpPHgubGVuZ3RoKCk7aSsrKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoeC5jaGFyQXQoaSkscmVhZGVyLnJlYWQoKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLHJlYWRlci5yZWFkKCkpOworICAgICAgICBlbnRyeUluID0gaW4uZ2V0TmV4dFRhckVudHJ5KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiY291bnRlci1tZXNzYWdlIixlbnRyeUluLmdldE5hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZ2xvYmFsLXdlYXNlbHMiLGVudHJ5SW4uZ2V0RXh0cmFQYXhIZWFkZXIoIlNDSElMTFkueGF0dHIudXNlci5vcmcuYXBhY2hlLndlYXNlbHMiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygidW5rbm93biIsZW50cnlJbi5nZXRFeHRyYVBheEhlYWRlcigiU0NISUxMWS54YXR0ci51c2VyLm9yZy5hcGFjaGUud2Vhc2Vscy5zcGVjaWVzIikpOworICAgICAgICBhc3NlcnROdWxsKGluLmdldE5leHRUYXJFbnRyeSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXaGVuIHVzaW5nIGxvbmcgZmlsZSBuYW1lcyB0aGUgbG9uZ0xpbmtFbnRyeSBpbmNsdWRlZCB0aGUgY3VycmVudCB0aW1lc3RhbXAgYXMgdGhlIEVudHJ5CisgICAgICogbW9kaWZpY2F0aW9uIGRhdGUuIFRoaXMgd2FzIG5ldmVyIGV4cG9zZWQgdG8gdGhlIGNsaWVudCBidXQgaXQgY2F1c2VkIGlkZW50aWNhbCBhcmNoaXZlcyB0bworICAgICAqIGhhdmUgZGlmZmVyZW50IE1ENSBoYXNoZXMuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TG9uZ05hbWVNZDVIYXNoKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFN0cmluZyBsb25nRmlsZU5hbWUgPSAiYS9jb25zaWRlcmFibHkvbG9uZ2VyL2ZpbGUvbmFtZS93aGljaC9mb3JjZXMvdXNlL29mL3RoZS9sb25nL2xpbmsvaGVhZGVyL3doaWNoL2FwcGVhcnMvdG8vYWx3YXlzL3VzZS90aGUvY3VycmVudC90aW1lL2FzL21vZGlmaWNhdGlvbi9kYXRlIjsKKyAgICAgICAgZmluYWwgU3RyaW5nIGZuYW1lID0gbG9uZ0ZpbGVOYW1lOworICAgICAgICBmaW5hbCBEYXRlIG1vZGlmaWNhdGlvbkRhdGUgPSBuZXcgRGF0ZSgpOworCisgICAgICAgIGZpbmFsIGJ5dGVbXSBhcmNoaXZlMSA9IGNyZWF0ZVRhckFyY2hpdmVDb250YWluaW5nT25lRGlyZWN0b3J5KGZuYW1lLCBtb2RpZmljYXRpb25EYXRlKTsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGRpZ2VzdDEgPSBNZXNzYWdlRGlnZXN0LmdldEluc3RhbmNlKCJNRDUiKS5kaWdlc3QoYXJjaGl2ZTEpOworCisgICAgICAgIC8vIGxldCBhIHNlY29uZCBlbGFwc2Ugb3RoZXJ3aXNlIHRoZSBtb2RpZmljYXRpb24gZGF0ZXMgd2lsbCBiZSBlcXVhbAorICAgICAgICBUaHJlYWQuc2xlZXAoMTAwMEwpOworCisgICAgICAgIC8vIG5vdyByZWNyZWF0ZSBleGFjdGx5IHRoZSBzYW1lIHRhciBmaWxlCisgICAgICAgIGZpbmFsIGJ5dGVbXSBhcmNoaXZlMiA9IGNyZWF0ZVRhckFyY2hpdmVDb250YWluaW5nT25lRGlyZWN0b3J5KGZuYW1lLCBtb2RpZmljYXRpb25EYXRlKTsKKyAgICAgICAgLy8gYW5kIEkgd291bGQgZXhwZWN0IHRoZSBNRDUgaGFzaCB0byBiZSB0aGUgc2FtZSwgYnV0IGZvciBsb25nIG5hbWVzIGl0IGlzbid0CisgICAgICAgIGZpbmFsIGJ5dGVbXSBkaWdlc3QyID0gTWVzc2FnZURpZ2VzdC5nZXRJbnN0YW5jZSgiTUQ1IikuZGlnZXN0KGFyY2hpdmUyKTsKKworICAgICAgICBBc3NlcnQuYXNzZXJ0QXJyYXlFcXVhbHMoZGlnZXN0MSwgZGlnZXN0Mik7CisKKyAgICAgICAgLy8gZG8gSSBzdGlsbCBoYXZlIHRoZSBjb3JyZWN0IG1vZGlmaWNhdGlvbiBkYXRlPworICAgICAgICAvLyBsZXQgYSBzZWNvbmQgZWxhcHNlIHNvIHdlIGRvbid0IGdldCB0aGUgY3VycmVudCB0aW1lCisgICAgICAgIFRocmVhZC5zbGVlcCgxMDAwKTsKKyAgICAgICAgZmluYWwgVGFyQXJjaGl2ZUlucHV0U3RyZWFtIHRhckluID0gbmV3IFRhckFyY2hpdmVJbnB1dFN0cmVhbSgKKyAgICAgICAgICAgIG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShhcmNoaXZlMikpOworICAgICAgICBmaW5hbCBBcmNoaXZlRW50cnkgbmV4dEVudHJ5ID0gdGFySW4uZ2V0TmV4dEVudHJ5KCk7CisgICAgICAgIGFzc2VydEVxdWFscyhsb25nRmlsZU5hbWUsIG5leHRFbnRyeS5nZXROYW1lKCkpOworICAgICAgICAvLyB0YXIgYXJjaGl2ZSBzdG9yZXMgbW9kaWZpY2F0aW9uIHRpbWUgdG8gc2Vjb25kIGdyYW51bGFyaXR5IG9ubHkgKGZsb29yZWQpCisgICAgICAgIGFzc2VydEVxdWFscyhtb2RpZmljYXRpb25EYXRlLmdldFRpbWUoKSAvIDEwMDAsCisgICAgICAgICAgICBuZXh0RW50cnkuZ2V0TGFzdE1vZGlmaWVkRGF0ZSgpLmdldFRpbWUoKSAvIDEwMDApOworICAgICAgICB0YXJJbi5jbG9zZSgpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGJ5dGVbXSBjcmVhdGVUYXJBcmNoaXZlQ29udGFpbmluZ09uZURpcmVjdG9yeShmaW5hbCBTdHJpbmcgZm5hbWUsCisgICAgICAgIGZpbmFsIERhdGUgbW9kaWZpY2F0aW9uRGF0ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJhb3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIGZpbmFsIFRhckFyY2hpdmVPdXRwdXRTdHJlYW0gdGFyT3V0ID0gbmV3IFRhckFyY2hpdmVPdXRwdXRTdHJlYW0oYmFvcywgMTAyNCk7CisgICAgICAgIHRhck91dC5zZXRMb25nRmlsZU1vZGUoVGFyQXJjaGl2ZU91dHB1dFN0cmVhbS5MT05HRklMRV9HTlUpOworICAgICAgICBmaW5hbCBUYXJBcmNoaXZlRW50cnkgdGFyRW50cnkgPSBuZXcgVGFyQXJjaGl2ZUVudHJ5KCJkIik7CisgICAgICAgIHRhckVudHJ5LnNldE1vZFRpbWUobW9kaWZpY2F0aW9uRGF0ZSk7CisgICAgICAgIHRhckVudHJ5LnNldE1vZGUoVGFyQXJjaGl2ZUVudHJ5LkRFRkFVTFRfRElSX01PREUpOworICAgICAgICB0YXJFbnRyeS5zZXRNb2RUaW1lKG1vZGlmaWNhdGlvbkRhdGUuZ2V0VGltZSgpKTsKKyAgICAgICAgdGFyRW50cnkuc2V0TmFtZShmbmFtZSk7CisgICAgICAgIHRhck91dC5wdXRBcmNoaXZlRW50cnkodGFyRW50cnkpOworICAgICAgICB0YXJPdXQuY2xvc2VBcmNoaXZlRW50cnkoKTsKKyAgICAgICAgdGFyT3V0LmNsb3NlKCk7CisKKyAgICAgICAgcmV0dXJuIGJhb3MudG9CeXRlQXJyYXkoKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy90YXIvVGFyTGlzdGVyLmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvdGFyL1Rhckxpc3Rlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZkMmEzMmUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvdGFyL1Rhckxpc3Rlci5qYXZhCkBAIC0wLDAgKzEsMTA2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy50YXI7CisKK2ltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CisKKy8qKgorICogU2ltcGxlIGNvbW1hbmQgbGluZSBhcHBsaWNhdGlvbiB0aGF0IGxpc3RzIHRoZSBjb250ZW50cyBvZiBhIHRhciBhcmNoaXZlLgorICoKKyAqIDxwPlRoZSBuYW1lIG9mIHRoZSBhcmNoaXZlIG11c3QgYmUgZ2l2ZW4gYXMgYSBjb21tYW5kIGxpbmUgYXJndW1lbnQuPC9wPgorICogPHA+VGhlIG9wdGlvbmFsIHNlY29uZCBhcmd1bWVudCBzcGVjaWZpZXMgdGhlIGVuY29kaW5nIHRvIGFzc3VtZSBmb3IgZmlsZSBuYW1lcy48L3A+CisgKgorICogQHNpbmNlIDEuMTEKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFRhckxpc3RlciB7CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGFyZ3MubGVuZ3RoID09IDApIHsKKyAgICAgICAgICAgIHVzYWdlKCk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJBbmFseXNpbmcgIiArIGFyZ3NbMF0pOworICAgICAgICBmaW5hbCBGaWxlIGYgPSBuZXcgRmlsZShhcmdzWzBdKTsKKyAgICAgICAgaWYgKCFmLmlzRmlsZSgpKSB7CisgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oZiArICIgZG9lc24ndCBleGlzdCBvciBpcyBhIGRpcmVjdG9yeSIpOworICAgICAgICB9CisgICAgICAgIGZpbmFsIElucHV0U3RyZWFtIGZpcyA9IG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKG5ldyBGaWxlSW5wdXRTdHJlYW0oZikpOworICAgICAgICBUYXJBcmNoaXZlSW5wdXRTdHJlYW0gYWlzOworICAgICAgICBpZiAoYXJncy5sZW5ndGggPiAxKSB7CisgICAgICAgICAgICBhaXMgPSBuZXcgVGFyQXJjaGl2ZUlucHV0U3RyZWFtKGZpcywgYXJnc1sxXSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBhaXMgPSBuZXcgVGFyQXJjaGl2ZUlucHV0U3RyZWFtKGZpcyk7CisgICAgICAgIH0KKyAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJDcmVhdGVkICIgKyBhaXMudG9TdHJpbmcoKSk7CisgICAgICAgIFRhckFyY2hpdmVFbnRyeSBhZTsKKyAgICAgICAgd2hpbGUoKGFlPWFpcy5nZXROZXh0VGFyRW50cnkoKSkgIT0gbnVsbCl7CisgICAgICAgICAgICBsb2coYWUpOworICAgICAgICB9CisgICAgICAgIGFpcy5jbG9zZSgpOworICAgICAgICBmaXMuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHVzYWdlKCkgeworICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlBhcmFtZXRlcnM6IGFyY2hpdmUtbmFtZSBbZW5jb2RpbmddIik7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBsb2coZmluYWwgVGFyQXJjaGl2ZUVudHJ5IGFlKSB7CisgICAgICAgIGZpbmFsIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcihJbnRlZ2VyLnRvT2N0YWxTdHJpbmcoYWUuZ2V0TW9kZSgpKSkKKyAgICAgICAgICAgIC5hcHBlbmQoIiAiKTsKKyAgICAgICAgU3RyaW5nIG5hbWUgPSBhZS5nZXRVc2VyTmFtZSgpOworICAgICAgICBpZiAobmFtZSAhPSBudWxsICYmIG5hbWUubGVuZ3RoKCkgPiAwKSB7CisgICAgICAgICAgICBzYi5hcHBlbmQobmFtZSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBzYi5hcHBlbmQoYWUuZ2V0TG9uZ1VzZXJJZCgpKTsKKyAgICAgICAgfQorICAgICAgICBzYi5hcHBlbmQoIi8iKTsKKyAgICAgICAgbmFtZSA9IGFlLmdldEdyb3VwTmFtZSgpOworICAgICAgICBpZiAobmFtZSAhPSBudWxsICYmIG5hbWUubGVuZ3RoKCkgPiAwKSB7CisgICAgICAgICAgICBzYi5hcHBlbmQobmFtZSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBzYi5hcHBlbmQoYWUuZ2V0TG9uZ0dyb3VwSWQoKSk7CisgICAgICAgIH0KKyAgICAgICAgc2IuYXBwZW5kKCIgIik7CisgICAgICAgIGlmIChhZS5pc1NwYXJzZSgpKSB7CisgICAgICAgICAgICBzYi5hcHBlbmQoYWUuZ2V0UmVhbFNpemUoKSk7CisgICAgICAgIH0gZWxzZSBpZiAoYWUuaXNDaGFyYWN0ZXJEZXZpY2UoKSB8fCBhZS5pc0Jsb2NrRGV2aWNlKCkpIHsKKyAgICAgICAgICAgIHNiLmFwcGVuZChhZS5nZXREZXZNYWpvcigpKS5hcHBlbmQoIiwiKS5hcHBlbmQoYWUuZ2V0RGV2TWlub3IoKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBzYi5hcHBlbmQoYWUuZ2V0U2l6ZSgpKTsKKyAgICAgICAgfQorICAgICAgICBzYi5hcHBlbmQoIiAiKS5hcHBlbmQoYWUuZ2V0TGFzdE1vZGlmaWVkRGF0ZSgpKS5hcHBlbmQoIiAiKTsKKyAgICAgICAgc2IuYXBwZW5kKGFlLmdldE5hbWUoKSk7CisgICAgICAgIGlmIChhZS5pc1N5bWJvbGljTGluaygpIHx8IGFlLmlzTGluaygpKSB7CisgICAgICAgICAgICBpZiAoYWUuaXNTeW1ib2xpY0xpbmsoKSkgeworICAgICAgICAgICAgICAgIHNiLmFwcGVuZCgiIC0+ICIpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBzYi5hcHBlbmQoIiBsaW5rIHRvICIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgc2IuYXBwZW5kKGFlLmdldExpbmtOYW1lKCkpOworICAgICAgICB9CisgICAgICAgIGlmIChhZS5pc1NwYXJzZSgpKSB7CisgICAgICAgICAgICBzYi5hcHBlbmQoIiAoc3BhcnNlKSIpOworICAgICAgICB9CisgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihzYik7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvdGFyL1RhclV0aWxzVGVzdC5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3Rhci9UYXJVdGlsc1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zOTNjMGFhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3Rhci9UYXJVdGlsc1Rlc3QuamF2YQpAQCAtMCwwICsxLDM4NCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnRhcjsKKworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEVxdWFsczsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRGYWxzZTsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUcnVlOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmZhaWw7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcC5aaXBFbmNvZGluZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcC5aaXBFbmNvZGluZ0hlbHBlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuQ2hhcnNldE5hbWVzOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworCitwdWJsaWMgY2xhc3MgVGFyVXRpbHNUZXN0IHsKKworCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TmFtZSgpeworICAgICAgICBieXRlIFtdIGJ1ZmYgPSBuZXcgYnl0ZVsyMF07CisgICAgICAgIGZpbmFsIFN0cmluZyBzYjEgPSAiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoiOworICAgICAgICBpbnQgb2ZmID0gVGFyVXRpbHMuZm9ybWF0TmFtZUJ5dGVzKHNiMSwgYnVmZiwgMSwgYnVmZi5sZW5ndGgtMSk7CisgICAgICAgIGFzc2VydEVxdWFscyhvZmYsIDIwKTsKKyAgICAgICAgU3RyaW5nIHNiMiA9IFRhclV0aWxzLnBhcnNlTmFtZShidWZmLCAxLCAxMCk7CisgICAgICAgIGFzc2VydEVxdWFscyhzYjIsc2IxLnN1YnN0cmluZygwLDEwKSk7CisgICAgICAgIHNiMiA9IFRhclV0aWxzLnBhcnNlTmFtZShidWZmLCAxLCAxOSk7CisgICAgICAgIGFzc2VydEVxdWFscyhzYjIsc2IxLnN1YnN0cmluZygwLDE5KSk7CisgICAgICAgIGJ1ZmYgPSBuZXcgYnl0ZVszMF07CisgICAgICAgIG9mZiA9IFRhclV0aWxzLmZvcm1hdE5hbWVCeXRlcyhzYjEsIGJ1ZmYsIDEsIGJ1ZmYubGVuZ3RoLTEpOworICAgICAgICBhc3NlcnRFcXVhbHMob2ZmLCAzMCk7CisgICAgICAgIHNiMiA9IFRhclV0aWxzLnBhcnNlTmFtZShidWZmLCAxLCBidWZmLmxlbmd0aC0xKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHNiMSwgc2IyKTsKKyAgICAgICAgYnVmZiA9IG5ldyBieXRlW117MCwgMSwgMH07CisgICAgICAgIHNiMiA9IFRhclV0aWxzLnBhcnNlTmFtZShidWZmLCAwLCAzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCBzYjIpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFBhcnNlT2N0YWwoKSB0aHJvd3MgRXhjZXB0aW9ueworICAgICAgICBsb25nIHZhbHVlOworICAgICAgICBieXRlIFtdIGJ1ZmZlcjsKKyAgICAgICAgZmluYWwgbG9uZyBNQVhfT0NUQUwgID0gMDc3Nzc3Nzc3Nzc3TDsgLy8gQWxsb3dlZCAxMSBkaWdpdHMKKyAgICAgICAgZmluYWwgbG9uZyBNQVhfT0NUQUxfT1ZFUkZMT1cgID0gMDc3Nzc3Nzc3Nzc3N0w7IC8vIGluIGZhY3QgMTIgZm9yIHNvbWUgaW1wbGVtZW50YXRpb25zCisgICAgICAgIGZpbmFsIFN0cmluZyBtYXhPY3RhbCA9ICI3Nzc3Nzc3Nzc3NzciOyAvLyBNYXhpbXVtIHZhbGlkIG9jdGFsCisgICAgICAgIGJ1ZmZlciA9IG1heE9jdGFsLmdldEJ5dGVzKENoYXJzZXROYW1lcy5VVEZfOCk7CisgICAgICAgIHZhbHVlID0gVGFyVXRpbHMucGFyc2VPY3RhbChidWZmZXIsMCwgYnVmZmVyLmxlbmd0aCk7CisgICAgICAgIGFzc2VydEVxdWFscyhNQVhfT0NUQUxfT1ZFUkZMT1csIHZhbHVlKTsKKyAgICAgICAgYnVmZmVyW2J1ZmZlci5sZW5ndGggLSAxXSA9ICcgJzsKKyAgICAgICAgdmFsdWUgPSBUYXJVdGlscy5wYXJzZU9jdGFsKGJ1ZmZlciwwLCBidWZmZXIubGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKE1BWF9PQ1RBTCwgdmFsdWUpOworICAgICAgICBidWZmZXJbYnVmZmVyLmxlbmd0aC0xXT0wOworICAgICAgICB2YWx1ZSA9IFRhclV0aWxzLnBhcnNlT2N0YWwoYnVmZmVyLDAsIGJ1ZmZlci5sZW5ndGgpOworICAgICAgICBhc3NlcnRFcXVhbHMoTUFYX09DVEFMLCB2YWx1ZSk7CisgICAgICAgIGJ1ZmZlcj1uZXcgYnl0ZVtdezAsMH07CisgICAgICAgIHZhbHVlID0gVGFyVXRpbHMucGFyc2VPY3RhbChidWZmZXIsMCwgYnVmZmVyLmxlbmd0aCk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCB2YWx1ZSk7CisgICAgICAgIGJ1ZmZlcj1uZXcgYnl0ZVtdezAsJyAnfTsKKyAgICAgICAgdmFsdWUgPSBUYXJVdGlscy5wYXJzZU9jdGFsKGJ1ZmZlciwwLCBidWZmZXIubGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIHZhbHVlKTsKKyAgICAgICAgYnVmZmVyPW5ldyBieXRlW117JyAnLDB9OworICAgICAgICB2YWx1ZSA9IFRhclV0aWxzLnBhcnNlT2N0YWwoYnVmZmVyLDAsIGJ1ZmZlci5sZW5ndGgpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgdmFsdWUpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFBhcnNlT2N0YWxJbnZhbGlkKCkgdGhyb3dzIEV4Y2VwdGlvbnsKKyAgICAgICAgYnl0ZSBbXSBidWZmZXI7CisgICAgICAgIGJ1ZmZlcj1uZXcgYnl0ZVswXTsgLy8gZW1wdHkgYnl0ZSBhcnJheQorICAgICAgICB0cnkgeworICAgICAgICAgICAgVGFyVXRpbHMucGFyc2VPY3RhbChidWZmZXIsMCwgYnVmZmVyLmxlbmd0aCk7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gLSBzaG91bGQgYmUgYXQgbGVhc3QgMiBieXRlcyBsb25nIik7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIGJ1ZmZlcj1uZXcgYnl0ZVtdezB9OyAvLyAxLWJ5dGUgYXJyYXkKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFRhclV0aWxzLnBhcnNlT2N0YWwoYnVmZmVyLDAsIGJ1ZmZlci5sZW5ndGgpOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIC0gc2hvdWxkIGJlIGF0IGxlYXN0IDIgYnl0ZXMgbG9uZyIpOworICAgICAgICB9IGNhdGNoIChmaW5hbCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICBidWZmZXIgPSAiYWJjZGVmICIuZ2V0Qnl0ZXMoQ2hhcnNldE5hbWVzLlVURl84KTsgLy8gSW52YWxpZCBpbnB1dAorICAgICAgICB0cnkgeworICAgICAgICAgICAgVGFyVXRpbHMucGFyc2VPY3RhbChidWZmZXIsMCwgYnVmZmVyLmxlbmd0aCk7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgYnVmZmVyID0gIiAwIDA3ICIuZ2V0Qnl0ZXMoQ2hhcnNldE5hbWVzLlVURl84KTsgLy8gSW52YWxpZCAtIGVtYmVkZGVkIHNwYWNlCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBUYXJVdGlscy5wYXJzZU9jdGFsKGJ1ZmZlciwwLCBidWZmZXIubGVuZ3RoKTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiAtIGVtYmVkZGVkIHNwYWNlIik7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIGJ1ZmZlciA9ICIgMFwwMDAwNyAiLmdldEJ5dGVzKENoYXJzZXROYW1lcy5VVEZfOCk7IC8vIEludmFsaWQgLSBlbWJlZGRlZCBOVUwKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFRhclV0aWxzLnBhcnNlT2N0YWwoYnVmZmVyLDAsIGJ1ZmZlci5sZW5ndGgpOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIC0gZW1iZWRkZWQgTlVMIik7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrUm91bmRUcmlwT2N0YWwoZmluYWwgbG9uZyB2YWx1ZSwgZmluYWwgaW50IGJ1ZnNpemUpIHsKKyAgICAgICAgZmluYWwgYnl0ZSBbXSBidWZmZXIgPSBuZXcgYnl0ZVtidWZzaXplXTsKKyAgICAgICAgbG9uZyBwYXJzZVZhbHVlOworICAgICAgICBUYXJVdGlscy5mb3JtYXRMb25nT2N0YWxCeXRlcyh2YWx1ZSwgYnVmZmVyLCAwLCBidWZmZXIubGVuZ3RoKTsKKyAgICAgICAgcGFyc2VWYWx1ZSA9IFRhclV0aWxzLnBhcnNlT2N0YWwoYnVmZmVyLDAsIGJ1ZmZlci5sZW5ndGgpOworICAgICAgICBhc3NlcnRFcXVhbHModmFsdWUscGFyc2VWYWx1ZSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrUm91bmRUcmlwT2N0YWwoZmluYWwgbG9uZyB2YWx1ZSkgeworICAgICAgICBjaGVja1JvdW5kVHJpcE9jdGFsKHZhbHVlLCBUYXJDb25zdGFudHMuU0laRUxFTik7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Um91bmRUcmlwT2N0YWwoKSB7CisgICAgICAgIGNoZWNrUm91bmRUcmlwT2N0YWwoMCk7CisgICAgICAgIGNoZWNrUm91bmRUcmlwT2N0YWwoMSk7CisvLyAgICAgICAgY2hlY2tSb3VuZFRyaXBPY3RhbCgtMSk7IC8vIFRPRE8gV2hhdCBzaG91bGQgdGhpcyBkbz8KKyAgICAgICAgY2hlY2tSb3VuZFRyaXBPY3RhbChUYXJDb25zdGFudHMuTUFYU0laRSk7CisvLyAgICAgICAgY2hlY2tSb3VuZFRyaXBPY3RhbCgwMTAwMDAwMDAwMDAwTCk7IC8vIFRPRE8gV2hhdCBzaG91bGQgdGhpcyBkbz8KKworICAgICAgICBjaGVja1JvdW5kVHJpcE9jdGFsKDAsIFRhckNvbnN0YW50cy5VSURMRU4pOworICAgICAgICBjaGVja1JvdW5kVHJpcE9jdGFsKDEsIFRhckNvbnN0YW50cy5VSURMRU4pOworICAgICAgICBjaGVja1JvdW5kVHJpcE9jdGFsKFRhckNvbnN0YW50cy5NQVhJRCwgOCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrUm91bmRUcmlwT2N0YWxPckJpbmFyeShmaW5hbCBsb25nIHZhbHVlLCBmaW5hbCBpbnQgYnVmc2l6ZSkgeworICAgICAgICBmaW5hbCBieXRlIFtdIGJ1ZmZlciA9IG5ldyBieXRlW2J1ZnNpemVdOworICAgICAgICBsb25nIHBhcnNlVmFsdWU7CisgICAgICAgIFRhclV0aWxzLmZvcm1hdExvbmdPY3RhbE9yQmluYXJ5Qnl0ZXModmFsdWUsIGJ1ZmZlciwgMCwgYnVmZmVyLmxlbmd0aCk7CisgICAgICAgIHBhcnNlVmFsdWUgPSBUYXJVdGlscy5wYXJzZU9jdGFsT3JCaW5hcnkoYnVmZmVyLDAsIGJ1ZmZlci5sZW5ndGgpOworICAgICAgICBhc3NlcnRFcXVhbHModmFsdWUscGFyc2VWYWx1ZSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Um91bmRUcmlwT2N0YWxPckJpbmFyeTgoKSB7CisgICAgICAgIHRlc3RSb3VuZFRyaXBPY3RhbE9yQmluYXJ5KDgpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFJvdW5kVHJpcE9jdGFsT3JCaW5hcnkxMigpIHsKKyAgICAgICAgdGVzdFJvdW5kVHJpcE9jdGFsT3JCaW5hcnkoMTIpOworICAgICAgICBjaGVja1JvdW5kVHJpcE9jdGFsT3JCaW5hcnkoTG9uZy5NQVhfVkFMVUUsIDEyKTsKKyAgICAgICAgY2hlY2tSb3VuZFRyaXBPY3RhbE9yQmluYXJ5KExvbmcuTUlOX1ZBTFVFICsgMSwgMTIpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0Um91bmRUcmlwT2N0YWxPckJpbmFyeShmaW5hbCBpbnQgbGVuZ3RoKSB7CisgICAgICAgIGNoZWNrUm91bmRUcmlwT2N0YWxPckJpbmFyeSgwLCBsZW5ndGgpOworICAgICAgICBjaGVja1JvdW5kVHJpcE9jdGFsT3JCaW5hcnkoMSwgbGVuZ3RoKTsKKyAgICAgICAgY2hlY2tSb3VuZFRyaXBPY3RhbE9yQmluYXJ5KFRhckNvbnN0YW50cy5NQVhTSVpFLCBsZW5ndGgpOyAvLyB3aWxsIG5lZWQgYmluYXJ5IGZvcm1hdAorICAgICAgICBjaGVja1JvdW5kVHJpcE9jdGFsT3JCaW5hcnkoLTEsIGxlbmd0aCk7IC8vIHdpbGwgbmVlZCBiaW5hcnkgZm9ybWF0CisgICAgICAgIGNoZWNrUm91bmRUcmlwT2N0YWxPckJpbmFyeSgweGZmZmZmZmZmZmZmZmZmbCwgbGVuZ3RoKTsKKyAgICAgICAgY2hlY2tSb3VuZFRyaXBPY3RhbE9yQmluYXJ5KC0weGZmZmZmZmZmZmZmZmZmbCwgbGVuZ3RoKTsKKyAgICB9CisKKyAgICAvLyBDaGVjayBjb3JyZWN0IHRyYWlsaW5nIGJ5dGVzIGFyZSBnZW5lcmF0ZWQKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RUcmFpbGVycygpIHsKKyAgICAgICAgZmluYWwgYnl0ZSBbXSBidWZmZXIgPSBuZXcgYnl0ZVsxMl07CisgICAgICAgIFRhclV0aWxzLmZvcm1hdExvbmdPY3RhbEJ5dGVzKDEyMywgYnVmZmVyLCAwLCBidWZmZXIubGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCcgJywgYnVmZmVyW2J1ZmZlci5sZW5ndGgtMV0pOworICAgICAgICBhc3NlcnRFcXVhbHMoJzMnLCBidWZmZXJbYnVmZmVyLmxlbmd0aC0yXSk7IC8vIGVuZCBvZiBudW1iZXIKKyAgICAgICAgVGFyVXRpbHMuZm9ybWF0T2N0YWxCeXRlcygxMjMsIGJ1ZmZlciwgMCwgYnVmZmVyLmxlbmd0aCk7CisgICAgICAgIGFzc2VydEVxdWFscygwICAsIGJ1ZmZlcltidWZmZXIubGVuZ3RoLTFdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCcgJywgYnVmZmVyW2J1ZmZlci5sZW5ndGgtMl0pOworICAgICAgICBhc3NlcnRFcXVhbHMoJzMnLCBidWZmZXJbYnVmZmVyLmxlbmd0aC0zXSk7IC8vIGVuZCBvZiBudW1iZXIKKyAgICAgICAgVGFyVXRpbHMuZm9ybWF0Q2hlY2tTdW1PY3RhbEJ5dGVzKDEyMywgYnVmZmVyLCAwLCBidWZmZXIubGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCcgJywgYnVmZmVyW2J1ZmZlci5sZW5ndGgtMV0pOworICAgICAgICBhc3NlcnRFcXVhbHMoMCAgLCBidWZmZXJbYnVmZmVyLmxlbmd0aC0yXSk7CisgICAgICAgIGFzc2VydEVxdWFscygnMycsIGJ1ZmZlcltidWZmZXIubGVuZ3RoLTNdKTsgLy8gZW5kIG9mIG51bWJlcgorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdE5lZ2F0aXZlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIGJ5dGUgW10gYnVmZmVyID0gbmV3IGJ5dGVbMjJdOworICAgICAgICBUYXJVdGlscy5mb3JtYXRVbnNpZ25lZE9jdGFsU3RyaW5nKC0xLCBidWZmZXIsIDAsIGJ1ZmZlci5sZW5ndGgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjE3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3NzciLCBuZXcgU3RyaW5nKGJ1ZmZlciwgQ2hhcnNldE5hbWVzLlVURl84KSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0T3ZlcmZsb3coKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgYnl0ZSBbXSBidWZmZXIgPSBuZXcgYnl0ZVs4LTFdOyAvLyBhIGxvdCBvZiB0aGUgbnVtYmVycyBoYXZlIDgtYnl0ZSBidWZmZXJzIChudWwgdGVybSkKKyAgICAgICAgVGFyVXRpbHMuZm9ybWF0VW5zaWduZWRPY3RhbFN0cmluZygwNzc3Nzc3N0wsIGJ1ZmZlciwgMCwgYnVmZmVyLmxlbmd0aCk7CisgICAgICAgIGFzc2VydEVxdWFscygiNzc3Nzc3NyIsIG5ldyBTdHJpbmcoYnVmZmVyLCBDaGFyc2V0TmFtZXMuVVRGXzgpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFRhclV0aWxzLmZvcm1hdFVuc2lnbmVkT2N0YWxTdHJpbmcoMDE3Nzc3Nzc3TCwgYnVmZmVyLCAwLCBidWZmZXIubGVuZ3RoKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCBoYXZlIGNhdXNlIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChmaW5hbCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFJvdW5kVHJpcE5hbWVzKCl7CisgICAgICAgIGNoZWNrTmFtZSgiIik7CisgICAgICAgIGNoZWNrTmFtZSgiVGhlIHF1aWNrIGJyb3duIGZveFxuIik7CisgICAgICAgIGNoZWNrTmFtZSgiXDE3NyIpOworICAgICAgICAvLyBjaGVja05hbWUoIlwwIik7IC8vIGRvZXMgbm90IHdvcmssIGJlY2F1c2UgTlVMIGlzIGlnbm9yZWQKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RSb3VuZEVuY29kaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIENPTVBSRVNTLTExNAorICAgICAgICBmaW5hbCBaaXBFbmNvZGluZyBlbmMgPSBaaXBFbmNvZGluZ0hlbHBlci5nZXRaaXBFbmNvZGluZyhDaGFyc2V0TmFtZXMuSVNPXzg4NTlfMSk7CisgICAgICAgIGZpbmFsIFN0cmluZyBzID0gIjAzMDItMDYwMS0zXHUwMGIxXHUwMGIxXHUwMGIxRjA2XHUwMGIxVzIyMFx1MDBiMVpCXHUwMGIxTEFMQUxBXHUwMGIxXHUwMGIxXHUwMGIxXHUwMGIxXHUwMGIxXHUwMGIxXHUwMGIxXHUwMGIxXHUwMGIxXHUwMGIxQ0FOXHUwMGIxXHUwMGIxRENcdTAwYjFcdTAwYjFcdTAwYjEwNFx1MDBiMTA2MDMwMlx1MDBiMU1PRS5tb2RlbCI7CisgICAgICAgIGZpbmFsIGJ5dGUgYnVmZltdID0gbmV3IGJ5dGVbMTAwXTsKKyAgICAgICAgZmluYWwgaW50IGxlbiA9IFRhclV0aWxzLmZvcm1hdE5hbWVCeXRlcyhzLCBidWZmLCAwLCBidWZmLmxlbmd0aCwgZW5jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHMsIFRhclV0aWxzLnBhcnNlTmFtZShidWZmLCAwLCBsZW4sIGVuYykpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBjaGVja05hbWUoZmluYWwgU3RyaW5nIHN0cmluZykgeworICAgICAgICBmaW5hbCBieXRlIGJ1ZmZbXSA9IG5ldyBieXRlWzEwMF07CisgICAgICAgIGZpbmFsIGludCBsZW4gPSBUYXJVdGlscy5mb3JtYXROYW1lQnl0ZXMoc3RyaW5nLCBidWZmLCAwLCBidWZmLmxlbmd0aCk7CisgICAgICAgIGFzc2VydEVxdWFscyhzdHJpbmcsIFRhclV0aWxzLnBhcnNlTmFtZShidWZmLCAwLCBsZW4pKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RSZWFkTmVnYXRpdmVCaW5hcnk4Qnl0ZSgpIHsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGIgPSBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgIChieXRlKSAweGZmLCAoYnl0ZSkgMHhmZiwgKGJ5dGUpIDB4ZmYsIChieXRlKSAweGZmLAorICAgICAgICAgICAgKGJ5dGUpIDB4ZmYsIChieXRlKSAweGZmLCAoYnl0ZSkgMHhmMSwgKGJ5dGUpIDB4ZWYsCisgICAgICAgIH07CisgICAgICAgIGFzc2VydEVxdWFscygtMzYwMWwsIFRhclV0aWxzLnBhcnNlT2N0YWxPckJpbmFyeShiLCAwLCA4KSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVhZE5lZ2F0aXZlQmluYXJ5MTJCeXRlKCkgeworICAgICAgICBmaW5hbCBieXRlW10gYiA9IG5ldyBieXRlW10geworICAgICAgICAgICAgKGJ5dGUpIDB4ZmYsIChieXRlKSAweGZmLCAoYnl0ZSkgMHhmZiwgKGJ5dGUpIDB4ZmYsCisgICAgICAgICAgICAoYnl0ZSkgMHhmZiwgKGJ5dGUpIDB4ZmYsIChieXRlKSAweGZmLCAoYnl0ZSkgMHhmZiwKKyAgICAgICAgICAgIChieXRlKSAweGZmLCAoYnl0ZSkgMHhmZiwgKGJ5dGUpIDB4ZjEsIChieXRlKSAweGVmLAorICAgICAgICB9OworICAgICAgICBhc3NlcnRFcXVhbHMoLTM2MDFsLCBUYXJVdGlscy5wYXJzZU9jdGFsT3JCaW5hcnkoYiwgMCwgMTIpKTsKKyAgICB9CisKKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFdyaXRlTmVnYXRpdmVCaW5hcnk4Qnl0ZSgpIHsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGIgPSBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgIChieXRlKSAweGZmLCAoYnl0ZSkgMHhmZiwgKGJ5dGUpIDB4ZmYsIChieXRlKSAweGZmLAorICAgICAgICAgICAgKGJ5dGUpIDB4ZmYsIChieXRlKSAweGZmLCAoYnl0ZSkgMHhmMSwgKGJ5dGUpIDB4ZWYsCisgICAgICAgIH07CisgICAgICAgIGFzc2VydEVxdWFscygtMzYwMWwsIFRhclV0aWxzLnBhcnNlT2N0YWxPckJpbmFyeShiLCAwLCA4KSk7CisgICAgfQorCisgICAgLy8gaHR0cHM6Ly9pc3N1ZXMuYXBhY2hlLm9yZy9qaXJhL2Jyb3dzZS9DT01QUkVTUy0xOTEKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RWZXJpZnlIZWFkZXJDaGVja1N1bSgpIHsKKyAgICAgICAgZmluYWwgYnl0ZVtdIHZhbGlkID0geyAvLyBmcm9tIGJsYS50YXIKKyAgICAgICAgICAgICAgICAxMTYsIDEwMSwgMTE1LCAxMTYsIDQ5LCA0NiwgMTIwLCAxMDksIDEwOCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgICAgIDAsIDQ4LCA0OCwgNDgsIDQ4LCA1NCwgNTIsIDUyLCAwLCA0OCwgNDgsIDQ4LCA0OCwgNTUsIDU0LCA1MywKKyAgICAgICAgICAgICAgICAwLCA0OCwgNDgsIDQ4LCA0OCwgNTUsIDU0LCA1MywgMCwgNDgsIDQ4LCA0OCwgNDgsIDQ4LCA0OCwgNDgsCisgICAgICAgICAgICAgICAgNDksIDQ5LCA1MiwgNTAsIDAsIDQ5LCA0OCwgNTUsIDQ5LCA1NCwgNTMsIDUyLCA1MywgNTQsIDUwLCA1NCwKKyAgICAgICAgICAgICAgICAwLCA0OCwgNDksIDUwLCA1MCwgNTQsIDQ4LCAwLCAzMiwgNDgsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAxMTcsIDExNSwgMTE2LCA5NywgMTE0LCAzMiwgMzIsIDAsCisgICAgICAgICAgICAgICAgMTE2LCA5OSwgMTE3LCAxMTQsIDEwMCwgMTE2LCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDExNiwgOTksIDExNywKKyAgICAgICAgICAgICAgICAxMTQsIDEwMCwgMTE2LCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgICAgIDAsIDAsIDAsIDAgfTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShUYXJVdGlscy52ZXJpZnlDaGVja1N1bSh2YWxpZCkpOworCisgICAgICAgIGZpbmFsIGJ5dGVbXSBjb21wcmVzczExNyA9IHsgLy8gZnJvbSBDT01QUkVTUy0xMTcKKyAgICAgICAgICAgIChieXRlKSAweDM3LCAoYnl0ZSkgMHg3YSwgKGJ5dGUpIDB4NDMsIChieXRlKSAweDJlLCAoYnl0ZSkgMHg3NCwgKGJ5dGUpIDB4NzgsIChieXRlKSAweDc0LCAoYnl0ZSkgMHgwMCwKKyAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgIDAsIDAsIDAsIDAsIChieXRlKSAweDMxLCAoYnl0ZSkgMHgzMCwgKGJ5dGUpIDB4MzAsIChieXRlKSAweDM3LAorICAgICAgICAgICAgKGJ5dGUpIDB4MzcsIChieXRlKSAweDM3LCAoYnl0ZSkgMHgyMCwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDIwLCAoYnl0ZSkgMHgyMCwgKGJ5dGUpIDB4MjAsIChieXRlKSAweDIwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MjAsIChieXRlKSAweDMwLCAoYnl0ZSkgMHgyMCwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDIwLCAoYnl0ZSkgMHgyMCwgKGJ5dGUpIDB4MjAsIChieXRlKSAweDIwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MjAsIChieXRlKSAweDMwLCAoYnl0ZSkgMHgyMCwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDIwLCAoYnl0ZSkgMHgyMCwgKGJ5dGUpIDB4MjAsIChieXRlKSAweDIwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MjAsIChieXRlKSAweDIwLCAoYnl0ZSkgMHgzMSwgKGJ5dGUpIDB4MzMsIChieXRlKSAweDMwLCAoYnl0ZSkgMHgzMywgKGJ5dGUpIDB4MzMsIChieXRlKSAweDIwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MzEsIChieXRlKSAweDMxLCAoYnl0ZSkgMHgzMSwgKGJ5dGUpIDB4MzEsIChieXRlKSAweDM1LCAoYnl0ZSkgMHgzMSwgKGJ5dGUpIDB4MzYsIChieXRlKSAweDM2LAorICAgICAgICAgICAgKGJ5dGUpIDB4MzAsIChieXRlKSAweDMxLCAoYnl0ZSkgMHgzNiwgKGJ5dGUpIDB4MjAsIChieXRlKSAweDIwLCAoYnl0ZSkgMHgyMCwgKGJ5dGUpIDB4MzUsIChieXRlKSAweDM0LAorICAgICAgICAgICAgKGJ5dGUpIDB4MzEsIChieXRlKSAweDM3LCAoYnl0ZSkgMHgyMCwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDMwLCAoYnl0ZSkgMHgwMCwgMCwgMCwKKyAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgIH07CisgICAgICAgIGFzc2VydFRydWUoVGFyVXRpbHMudmVyaWZ5Q2hlY2tTdW0oY29tcHJlc3MxMTcpKTsKKworICAgICAgICBmaW5hbCBieXRlW10gaW52YWxpZCA9IHsgLy8gZnJvbSB0aGUgdGVzdEFJRkYuYWlmIGZpbGUgaW4gVGlrYQorICAgICAgICAgICAgICAgIDcwLCA3OSwgODIsIDc3LCAwLCAwLCAxNSwgNDYsIDY1LCA3MywgNzAsIDcwLCA2NywgNzksIDc3LCA3NywKKyAgICAgICAgICAgICAgICAwLCAwLCAwLCAxOCwgMCwgMiwgMCwgMCwgMywgLTY0LCAwLCAxNiwgNjQsIDE0LCAtODQsIDY4LCAwLCAwLAorICAgICAgICAgICAgICAgIDAsIDAsIDAsIDAsIDgzLCA4MywgNzgsIDY4LCAwLCAwLCAxNSwgOCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgICAgICAwLCAwLCAxLCAtMSwgLTEsIDAsIDEsIC0xLCAtMSwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMSwgLTEsIC0xLAorICAgICAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIC0xLCAtMSwgMCwgMiwgLTEsIC0yLCAwLCAyLCAtMSwgLTEsIDAsIDAsIDAsCisgICAgICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMSwgLTEsIC0xLCAwLCAwLCAtMSwgLTEsIDAsIDEsIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAgICAgMCwgMCwgMCwgMSwgLTEsIC0xLCAwLCAxLCAtMSwgLTIsIDAsIDEsIC0xLCAtMSwgMCwgMSwgMCwgMCwgMCwKKyAgICAgICAgICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAtMSwgLTEsIDAsCisgICAgICAgICAgICAgICAgMiwgLTEsIC0yLCAwLCAyLCAtMSwgLTEsIDAsIDAsIDAsIDEsIC0xLCAtMSwgMCwgMSwgLTEsIC0xLCAwLAorICAgICAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDEsIC0xLCAtMiwgMCwgMiwgLTEsIC0yLCAwLCAxLCAwLCAwLAorICAgICAgICAgICAgICAgIDAsIDEsIC0xLCAtMSwgMCwgMCwgMCwgMSwgLTEsIC0xLCAwLCAwLCAwLCAxLCAtMSwgLTIsIDAsIDIsCisgICAgICAgICAgICAgICAgLTEsIC0xLCAwLCAwLCAwLCAwLCAwLCAwLCAtMSwgLTEsIDAsIDEsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgLTEsIC0xLCAwLCAxLCAtMSwgLTEsIDAsIDIsIC0xLCAtMiwKKyAgICAgICAgICAgICAgICAwLCAyLCAtMSwgLTIsIDAsIDIsIC0xLCAtMiwgMCwgMSwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMSwgLTEsCisgICAgICAgICAgICAgICAgLTIsIDAsIDIsIC0xLCAtMiwgMCwgMSwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgICAgICAtMSwgLTEsIDAsIDEsIDAsIDAsIC0xLCAtMSwgMCwgMiwgLTEsIC0yLCAwLCAyLCAtMSwgLTEsIDAsIDAsCisgICAgICAgICAgICAgICAgMCwgMCwgMCwgMCwgLTEsIC0xLCAwLCAxLCAtMSwgLTEsIDAsIDEsIC0xLCAtMSwgMCwgMiwgLTEsIC0yLAorICAgICAgICAgICAgICAgIDAsIDEsIDAsIDAsIC0xLCAtMSwgMCwgMiwgLTEsIC0yLCAwLCAyLCAtMSwgLTIsIDAsIDEsIDAsIDAsIDAsCisgICAgICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMSwgLTEsIC0xLCAwLCAwLCAwLAorICAgICAgICAgICAgICAgIDAsIC0xLCAtMSwgMCwgMSwgMCwgMCwgMCwgMCwgMCwgMSwgLTEsIC0xLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDEsIC0xLCAtMiwgMCwgMiwgLTEsIC0xLCAwLAorICAgICAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDEsIC0xLCAtMiwgMCwgMSwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAxLCAtMSwgLTEsIDAsIDAsIDAsIDAsIC0xLCAtMSwgMCwgMiwgLTEsIC0yLAorICAgICAgICAgICAgICAgIDAsIDIsIC0xLCAtMiwgMCwgMiwgLTEsIC0xLCAwLCAwLCAwLCAwLCAtMSwgLTEsIDAsIDEsIC0xLCAtMSwKKyAgICAgICAgICAgICAgICAwLCAxLCAtMSwgLTEsIDAsIDEsIC0xLCAtMSwgMCwgMSwgLTEsIC0xLCAwLCAxLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgICAgIC0xLCAtMSwgMCwgMiwgLTEsIC0yLCAwLCAxLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgICAgIDEsIC0xLCAtMSwgMCwgMCwgMCwgMCwgLTEsIC0xLCAwLCAxLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDEgfTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoVGFyVXRpbHMudmVyaWZ5Q2hlY2tTdW0oaW52YWxpZCkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFBhcnNlT2N0YWxDb21wcmVzczMzMCgpIHRocm93cyBFeGNlcHRpb257CisgICAgICAgIGZpbmFsIGxvbmcgZXhwZWN0ZWQgPSAwMTAwMDAwOworICAgICAgICBmaW5hbCBieXRlIFtdIGJ1ZmZlciA9IG5ldyBieXRlW10geworICAgICAgICAgICAgMzIsIDMyLCAzMiwgMzIsIDMyLCA0OSwgNDgsIDQ4LCA0OCwgNDgsIDQ4LCAzMgorICAgICAgICB9OworICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWQsIFRhclV0aWxzLnBhcnNlT2N0YWxPckJpbmFyeShidWZmZXIsIDAsIGJ1ZmZlci5sZW5ndGgpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RSb3VuZFRyaXBPY3RhbE9yQmluYXJ5OF9WYWx1ZVRvb0JpZ0ZvckJpbmFyeSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNoZWNrUm91bmRUcmlwT2N0YWxPckJpbmFyeShMb25nLk1BWF9WQUxVRSwgOCk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgZXhjZXB0aW9uIC0gdmFsdWUgaXMgdG9vIGxvbmcgdG8gZml0IGJ1ZmZlciBvZiB0aGlzIGxlbiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJWYWx1ZSA5MjIzMzcyMDM2ODU0Nzc1ODA3IGlzIHRvbyBsYXJnZSBmb3IgOCBieXRlIGZpZWxkLiIsIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9Bc2lFeHRyYUZpZWxkVGVzdC5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9Bc2lFeHRyYUZpZWxkVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg0NDYyM2MKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL0FzaUV4dHJhRmllbGRUZXN0LmphdmEKQEAgLTAsMCArMSwxNjAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcDsKKworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0Lio7CisKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworLyoqCisgKiBKVW5pdCB0ZXN0Y2FzZXMgZm9yIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwLkFzaUV4dHJhRmllbGQuCisgKgorICovCitwdWJsaWMgY2xhc3MgQXNpRXh0cmFGaWVsZFRlc3QgaW1wbGVtZW50cyBVbml4U3RhdCB7CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZpbGUgbW9kZSBtYWdpYy4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RNb2RlcygpIHsKKyAgICAgICAgZmluYWwgQXNpRXh0cmFGaWVsZCBhID0gbmV3IEFzaUV4dHJhRmllbGQoKTsKKyAgICAgICAgYS5zZXRNb2RlKDAxMjMpOworICAgICAgICBhc3NlcnRFcXVhbHMoInBsYWluIGZpbGUiLCAwMTAwMTIzLCBhLmdldE1vZGUoKSk7CisgICAgICAgIGEuc2V0RGlyZWN0b3J5KHRydWUpOworICAgICAgICBhc3NlcnRFcXVhbHMoImRpcmVjdG9yeSIsIDA0MDEyMywgYS5nZXRNb2RlKCkpOworICAgICAgICBhLnNldExpbmtlZEZpbGUoInRlc3QiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJzeW1ib2xpYyBsaW5rIiwgMDEyMDEyMywgYS5nZXRNb2RlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgY29udGVudC4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RDb250ZW50KCkgeworICAgICAgICBmaW5hbCBBc2lFeHRyYUZpZWxkIGEgPSBuZXcgQXNpRXh0cmFGaWVsZCgpOworICAgICAgICBhLnNldE1vZGUoMDEyMyk7CisgICAgICAgIGEuc2V0VXNlcklkKDUpOworICAgICAgICBhLnNldEdyb3VwSWQoNik7CisgICAgICAgIGJ5dGVbXSBiID0gYS5nZXRMb2NhbEZpbGVEYXRhRGF0YSgpOworCisgICAgICAgIC8vIENSQyBtYW51YWxseSBjYWxjdWxhdGVkLCBzb3JyeQorICAgICAgICBieXRlW10gZXhwZWN0ID0geyhieXRlKTB4QzYsIDB4MDIsIDB4NzgsIChieXRlKTB4QjYsIC8vIENSQworICAgICAgICAgICAgICAgICAgICAgICAgIDAxMjMsIChieXRlKTB4ODAsICAgICAgICAgICAgICAgICAgIC8vIG1vZGUKKyAgICAgICAgICAgICAgICAgICAgICAgICAwLCAwLCAwLCAwLCAgICAgICAgICAgICAgICAgICAgICAgICAvLyBsaW5rIGxlbmd0aAorICAgICAgICAgICAgICAgICAgICAgICAgIDUsIDAsIDYsIDB9OyAgICAgICAgICAgICAgICAgICAgICAgIC8vIHVpZCwgZ2lkCisgICAgICAgIGFzc2VydEVxdWFscygibm8gbGluayIsIGV4cGVjdC5sZW5ndGgsIGIubGVuZ3RoKTsKKyAgICAgICAgZm9yIChpbnQgaT0wOyBpPGV4cGVjdC5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJubyBsaW5rLCBieXRlICIraSwgZXhwZWN0W2ldLCBiW2ldKTsKKyAgICAgICAgfQorCisgICAgICAgIGEuc2V0TGlua2VkRmlsZSgidGVzdCIpOworICAgICAgICBleHBlY3QgPSBuZXcgYnl0ZVtdIHsweDc1LCAoYnl0ZSkweDhFLCAweDQxLCAoYnl0ZSkweEZELCAvLyBDUkMKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMDEyMywgKGJ5dGUpMHhBMCwgICAgICAgICAgICAgICAgICAgLy8gbW9kZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICA0LCAwLCAwLCAwLCAgICAgICAgICAgICAgICAgICAgICAgICAvLyBsaW5rIGxlbmd0aAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICA1LCAwLCA2LCAwLCAgICAgICAgICAgICAgICAgICAgICAgICAvLyB1aWQsIGdpZAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkndCcsIChieXRlKSdlJywgKGJ5dGUpJ3MnLCAoYnl0ZSkndCd9OworICAgICAgICBiID0gYS5nZXRMb2NhbEZpbGVEYXRhRGF0YSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm5vIGxpbmsiLCBleHBlY3QubGVuZ3RoLCBiLmxlbmd0aCk7CisgICAgICAgIGZvciAoaW50IGk9MDsgaTxleHBlY3QubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygibm8gbGluaywgYnl0ZSAiK2ksIGV4cGVjdFtpXSwgYltpXSk7CisgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgcmVwYXJzZQorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFJlcGFyc2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gQ1JDIG1hbnVhbGx5IGNhbGN1bGF0ZWQsIHNvcnJ5CisgICAgICAgIGJ5dGVbXSBkYXRhID0geyhieXRlKTB4QzYsIDB4MDIsIDB4NzgsIChieXRlKTB4QjYsIC8vIENSQworICAgICAgICAgICAgICAgICAgICAgICAwMTIzLCAoYnl0ZSkweDgwLCAgICAgICAgICAgICAgICAgICAvLyBtb2RlCisgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsIDAsIDAsICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGxpbmsgbGVuZ3RoCisgICAgICAgICAgICAgICAgICAgICAgIDUsIDAsIDYsIDB9OyAgICAgICAgICAgICAgICAgICAgICAgIC8vIHVpZCwgZ2lkCisgICAgICAgIEFzaUV4dHJhRmllbGQgYSA9IG5ldyBBc2lFeHRyYUZpZWxkKCk7CisgICAgICAgIGEucGFyc2VGcm9tTG9jYWxGaWxlRGF0YShkYXRhLCAwLCBkYXRhLmxlbmd0aCk7CisgICAgICAgIGFzc2VydEVxdWFscygibGVuZ3RoIHBsYWluIGZpbGUiLCBkYXRhLmxlbmd0aCwKKyAgICAgICAgICAgICAgICAgICAgIGEuZ2V0TG9jYWxGaWxlRGF0YUxlbmd0aCgpLmdldFZhbHVlKCkpOworICAgICAgICBhc3NlcnRUcnVlKCJwbGFpbiBmaWxlLCBubyBsaW5rIiwgIWEuaXNMaW5rKCkpOworICAgICAgICBhc3NlcnRUcnVlKCJwbGFpbiBmaWxlLCBubyBkaXIiLCAhYS5pc0RpcmVjdG9yeSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJtb2RlIHBsYWluIGZpbGUiLCBGSUxFX0ZMQUcgfCAwMTIzLCBhLmdldE1vZGUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygidWlkIHBsYWluIGZpbGUiLCA1LCBhLmdldFVzZXJJZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJnaWQgcGxhaW4gZmlsZSIsIDYsIGEuZ2V0R3JvdXBJZCgpKTsKKworICAgICAgICBkYXRhID0gbmV3IGJ5dGVbXSB7MHg3NSwgKGJ5dGUpMHg4RSwgMHg0MSwgKGJ5dGUpMHhGRCwgLy8gQ1JDCisgICAgICAgICAgICAgICAgICAgICAgICAgICAwMTIzLCAoYnl0ZSkweEEwLCAgICAgICAgICAgICAgICAgICAvLyBtb2RlCisgICAgICAgICAgICAgICAgICAgICAgICAgICA0LCAwLCAwLCAwLCAgICAgICAgICAgICAgICAgICAgICAgICAvLyBsaW5rIGxlbmd0aAorICAgICAgICAgICAgICAgICAgICAgICAgICAgNSwgMCwgNiwgMCwgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdWlkLCBnaWQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSd0JywgKGJ5dGUpJ2UnLCAoYnl0ZSkncycsIChieXRlKSd0J307CisgICAgICAgIGEgPSBuZXcgQXNpRXh0cmFGaWVsZCgpOworICAgICAgICBhLnBhcnNlRnJvbUxvY2FsRmlsZURhdGEoZGF0YSwgMCwgZGF0YS5sZW5ndGgpOworICAgICAgICBhc3NlcnRFcXVhbHMoImxlbmd0aCBsaW5rIiwgZGF0YS5sZW5ndGgsCisgICAgICAgICAgICAgICAgICAgICBhLmdldExvY2FsRmlsZURhdGFMZW5ndGgoKS5nZXRWYWx1ZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgibGluaywgaXMgbGluayIsIGEuaXNMaW5rKCkpOworICAgICAgICBhc3NlcnRUcnVlKCJsaW5rLCBubyBkaXIiLCAhYS5pc0RpcmVjdG9yeSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJtb2RlIGxpbmsiLCBMSU5LX0ZMQUcgfCAwMTIzLCBhLmdldE1vZGUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygidWlkIGxpbmsiLCA1LCBhLmdldFVzZXJJZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJnaWQgbGluayIsIDYsIGEuZ2V0R3JvdXBJZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0ZXN0IiwgYS5nZXRMaW5rZWRGaWxlKCkpOworCisgICAgICAgIGRhdGEgPSBuZXcgYnl0ZVtdIHsoYnl0ZSkweDhFLCAweDAxLCAoYnl0ZSkweEJGLCAoYnl0ZSkweDBFLCAvLyBDUkMKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIDAxMjMsIChieXRlKTB4NDAsICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1vZGUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsIDAsIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGxpbmsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIDUsIDAsIDYsIDB9OyAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdWlkLCBnaWQKKyAgICAgICAgYSA9IG5ldyBBc2lFeHRyYUZpZWxkKCk7CisgICAgICAgIGEucGFyc2VGcm9tTG9jYWxGaWxlRGF0YShkYXRhLCAwLCBkYXRhLmxlbmd0aCk7CisgICAgICAgIGFzc2VydEVxdWFscygibGVuZ3RoIGRpciIsIGRhdGEubGVuZ3RoLAorICAgICAgICAgICAgICAgICAgICAgYS5nZXRMb2NhbEZpbGVEYXRhTGVuZ3RoKCkuZ2V0VmFsdWUoKSk7CisgICAgICAgIGFzc2VydFRydWUoImRpciwgbm8gbGluayIsICFhLmlzTGluaygpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiZGlyLCBpcyBkaXIiLCBhLmlzRGlyZWN0b3J5KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm1vZGUgZGlyIiwgRElSX0ZMQUcgfCAwMTIzLCBhLmdldE1vZGUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygidWlkIGRpciIsIDUsIGEuZ2V0VXNlcklkKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImdpZCBkaXIiLCA2LCBhLmdldEdyb3VwSWQoKSk7CisKKyAgICAgICAgZGF0YSA9IG5ldyBieXRlW10gezAsIDAsIDAsIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYmFkIENSQworICAgICAgICAgICAgICAgICAgICAgICAgICAgMDEyMywgKGJ5dGUpMHg0MCwgICAgICAgICAgICAgICAgICAgICAvLyBtb2RlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAwLCAwLCAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGxpbmsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIDUsIDAsIDYsIDB9OyAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdWlkLCBnaWQKKyAgICAgICAgYSA9IG5ldyBBc2lFeHRyYUZpZWxkKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhLnBhcnNlRnJvbUxvY2FsRmlsZURhdGEoZGF0YSwgMCwgZGF0YS5sZW5ndGgpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHJhaXNlIGJhZCBDUkMgZXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImJhZCBDUkMgY2hlY2tzdW0gMCBpbnN0ZWFkIG9mIGViZjAxOGUiLAorICAgICAgICAgICAgICAgICAgICAgICAgIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdENsb25lKCkgeworICAgICAgICBmaW5hbCBBc2lFeHRyYUZpZWxkIHMxID0gbmV3IEFzaUV4dHJhRmllbGQoKTsKKyAgICAgICAgczEuc2V0VXNlcklkKDQyKTsKKyAgICAgICAgczEuc2V0R3JvdXBJZCgxMik7CisgICAgICAgIHMxLnNldExpbmtlZEZpbGUoImZvbyIpOworICAgICAgICBzMS5zZXRNb2RlKDA2NDQpOworICAgICAgICBzMS5zZXREaXJlY3RvcnkodHJ1ZSk7CisgICAgICAgIGZpbmFsIEFzaUV4dHJhRmllbGQgczIgPSAoQXNpRXh0cmFGaWVsZCkgczEuY2xvbmUoKTsKKyAgICAgICAgYXNzZXJ0Tm90U2FtZShzMSwgczIpOworICAgICAgICBhc3NlcnRFcXVhbHMoczEuZ2V0VXNlcklkKCksIHMyLmdldFVzZXJJZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHMxLmdldEdyb3VwSWQoKSwgczIuZ2V0R3JvdXBJZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHMxLmdldExpbmtlZEZpbGUoKSwgczIuZ2V0TGlua2VkRmlsZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHMxLmdldE1vZGUoKSwgczIuZ2V0TW9kZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHMxLmlzRGlyZWN0b3J5KCksIHMyLmlzRGlyZWN0b3J5KCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvQmluYXJ5VHJlZVRlc3QuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvQmluYXJ5VHJlZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hZTRiYTlkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9CaW5hcnlUcmVlVGVzdC5qYXZhCkBAIC0wLDAgKzEsNzQgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwOworCitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuKjsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworCitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CisKK3B1YmxpYyBjbGFzcyBCaW5hcnlUcmVlVGVzdCB7CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3REZWNvZGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBJbnB1dFN0cmVhbSBpbiA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShuZXcgYnl0ZVtdIHsgMHgwMiwgMHg0MiwgMHgwMSwgMHgxMyB9KTsKKworICAgICAgICBmaW5hbCBCaW5hcnlUcmVlIHRyZWUgPSBCaW5hcnlUcmVlLmRlY29kZShpbiwgOCk7CisKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCh0cmVlKTsKKworICAgICAgICBmaW5hbCBCaXRTdHJlYW0gc3RyZWFtID0gbmV3IEJpdFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0obmV3IGJ5dGVbXSB7IChieXRlKSAweDhELCAoYnl0ZSkgMHhDNSwgKGJ5dGUpIDB4MTEsIDB4MDAgfSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgdHJlZS5yZWFkKHN0cmVhbSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgdHJlZS5yZWFkKHN0cmVhbSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgdHJlZS5yZWFkKHN0cmVhbSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMywgdHJlZS5yZWFkKHN0cmVhbSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoNCwgdHJlZS5yZWFkKHN0cmVhbSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoNSwgdHJlZS5yZWFkKHN0cmVhbSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoNiwgdHJlZS5yZWFkKHN0cmVhbSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoNywgdHJlZS5yZWFkKHN0cmVhbSkpOworICAgIH0KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RFeGNlcHRpb25zKCkgIHsKKyAgICAgICAgIEJpbmFyeVRyZWUgYmluYXJ5RmluYXJ5ID0gbmV3IEJpbmFyeVRyZWUoNCk7CisgICAgICAgICBiaW5hcnlGaW5hcnkuYWRkTGVhZigwLDAsMCwxKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJpbmFyeUZpbmFyeS5hZGRMZWFmKDAsMCwwLDEpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIGhhdmUgdGhyb3duIGlsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0obmV3IGJ5dGVbXXt9KTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEJpbmFyeVRyZWUuZGVjb2RlKGlzLDApOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIGhhdmUgdGhyb3duIElPRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKworICAgICAgICB9CisgICAgICAgIGJpbmFyeUZpbmFyeSA9IG5ldyBCaW5hcnlUcmVlKDQpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYmluYXJ5RmluYXJ5LnJlYWQobmV3IEJpdFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0obmV3IGJ5dGVbXSB7MH0pKSk7CisgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCByZWFkIGZhaWwiKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9CaXRTdHJlYW1UZXN0LmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL0JpdFN0cmVhbVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMzMwYzI5Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9CaXRTdHJlYW1UZXN0LmphdmEKQEAgLTAsMCArMSw5NCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXA7CisKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC4qOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKKworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworCitwdWJsaWMgY2xhc3MgQml0U3RyZWFtVGVzdCB7CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RFbXB0eVN0cmVhbSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBCaXRTdHJlYW0gc3RyZWFtID0gbmV3IEJpdFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0obmV3IGJ5dGVbMF0pKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJuZXh0IGJpdCIsIC0xLCBzdHJlYW0ubmV4dEJpdCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJuZXh0IGJpdCIsIC0xLCBzdHJlYW0ubmV4dEJpdCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJuZXh0IGJpdCIsIC0xLCBzdHJlYW0ubmV4dEJpdCgpKTsKKyAgICAgICAgc3RyZWFtLmNsb3NlKCk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U3RyZWFtKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEJpdFN0cmVhbSBzdHJlYW0gPSBuZXcgQml0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShuZXcgYnl0ZVtdIHsgKGJ5dGUpIDB4RUEsIDB4MDMgfSkpOworCisgICAgICAgIGFzc2VydEVxdWFscygiYml0IDAiLCAwLCBzdHJlYW0ubmV4dEJpdCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJiaXQgMSIsIDEsIHN0cmVhbS5uZXh0Qml0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImJpdCAyIiwgMCwgc3RyZWFtLm5leHRCaXQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYml0IDMiLCAxLCBzdHJlYW0ubmV4dEJpdCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJiaXQgNCIsIDAsIHN0cmVhbS5uZXh0Qml0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImJpdCA1IiwgMSwgc3RyZWFtLm5leHRCaXQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYml0IDYiLCAxLCBzdHJlYW0ubmV4dEJpdCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJiaXQgNyIsIDEsIHN0cmVhbS5uZXh0Qml0KCkpOworCisgICAgICAgIGFzc2VydEVxdWFscygiYml0IDgiLCAxLCBzdHJlYW0ubmV4dEJpdCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJiaXQgOSIsIDEsIHN0cmVhbS5uZXh0Qml0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImJpdCAxMCIsIDAsIHN0cmVhbS5uZXh0Qml0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImJpdCAxMSIsIDAsIHN0cmVhbS5uZXh0Qml0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImJpdCAxMiIsIDAsIHN0cmVhbS5uZXh0Qml0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImJpdCAxMyIsIDAsIHN0cmVhbS5uZXh0Qml0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImJpdCAxNCIsIDAsIHN0cmVhbS5uZXh0Qml0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImJpdCAxNSIsIDAsIHN0cmVhbS5uZXh0Qml0KCkpOworCisgICAgICAgIGFzc2VydEVxdWFscygibmV4dCBiaXQiLCAtMSwgc3RyZWFtLm5leHRCaXQoKSk7CisgICAgICAgIHN0cmVhbS5jbG9zZSgpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdE5leHRCeXRlRnJvbUVtcHR5U3RyZWFtKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEJpdFN0cmVhbSBzdHJlYW0gPSBuZXcgQml0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShuZXcgYnl0ZVswXSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm5leHQgYnl0ZSIsIC0xLCBzdHJlYW0ubmV4dEJ5dGUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygibmV4dCBieXRlIiwgLTEsIHN0cmVhbS5uZXh0Qnl0ZSgpKTsKKyAgICAgICAgc3RyZWFtLmNsb3NlKCk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVhZEFsaWduZWRCeXRlcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBCaXRTdHJlYW0gc3RyZWFtID0gbmV3IEJpdFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0obmV3IGJ5dGVbXSB7IChieXRlKSAweEVBLCAweDM1IH0pKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJuZXh0IGJ5dGUiLCAweEVBLCBzdHJlYW0ubmV4dEJ5dGUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygibmV4dCBieXRlIiwgMHgzNSwgc3RyZWFtLm5leHRCeXRlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm5leHQgYnl0ZSIsIC0xLCBzdHJlYW0ubmV4dEJ5dGUoKSk7CisgICAgICAgIHN0cmVhbS5jbG9zZSgpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdE5leHRCeXRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEJpdFN0cmVhbSBzdHJlYW0gPSBuZXcgQml0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShuZXcgYnl0ZVtdIHsgKGJ5dGUpIDB4RUEsIDB4MzUgfSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImJpdCAwIiwgMCwgc3RyZWFtLm5leHRCaXQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYml0IDEiLCAxLCBzdHJlYW0ubmV4dEJpdCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJiaXQgMiIsIDAsIHN0cmVhbS5uZXh0Qml0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImJpdCAzIiwgMSwgc3RyZWFtLm5leHRCaXQoKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJuZXh0IGJ5dGUiLCAweDVFLCBzdHJlYW0ubmV4dEJ5dGUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygibmV4dCBieXRlIiwgLTEsIHN0cmVhbS5uZXh0Qnl0ZSgpKTsgLy8gbm90IGVub3VnaCBiaXRzIGxlZnQgdG8gcmVhZCBhIGJ5dGUKKyAgICAgICAgc3RyZWFtLmNsb3NlKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9DaXJjdWxhckJ1ZmZlclRlc3QuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvQ2lyY3VsYXJCdWZmZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTdiNmIwMQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvQ2lyY3VsYXJCdWZmZXJUZXN0LmphdmEKQEAgLTAsMCArMSw4MCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXA7CisKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC4qOworCitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CisKK3B1YmxpYyBjbGFzcyBDaXJjdWxhckJ1ZmZlclRlc3QgeworCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHV0QW5kR2V0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIGludCBzaXplID0gMTY7CisgICAgICAgIGZpbmFsIENpcmN1bGFyQnVmZmVyIGJ1ZmZlciA9IG5ldyBDaXJjdWxhckJ1ZmZlcihzaXplKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplIC8gMjsgaSsrKSB7CisgICAgICAgICAgICBidWZmZXIucHV0KGkpOworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiYXZhaWxhYmxlIiwgYnVmZmVyLmF2YWlsYWJsZSgpKTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNpemUgLyAyOyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiYnVmZmVyWyIgKyBpICsgIl0iLCBpLCBidWZmZXIuZ2V0KCkpOworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBidWZmZXIuZ2V0KCkpOworICAgICAgICBhc3NlcnRGYWxzZSgiYXZhaWxhYmxlIiwgYnVmZmVyLmF2YWlsYWJsZSgpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RDb3B5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIENpcmN1bGFyQnVmZmVyIGJ1ZmZlciA9IG5ldyBDaXJjdWxhckJ1ZmZlcigxNik7CisKKyAgICAgICAgYnVmZmVyLnB1dCgxKTsKKyAgICAgICAgYnVmZmVyLnB1dCgyKTsKKyAgICAgICAgYnVmZmVyLmdldCgpOworICAgICAgICBidWZmZXIuZ2V0KCk7CisKKyAgICAgICAgLy8gY29weSB1bmluaXRpYWxpemVkIGRhdGEKKyAgICAgICAgYnVmZmVyLmNvcHkoNiwgOCk7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDI7IGkgPCA2OyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiYnVmZmVyWyIgKyBpICsgIl0iLCAwLCBidWZmZXIuZ2V0KCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygiYnVmZmVyWyIgKyA2ICsgIl0iLCAxLCBidWZmZXIuZ2V0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImJ1ZmZlclsiICsgNyArICJdIiwgMiwgYnVmZmVyLmdldCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJidWZmZXJbIiArIDggKyAiXSIsIDAsIGJ1ZmZlci5nZXQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYnVmZmVyWyIgKyA5ICsgIl0iLCAwLCBidWZmZXIuZ2V0KCkpOworCisgICAgICAgIGZvciAoaW50IGkgPSAxMDsgaSA8IDE0OyBpKyspIHsKKyAgICAgICAgICAgIGJ1ZmZlci5wdXQoaSk7CisgICAgICAgICAgICBidWZmZXIuZ2V0KCk7CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRGYWxzZSgiYXZhaWxhYmxlIiwgYnVmZmVyLmF2YWlsYWJsZSgpKTsKKworICAgICAgICAvLyBjb3B5IGRhdGEgYW5kIHdyYXAKKyAgICAgICAgYnVmZmVyLmNvcHkoMiwgOCk7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDE0OyBpIDwgMTg7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJidWZmZXJbIiArIGkgKyAiXSIsIGkgJSAyID09IDAgPyAxMiA6IDEzLCBidWZmZXIuZ2V0KCkpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9EYXRhRGVzY3JpcHRvclRlc3QuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvRGF0YURlc2NyaXB0b3JUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTIwNzhkZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvRGF0YURlc2NyaXB0b3JUZXN0LmphdmEKQEAgLTAsMCArMSwxODkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXA7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5JT1V0aWxzOworaW1wb3J0IG9yZy5qdW5pdC5BZnRlcjsKK2ltcG9ydCBvcmcuanVuaXQuQmVmb3JlOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworCitpbXBvcnQgc3RhdGljIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5BYnN0cmFjdFRlc3RDYXNlLm1rZGlyOworaW1wb3J0IHN0YXRpYyBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuQWJzdHJhY3RUZXN0Q2FzZS5ybWRpcjsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRBcnJheUVxdWFsczsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRFcXVhbHM7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0Tm90RXF1YWxzOworCitwdWJsaWMgY2xhc3MgRGF0YURlc2NyaXB0b3JUZXN0IHsKKworICAgIHByaXZhdGUgRmlsZSBkaXI7CisKKyAgICBAQmVmb3JlCisgICAgcHVibGljIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZGlyID0gbWtkaXIoImRkdGVzdCIpOworICAgIH0KKworICAgIEBBZnRlcgorICAgIHB1YmxpYyB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHJtZGlyKGRpcik7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB3cml0ZXNEYXRhRGVzY3JpcHRvckZvckRlZmxhdGVkRW50cnlPblVuc2Vla2FibGVPdXRwdXQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gbyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgdHJ5IChaaXBBcmNoaXZlT3V0cHV0U3RyZWFtIHpvcyA9IG5ldyBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtKG8pKSB7CisgICAgICAgICAgICB6b3MucHV0QXJjaGl2ZUVudHJ5KG5ldyBaaXBBcmNoaXZlRW50cnkoInRlc3QxLnR4dCIpKTsKKyAgICAgICAgICAgIHpvcy53cml0ZSgiZm9vIi5nZXRCeXRlcygiVVRGLTgiKSk7CisgICAgICAgICAgICB6b3MuY2xvc2VBcmNoaXZlRW50cnkoKTsKKyAgICAgICAgfQorICAgICAgICBieXRlW10gZGF0YSA9IG8udG9CeXRlQXJyYXkoKTsKKworICAgICAgICBieXRlW10gdmVyc2lvbkluTEZIID0gQXJyYXlzLmNvcHlPZlJhbmdlKGRhdGEsIDQsIDYpOworICAgICAgICAvLyAyLjAgYmVjYXVzZSBvZiBERAorICAgICAgICBhc3NlcnRBcnJheUVxdWFscyhuZXcgYnl0ZVtdIHsgMjAsIDAgfSwgdmVyc2lvbkluTEZIKTsKKyAgICAgICAgYnl0ZVtdIGdwYkluTEZIID0gQXJyYXlzLmNvcHlPZlJhbmdlKGRhdGEsIDYsIDgpOworICAgICAgICAvLyBERCBhbmQgRUZTIGZsYWdzCisgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKG5ldyBieXRlW10geyA4LCA4IH0sIGdwYkluTEZIKTsKKyAgICAgICAgYnl0ZVtdIGNyY0FuZFNpemVkSW5MRkggPSBBcnJheXMuY29weU9mUmFuZ2UoZGF0YSwgMTQsIDI2KTsKKyAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMobmV3IGJ5dGVbMTJdLCBjcmNBbmRTaXplZEluTEZIKTsKKworICAgICAgICBpbnQgY2RoU3RhcnQgPSBmaW5kQ2VudHJhbERpcmVjdG9yeShkYXRhKTsKKyAgICAgICAgYnl0ZVtdIHZlcnNpb25JbkNESCA9IEFycmF5cy5jb3B5T2ZSYW5nZShkYXRhLCBjZGhTdGFydCArIDYsIGNkaFN0YXJ0ICsgOCk7CisgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKG5ldyBieXRlW10geyAyMCwgMCB9LCB2ZXJzaW9uSW5DREgpOworICAgICAgICBieXRlW10gZ3BiSW5DREggPSBBcnJheXMuY29weU9mUmFuZ2UoZGF0YSwgY2RoU3RhcnQgKyA4LCBjZGhTdGFydCArIDEwKTsKKyAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMobmV3IGJ5dGVbXSB7IDgsIDggfSwgZ3BiSW5DREgpOworCisgICAgICAgIGludCBkZFN0YXJ0ID0gY2RoU3RhcnQgLSAxNjsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFppcExvbmcuRERfU0lHLCBuZXcgWmlwTG9uZyhkYXRhLCBkZFN0YXJ0KSk7CisgICAgICAgIGxvbmcgY3JjRnJvbUREID0gWmlwTG9uZy5nZXRWYWx1ZShkYXRhLCBkZFN0YXJ0ICsgNCk7CisgICAgICAgIGxvbmcgY1NpemVGcm9tREQgPSBaaXBMb25nLmdldFZhbHVlKGRhdGEsIGRkU3RhcnQgKyA4KTsKKyAgICAgICAgbG9uZyBzaXplRnJvbUREID0gWmlwTG9uZy5nZXRWYWx1ZShkYXRhLCBkZFN0YXJ0ICsgMTIpOworICAgICAgICBhc3NlcnRFcXVhbHMoMywgc2l6ZUZyb21ERCk7CisKKyAgICAgICAgbG9uZyBjcmNGcm9tQ0RIID0gWmlwTG9uZy5nZXRWYWx1ZShkYXRhLCBjZGhTdGFydCArIDE2KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGNyY0Zyb21ERCwgY3JjRnJvbUNESCk7CisgICAgICAgIGxvbmcgY1NpemVGcm9tQ0RIID0gWmlwTG9uZy5nZXRWYWx1ZShkYXRhLCBjZGhTdGFydCArIDIwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGNTaXplRnJvbURELCBjU2l6ZUZyb21DREgpOworICAgICAgICBsb25nIHNpemVGcm9tQ0RIID0gWmlwTG9uZy5nZXRWYWx1ZShkYXRhLCBjZGhTdGFydCArIDI0KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHNpemVGcm9tREQsIHNpemVGcm9tQ0RIKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIGRvZXNudFdyaXRlRGF0YURlc2NyaXB0b3JGb3JEZWZsYXRlZEVudHJ5T25TZWVrYWJsZU91dHB1dCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEZpbGUgZiA9IG5ldyBGaWxlKGRpciwgInRlc3QuemlwIik7CisgICAgICAgIHRyeSAoWmlwQXJjaGl2ZU91dHB1dFN0cmVhbSB6b3MgPSBuZXcgWmlwQXJjaGl2ZU91dHB1dFN0cmVhbShmKSkgeworICAgICAgICAgICAgem9zLnB1dEFyY2hpdmVFbnRyeShuZXcgWmlwQXJjaGl2ZUVudHJ5KCJ0ZXN0MS50eHQiKSk7CisgICAgICAgICAgICB6b3Mud3JpdGUoImZvbyIuZ2V0Qnl0ZXMoIlVURi04IikpOworICAgICAgICAgICAgem9zLmNsb3NlQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgIH0KKworICAgICAgICBieXRlW10gZGF0YTsKKyAgICAgICAgdHJ5IChGaWxlSW5wdXRTdHJlYW0gZmlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShmKSkgeworICAgICAgICAgICAgZGF0YSA9IElPVXRpbHMudG9CeXRlQXJyYXkoZmlzKTsKKyAgICAgICAgfQorCisgICAgICAgIGJ5dGVbXSB2ZXJzaW9uSW5MRkggPSBBcnJheXMuY29weU9mUmFuZ2UoZGF0YSwgNCwgNik7CisgICAgICAgIC8vIHN0aWxsIDIuMCBiZWNhdXNlIG9mIERlZmxhdGUKKyAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMobmV3IGJ5dGVbXSB7IDIwLCAwIH0sIHZlcnNpb25JbkxGSCk7CisgICAgICAgIGJ5dGVbXSBncGJJbkxGSCA9IEFycmF5cy5jb3B5T2ZSYW5nZShkYXRhLCA2LCA4KTsKKyAgICAgICAgLy8gbm8gREQgYnV0IEVGUyBmbGFnCisgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKG5ldyBieXRlW10geyAwLCA4IH0sIGdwYkluTEZIKTsKKworICAgICAgICBpbnQgY2RoU3RhcnQgPSBmaW5kQ2VudHJhbERpcmVjdG9yeShkYXRhKTsKKyAgICAgICAgYnl0ZVtdIHZlcnNpb25JbkNESCA9IEFycmF5cy5jb3B5T2ZSYW5nZShkYXRhLCBjZGhTdGFydCArIDYsIGNkaFN0YXJ0ICsgOCk7CisgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKG5ldyBieXRlW10geyAyMCwgMCB9LCB2ZXJzaW9uSW5DREgpOworICAgICAgICBieXRlW10gZ3BiSW5DREggPSBBcnJheXMuY29weU9mUmFuZ2UoZGF0YSwgY2RoU3RhcnQgKyA4LCBjZGhTdGFydCArIDEwKTsKKyAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMobmV3IGJ5dGVbXSB7IDAsIDggfSwgZ3BiSW5DREgpOworCisgICAgICAgIGludCBkZFN0YXJ0ID0gY2RoU3RhcnQgLSAxNjsKKyAgICAgICAgYXNzZXJ0Tm90RXF1YWxzKFppcExvbmcuRERfU0lHLCBuZXcgWmlwTG9uZyhkYXRhLCBkZFN0YXJ0KSk7CisgICAgICAgIGxvbmcgY3JjRnJvbUxGSCA9IFppcExvbmcuZ2V0VmFsdWUoZGF0YSwgMTQpOworICAgICAgICBsb25nIGNTaXplRnJvbUxGSCA9IFppcExvbmcuZ2V0VmFsdWUoZGF0YSwgMTgpOworICAgICAgICBsb25nIHNpemVGcm9tTEZIID0gWmlwTG9uZy5nZXRWYWx1ZShkYXRhLCAyMik7CisgICAgICAgIGFzc2VydEVxdWFscygzLCBzaXplRnJvbUxGSCk7CisKKyAgICAgICAgbG9uZyBjcmNGcm9tQ0RIID0gWmlwTG9uZy5nZXRWYWx1ZShkYXRhLCBjZGhTdGFydCArIDE2KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGNyY0Zyb21MRkgsIGNyY0Zyb21DREgpOworICAgICAgICBsb25nIGNTaXplRnJvbUNESCA9IFppcExvbmcuZ2V0VmFsdWUoZGF0YSwgY2RoU3RhcnQgKyAyMCk7CisgICAgICAgIGFzc2VydEVxdWFscyhjU2l6ZUZyb21MRkgsIGNTaXplRnJvbUNESCk7CisgICAgICAgIGxvbmcgc2l6ZUZyb21DREggPSBaaXBMb25nLmdldFZhbHVlKGRhdGEsIGNkaFN0YXJ0ICsgMjQpOworICAgICAgICBhc3NlcnRFcXVhbHMoc2l6ZUZyb21MRkgsIHNpemVGcm9tQ0RIKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIGRvZXNudFdyaXRlRGF0YURlc2NyaXB0b3JXaGVuQWRkaW5nUmF3RW50cmllcygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBpbml0ID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICB0cnkgKFppcEFyY2hpdmVPdXRwdXRTdHJlYW0gem9zID0gbmV3IFppcEFyY2hpdmVPdXRwdXRTdHJlYW0oaW5pdCkpIHsKKyAgICAgICAgICAgIHpvcy5wdXRBcmNoaXZlRW50cnkobmV3IFppcEFyY2hpdmVFbnRyeSgidGVzdDEudHh0IikpOworICAgICAgICAgICAgem9zLndyaXRlKCJmb28iLmdldEJ5dGVzKCJVVEYtOCIpKTsKKyAgICAgICAgICAgIHpvcy5jbG9zZUFyY2hpdmVFbnRyeSgpOworICAgICAgICB9CisKKyAgICAgICAgRmlsZSBmID0gbmV3IEZpbGUoZGlyLCAidGVzdC56aXAiKTsKKyAgICAgICAgdHJ5IChGaWxlT3V0cHV0U3RyZWFtIGZvcyA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKGYpKSB7CisgICAgICAgICAgICBmb3Mud3JpdGUoaW5pdC50b0J5dGVBcnJheSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBvID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICBaaXBBcmNoaXZlRW50cnkgemFlOworICAgICAgICB0cnkgKFppcEZpbGUgemYgPSBuZXcgWmlwRmlsZShmKTsKKyAgICAgICAgICAgICBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtIHpvcyA9IG5ldyBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtKG8pKSB7CisgICAgICAgICAgICB6YWUgPSB6Zi5nZXRFbnRyeSgidGVzdDEudHh0Iik7CisgICAgICAgICAgICB6b3MuYWRkUmF3QXJjaGl2ZUVudHJ5KHphZSwgemYuZ2V0UmF3SW5wdXRTdHJlYW0oemFlKSk7CisgICAgICAgIH0KKworICAgICAgICBieXRlW10gZGF0YSA9IG8udG9CeXRlQXJyYXkoKTsKKyAgICAgICAgYnl0ZVtdIHZlcnNpb25JbkxGSCA9IEFycmF5cy5jb3B5T2ZSYW5nZShkYXRhLCA0LCA2KTsKKyAgICAgICAgLy8gc3RpbGwgMi4wIGJlY2F1c2Ugb2YgRGVmbGF0ZQorICAgICAgICBhc3NlcnRBcnJheUVxdWFscyhuZXcgYnl0ZVtdIHsgMjAsIDAgfSwgdmVyc2lvbkluTEZIKTsKKyAgICAgICAgYnl0ZVtdIGdwYkluTEZIID0gQXJyYXlzLmNvcHlPZlJhbmdlKGRhdGEsIDYsIDgpOworICAgICAgICAvLyBubyBERCBidXQgRUZTIGZsYWcKKyAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMobmV3IGJ5dGVbXSB7IDAsIDggfSwgZ3BiSW5MRkgpOworCisgICAgICAgIGludCBjZGhTdGFydCA9IGZpbmRDZW50cmFsRGlyZWN0b3J5KGRhdGEpOworICAgICAgICBieXRlW10gdmVyc2lvbkluQ0RIID0gQXJyYXlzLmNvcHlPZlJhbmdlKGRhdGEsIGNkaFN0YXJ0ICsgNiwgY2RoU3RhcnQgKyA4KTsKKyAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMobmV3IGJ5dGVbXSB7IDIwLCAwIH0sIHZlcnNpb25JbkNESCk7CisgICAgICAgIGJ5dGVbXSBncGJJbkNESCA9IEFycmF5cy5jb3B5T2ZSYW5nZShkYXRhLCBjZGhTdGFydCArIDgsIGNkaFN0YXJ0ICsgMTApOworICAgICAgICBhc3NlcnRBcnJheUVxdWFscyhuZXcgYnl0ZVtdIHsgMCwgOCB9LCBncGJJbkNESCk7CisKKyAgICAgICAgaW50IGRkU3RhcnQgPSBjZGhTdGFydCAtIDE2OworICAgICAgICBhc3NlcnROb3RFcXVhbHMoWmlwTG9uZy5ERF9TSUcsIG5ldyBaaXBMb25nKGRhdGEsIGRkU3RhcnQpKTsKKyAgICAgICAgbG9uZyBjcmNGcm9tTEZIID0gWmlwTG9uZy5nZXRWYWx1ZShkYXRhLCAxNCk7CisgICAgICAgIGxvbmcgY1NpemVGcm9tTEZIID0gWmlwTG9uZy5nZXRWYWx1ZShkYXRhLCAxOCk7CisgICAgICAgIGxvbmcgc2l6ZUZyb21MRkggPSBaaXBMb25nLmdldFZhbHVlKGRhdGEsIDIyKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIHNpemVGcm9tTEZIKTsKKworICAgICAgICBsb25nIGNyY0Zyb21DREggPSBaaXBMb25nLmdldFZhbHVlKGRhdGEsIGNkaFN0YXJ0ICsgMTYpOworICAgICAgICBhc3NlcnRFcXVhbHMoY3JjRnJvbUxGSCwgY3JjRnJvbUNESCk7CisgICAgICAgIGxvbmcgY1NpemVGcm9tQ0RIID0gWmlwTG9uZy5nZXRWYWx1ZShkYXRhLCBjZGhTdGFydCArIDIwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGNTaXplRnJvbUxGSCwgY1NpemVGcm9tQ0RIKTsKKyAgICAgICAgbG9uZyBzaXplRnJvbUNESCA9IFppcExvbmcuZ2V0VmFsdWUoZGF0YSwgY2RoU3RhcnQgKyAyNCk7CisgICAgICAgIGFzc2VydEVxdWFscyhzaXplRnJvbUxGSCwgc2l6ZUZyb21DREgpOworICAgIH0KKworICAgIHByaXZhdGUgaW50IGZpbmRDZW50cmFsRGlyZWN0b3J5KGJ5dGVbXSBkYXRhKSB7CisgICAgICAgIC8vIG5vdCBhIFpJUDY0IGFyY2hpdmUsIG5vIGNvbW1lbnQsICJFbmQgb2YgY2VudHJhbCBkaXJlY3RvcnkgcmVjb3JkIiBhdCB0aGUgZW5kCisgICAgICAgIHJldHVybiAoaW50KSBaaXBMb25nLmdldFZhbHVlKGRhdGEsIGRhdGEubGVuZ3RoIC0gMjIgKyAxNik7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9FbmNyeXB0ZWRBcmNoaXZlVGVzdC5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9FbmNyeXB0ZWRBcmNoaXZlVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhjMDRjNTIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL0VuY3J5cHRlZEFyY2hpdmVUZXN0LmphdmEKQEAgLTAsMCArMSw4MSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICoKKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwOworCitpbXBvcnQgc3RhdGljIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5BYnN0cmFjdFRlc3RDYXNlLmdldEZpbGU7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuKjsKKworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CisKK3B1YmxpYyBjbGFzcyBFbmNyeXB0ZWRBcmNoaXZlVGVzdCB7CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RSZWFkUGFzc3dvcmRFbmNyeXB0ZWRFbnRyeVZpYVppcEZpbGUoKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlIGZpbGUgPSBnZXRGaWxlKCJwYXNzd29yZC1lbmNyeXB0ZWQuemlwIik7CisgICAgICAgIFppcEZpbGUgemYgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgemYgPSBuZXcgWmlwRmlsZShmaWxlKTsKKyAgICAgICAgICAgIGZpbmFsIFppcEFyY2hpdmVFbnRyeSB6YWUgPSB6Zi5nZXRFbnRyeSgiTElDRU5TRS50eHQiKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoemFlLmdldEdlbmVyYWxQdXJwb3NlQml0KCkudXNlc0VuY3J5cHRpb24oKSk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZSh6YWUuZ2V0R2VuZXJhbFB1cnBvc2VCaXQoKS51c2VzU3Ryb25nRW5jcnlwdGlvbigpKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKHpmLmNhblJlYWRFbnRyeURhdGEoemFlKSk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHpmLmdldElucHV0U3RyZWFtKHphZSk7CisgICAgICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgYW4gZXhjZXB0aW9uIik7CisgICAgICAgICAgICB9IGNhdGNoIChmaW5hbCBVbnN1cHBvcnRlZFppcEZlYXR1cmVFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRTYW1lKFVuc3VwcG9ydGVkWmlwRmVhdHVyZUV4Y2VwdGlvbi5GZWF0dXJlLkVOQ1JZUFRJT04sCisgICAgICAgICAgICAgICAgICAgICAgICAgICBleC5nZXRGZWF0dXJlKCkpOworICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgWmlwRmlsZS5jbG9zZVF1aWV0bHkoemYpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVhZFBhc3N3b3JkRW5jcnlwdGVkRW50cnlWaWFTdHJlYW0oKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlIGZpbGUgPSBnZXRGaWxlKCJwYXNzd29yZC1lbmNyeXB0ZWQuemlwIik7CisgICAgICAgIFppcEFyY2hpdmVJbnB1dFN0cmVhbSB6aW4gPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgemluID0gbmV3IFppcEFyY2hpdmVJbnB1dFN0cmVhbShuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGUpKTsKKyAgICAgICAgICAgIGZpbmFsIFppcEFyY2hpdmVFbnRyeSB6YWUgPSB6aW4uZ2V0TmV4dFppcEVudHJ5KCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkxJQ0VOU0UudHh0IiwgemFlLmdldE5hbWUoKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKHphZS5nZXRHZW5lcmFsUHVycG9zZUJpdCgpLnVzZXNFbmNyeXB0aW9uKCkpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoemFlLmdldEdlbmVyYWxQdXJwb3NlQml0KCkudXNlc1N0cm9uZ0VuY3J5cHRpb24oKSk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZSh6aW4uY2FuUmVhZEVudHJ5RGF0YSh6YWUpKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZmluYWwgYnl0ZVtdIGJ1ZiA9IG5ldyBieXRlWzEwMjRdOworICAgICAgICAgICAgICAgIHppbi5yZWFkKGJ1ZiwgMCwgYnVmLmxlbmd0aCk7CisgICAgICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgYW4gZXhjZXB0aW9uIik7CisgICAgICAgICAgICB9IGNhdGNoIChmaW5hbCBVbnN1cHBvcnRlZFppcEZlYXR1cmVFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRTYW1lKFVuc3VwcG9ydGVkWmlwRmVhdHVyZUV4Y2VwdGlvbi5GZWF0dXJlLkVOQ1JZUFRJT04sCisgICAgICAgICAgICAgICAgICAgICAgICAgICBleC5nZXRGZWF0dXJlKCkpOworICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKHppbiAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgemluLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL0V4cGxvZGVTdXBwb3J0VGVzdC5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9FeHBsb2RlU3VwcG9ydFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42N2ZiYmIxCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9FeHBsb2RlU3VwcG9ydFRlc3QuamF2YQpAQCAtMCwwICsxLDEyMCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXA7CisKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC4qOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC56aXAuQ1JDMzI7CitpbXBvcnQgamF2YS51dGlsLnppcC5DaGVja2VkT3V0cHV0U3RyZWFtOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLkJvdW5kZWRJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuSU9VdGlsczsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworcHVibGljIGNsYXNzIEV4cGxvZGVTdXBwb3J0VGVzdCB7CisKKyAgICBwcml2YXRlIHZvaWQgdGVzdEFyY2hpdmVXaXRoSW1wbG9kZUNvbXByZXNzaW9uKGZpbmFsIFN0cmluZyBmaWxlbmFtZSwgZmluYWwgU3RyaW5nIGVudHJ5TmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgWmlwRmlsZSB6aXAgPSBuZXcgWmlwRmlsZShuZXcgRmlsZShmaWxlbmFtZSkpOworICAgICAgICBmaW5hbCBaaXBBcmNoaXZlRW50cnkgZW50cnkgPSB6aXAuZ2V0RW50cmllcygpLm5leHRFbGVtZW50KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiZW50cnkgbmFtZSIsIGVudHJ5TmFtZSwgZW50cnkuZ2V0TmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiZW50cnkgY2FuJ3QgYmUgcmVhZCIsIHppcC5jYW5SZWFkRW50cnlEYXRhKGVudHJ5KSk7CisgICAgICAgIGFzc2VydEVxdWFscygibWV0aG9kIiwgWmlwTWV0aG9kLklNUExPRElORy5nZXRDb2RlKCksIGVudHJ5LmdldE1ldGhvZCgpKTsKKworICAgICAgICBmaW5hbCBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm91dCA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgZmluYWwgQ2hlY2tlZE91dHB1dFN0cmVhbSBvdXQgPSBuZXcgQ2hlY2tlZE91dHB1dFN0cmVhbShib3V0LCBuZXcgQ1JDMzIoKSk7CisgICAgICAgIElPVXRpbHMuY29weSh6aXAuZ2V0SW5wdXRTdHJlYW0oZW50cnkpLCBvdXQpOworCisgICAgICAgIG91dC5mbHVzaCgpOworCisgICAgICAgIGFzc2VydEVxdWFscygiQ1JDMzIiLCBlbnRyeS5nZXRDcmMoKSwgb3V0LmdldENoZWNrc3VtKCkuZ2V0VmFsdWUoKSk7CisgICAgICAgIHppcC5jbG9zZSgpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEFyY2hpdmVXaXRoSW1wbG9kZUNvbXByZXNzaW9uNEsyVHJlZXMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0ZXN0QXJjaGl2ZVdpdGhJbXBsb2RlQ29tcHJlc3Npb24oInRhcmdldC90ZXN0LWNsYXNzZXMvaW1wbG9kaW5nLTRLZGljdC0ydHJlZXMuemlwIiwgIkhFQURFUi5UWFQiKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RBcmNoaXZlV2l0aEltcGxvZGVDb21wcmVzc2lvbjhLM1RyZWVzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdEFyY2hpdmVXaXRoSW1wbG9kZUNvbXByZXNzaW9uKCJ0YXJnZXQvdGVzdC1jbGFzc2VzL2ltcGxvZGluZy04S2RpY3QtM3RyZWVzLnppcCIsICJMSUNFTlNFLlRYVCIpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFRpa2FUZXN0QXJjaGl2ZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RBcmNoaXZlV2l0aEltcGxvZGVDb21wcmVzc2lvbigidGFyZ2V0L3Rlc3QtY2xhc3Nlcy9tb2J5LWltcGxvZGVkLnppcCIsICJSRUFETUUiKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdGVzdFppcFN0cmVhbVdpdGhJbXBsb2RlQ29tcHJlc3Npb24oZmluYWwgU3RyaW5nIGZpbGVuYW1lLCBmaW5hbCBTdHJpbmcgZW50cnlOYW1lKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBaaXBBcmNoaXZlSW5wdXRTdHJlYW0gemluID0gbmV3IFppcEFyY2hpdmVJbnB1dFN0cmVhbShuZXcgRmlsZUlucHV0U3RyZWFtKG5ldyBGaWxlKGZpbGVuYW1lKSkpOworICAgICAgICBmaW5hbCBaaXBBcmNoaXZlRW50cnkgZW50cnkgPSB6aW4uZ2V0TmV4dFppcEVudHJ5KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiZW50cnkgbmFtZSIsIGVudHJ5TmFtZSwgZW50cnkuZ2V0TmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiZW50cnkgY2FuJ3QgYmUgcmVhZCIsIHppbi5jYW5SZWFkRW50cnlEYXRhKGVudHJ5KSk7CisgICAgICAgIGFzc2VydEVxdWFscygibWV0aG9kIiwgWmlwTWV0aG9kLklNUExPRElORy5nZXRDb2RlKCksIGVudHJ5LmdldE1ldGhvZCgpKTsKKworICAgICAgICBmaW5hbCBJbnB1dFN0cmVhbSBiaW8gPSBuZXcgQm91bmRlZElucHV0U3RyZWFtKHppbiwgZW50cnkuZ2V0U2l6ZSgpKTsKKworICAgICAgICBmaW5hbCBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm91dCA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgZmluYWwgQ2hlY2tlZE91dHB1dFN0cmVhbSBvdXQgPSBuZXcgQ2hlY2tlZE91dHB1dFN0cmVhbShib3V0LCBuZXcgQ1JDMzIoKSk7CisgICAgICAgIElPVXRpbHMuY29weShiaW8sIG91dCk7CisKKyAgICAgICAgb3V0LmZsdXNoKCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJDUkMzMiIsIGVudHJ5LmdldENyYygpLCBvdXQuZ2V0Q2hlY2tzdW0oKS5nZXRWYWx1ZSgpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RaaXBTdHJlYW1XaXRoSW1wbG9kZUNvbXByZXNzaW9uNEsyVHJlZXMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0ZXN0WmlwU3RyZWFtV2l0aEltcGxvZGVDb21wcmVzc2lvbigidGFyZ2V0L3Rlc3QtY2xhc3Nlcy9pbXBsb2RpbmctNEtkaWN0LTJ0cmVlcy56aXAiLCAiSEVBREVSLlRYVCIpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFppcFN0cmVhbVdpdGhJbXBsb2RlQ29tcHJlc3Npb244SzNUcmVlcygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RaaXBTdHJlYW1XaXRoSW1wbG9kZUNvbXByZXNzaW9uKCJ0YXJnZXQvdGVzdC1jbGFzc2VzL2ltcGxvZGluZy04S2RpY3QtM3RyZWVzLnppcCIsICJMSUNFTlNFLlRYVCIpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFRpa2FUZXN0U3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdFppcFN0cmVhbVdpdGhJbXBsb2RlQ29tcHJlc3Npb24oInRhcmdldC90ZXN0LWNsYXNzZXMvbW9ieS1pbXBsb2RlZC56aXAiLCAiUkVBRE1FIik7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29uc3RydWN0b3JUaHJvd3NFeGNlcHRpb25zKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgRXhwbG9kaW5nSW5wdXRTdHJlYW0gZWlzID0gbmV3ICBFeHBsb2RpbmdJbnB1dFN0cmVhbSg0MDk1LDIsbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKG5ldyBieXRlW10ge30pKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCBoYXZlIGZhaWxlZCB3aXRoIGlsbGVnYWwgYXJndW1lbnQgZXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgRXhwbG9kaW5nSW5wdXRTdHJlYW0gZWlzID0gbmV3ICBFeHBsb2RpbmdJbnB1dFN0cmVhbSg0MDk2LDQsbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKG5ldyBieXRlW10ge30pKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCBoYXZlIGZhaWxlZCB3aXRoIGlsbGVnYWwgYXJndW1lbnQgZXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9FeHRyYUZpZWxkVXRpbHNUZXN0LmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL0V4dHJhRmllbGRVdGlsc1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NmI3ZDc2Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9FeHRyYUZpZWxkVXRpbHNUZXN0LmphdmEKQEAgLTAsMCArMSwyNDkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcDsKKworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0Lio7CisKK2ltcG9ydCBvcmcuanVuaXQuQmVmb3JlOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworCitpbXBvcnQgamF2YS51dGlsLnppcC5aaXBFeGNlcHRpb247CisKKy8qKgorICogSlVuaXQgdGVzdGNhc2VzIGZvciBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcC5FeHRyYUZpZWxkVXRpbHMuCisgKgorICovCitwdWJsaWMgY2xhc3MgRXh0cmFGaWVsZFV0aWxzVGVzdCBpbXBsZW1lbnRzIFVuaXhTdGF0IHsKKworICAgIC8qKgorICAgICAqIEhlYWRlci1JRCBvZiBhIFppcEV4dHJhRmllbGQgbm90IHN1cHBvcnRlZCBieSBDb21tb25zIENvbXByZXNzLgorICAgICAqCisgICAgICogPHA+VXNlZCB0byBiZSBaaXBTaG9ydCgxKSBidXQgdGhpcyBpcyB0aGUgSUQgb2YgdGhlIFppcDY0IGV4dHJhCisgICAgICogZmllbGQuPC9wPgorICAgICAqLworICAgIHN0YXRpYyBmaW5hbCBaaXBTaG9ydCBVTlJFQ09HTklaRURfSEVBREVSID0gbmV3IFppcFNob3J0KDB4NTU1NSk7CisKKyAgICBwcml2YXRlIEFzaUV4dHJhRmllbGQgYTsKKyAgICBwcml2YXRlIFVucmVjb2duaXplZEV4dHJhRmllbGQgZHVtbXk7CisgICAgcHJpdmF0ZSBieXRlW10gZGF0YTsKKyAgICBwcml2YXRlIGJ5dGVbXSBhTG9jYWw7CisKKyAgICBAQmVmb3JlCisgICAgcHVibGljIHZvaWQgc2V0VXAoKSB7CisgICAgICAgIGEgPSBuZXcgQXNpRXh0cmFGaWVsZCgpOworICAgICAgICBhLnNldE1vZGUoMDc1NSk7CisgICAgICAgIGEuc2V0RGlyZWN0b3J5KHRydWUpOworICAgICAgICBkdW1teSA9IG5ldyBVbnJlY29nbml6ZWRFeHRyYUZpZWxkKCk7CisgICAgICAgIGR1bW15LnNldEhlYWRlcklkKFVOUkVDT0dOSVpFRF9IRUFERVIpOworICAgICAgICBkdW1teS5zZXRMb2NhbEZpbGVEYXRhRGF0YShuZXcgYnl0ZVtdIHswfSk7CisgICAgICAgIGR1bW15LnNldENlbnRyYWxEaXJlY3RvcnlEYXRhKG5ldyBieXRlW10gezB9KTsKKworICAgICAgICBhTG9jYWwgPSBhLmdldExvY2FsRmlsZURhdGFEYXRhKCk7CisgICAgICAgIGZpbmFsIGJ5dGVbXSBkdW1teUxvY2FsID0gZHVtbXkuZ2V0TG9jYWxGaWxlRGF0YURhdGEoKTsKKyAgICAgICAgZGF0YSA9IG5ldyBieXRlWzQgKyBhTG9jYWwubGVuZ3RoICsgNCArIGR1bW15TG9jYWwubGVuZ3RoXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShhLmdldEhlYWRlcklkKCkuZ2V0Qnl0ZXMoKSwgMCwgZGF0YSwgMCwgMik7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYS5nZXRMb2NhbEZpbGVEYXRhTGVuZ3RoKCkuZ2V0Qnl0ZXMoKSwgMCwgZGF0YSwgMiwgMik7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYUxvY2FsLCAwLCBkYXRhLCA0LCBhTG9jYWwubGVuZ3RoKTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShkdW1teS5nZXRIZWFkZXJJZCgpLmdldEJ5dGVzKCksIDAsIGRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgNCthTG9jYWwubGVuZ3RoLCAyKTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShkdW1teS5nZXRMb2NhbEZpbGVEYXRhTGVuZ3RoKCkuZ2V0Qnl0ZXMoKSwgMCwgZGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICA0K2FMb2NhbC5sZW5ndGgrMiwgMik7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZHVtbXlMb2NhbCwgMCwgZGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICA0K2FMb2NhbC5sZW5ndGgrNCwgZHVtbXlMb2NhbC5sZW5ndGgpOworCisgICAgfQorCisgICAgLyoqCisgICAgICogdGVzdCBwYXJzZXIuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UGFyc2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgWmlwRXh0cmFGaWVsZFtdIHplID0gRXh0cmFGaWVsZFV0aWxzLnBhcnNlKGRhdGEpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm51bWJlciBvZiBmaWVsZHMiLCAyLCB6ZS5sZW5ndGgpOworICAgICAgICBhc3NlcnRUcnVlKCJ0eXBlIGZpZWxkIDEiLCB6ZVswXSBpbnN0YW5jZW9mIEFzaUV4dHJhRmllbGQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm1vZGUgZmllbGQgMSIsIDA0MDc1NSwKKyAgICAgICAgICAgICAgICAgICAgICgoQXNpRXh0cmFGaWVsZCkgemVbMF0pLmdldE1vZGUoKSk7CisgICAgICAgIGFzc2VydFRydWUoInR5cGUgZmllbGQgMiIsIHplWzFdIGluc3RhbmNlb2YgVW5yZWNvZ25pemVkRXh0cmFGaWVsZCk7CisgICAgICAgIGFzc2VydEVxdWFscygiZGF0YSBsZW5ndGggZmllbGQgMiIsIDEsCisgICAgICAgICAgICAgICAgICAgICB6ZVsxXS5nZXRMb2NhbEZpbGVEYXRhTGVuZ3RoKCkuZ2V0VmFsdWUoKSk7CisKKyAgICAgICAgZmluYWwgYnl0ZVtdIGRhdGEyID0gbmV3IGJ5dGVbZGF0YS5sZW5ndGgtMV07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZGF0YSwgMCwgZGF0YTIsIDAsIGRhdGEyLmxlbmd0aCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBFeHRyYUZpZWxkVXRpbHMucGFyc2UoZGF0YTIpOworICAgICAgICAgICAgZmFpbCgiZGF0YSBzaG91bGQgYmUgaW52YWxpZCIpOworICAgICAgICB9IGNhdGNoIChmaW5hbCBFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJtZXNzYWdlIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAiYmFkIGV4dHJhIGZpZWxkIHN0YXJ0aW5nIGF0ICIrKDQgKyBhTG9jYWwubGVuZ3RoKQorICAgICAgICAgICAgICAgICAgICAgICAgICsgIi4gIEJsb2NrIGxlbmd0aCBvZiAxIGJ5dGVzIGV4Y2VlZHMgcmVtYWluaW5nIGRhdGEgb2YgMCBieXRlcy4iLAorICAgICAgICAgICAgICAgICAgICAgICAgIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgcGFyc2VUdXJuc0FycmF5SW5kZXhPdXRPZkJvdW5kc0ludG9aaXBFeGNlcHRpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQXNpRXh0cmFGaWVsZCBmID0gbmV3IEFzaUV4dHJhRmllbGQoKTsKKyAgICAgICAgZi5zZXRMaW5rZWRGaWxlKCJmb28iKTsKKyAgICAgICAgYnl0ZVtdIGwgPSBmLmdldExvY2FsRmlsZURhdGFEYXRhKCk7CisgICAgICAgIC8vIG1hbmlwdWxhdGUgc2l6ZSBvZiBwYXRoIG5hbWUgdG8gcmVhZCA0IHJhdGhlciB0aGFuIDMKKyAgICAgICAgbFs5XSA9IDQ7CisgICAgICAgIC8vIGFuZCBmYWtlIENSQyBzbyB3ZSBhY3R1YWxseSByZWFjaCB0aGUgQUlPQkUKKyAgICAgICAgbFswXSA9IChieXRlKSAweDUyOworICAgICAgICBsWzFdID0gKGJ5dGUpIDB4MjY7CisgICAgICAgIGxbMl0gPSAoYnl0ZSkgMHgxODsKKyAgICAgICAgbFszXSA9IChieXRlKSAweDE5OworICAgICAgICBieXRlW10gZCA9IG5ldyBieXRlWzQgKyBsLmxlbmd0aF07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZi5nZXRIZWFkZXJJZCgpLmdldEJ5dGVzKCksIDAsIGQsIDAsIDIpOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGYuZ2V0TG9jYWxGaWxlRGF0YUxlbmd0aCgpLmdldEJ5dGVzKCksIDAsIGQsIDIsIDIpOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGwsIDAsIGQsIDQsIGwubGVuZ3RoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEV4dHJhRmllbGRVdGlscy5wYXJzZShkKTsKKyAgICAgICAgICAgIGZhaWwoImRhdGEgc2hvdWxkIGJlIGludmFsaWQiKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgWmlwRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygibWVzc2FnZSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgIkZhaWxlZCB0byBwYXJzZSBjb3JydXB0IFpJUCBleHRyYSBmaWVsZCBvZiB0eXBlIDc1NmUiLAorICAgICAgICAgICAgICAgICAgICAgICAgIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFBhcnNlQ2VudHJhbCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBaaXBFeHRyYUZpZWxkW10gemUgPSBFeHRyYUZpZWxkVXRpbHMucGFyc2UoZGF0YSxmYWxzZSk7CisgICAgICAgIGFzc2VydEVxdWFscygibnVtYmVyIG9mIGZpZWxkcyIsIDIsIHplLmxlbmd0aCk7CisgICAgICAgIGFzc2VydFRydWUoInR5cGUgZmllbGQgMSIsIHplWzBdIGluc3RhbmNlb2YgQXNpRXh0cmFGaWVsZCk7CisgICAgICAgIGFzc2VydEVxdWFscygibW9kZSBmaWVsZCAxIiwgMDQwNzU1LAorICAgICAgICAgICAgICAgICAgICAgKChBc2lFeHRyYUZpZWxkKSB6ZVswXSkuZ2V0TW9kZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgidHlwZSBmaWVsZCAyIiwgemVbMV0gaW5zdGFuY2VvZiBVbnJlY29nbml6ZWRFeHRyYUZpZWxkKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJkYXRhIGxlbmd0aCBmaWVsZCAyIiwgMSwKKyAgICAgICAgICAgICAgICAgICAgIHplWzFdLmdldENlbnRyYWxEaXJlY3RvcnlMZW5ndGgoKS5nZXRWYWx1ZSgpKTsKKworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFBhcnNlV2l0aFJlYWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgWmlwRXh0cmFGaWVsZFtdIHplID0KKyAgICAgICAgICAgIEV4dHJhRmllbGRVdGlscy5wYXJzZShkYXRhLCB0cnVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV4dHJhRmllbGRVdGlscy5VbnBhcnNlYWJsZUV4dHJhRmllbGQuUkVBRCk7CisgICAgICAgIGFzc2VydEVxdWFscygibnVtYmVyIG9mIGZpZWxkcyIsIDIsIHplLmxlbmd0aCk7CisgICAgICAgIGFzc2VydFRydWUoInR5cGUgZmllbGQgMSIsIHplWzBdIGluc3RhbmNlb2YgQXNpRXh0cmFGaWVsZCk7CisgICAgICAgIGFzc2VydEVxdWFscygibW9kZSBmaWVsZCAxIiwgMDQwNzU1LAorICAgICAgICAgICAgICAgICAgICAgKChBc2lFeHRyYUZpZWxkKSB6ZVswXSkuZ2V0TW9kZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgidHlwZSBmaWVsZCAyIiwgemVbMV0gaW5zdGFuY2VvZiBVbnJlY29nbml6ZWRFeHRyYUZpZWxkKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJkYXRhIGxlbmd0aCBmaWVsZCAyIiwgMSwKKyAgICAgICAgICAgICAgICAgICAgIHplWzFdLmdldExvY2FsRmlsZURhdGFMZW5ndGgoKS5nZXRWYWx1ZSgpKTsKKworICAgICAgICBmaW5hbCBieXRlW10gZGF0YTIgPSBuZXcgYnl0ZVtkYXRhLmxlbmd0aC0xXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShkYXRhLCAwLCBkYXRhMiwgMCwgZGF0YTIubGVuZ3RoKTsKKyAgICAgICAgemUgPSBFeHRyYUZpZWxkVXRpbHMucGFyc2UoZGF0YTIsIHRydWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV4dHJhRmllbGRVdGlscy5VbnBhcnNlYWJsZUV4dHJhRmllbGQuUkVBRCk7CisgICAgICAgIGFzc2VydEVxdWFscygibnVtYmVyIG9mIGZpZWxkcyIsIDIsIHplLmxlbmd0aCk7CisgICAgICAgIGFzc2VydFRydWUoInR5cGUgZmllbGQgMSIsIHplWzBdIGluc3RhbmNlb2YgQXNpRXh0cmFGaWVsZCk7CisgICAgICAgIGFzc2VydEVxdWFscygibW9kZSBmaWVsZCAxIiwgMDQwNzU1LAorICAgICAgICAgICAgICAgICAgICAgKChBc2lFeHRyYUZpZWxkKSB6ZVswXSkuZ2V0TW9kZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgidHlwZSBmaWVsZCAyIiwgemVbMV0gaW5zdGFuY2VvZiBVbnBhcnNlYWJsZUV4dHJhRmllbGREYXRhKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJkYXRhIGxlbmd0aCBmaWVsZCAyIiwgNCwKKyAgICAgICAgICAgICAgICAgICAgIHplWzFdLmdldExvY2FsRmlsZURhdGFMZW5ndGgoKS5nZXRWYWx1ZSgpKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA0OyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiYnl0ZSBudW1iZXIgIiArIGksCisgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YTJbZGF0YS5sZW5ndGggLSA1ICsgaV0sCisgICAgICAgICAgICAgICAgICAgICAgICAgemVbMV0uZ2V0TG9jYWxGaWxlRGF0YURhdGEoKVtpXSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RQYXJzZVdpdGhTa2lwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFppcEV4dHJhRmllbGRbXSB6ZSA9CisgICAgICAgICAgICBFeHRyYUZpZWxkVXRpbHMucGFyc2UoZGF0YSwgdHJ1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFeHRyYUZpZWxkVXRpbHMuVW5wYXJzZWFibGVFeHRyYUZpZWxkLlNLSVApOworICAgICAgICBhc3NlcnRFcXVhbHMoIm51bWJlciBvZiBmaWVsZHMiLCAyLCB6ZS5sZW5ndGgpOworICAgICAgICBhc3NlcnRUcnVlKCJ0eXBlIGZpZWxkIDEiLCB6ZVswXSBpbnN0YW5jZW9mIEFzaUV4dHJhRmllbGQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm1vZGUgZmllbGQgMSIsIDA0MDc1NSwKKyAgICAgICAgICAgICAgICAgICAgICgoQXNpRXh0cmFGaWVsZCkgemVbMF0pLmdldE1vZGUoKSk7CisgICAgICAgIGFzc2VydFRydWUoInR5cGUgZmllbGQgMiIsIHplWzFdIGluc3RhbmNlb2YgVW5yZWNvZ25pemVkRXh0cmFGaWVsZCk7CisgICAgICAgIGFzc2VydEVxdWFscygiZGF0YSBsZW5ndGggZmllbGQgMiIsIDEsCisgICAgICAgICAgICAgICAgICAgICB6ZVsxXS5nZXRMb2NhbEZpbGVEYXRhTGVuZ3RoKCkuZ2V0VmFsdWUoKSk7CisKKyAgICAgICAgZmluYWwgYnl0ZVtdIGRhdGEyID0gbmV3IGJ5dGVbZGF0YS5sZW5ndGgtMV07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZGF0YSwgMCwgZGF0YTIsIDAsIGRhdGEyLmxlbmd0aCk7CisgICAgICAgIHplID0gRXh0cmFGaWVsZFV0aWxzLnBhcnNlKGRhdGEyLCB0cnVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFeHRyYUZpZWxkVXRpbHMuVW5wYXJzZWFibGVFeHRyYUZpZWxkLlNLSVApOworICAgICAgICBhc3NlcnRFcXVhbHMoIm51bWJlciBvZiBmaWVsZHMiLCAxLCB6ZS5sZW5ndGgpOworICAgICAgICBhc3NlcnRUcnVlKCJ0eXBlIGZpZWxkIDEiLCB6ZVswXSBpbnN0YW5jZW9mIEFzaUV4dHJhRmllbGQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm1vZGUgZmllbGQgMSIsIDA0MDc1NSwKKyAgICAgICAgICAgICAgICAgICAgICgoQXNpRXh0cmFGaWVsZCkgemVbMF0pLmdldE1vZGUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBtZXJnZSBtZXRob2RzCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWVyZ2UoKSB7CisgICAgICAgIGZpbmFsIGJ5dGVbXSBsb2NhbCA9CisgICAgICAgICAgICBFeHRyYUZpZWxkVXRpbHMubWVyZ2VMb2NhbEZpbGVEYXRhRGF0YShuZXcgWmlwRXh0cmFGaWVsZFtdIHthLCBkdW1teX0pOworICAgICAgICBhc3NlcnRFcXVhbHMoImxvY2FsIGxlbmd0aCIsIGRhdGEubGVuZ3RoLCBsb2NhbC5sZW5ndGgpOworICAgICAgICBmb3IgKGludCBpPTA7IGk8bG9jYWwubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygibG9jYWwgYnl0ZSAiK2ksIGRhdGFbaV0sIGxvY2FsW2ldKTsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIGJ5dGVbXSBkdW1teUNlbnRyYWwgPSBkdW1teS5nZXRDZW50cmFsRGlyZWN0b3J5RGF0YSgpOworICAgICAgICBmaW5hbCBieXRlW10gZGF0YTIgPSBuZXcgYnl0ZVs0ICsgYUxvY2FsLmxlbmd0aCArIDQgKyBkdW1teUNlbnRyYWwubGVuZ3RoXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShkYXRhLCAwLCBkYXRhMiwgMCwgNCArIGFMb2NhbC5sZW5ndGggKyAyKTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShkdW1teS5nZXRDZW50cmFsRGlyZWN0b3J5TGVuZ3RoKCkuZ2V0Qnl0ZXMoKSwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhMiwgNCthTG9jYWwubGVuZ3RoKzIsIDIpOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGR1bW15Q2VudHJhbCwgMCwgZGF0YTIsCisgICAgICAgICAgICAgICAgICAgICAgICAgNCthTG9jYWwubGVuZ3RoKzQsIGR1bW15Q2VudHJhbC5sZW5ndGgpOworCisKKyAgICAgICAgZmluYWwgYnl0ZVtdIGNlbnRyYWwgPQorICAgICAgICAgICAgRXh0cmFGaWVsZFV0aWxzLm1lcmdlQ2VudHJhbERpcmVjdG9yeURhdGEobmV3IFppcEV4dHJhRmllbGRbXSB7YSwgZHVtbXl9KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJjZW50cmFsIGxlbmd0aCIsIGRhdGEyLmxlbmd0aCwgY2VudHJhbC5sZW5ndGgpOworICAgICAgICBmb3IgKGludCBpPTA7IGk8Y2VudHJhbC5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJjZW50cmFsIGJ5dGUgIitpLCBkYXRhMltpXSwgY2VudHJhbFtpXSk7CisgICAgICAgIH0KKworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdE1lcmdlV2l0aFVucGFyc2VhYmxlRGF0YSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBaaXBFeHRyYUZpZWxkIGQgPSBuZXcgVW5wYXJzZWFibGVFeHRyYUZpZWxkRGF0YSgpOworICAgICAgICBmaW5hbCBieXRlW10gYiA9IFVOUkVDT0dOSVpFRF9IRUFERVIuZ2V0Qnl0ZXMoKTsKKyAgICAgICAgZC5wYXJzZUZyb21Mb2NhbEZpbGVEYXRhKG5ldyBieXRlW10ge2JbMF0sIGJbMV0sIDEsIDB9LCAwLCA0KTsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGxvY2FsID0KKyAgICAgICAgICAgIEV4dHJhRmllbGRVdGlscy5tZXJnZUxvY2FsRmlsZURhdGFEYXRhKG5ldyBaaXBFeHRyYUZpZWxkW10ge2EsIGR9KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJsb2NhbCBsZW5ndGgiLCBkYXRhLmxlbmd0aCAtIDEsIGxvY2FsLmxlbmd0aCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbG9jYWwubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygibG9jYWwgYnl0ZSAiICsgaSwgZGF0YVtpXSwgbG9jYWxbaV0pOworICAgICAgICB9CisKKyAgICAgICAgZmluYWwgYnl0ZVtdIGRDZW50cmFsID0gZC5nZXRDZW50cmFsRGlyZWN0b3J5RGF0YSgpOworICAgICAgICBmaW5hbCBieXRlW10gZGF0YTIgPSBuZXcgYnl0ZVs0ICsgYUxvY2FsLmxlbmd0aCArIGRDZW50cmFsLmxlbmd0aF07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZGF0YSwgMCwgZGF0YTIsIDAsIDQgKyBhTG9jYWwubGVuZ3RoICsgMik7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZENlbnRyYWwsIDAsIGRhdGEyLAorICAgICAgICAgICAgICAgICAgICAgICAgIDQgKyBhTG9jYWwubGVuZ3RoLCBkQ2VudHJhbC5sZW5ndGgpOworCisKKyAgICAgICAgZmluYWwgYnl0ZVtdIGNlbnRyYWwgPQorICAgICAgICAgICAgRXh0cmFGaWVsZFV0aWxzLm1lcmdlQ2VudHJhbERpcmVjdG9yeURhdGEobmV3IFppcEV4dHJhRmllbGRbXSB7YSwgZH0pOworICAgICAgICBhc3NlcnRFcXVhbHMoImNlbnRyYWwgbGVuZ3RoIiwgZGF0YTIubGVuZ3RoLCBjZW50cmFsLmxlbmd0aCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY2VudHJhbC5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJjZW50cmFsIGJ5dGUgIiArIGksIGRhdGEyW2ldLCBjZW50cmFsW2ldKTsKKyAgICAgICAgfQorCisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9HZW5lcmFsUHVycG9zZUJpdFRlc3QuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvR2VuZXJhbFB1cnBvc2VCaXRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGZjMTE5YQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvR2VuZXJhbFB1cnBvc2VCaXRUZXN0LmphdmEKQEAgLTAsMCArMSwxMTIgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwOworCitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuKjsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CisKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworcHVibGljIGNsYXNzIEdlbmVyYWxQdXJwb3NlQml0VGVzdCB7CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3REZWZhdWx0cygpIHsKKyAgICAgICAgYXNzZXJ0RmFsc2UobmV3IEdlbmVyYWxQdXJwb3NlQml0KCkudXNlc0RhdGFEZXNjcmlwdG9yKCkpOworICAgICAgICBhc3NlcnRGYWxzZShuZXcgR2VuZXJhbFB1cnBvc2VCaXQoKS51c2VzVVRGOEZvck5hbWVzKCkpOworICAgICAgICBhc3NlcnRGYWxzZShuZXcgR2VuZXJhbFB1cnBvc2VCaXQoKS51c2VzRW5jcnlwdGlvbigpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobmV3IEdlbmVyYWxQdXJwb3NlQml0KCkudXNlc1N0cm9uZ0VuY3J5cHRpb24oKSk7CisgICAgICAgIGZpbmFsIGJ5dGVbXSBiID0gbmV3IGJ5dGVbMl07CisgICAgICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhiLCBuZXcgR2VuZXJhbFB1cnBvc2VCaXQoKS5lbmNvZGUoKSkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFBhcnNlRWRnZUNhc2VzKCkgeworICAgICAgICBhc3NlcnRGYWxzZShHZW5lcmFsUHVycG9zZUJpdC5wYXJzZShuZXcgYnl0ZVsyXSwgMCkKKyAgICAgICAgICAgICAgICAgICAgLnVzZXNEYXRhRGVzY3JpcHRvcigpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoR2VuZXJhbFB1cnBvc2VCaXQucGFyc2UobmV3IGJ5dGVbMl0sIDApCisgICAgICAgICAgICAgICAgICAgIC51c2VzVVRGOEZvck5hbWVzKCkpOworICAgICAgICBhc3NlcnRGYWxzZShHZW5lcmFsUHVycG9zZUJpdC5wYXJzZShuZXcgYnl0ZVsyXSwgMCkKKyAgICAgICAgICAgICAgICAgICAgLnVzZXNFbmNyeXB0aW9uKCkpOworICAgICAgICBhc3NlcnRGYWxzZShHZW5lcmFsUHVycG9zZUJpdC5wYXJzZShuZXcgYnl0ZVsyXSwgMCkKKyAgICAgICAgICAgICAgICAgICAgLnVzZXNTdHJvbmdFbmNyeXB0aW9uKCkpOworICAgICAgICBhc3NlcnRUcnVlKEdlbmVyYWxQdXJwb3NlQml0LnBhcnNlKG5ldyBieXRlW10geyhieXRlKSAyNTUsIChieXRlKSAyNTV9LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDApCisgICAgICAgICAgICAgICAgICAgLnVzZXNEYXRhRGVzY3JpcHRvcigpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShHZW5lcmFsUHVycG9zZUJpdC5wYXJzZShuZXcgYnl0ZVtdIHsoYnl0ZSkgMjU1LCAoYnl0ZSkgMjU1fSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwKQorICAgICAgICAgICAgICAgICAgIC51c2VzVVRGOEZvck5hbWVzKCkpOworICAgICAgICBhc3NlcnRUcnVlKEdlbmVyYWxQdXJwb3NlQml0LnBhcnNlKG5ldyBieXRlW10geyhieXRlKSAyNTUsIChieXRlKSAyNTV9LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDApCisgICAgICAgICAgICAgICAgICAgLnVzZXNFbmNyeXB0aW9uKCkpOworICAgICAgICBhc3NlcnRUcnVlKEdlbmVyYWxQdXJwb3NlQml0LnBhcnNlKG5ldyBieXRlW10geyhieXRlKSAyNTUsIChieXRlKSAyNTV9LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDApCisgICAgICAgICAgICAgICAgICAgLnVzZXNTdHJvbmdFbmNyeXB0aW9uKCkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdERhdGFEZXNjcmlwdG9yKCkgeworICAgICAgICBmaW5hbCBieXRlW10gZmxhZ3MgPSBuZXcgYnl0ZVtdIHsoYnl0ZSkgOCwgKGJ5dGUpIDB9OworICAgICAgICBhc3NlcnRUcnVlKEdlbmVyYWxQdXJwb3NlQml0LnBhcnNlKGZsYWdzLCAwKS51c2VzRGF0YURlc2NyaXB0b3IoKSk7CisgICAgICAgIGZpbmFsIEdlbmVyYWxQdXJwb3NlQml0IGIgPSBuZXcgR2VuZXJhbFB1cnBvc2VCaXQoKTsKKyAgICAgICAgYi51c2VEYXRhRGVzY3JpcHRvcih0cnVlKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKGZsYWdzLCBiLmVuY29kZSgpKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TGFuZ3VhZ2VFbmNvZGluZ0ZsYWcoKSB7CisgICAgICAgIGZpbmFsIGJ5dGVbXSBmbGFncyA9IG5ldyBieXRlW10geyhieXRlKSAwLCAoYnl0ZSkgOH07CisgICAgICAgIGFzc2VydFRydWUoR2VuZXJhbFB1cnBvc2VCaXQucGFyc2UoZmxhZ3MsIDApLnVzZXNVVEY4Rm9yTmFtZXMoKSk7CisgICAgICAgIGZpbmFsIEdlbmVyYWxQdXJwb3NlQml0IGIgPSBuZXcgR2VuZXJhbFB1cnBvc2VCaXQoKTsKKyAgICAgICAgYi51c2VVVEY4Rm9yTmFtZXModHJ1ZSk7CisgICAgICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhmbGFncywgYi5lbmNvZGUoKSkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEVuY3J5cHRpb24oKSB7CisgICAgICAgIGZpbmFsIGJ5dGVbXSBmbGFncyA9IG5ldyBieXRlW10geyhieXRlKSAxLCAoYnl0ZSkgMH07CisgICAgICAgIGFzc2VydFRydWUoR2VuZXJhbFB1cnBvc2VCaXQucGFyc2UoZmxhZ3MsIDApLnVzZXNFbmNyeXB0aW9uKCkpOworICAgICAgICBmaW5hbCBHZW5lcmFsUHVycG9zZUJpdCBiID0gbmV3IEdlbmVyYWxQdXJwb3NlQml0KCk7CisgICAgICAgIGIudXNlRW5jcnlwdGlvbih0cnVlKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKGZsYWdzLCBiLmVuY29kZSgpKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U3Ryb25nRW5jcnlwdGlvbigpIHsKKyAgICAgICAgYnl0ZVtdIGZsYWdzID0gbmV3IGJ5dGVbXSB7KGJ5dGUpIDY1LCAoYnl0ZSkgMH07CisgICAgICAgIGFzc2VydFRydWUoR2VuZXJhbFB1cnBvc2VCaXQucGFyc2UoZmxhZ3MsIDApLnVzZXNTdHJvbmdFbmNyeXB0aW9uKCkpOworICAgICAgICBmaW5hbCBHZW5lcmFsUHVycG9zZUJpdCBiID0gbmV3IEdlbmVyYWxQdXJwb3NlQml0KCk7CisgICAgICAgIGIudXNlU3Ryb25nRW5jcnlwdGlvbih0cnVlKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShiLnVzZXNFbmNyeXB0aW9uKCkpOworICAgICAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMoZmxhZ3MsIGIuZW5jb2RlKCkpKTsKKworICAgICAgICBmbGFncyA9IG5ldyBieXRlW10geyhieXRlKSA2NCwgKGJ5dGUpIDB9OworICAgICAgICBhc3NlcnRGYWxzZShHZW5lcmFsUHVycG9zZUJpdC5wYXJzZShmbGFncywgMCkudXNlc1N0cm9uZ0VuY3J5cHRpb24oKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2xvbmUoKSB7CisgICAgICAgIGZpbmFsIEdlbmVyYWxQdXJwb3NlQml0IGIgPSBuZXcgR2VuZXJhbFB1cnBvc2VCaXQoKTsKKyAgICAgICAgYi51c2VTdHJvbmdFbmNyeXB0aW9uKHRydWUpOworICAgICAgICBiLnVzZVVURjhGb3JOYW1lcyh0cnVlKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGIsIGIuY2xvbmUoKSk7CisgICAgICAgIGFzc2VydE5vdFNhbWUoYiwgYi5jbG9uZSgpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL0xpc3Rlci5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9MaXN0ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hNjMzNzE1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9MaXN0ZXIuamF2YQpAQCAtMCwwICsxLDE1MCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICoKKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwOworCitpbXBvcnQgamF2YS5pby5CdWZmZXJlZElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZUVudHJ5OworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5JT1V0aWxzOworCisvKioKKyAqIFNpbXBsZSBjb21tYW5kIGxpbmUgYXBwbGljYXRpb24gdGhhdCBsaXN0cyB0aGUgY29udGVudHMgb2YgYSBaSVAgYXJjaGl2ZS4KKyAqCisgKiA8cD5UaGUgbmFtZSBvZiB0aGUgYXJjaGl2ZSBtdXN0IGJlIGdpdmVuIGFzIGEgY29tbWFuZCBsaW5lIGFyZ3VtZW50LjwvcD4KKyAqCisgKiA8cD5PcHRpb25hbCBjb21tYW5kIGxpbmUgYXJndW1lbnRzIHNwZWNpZnkgdGhlIGVuY29kaW5nIHRvIGFzc3VtZQorICogYW5kIHdoZXRoZXIgdG8gdXNlIFppcEZpbGUgb3IgWmlwQXJjaGl2ZUlucHV0U3RyZWFtLjwvcD4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIExpc3RlciB7CisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgQ29tbWFuZExpbmUgeworICAgICAgICBTdHJpbmcgYXJjaGl2ZTsKKyAgICAgICAgYm9vbGVhbiB1c2VTdHJlYW0gPSBmYWxzZTsKKyAgICAgICAgU3RyaW5nIGVuY29kaW5nOworICAgICAgICBib29sZWFuIGFsbG93U3RvcmVkRW50cmllc1dpdGhEYXRhRGVzY3JpcHRvciA9IGZhbHNlOworICAgICAgICBTdHJpbmcgZGlyOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIENvbW1hbmRMaW5lIGNsID0gcGFyc2UoYXJncyk7CisgICAgICAgIGZpbmFsIEZpbGUgZiA9IG5ldyBGaWxlKGNsLmFyY2hpdmUpOworICAgICAgICBpZiAoIWYuaXNGaWxlKCkpIHsKKyAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbihmICsgIiBkb2Vzbid0IGV4aXN0cyBvciBpcyBhIGRpcmVjdG9yeSIpOworICAgICAgICAgICAgdXNhZ2UoKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoY2wudXNlU3RyZWFtKSB7CisgICAgICAgICAgICB0cnkgKEJ1ZmZlcmVkSW5wdXRTdHJlYW0gZnMgPSBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShuZXcgRmlsZUlucHV0U3RyZWFtKGYpKSkgeworICAgICAgICAgICAgICAgIGZpbmFsIFppcEFyY2hpdmVJbnB1dFN0cmVhbSB6cyA9CisgICAgICAgICAgICAgICAgICAgICAgICBuZXcgWmlwQXJjaGl2ZUlucHV0U3RyZWFtKGZzLCBjbC5lbmNvZGluZywgdHJ1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2wuYWxsb3dTdG9yZWRFbnRyaWVzV2l0aERhdGFEZXNjcmlwdG9yKTsKKyAgICAgICAgICAgICAgICBmb3IgKEFyY2hpdmVFbnRyeSBlbnRyeSA9IHpzLmdldE5leHRFbnRyeSgpOworICAgICAgICAgICAgICAgICAgICAgZW50cnkgIT0gbnVsbDsKKyAgICAgICAgICAgICAgICAgICAgIGVudHJ5ID0genMuZ2V0TmV4dEVudHJ5KCkpIHsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgWmlwQXJjaGl2ZUVudHJ5IHplID0gKFppcEFyY2hpdmVFbnRyeSkgZW50cnk7CisgICAgICAgICAgICAgICAgICAgIGxpc3QoemUpOworICAgICAgICAgICAgICAgICAgICBpZiAoY2wuZGlyICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGV4dHJhY3QoY2wuZGlyLCB6ZSwgenMpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdHJ5IChaaXBGaWxlIHpmID0gbmV3IFppcEZpbGUoZiwgY2wuZW5jb2RpbmcpKSB7CisgICAgICAgICAgICAgICAgZm9yIChmaW5hbCBFbnVtZXJhdGlvbjxaaXBBcmNoaXZlRW50cnk+IGVudHJpZXMgPSB6Zi5nZXRFbnRyaWVzKCk7CisgICAgICAgICAgICAgICAgICAgICBlbnRyaWVzLmhhc01vcmVFbGVtZW50cygpOyApIHsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgWmlwQXJjaGl2ZUVudHJ5IHplID0gZW50cmllcy5uZXh0RWxlbWVudCgpOworICAgICAgICAgICAgICAgICAgICBsaXN0KHplKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGNsLmRpciAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0cnkgKElucHV0U3RyZWFtIGlzID0gemYuZ2V0SW5wdXRTdHJlYW0oemUpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0cmFjdChjbC5kaXIsIHplLCBpcyk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGxpc3QoZmluYWwgWmlwQXJjaGl2ZUVudHJ5IGVudHJ5KSB7CisgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihlbnRyeS5nZXROYW1lKCkpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgZXh0cmFjdChmaW5hbCBTdHJpbmcgZGlyLCBmaW5hbCBaaXBBcmNoaXZlRW50cnkgZW50cnksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIElucHV0U3RyZWFtIGlzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlIGYgPSBuZXcgRmlsZShkaXIsIGVudHJ5LmdldE5hbWUoKSk7CisgICAgICAgIGlmICghZi5nZXRQYXJlbnRGaWxlKCkuZXhpc3RzKCkpIHsKKyAgICAgICAgICAgIGYuZ2V0UGFyZW50RmlsZSgpLm1rZGlycygpOworICAgICAgICB9CisgICAgICAgIEZpbGVPdXRwdXRTdHJlYW0gZm9zID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZvcyA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKGYpOworICAgICAgICAgICAgSU9VdGlscy5jb3B5KGlzLCBmb3MpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKGZvcyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgZm9zLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBDb21tYW5kTGluZSBwYXJzZShmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIGZpbmFsIENvbW1hbmRMaW5lIGNsID0gbmV3IENvbW1hbmRMaW5lKCk7CisgICAgICAgIGJvb2xlYW4gZXJyb3IgPSBmYWxzZTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcmdzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBpZiAoYXJnc1tpXS5lcXVhbHMoIi1lbmMiKSkgeworICAgICAgICAgICAgICAgIGlmIChhcmdzLmxlbmd0aCA+IGkgKyAxKSB7CisgICAgICAgICAgICAgICAgICAgIGNsLmVuY29kaW5nID0gYXJnc1srK2ldOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigibWlzc2luZyBhcmd1bWVudCB0byAtZW5jIik7CisgICAgICAgICAgICAgICAgICAgIGVycm9yID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgaWYgKGFyZ3NbaV0uZXF1YWxzKCItZXh0cmFjdCIpKSB7CisgICAgICAgICAgICAgICAgaWYgKGFyZ3MubGVuZ3RoID4gaSArIDEpIHsKKyAgICAgICAgICAgICAgICAgICAgY2wuZGlyID0gYXJnc1srK2ldOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigibWlzc2luZyBhcmd1bWVudCB0byAtZXh0cmFjdCIpOworICAgICAgICAgICAgICAgICAgICBlcnJvciA9IHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIGlmIChhcmdzW2ldLmVxdWFscygiLXN0cmVhbSIpKSB7CisgICAgICAgICAgICAgICAgY2wudXNlU3RyZWFtID0gdHJ1ZTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoYXJnc1tpXS5lcXVhbHMoIitzdG9yZWRkZCIpKSB7CisgICAgICAgICAgICAgICAgY2wuYWxsb3dTdG9yZWRFbnRyaWVzV2l0aERhdGFEZXNjcmlwdG9yID0gdHJ1ZTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoYXJnc1tpXS5lcXVhbHMoIi1maWxlIikpIHsKKyAgICAgICAgICAgICAgICBjbC51c2VTdHJlYW0gPSBmYWxzZTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoY2wuYXJjaGl2ZSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJPbmx5IG9uZSBhcmNoaXZlIik7CisgICAgICAgICAgICAgICAgZXJyb3IgPSB0cnVlOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBjbC5hcmNoaXZlID0gYXJnc1tpXTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoZXJyb3IgfHwgY2wuYXJjaGl2ZSA9PSBudWxsKSB7CisgICAgICAgICAgICB1c2FnZSgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBjbDsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHVzYWdlKCkgeworICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oImxpc3RlciBbLWVuYyBlbmNvZGluZ10gWy1zdHJlYW1dIFstZmlsZV0iCisgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgWytzdG9yZWRkZF0gWy1leHRyYWN0IGRpcl0gYXJjaGl2ZSIpOworICAgICAgICBTeXN0ZW0uZXhpdCgxKTsKKyAgICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9NYXZlbjIyMU11bHRpVm9sdW1lVGVzdC5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9NYXZlbjIyMU11bHRpVm9sdW1lVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBhOTA1ZTMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL01hdmVuMjIxTXVsdGlWb2x1bWVUZXN0LmphdmEKQEAgLTAsMCArMSwxMjggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcDsKKworaW1wb3J0IHN0YXRpYyBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuQWJzdHJhY3RUZXN0Q2FzZS5nZXRGaWxlOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0Lio7CisKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZUVudHJ5OworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworCisvKioKKyAqIEpVbml0IHRlc3RjYXNlIGZvciBhIG11bHRpLXZvbHVtZSB6aXAgZmlsZS4KKyAqCisgKiBTb21lIHRvb2xzIChsaWtlIDctemlwKSBhbGxvdyB1c2VycyB0byBzcGxpdCBhIGxhcmdlIGFyY2hpdmVzIGludG8gJ3ZvbHVtZXMnCisgKiB3aXRoIGEgZ2l2ZW4gc2l6ZSB0byBmaXQgdGhlbSBpbnRvIG11bHRpcGxlIGNkcywgdXNiIGRyaXZlcywgb3IgZW1haWxzIHdpdGgKKyAqIGFuIGF0dGFjaG1lbnQgc2l6ZSBsaW1pdC4gSXQncyBiYXNpY2FsbHkgdGhlIHNhbWUgZmlsZSBzcGxpdCBpbnRvIGNodW5rcyBvZgorICogZXhhY3RseSA2NTUzNiBieXRlcyBsZW5ndGguIENvbmNhdGVuYXRpbmcgdm9sdW1lcyB5aWVsZHMgZXhhY3RseSB0aGUgb3JpZ2luYWwKKyAqIGZpbGUuIFRoZXJlIGlzIG5vIG1lY2hhbmlzbSBpbiB0aGUgWklQIGFsZ29yaXRobSB0byBhY2NvbW1vZGF0ZSBmb3IgdGhpcy4KKyAqIEJlZm9yZSBjb21tb25zLWNvbXByZXNzIHVzZWQgdG8gZW50ZXIgYW4gaW5maW5pdGUgbG9vcCBvbiB0aGUgbGFzdCBlbnRyeSBmb3IKKyAqIHN1Y2ggYSBmaWxlLiBUaGlzIHRlc3QgaXMgaW50ZW5kZWQgdG8gcHJvdmUgdGhhdCB0aGlzIGVycm9yIGRvZXNuJ3Qgb2NjdXIKKyAqIGFueW1vcmUuIEFsbCBlbnRyaWVzIGJ1dCB0aGUgbGFzdCBvbmUgYXJlIHJldHVybmVkIGNvcnJlY3RseSwgdGhlIGxhc3QgZW50cnkKKyAqIHlpZWxkcyBhbiBleGNlcHRpb24uCisgKgorICovCitwdWJsaWMgY2xhc3MgTWF2ZW4yMjFNdWx0aVZvbHVtZVRlc3QgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFtdIEVOVFJJRVMgPSBuZXcgU3RyaW5nIFtdIHsKKyAgICAgICAgImFwYWNoZS1tYXZlbi0yLjIuMS8iLAorICAgICAgICAiYXBhY2hlLW1hdmVuLTIuMi4xL0xJQ0VOU0UudHh0IiwKKyAgICAgICAgImFwYWNoZS1tYXZlbi0yLjIuMS9OT1RJQ0UudHh0IiwKKyAgICAgICAgImFwYWNoZS1tYXZlbi0yLjIuMS9SRUFETUUudHh0IiwKKyAgICAgICAgImFwYWNoZS1tYXZlbi0yLjIuMS9iaW4vIiwKKyAgICAgICAgImFwYWNoZS1tYXZlbi0yLjIuMS9iaW4vbTIuY29uZiIsCisgICAgICAgICJhcGFjaGUtbWF2ZW4tMi4yLjEvYmluL212biIsCisgICAgICAgICJhcGFjaGUtbWF2ZW4tMi4yLjEvYmluL212bi5iYXQiLAorICAgICAgICAiYXBhY2hlLW1hdmVuLTIuMi4xL2Jpbi9tdm5EZWJ1ZyIsCisgICAgICAgICJhcGFjaGUtbWF2ZW4tMi4yLjEvYmluL212bkRlYnVnLmJhdCIsCisgICAgICAgICJhcGFjaGUtbWF2ZW4tMi4yLjEvYm9vdC8iLAorICAgICAgICAiYXBhY2hlLW1hdmVuLTIuMi4xL2Jvb3QvY2xhc3N3b3JsZHMtMS4xLmphciIsCisgICAgICAgICJhcGFjaGUtbWF2ZW4tMi4yLjEvY29uZi8iLAorICAgICAgICAiYXBhY2hlLW1hdmVuLTIuMi4xL2NvbmYvc2V0dGluZ3MueG1sIiwKKyAgICAgICAgImFwYWNoZS1tYXZlbi0yLjIuMS9saWIvIgorICAgIH07CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgTEFTVF9FTlRSWV9OQU1FID0KKyAgICAgICAgImFwYWNoZS1tYXZlbi0yLjIuMS9saWIvbWF2ZW4tMi4yLjEtdWJlci5qYXIiOworCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVhZDdaaXBNdWx0aVZvbHVtZUFyY2hpdmVGb3JTdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb24geworCisgICAgICAgIGZpbmFsIEZpbGVJbnB1dFN0cmVhbSBhcmNoaXZlID0KKyAgICAgICAgICAgIG5ldyBGaWxlSW5wdXRTdHJlYW0oZ2V0RmlsZSgiYXBhY2hlLW1hdmVuLTIuMi4xLnppcC4wMDEiKSk7CisgICAgICAgIFppcEFyY2hpdmVJbnB1dFN0cmVhbSB6aSA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB6aSA9IG5ldyBaaXBBcmNoaXZlSW5wdXRTdHJlYW0oYXJjaGl2ZSxudWxsLGZhbHNlKTsKKworICAgICAgICAgICAgLy8gdGhlc2UgYXJlIHRoZSBlbnRyaWVzIHRoYXQgYXJlIHN1cHBvc2VkIHRvIGJlIHByb2Nlc3NlZAorICAgICAgICAgICAgLy8gY29ycmVjdGx5IHdpdGhvdXQgYW55IHByb2JsZW1zCisgICAgICAgICAgICBmb3IgKGZpbmFsIFN0cmluZyBlbGVtZW50IDogRU5UUklFUykgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhlbGVtZW50LCB6aS5nZXROZXh0RW50cnkoKS5nZXROYW1lKCkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyB0aGlzIGlzIHRoZSBsYXN0IGVudHJ5IHRoYXQgaXMgdHJ1bmNhdGVkCisgICAgICAgICAgICBmaW5hbCBBcmNoaXZlRW50cnkgbGFzdEVudHJ5ID0gemkuZ2V0TmV4dEVudHJ5KCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoTEFTVF9FTlRSWV9OQU1FLCBsYXN0RW50cnkuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIGZpbmFsIGJ5dGUgW10gYnVmZmVyID0gbmV3IGJ5dGUgWzQwOTZdOworCisgICAgICAgICAgICAvLyBiZWZvcmUgdGhlIGZpeCwgd2UnZCBnZXQgMCBieXRlcyBvbiB0aGlzIHJlYWQgYW5kIGFsbAorICAgICAgICAgICAgLy8gc3Vic2VxdWVudCByZWFkcyB0aHVzIGEgY2xpZW50IGFwcGxpY2F0aW9uIG1pZ2h0IGVudGVyCisgICAgICAgICAgICAvLyBhbiBpbmZpbml0ZSBsb29wIGFmdGVyIHRoZSBmaXgsIHdlIHNob3VsZCBnZXQgYW4KKyAgICAgICAgICAgIC8vIGV4Y2VwdGlvbgorICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICB3aGlsZSAoemkucmVhZChidWZmZXIpID4gMCkgeyB9CisgICAgICAgICAgICAgICAgZmFpbCgic2hvdWxkbid0IGJlIGFibGUgdG8gcmVhZCBmcm9tIHRydW5jYXRlZCBlbnRyeSIpOworICAgICAgICAgICAgfSBjYXRjaCAoZmluYWwgSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiVHJ1bmNhdGVkIFpJUCBmaWxlIiwgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHppLnJlYWQoYnVmZmVyKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJzaG91bGRuJ3QgYmUgYWJsZSB0byByZWFkIGZyb20gdHJ1bmNhdGVkIGVudHJ5IGFmdGVyIGV4Y2VwdGlvbiIpOworICAgICAgICAgICAgfSBjYXRjaCAoZmluYWwgSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiVHJ1bmNhdGVkIFpJUCBmaWxlIiwgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBhbmQgbm93IHdlIGdldCBhbm90aGVyIGVudHJ5LCB3aGljaCBzaG91bGQgYWxzbyB5aWVsZAorICAgICAgICAgICAgLy8gYW4gZXhjZXB0aW9uCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHppLmdldE5leHRFbnRyeSgpOworICAgICAgICAgICAgICAgIGZhaWwoInNob3VsZG4ndCBiZSBhYmxlIHRvIHJlYWQgYW5vdGhlciBlbnRyeSBmcm9tIHRydW5jYXRlZCIKKyAgICAgICAgICAgICAgICAgICAgICsgIiBmaWxlIik7CisgICAgICAgICAgICB9IGNhdGNoIChmaW5hbCBJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gdGhpcyBpcyB0byBiZSBleHBlY3RlZAorICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKHppICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICB6aS5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QoZXhwZWN0ZWQ9SU9FeGNlcHRpb24uY2xhc3MpCisgICAgcHVibGljIHZvaWQgdGVzdFJlYWQ3WmlwTXVsdGlWb2x1bWVBcmNoaXZlRm9yRmlsZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGUgZmlsZSA9IGdldEZpbGUoImFwYWNoZS1tYXZlbi0yLjIuMS56aXAuMDAxIik7CisgICAgICAgIFppcEZpbGUgemYgPSBuZXcgWmlwRmlsZShmaWxlKTsKKyAgICAgICAgemYuY2xvc2UoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1BhcmFsbGVsU2NhdHRlclppcENyZWF0b3JUZXN0LmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1BhcmFsbGVsU2NhdHRlclppcENyZWF0b3JUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTlhOGZlOQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvUGFyYWxsZWxTY2F0dGVyWmlwQ3JlYXRvclRlc3QuamF2YQpAQCAtMCwwICsxLDE3NCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICoKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcDsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5wYXJhbGxlbC5GaWxlQmFzZWRTY2F0dGVyR2F0aGVyQmFja2luZ1N0b3JlOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5wYXJhbGxlbC5JbnB1dFN0cmVhbVN1cHBsaWVyOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5wYXJhbGxlbC5TY2F0dGVyR2F0aGVyQmFja2luZ1N0b3JlOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5wYXJhbGxlbC5TY2F0dGVyR2F0aGVyQmFja2luZ1N0b3JlU3VwcGxpZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLklPVXRpbHM7CitpbXBvcnQgb3JnLmp1bml0LkFmdGVyOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkNhbGxhYmxlOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dG9yU2VydmljZTsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRvcnM7CitpbXBvcnQgamF2YS51dGlsLnppcC5aaXBFbnRyeTsKKworaW1wb3J0IHN0YXRpYyBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuQWJzdHJhY3RUZXN0Q2FzZS50cnlIYXJkVG9EZWxldGU7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuKjsKKworcHVibGljIGNsYXNzIFBhcmFsbGVsU2NhdHRlclppcENyZWF0b3JUZXN0IHsKKworICAgIHByaXZhdGUgZmluYWwgaW50IE5VTUlURU1TID0gNTAwMDsKKworICAgIHByaXZhdGUgRmlsZSByZXN1bHQ7CisgICAgcHJpdmF0ZSBGaWxlIHRtcDsKKworICAgIEBBZnRlcgorICAgIHB1YmxpYyB2b2lkIGNsZWFudXAoKSB7CisgICAgICAgIHRyeUhhcmRUb0RlbGV0ZShyZXN1bHQpOworICAgICAgICB0cnlIYXJkVG9EZWxldGUodG1wKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIGNvbmN1cnJlbnQoKQorICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHJlc3VsdCA9IEZpbGUuY3JlYXRlVGVtcEZpbGUoInBhcmFsbGVsU2NhdHRlckdhdGhlcjEiLCAiIik7CisgICAgICAgIGZpbmFsIFppcEFyY2hpdmVPdXRwdXRTdHJlYW0gem9zID0gbmV3IFppcEFyY2hpdmVPdXRwdXRTdHJlYW0ocmVzdWx0KTsKKyAgICAgICAgem9zLnNldEVuY29kaW5nKCJVVEYtOCIpOworICAgICAgICBmaW5hbCBQYXJhbGxlbFNjYXR0ZXJaaXBDcmVhdG9yIHppcENyZWF0b3IgPSBuZXcgUGFyYWxsZWxTY2F0dGVyWmlwQ3JlYXRvcigpOworCisgICAgICAgIGZpbmFsIE1hcDxTdHJpbmcsIGJ5dGVbXT4gZW50cmllcyA9IHdyaXRlRW50cmllcyh6aXBDcmVhdG9yKTsKKyAgICAgICAgemlwQ3JlYXRvci53cml0ZVRvKHpvcyk7CisgICAgICAgIHpvcy5jbG9zZSgpOworICAgICAgICByZW1vdmVFbnRyaWVzRm91bmRJblppcEZpbGUocmVzdWx0LCBlbnRyaWVzKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShlbnRyaWVzLnNpemUoKSA9PSAwKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCggemlwQ3JlYXRvci5nZXRTdGF0aXN0aWNzTWVzc2FnZSgpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIGNhbGxhYmxlQXBpKCkKKyAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICByZXN1bHQgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKCJwYXJhbGxlbFNjYXR0ZXJHYXRoZXIyIiwgIiIpOworICAgICAgICBmaW5hbCBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtIHpvcyA9IG5ldyBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtKHJlc3VsdCk7CisgICAgICAgIHpvcy5zZXRFbmNvZGluZygiVVRGLTgiKTsKKyAgICAgICAgZmluYWwgRXhlY3V0b3JTZXJ2aWNlIGVzID0gRXhlY3V0b3JzLm5ld0ZpeGVkVGhyZWFkUG9vbCgxKTsKKworICAgICAgICBmaW5hbCBTY2F0dGVyR2F0aGVyQmFja2luZ1N0b3JlU3VwcGxpZXIgc3VwcCA9IG5ldyBTY2F0dGVyR2F0aGVyQmFja2luZ1N0b3JlU3VwcGxpZXIoKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBTY2F0dGVyR2F0aGVyQmFja2luZ1N0b3JlIGdldCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBGaWxlQmFzZWRTY2F0dGVyR2F0aGVyQmFja2luZ1N0b3JlKHRtcCA9IEZpbGUuY3JlYXRlVGVtcEZpbGUoInBhcmFsbGVsc2NhdHRlciIsICJuMSIpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgICAgICBmaW5hbCBQYXJhbGxlbFNjYXR0ZXJaaXBDcmVhdG9yIHppcENyZWF0b3IgPSBuZXcgUGFyYWxsZWxTY2F0dGVyWmlwQ3JlYXRvcihlcywgc3VwcCk7CisgICAgICAgIGZpbmFsIE1hcDxTdHJpbmcsIGJ5dGVbXT4gZW50cmllcyA9IHdyaXRlRW50cmllc0FzQ2FsbGFibGUoemlwQ3JlYXRvcik7CisgICAgICAgIHppcENyZWF0b3Iud3JpdGVUbyh6b3MpOworICAgICAgICB6b3MuY2xvc2UoKTsKKworCisgICAgICAgIHJlbW92ZUVudHJpZXNGb3VuZEluWmlwRmlsZShyZXN1bHQsIGVudHJpZXMpOworICAgICAgICBhc3NlcnRUcnVlKGVudHJpZXMuc2l6ZSgpID09IDApOworICAgICAgICBhc3NlcnROb3ROdWxsKHppcENyZWF0b3IuZ2V0U3RhdGlzdGljc01lc3NhZ2UoKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHJlbW92ZUVudHJpZXNGb3VuZEluWmlwRmlsZShmaW5hbCBGaWxlIHJlc3VsdCwgZmluYWwgTWFwPFN0cmluZywgYnl0ZVtdPiBlbnRyaWVzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBaaXBGaWxlIHpmID0gbmV3IFppcEZpbGUocmVzdWx0KTsKKyAgICAgICAgZmluYWwgRW51bWVyYXRpb248WmlwQXJjaGl2ZUVudHJ5PiBlbnRyaWVzSW5QaHlzaWNhbE9yZGVyID0gemYuZ2V0RW50cmllc0luUGh5c2ljYWxPcmRlcigpOworICAgICAgICB3aGlsZSAoZW50cmllc0luUGh5c2ljYWxPcmRlci5oYXNNb3JlRWxlbWVudHMoKSl7CisgICAgICAgICAgICBmaW5hbCBaaXBBcmNoaXZlRW50cnkgemlwQXJjaGl2ZUVudHJ5ID0gZW50cmllc0luUGh5c2ljYWxPcmRlci5uZXh0RWxlbWVudCgpOworICAgICAgICAgICAgZmluYWwgSW5wdXRTdHJlYW0gaW5wdXRTdHJlYW0gPSB6Zi5nZXRJbnB1dFN0cmVhbSh6aXBBcmNoaXZlRW50cnkpOworICAgICAgICAgICAgZmluYWwgYnl0ZVtdIGFjdHVhbCA9IElPVXRpbHMudG9CeXRlQXJyYXkoaW5wdXRTdHJlYW0pOworICAgICAgICAgICAgZmluYWwgYnl0ZVtdIGV4cGVjdGVkID0gZW50cmllcy5yZW1vdmUoemlwQXJjaGl2ZUVudHJ5LmdldE5hbWUoKSk7CisgICAgICAgICAgICBhc3NlcnRBcnJheUVxdWFscyggIkZvciAiICsgemlwQXJjaGl2ZUVudHJ5LmdldE5hbWUoKSwgIGV4cGVjdGVkLCBhY3R1YWwpOworICAgICAgICB9CisgICAgICAgIHpmLmNsb3NlKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBNYXA8U3RyaW5nLCBieXRlW10+IHdyaXRlRW50cmllcyhmaW5hbCBQYXJhbGxlbFNjYXR0ZXJaaXBDcmVhdG9yIHppcENyZWF0b3IpIHsKKyAgICAgICAgZmluYWwgTWFwPFN0cmluZywgYnl0ZVtdPiBlbnRyaWVzID0gbmV3IEhhc2hNYXA8PigpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IE5VTUlURU1TOyBpKyspeworICAgICAgICAgICAgZmluYWwgYnl0ZVtdIHBheWxvYWRCeXRlcyA9ICgiY29udGVudCIgKyBpKS5nZXRCeXRlcygpOworICAgICAgICAgICAgZmluYWwgWmlwQXJjaGl2ZUVudHJ5IHphID0gY3JlYXRlWmlwQXJjaGl2ZUVudHJ5KGVudHJpZXMsIGksIHBheWxvYWRCeXRlcyk7CisgICAgICAgICAgICBmaW5hbCBJbnB1dFN0cmVhbVN1cHBsaWVyIGlzcyA9IG5ldyBJbnB1dFN0cmVhbVN1cHBsaWVyKCkgeworICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgIHB1YmxpYyBJbnB1dFN0cmVhbSBnZXQoKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0ocGF5bG9hZEJ5dGVzKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9OworICAgICAgICAgICAgaWYgKGkgJSAyID09IDApIHsKKyAgICAgICAgICAgICAgICB6aXBDcmVhdG9yLmFkZEFyY2hpdmVFbnRyeSh6YSwgaXNzKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZmluYWwgWmlwQXJjaGl2ZUVudHJ5UmVxdWVzdFN1cHBsaWVyIHphU3VwcGxpZXIgPSBuZXcgWmlwQXJjaGl2ZUVudHJ5UmVxdWVzdFN1cHBsaWVyKCkgeworICAgICAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICAgICAgcHVibGljIFppcEFyY2hpdmVFbnRyeVJlcXVlc3QgZ2V0KCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFppcEFyY2hpdmVFbnRyeVJlcXVlc3QuY3JlYXRlWmlwQXJjaGl2ZUVudHJ5UmVxdWVzdCh6YSwgaXNzKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH07CisgICAgICAgICAgICAgICAgemlwQ3JlYXRvci5hZGRBcmNoaXZlRW50cnkoemFTdXBwbGllcik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGVudHJpZXM7CisgICAgfQorCisgICAgcHJpdmF0ZSBNYXA8U3RyaW5nLCBieXRlW10+IHdyaXRlRW50cmllc0FzQ2FsbGFibGUoZmluYWwgUGFyYWxsZWxTY2F0dGVyWmlwQ3JlYXRvciB6aXBDcmVhdG9yKSB7CisgICAgICAgIGZpbmFsIE1hcDxTdHJpbmcsIGJ5dGVbXT4gZW50cmllcyA9IG5ldyBIYXNoTWFwPD4oKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBOVU1JVEVNUzsgaSsrKXsKKyAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBwYXlsb2FkQnl0ZXMgPSAoImNvbnRlbnQiICsgaSkuZ2V0Qnl0ZXMoKTsKKyAgICAgICAgICAgIGZpbmFsIFppcEFyY2hpdmVFbnRyeSB6YSA9IGNyZWF0ZVppcEFyY2hpdmVFbnRyeShlbnRyaWVzLCBpLCBwYXlsb2FkQnl0ZXMpOworICAgICAgICAgICAgZmluYWwgSW5wdXRTdHJlYW1TdXBwbGllciBpc3MgPSBuZXcgSW5wdXRTdHJlYW1TdXBwbGllcigpIHsKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICBwdWJsaWMgSW5wdXRTdHJlYW0gZ2V0KCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKHBheWxvYWRCeXRlcyk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfTsKKyAgICAgICAgICAgIGZpbmFsIENhbGxhYmxlPE9iamVjdD4gY2FsbGFibGU7CisgICAgICAgICAgICBpZiAoaSAlIDIgPT0gMCkgeworICAgICAgICAgICAgICAgIGNhbGxhYmxlID0gemlwQ3JlYXRvci5jcmVhdGVDYWxsYWJsZSh6YSwgaXNzKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZmluYWwgWmlwQXJjaGl2ZUVudHJ5UmVxdWVzdFN1cHBsaWVyIHphU3VwcGxpZXIgPSBuZXcgWmlwQXJjaGl2ZUVudHJ5UmVxdWVzdFN1cHBsaWVyKCkgeworICAgICAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICAgICAgcHVibGljIFppcEFyY2hpdmVFbnRyeVJlcXVlc3QgZ2V0KCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFppcEFyY2hpdmVFbnRyeVJlcXVlc3QuY3JlYXRlWmlwQXJjaGl2ZUVudHJ5UmVxdWVzdCh6YSwgaXNzKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH07CisgICAgICAgICAgICAgICAgY2FsbGFibGUgPSB6aXBDcmVhdG9yLmNyZWF0ZUNhbGxhYmxlKHphU3VwcGxpZXIpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICB6aXBDcmVhdG9yLnN1Ym1pdChjYWxsYWJsZSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGVudHJpZXM7CisgICAgfQorCisgICAgcHJpdmF0ZSBaaXBBcmNoaXZlRW50cnkgY3JlYXRlWmlwQXJjaGl2ZUVudHJ5KGZpbmFsIE1hcDxTdHJpbmcsIGJ5dGVbXT4gZW50cmllcywgZmluYWwgaW50IGksIGZpbmFsIGJ5dGVbXSBwYXlsb2FkQnl0ZXMpIHsKKyAgICAgICAgZmluYWwgWmlwQXJjaGl2ZUVudHJ5IHphID0gbmV3IFppcEFyY2hpdmVFbnRyeSggImZpbGUiICsgaSk7CisgICAgICAgIGVudHJpZXMucHV0KCB6YS5nZXROYW1lKCksIHBheWxvYWRCeXRlcyk7CisgICAgICAgIHphLnNldE1ldGhvZChaaXBFbnRyeS5ERUZMQVRFRCk7CisgICAgICAgIHphLnNldFNpemUocGF5bG9hZEJ5dGVzLmxlbmd0aCk7CisgICAgICAgIHphLnNldFVuaXhNb2RlKFVuaXhTdGF0LkZJTEVfRkxBRyB8IDA2NjQpOworICAgICAgICByZXR1cm4gemE7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9Qa1dhcmVFeHRyYUhlYWRlclRlc3QuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvUGtXYXJlRXh0cmFIZWFkZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2ZlMTczMAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvUGtXYXJlRXh0cmFIZWFkZXJUZXN0LmphdmEKQEAgLTAsMCArMSw0NiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwOworCitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0RXF1YWxzOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydE5vdE51bGw7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcC5QS1dhcmVFeHRyYUhlYWRlci5FbmNyeXB0aW9uQWxnb3JpdGhtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwLlBLV2FyZUV4dHJhSGVhZGVyLkhhc2hBbGdvcml0aG07CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CisKK3B1YmxpYyBjbGFzcyBQa1dhcmVFeHRyYUhlYWRlclRlc3QgeworCisgICAgQFRlc3QgcHVibGljIHZvaWQgdGVzdEVuY3J5cHRpb25BbGdvcml0aG0oKSB7CisgICAgICAgIFN0cmluZyBuYW1lID0gIkFFUzI1NiI7CisgICAgICAgIGludCBjb2RlID0gRW5jcnlwdGlvbkFsZ29yaXRobS5BRVMyNTYuZ2V0Q29kZSgpOworICAgICAgICBFbmNyeXB0aW9uQWxnb3JpdGhtIGUgPSBFbmNyeXB0aW9uQWxnb3JpdGhtLnZhbHVlT2YobmFtZSk7CisgICAgICAgIGFzc2VydEVxdWFscyhjb2RlLGUuZ2V0Q29kZSgpKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChlKTsKKyAgICB9CisKKyAgICBAVGVzdCBwdWJsaWMgdm9pZCB0ZXN0SGFzaEFsZ29yaXRobSgpIHsKKyAgICAgICAgU3RyaW5nIG5hbWUgPSAiU0hBMjU2IjsKKyAgICAgICAgaW50IGNvZGUgPSBIYXNoQWxnb3JpdGhtLlNIQTI1Ni5nZXRDb2RlKCk7CisgICAgICAgIEhhc2hBbGdvcml0aG0gZSA9IEhhc2hBbGdvcml0aG0udmFsdWVPZihuYW1lKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGNvZGUsZS5nZXRDb2RlKCkpOworICAgICAgICBhc3NlcnROb3ROdWxsKGUpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9TY2F0dGVyU2FtcGxlLmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1NjYXR0ZXJTYW1wbGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kZWI3YTdlCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9TY2F0dGVyU2FtcGxlLmphdmEKQEAgLTAsMCArMSw0OCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICoKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcDsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5wYXJhbGxlbC5JbnB1dFN0cmVhbVN1cHBsaWVyOworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0aW9uRXhjZXB0aW9uOworCitwdWJsaWMgY2xhc3MgU2NhdHRlclNhbXBsZSB7CisKKyAgICBQYXJhbGxlbFNjYXR0ZXJaaXBDcmVhdG9yIHNjYXR0ZXJaaXBDcmVhdG9yID0gbmV3IFBhcmFsbGVsU2NhdHRlclppcENyZWF0b3IoKTsKKyAgICBTY2F0dGVyWmlwT3V0cHV0U3RyZWFtIGRpcnMgPSBTY2F0dGVyWmlwT3V0cHV0U3RyZWFtLmZpbGVCYXNlZChGaWxlLmNyZWF0ZVRlbXBGaWxlKCJzY2F0dGVyLWRpcnMiLCAidG1wIikpOworCisgICAgcHVibGljIFNjYXR0ZXJTYW1wbGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGFkZEVudHJ5KGZpbmFsIFppcEFyY2hpdmVFbnRyeSB6aXBBcmNoaXZlRW50cnksIGZpbmFsIElucHV0U3RyZWFtU3VwcGxpZXIgc3RyZWFtU3VwcGxpZXIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICh6aXBBcmNoaXZlRW50cnkuaXNEaXJlY3RvcnkoKSAmJiAhemlwQXJjaGl2ZUVudHJ5LmlzVW5peFN5bWxpbmsoKSkgeworICAgICAgICAgICAgZGlycy5hZGRBcmNoaXZlRW50cnkoWmlwQXJjaGl2ZUVudHJ5UmVxdWVzdC5jcmVhdGVaaXBBcmNoaXZlRW50cnlSZXF1ZXN0KHppcEFyY2hpdmVFbnRyeSwgc3RyZWFtU3VwcGxpZXIpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHNjYXR0ZXJaaXBDcmVhdG9yLmFkZEFyY2hpdmVFbnRyeSggemlwQXJjaGl2ZUVudHJ5LCBzdHJlYW1TdXBwbGllcik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGZpbmFsIFppcEFyY2hpdmVPdXRwdXRTdHJlYW0gemlwQXJjaGl2ZU91dHB1dFN0cmVhbSkKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgRXhlY3V0aW9uRXhjZXB0aW9uLCBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIGRpcnMud3JpdGVUbyh6aXBBcmNoaXZlT3V0cHV0U3RyZWFtKTsKKyAgICAgICAgZGlycy5jbG9zZSgpOworICAgICAgICBzY2F0dGVyWmlwQ3JlYXRvci53cml0ZVRvKHppcEFyY2hpdmVPdXRwdXRTdHJlYW0pOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvU2NhdHRlclNhbXBsZVRlc3QuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvU2NhdHRlclNhbXBsZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kOTRmMjk0Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9TY2F0dGVyU2FtcGxlVGVzdC5qYXZhCkBAIC0wLDAgKzEsNzMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXA7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MucGFyYWxsZWwuSW5wdXRTdHJlYW1TdXBwbGllcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuSU9VdGlsczsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRpb25FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLnppcC5aaXBFbnRyeTsKKworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0Lio7CisKK3B1YmxpYyBjbGFzcyBTY2F0dGVyU2FtcGxlVGVzdCB7CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RTYW1wbGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgRmlsZSByZXN1bHQgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKCJ0ZXN0U2FtcGxlIiwgImZlIik7CisKKyAgICAgICAgY3JlYXRlRmlsZShyZXN1bHQpOworICAgICAgICBjaGVja0ZpbGUocmVzdWx0KTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY3JlYXRlRmlsZShmaW5hbCBGaWxlIHJlc3VsdCkgdGhyb3dzIElPRXhjZXB0aW9uLCBFeGVjdXRpb25FeGNlcHRpb24sIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgU2NhdHRlclNhbXBsZSBzY2F0dGVyU2FtcGxlID0gbmV3IFNjYXR0ZXJTYW1wbGUoKTsKKyAgICAgICAgZmluYWwgWmlwQXJjaGl2ZUVudHJ5IGFyY2hpdmVFbnRyeSA9IG5ldyBaaXBBcmNoaXZlRW50cnkoInRlc3QxLnhtbCIpOworICAgICAgICBhcmNoaXZlRW50cnkuc2V0TWV0aG9kKFppcEVudHJ5LkRFRkxBVEVEKTsKKyAgICAgICAgZmluYWwgSW5wdXRTdHJlYW1TdXBwbGllciBzdXBwID0gbmV3IElucHV0U3RyZWFtU3VwcGxpZXIoKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBJbnB1dFN0cmVhbSBnZXQoKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbSgiSGVsbG8iLmdldEJ5dGVzKCkpOworICAgICAgICAgICAgfQorICAgICAgICB9OworCisgICAgICAgIHNjYXR0ZXJTYW1wbGUuYWRkRW50cnkoYXJjaGl2ZUVudHJ5LCBzdXBwKTsKKyAgICAgICAgZmluYWwgWmlwQXJjaGl2ZU91dHB1dFN0cmVhbSB6aXBBcmNoaXZlT3V0cHV0U3RyZWFtID0gbmV3IFppcEFyY2hpdmVPdXRwdXRTdHJlYW0ocmVzdWx0KTsKKyAgICAgICAgc2NhdHRlclNhbXBsZS53cml0ZVRvKHppcEFyY2hpdmVPdXRwdXRTdHJlYW0pOworICAgICAgICB6aXBBcmNoaXZlT3V0cHV0U3RyZWFtLmNsb3NlKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrRmlsZShmaW5hbCBGaWxlIHJlc3VsdCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgWmlwRmlsZSB6ZiA9IG5ldyBaaXBGaWxlKHJlc3VsdCk7CisgICAgICAgIGZpbmFsIFppcEFyY2hpdmVFbnRyeSBhcmNoaXZlRW50cnkxID0gemYuZ2V0RW50cmllcygpLm5leHRFbGVtZW50KCk7CisgICAgICAgIGFzc2VydEVxdWFscyggInRlc3QxLnhtbCIsIGFyY2hpdmVFbnRyeTEuZ2V0TmFtZSgpKTsKKyAgICAgICAgZmluYWwgSW5wdXRTdHJlYW0gaW5wdXRTdHJlYW0gPSB6Zi5nZXRJbnB1dFN0cmVhbShhcmNoaXZlRW50cnkxKTsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGIgPSBuZXcgYnl0ZVs2XTsKKyAgICAgICAgZmluYWwgaW50IGkgPSBJT1V0aWxzLnJlYWRGdWxseShpbnB1dFN0cmVhbSwgYik7CisgICAgICAgIGFzc2VydEVxdWFscyg1LCBpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCdIJywgYlswXSk7CisgICAgICAgIGFzc2VydEVxdWFscygnbycsIGJbNF0pOworICAgICAgICB6Zi5jbG9zZSgpOworICAgICAgICByZXN1bHQuZGVsZXRlKCk7CisgICAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvU2NhdHRlclppcE91dHB1dFN0cmVhbVRlc3QuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvU2NhdHRlclppcE91dHB1dFN0cmVhbVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMjRjZjlhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9TY2F0dGVyWmlwT3V0cHV0U3RyZWFtVGVzdC5qYXZhCkBAIC0wLDAgKzEsODggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXA7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MucGFyYWxsZWwuSW5wdXRTdHJlYW1TdXBwbGllcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuSU9VdGlsczsKK2ltcG9ydCBvcmcuanVuaXQuQWZ0ZXI7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC56aXAuWmlwRW50cnk7CisKK2ltcG9ydCBzdGF0aWMgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLkFic3RyYWN0VGVzdENhc2UudHJ5SGFyZFRvRGVsZXRlOworaW1wb3J0IHN0YXRpYyBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcC5aaXBBcmNoaXZlRW50cnlSZXF1ZXN0LmNyZWF0ZVppcEFyY2hpdmVFbnRyeVJlcXVlc3Q7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0QXJyYXlFcXVhbHM7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0RXF1YWxzOworCitwdWJsaWMgY2xhc3MgU2NhdHRlclppcE91dHB1dFN0cmVhbVRlc3QgeworCisgICAgcHJpdmF0ZSBGaWxlIHNjYXR0ZXJGaWxlID0gbnVsbDsKKyAgICBwcml2YXRlIEZpbGUgdGFyZ2V0ID0gbnVsbDsKKworICAgIEBBZnRlcgorICAgIHB1YmxpYyB2b2lkIGNsZWFudXAoKSB7CisgICAgICAgIHRyeUhhcmRUb0RlbGV0ZShzY2F0dGVyRmlsZSk7CisgICAgICAgIHRyeUhhcmRUb0RlbGV0ZSh0YXJnZXQpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgcHV0QXJjaGl2ZUVudHJ5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHNjYXR0ZXJGaWxlID0gRmlsZS5jcmVhdGVUZW1wRmlsZSgic2NhdHRlcnRlc3QiLCAiLm5vdHppcCIpOworICAgICAgICBmaW5hbCBTY2F0dGVyWmlwT3V0cHV0U3RyZWFtIHNjYXR0ZXJaaXBPdXRwdXRTdHJlYW0gPSBTY2F0dGVyWmlwT3V0cHV0U3RyZWFtLmZpbGVCYXNlZChzY2F0dGVyRmlsZSk7CisgICAgICAgIGZpbmFsIGJ5dGVbXSBCX1BBWUxPQUQgPSAiUkJCQkJCQlMiLmdldEJ5dGVzKCk7CisgICAgICAgIGZpbmFsIGJ5dGVbXSBBX1BBWUxPQUQgPSAiWEFBWSIuZ2V0Qnl0ZXMoKTsKKworICAgICAgICBmaW5hbCBaaXBBcmNoaXZlRW50cnkgemFiID0gbmV3IFppcEFyY2hpdmVFbnRyeSgiYi50eHQiKTsKKyAgICAgICAgemFiLnNldE1ldGhvZChaaXBFbnRyeS5ERUZMQVRFRCk7CisgICAgICAgIGZpbmFsIEJ5dGVBcnJheUlucHV0U3RyZWFtIHBheWxvYWQgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oQl9QQVlMT0FEKTsKKyAgICAgICAgc2NhdHRlclppcE91dHB1dFN0cmVhbS5hZGRBcmNoaXZlRW50cnkoY3JlYXRlWmlwQXJjaGl2ZUVudHJ5UmVxdWVzdCh6YWIsIGNyZWF0ZVBheWxvYWRTdXBwbGllcihwYXlsb2FkKSkpOworCisgICAgICAgIGZpbmFsIFppcEFyY2hpdmVFbnRyeSB6YWUgPSBuZXcgWmlwQXJjaGl2ZUVudHJ5KCJhLnR4dCIpOworICAgICAgICB6YWUuc2V0TWV0aG9kKFppcEVudHJ5LkRFRkxBVEVEKTsKKyAgICAgICAgZmluYWwgQnl0ZUFycmF5SW5wdXRTdHJlYW0gcGF5bG9hZDEgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oQV9QQVlMT0FEKTsKKyAgICAgICAgc2NhdHRlclppcE91dHB1dFN0cmVhbS5hZGRBcmNoaXZlRW50cnkoY3JlYXRlWmlwQXJjaGl2ZUVudHJ5UmVxdWVzdCh6YWUsIGNyZWF0ZVBheWxvYWRTdXBwbGllcihwYXlsb2FkMSkpKTsKKworICAgICAgICB0YXJnZXQgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKCJzY2F0dGVydGVzdCIsICIuemlwIik7CisgICAgICAgIGZpbmFsIFppcEFyY2hpdmVPdXRwdXRTdHJlYW0gb3V0cHV0U3RyZWFtID0gbmV3IFppcEFyY2hpdmVPdXRwdXRTdHJlYW0odGFyZ2V0KTsKKyAgICAgICAgc2NhdHRlclppcE91dHB1dFN0cmVhbS53cml0ZVRvKCBvdXRwdXRTdHJlYW0pOworICAgICAgICBvdXRwdXRTdHJlYW0uY2xvc2UoKTsKKyAgICAgICAgc2NhdHRlclppcE91dHB1dFN0cmVhbS5jbG9zZSgpOworCisgICAgICAgIGZpbmFsIFppcEZpbGUgemYgPSBuZXcgWmlwRmlsZSh0YXJnZXQpOworICAgICAgICBmaW5hbCBaaXBBcmNoaXZlRW50cnkgYl9lbnRyeSA9IHpmLmdldEVudHJpZXMoImIudHh0IikuaXRlcmF0b3IoKS5uZXh0KCk7CisgICAgICAgIGFzc2VydEVxdWFscyg4LCBiX2VudHJ5LmdldFNpemUoKSk7CisgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKEJfUEFZTE9BRCwgSU9VdGlscy50b0J5dGVBcnJheSh6Zi5nZXRJbnB1dFN0cmVhbShiX2VudHJ5KSkpOworCisgICAgICAgIGZpbmFsIFppcEFyY2hpdmVFbnRyeSBhX2VudHJ5ID0gemYuZ2V0RW50cmllcygiYS50eHQiKS5pdGVyYXRvcigpLm5leHQoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDQsIGFfZW50cnkuZ2V0U2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMoQV9QQVlMT0FELCBJT1V0aWxzLnRvQnl0ZUFycmF5KHpmLmdldElucHV0U3RyZWFtKGFfZW50cnkpKSk7CisgICAgICAgIHpmLmNsb3NlKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBJbnB1dFN0cmVhbVN1cHBsaWVyIGNyZWF0ZVBheWxvYWRTdXBwbGllcihmaW5hbCBCeXRlQXJyYXlJbnB1dFN0cmVhbSBwYXlsb2FkKSB7CisgICAgICAgIHJldHVybiBuZXcgSW5wdXRTdHJlYW1TdXBwbGllcigpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIElucHV0U3RyZWFtIGdldCgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gcGF5bG9hZDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1N0cmVhbUNvbXByZXNzb3JUZXN0LmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1N0cmVhbUNvbXByZXNzb3JUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzhlZDUzMQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvU3RyZWFtQ29tcHJlc3NvclRlc3QuamF2YQpAQCAtMCwwICsxLDcxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwOworCitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0QXJyYXlFcXVhbHM7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0RXF1YWxzOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydE5vdE51bGw7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRGF0YU91dHB1dDsKK2ltcG9ydCBqYXZhLmlvLkRhdGFPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLkRlZmxhdGVyOworaW1wb3J0IGphdmEudXRpbC56aXAuWmlwRW50cnk7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CisKK3B1YmxpYyBjbGFzcyBTdHJlYW1Db21wcmVzc29yVGVzdCB7CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHN0b3JlZEVudHJpZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJhb3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIGZpbmFsIFN0cmVhbUNvbXByZXNzb3Igc2MgPSBTdHJlYW1Db21wcmVzc29yLmNyZWF0ZSggYmFvcyk7CisgICAgICAgIHNjLmRlZmxhdGUobmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKCJBIi5nZXRCeXRlcygpKSwgWmlwRW50cnkuU1RPUkVEKTsKKyAgICAgICAgc2MuZGVmbGF0ZShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oIkJBRCIuZ2V0Qnl0ZXMoKSksIFppcEVudHJ5LlNUT1JFRCk7CisgICAgICAgIGFzc2VydEVxdWFscygzLCBzYy5nZXRCeXRlc1JlYWQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygzLCBzYy5nZXRCeXRlc1dyaXR0ZW5Gb3JMYXN0RW50cnkoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygzNDQ3NTA5NjEsIHNjLmdldENyYzMyKCkpOworICAgICAgICBzYy5kZWZsYXRlKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbSgiQ0FGRSIuZ2V0Qnl0ZXMoKSksIFppcEVudHJ5LlNUT1JFRCk7CisgICAgICAgIGFzc2VydEVxdWFscygiQUJBRENBRkUiLCBiYW9zLnRvU3RyaW5nKCkpOworICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBkZWZsYXRlZEVudHJpZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJhb3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIGZpbmFsIFN0cmVhbUNvbXByZXNzb3Igc2MgPSBTdHJlYW1Db21wcmVzc29yLmNyZWF0ZSggYmFvcyk7CisgICAgICAgIHNjLmRlZmxhdGUobmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKCJBQUFBQUFCQkJCQkIiLmdldEJ5dGVzKCkpLCBaaXBFbnRyeS5ERUZMQVRFRCk7CisgICAgICAgIGFzc2VydEVxdWFscygxMiwgc2MuZ2V0Qnl0ZXNSZWFkKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoOCwgc2MuZ2V0Qnl0ZXNXcml0dGVuRm9yTGFzdEVudHJ5KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMzI5OTU0Miwgc2MuZ2V0Q3JjMzIoKSk7CisKKyAgICAgICAgZmluYWwgYnl0ZVtdIGFjdHVhbHMgPSBiYW9zLnRvQnl0ZUFycmF5KCk7CisgICAgICAgIGZpbmFsIGJ5dGVbXSBleHBlY3RlZCA9IG5ldyBieXRlW117MTE1LDExNiw0LDEsMzksNDgsMCwwfTsKKyAgICAgICAgLy8gTm90ZSB0aGF0IHRoaXMgdGVzdCByZWFsbHkgYXNzZXJ0cyBzdHVmZiBhYm91dCB0aGUgamF2YSBEZWZsYXRlciwgd2hpY2ggbWlnaHQgYmUgYSBsaXR0bGUgYml0IGJyaXR0bGUKKyAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMoZXhwZWN0ZWQsIGFjdHVhbHMpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdENyZWF0ZURhdGFPdXRwdXRDb21wcmVzc29yKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgRGF0YU91dHB1dCBkYXRhT3V0cHV0U3RyZWFtID0gbmV3IERhdGFPdXRwdXRTdHJlYW0obmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpKTsKKyAgICAgICAgdHJ5IChTdHJlYW1Db21wcmVzc29yIHN0cmVhbUNvbXByZXNzb3IgPSBTdHJlYW1Db21wcmVzc29yCisgICAgICAgICAgICAuY3JlYXRlKGRhdGFPdXRwdXRTdHJlYW0sIG5ldyBEZWZsYXRlcig5KSkpIHsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoc3RyZWFtQ29tcHJlc3Nvcik7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1VURjhaaXBGaWxlc1Rlc3QuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvVVRGOFppcEZpbGVzVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRhOWJiMjQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1VURjhaaXBGaWxlc1Rlc3QuamF2YQpAQCAtMCwwICsxLDQwOCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICoKKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwOworCitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuKjsKKworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5VbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLkJ5dGVCdWZmZXI7CitpbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOworaW1wb3J0IGphdmEudXRpbC56aXAuQ1JDMzI7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuQWJzdHJhY3RUZXN0Q2FzZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuQ2hhcnNldE5hbWVzOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworCitwdWJsaWMgY2xhc3MgVVRGOFppcEZpbGVzVGVzdCBleHRlbmRzIEFic3RyYWN0VGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIENQNDM3ID0gImNwNDM3IjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVNDSUlfVFhUID0gImFzY2lpLnR4dCI7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEVVUk9fRk9SX0RPTExBUl9UWFQgPSAiXHUyMEFDX2Zvcl9Eb2xsYXIudHh0IjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgT0lMX0JBUlJFTF9UWFQgPSAiXHUwMEQ2bGZcdTAwRTRzc2VyLnR4dCI7CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RVdGY4RmlsZVJvdW5kdHJpcEV4cGxpY2l0VW5pY29kZUV4dHJhKCkKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdEZpbGVSb3VuZHRyaXAoQ2hhcnNldE5hbWVzLlVURl84LCB0cnVlLCB0cnVlKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RVdGY4RmlsZVJvdW5kdHJpcE5vRUZTRXhwbGljaXRVbmljb2RlRXh0cmEoKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0ZXN0RmlsZVJvdW5kdHJpcChDaGFyc2V0TmFtZXMuVVRGXzgsIGZhbHNlLCB0cnVlKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RDUDQzN0ZpbGVSb3VuZHRyaXBFeHBsaWNpdFVuaWNvZGVFeHRyYSgpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RGaWxlUm91bmR0cmlwKENQNDM3LCBmYWxzZSwgdHJ1ZSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QVNDSUlGaWxlUm91bmR0cmlwRXhwbGljaXRVbmljb2RlRXh0cmEoKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0ZXN0RmlsZVJvdW5kdHJpcChDaGFyc2V0TmFtZXMuVVNfQVNDSUksIGZhbHNlLCB0cnVlKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RVdGY4RmlsZVJvdW5kdHJpcEltcGxpY2l0VW5pY29kZUV4dHJhKCkKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdEZpbGVSb3VuZHRyaXAoQ2hhcnNldE5hbWVzLlVURl84LCB0cnVlLCBmYWxzZSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VXRmOEZpbGVSb3VuZHRyaXBOb0VGU0ltcGxpY2l0VW5pY29kZUV4dHJhKCkKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdEZpbGVSb3VuZHRyaXAoQ2hhcnNldE5hbWVzLlVURl84LCBmYWxzZSwgZmFsc2UpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdENQNDM3RmlsZVJvdW5kdHJpcEltcGxpY2l0VW5pY29kZUV4dHJhKCkKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdEZpbGVSb3VuZHRyaXAoQ1A0MzcsIGZhbHNlLCBmYWxzZSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QVNDSUlGaWxlUm91bmR0cmlwSW1wbGljaXRVbmljb2RlRXh0cmEoKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0ZXN0RmlsZVJvdW5kdHJpcChDaGFyc2V0TmFtZXMuVVNfQVNDSUksIGZhbHNlLCBmYWxzZSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiA3LVpJUCBjcmVhdGVkIGFyY2hpdmUsIHVzZXMgRUZTIHRvIHNpZ25hbCBVVEYtOCBmaWxlbmFtZXMuCisgICAgICoKKyAgICAgKiA3LVpJUCBkb2Vzbid0IHVzZSBFRlMgZm9yIHN0cmluZ3MgdGhhdCBjYW4gYmUgZW5jb2RlZCBpbiBDUDQzNworICAgICAqIC0gd2hpY2ggaXMgdHJ1ZSBmb3IgT0lMX0JBUlJFTF9UWFQuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVhZDdaaXBBcmNoaXZlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgRmlsZSBhcmNoaXZlID0gZ2V0RmlsZSgidXRmOC03emlwLXRlc3QuemlwIik7CisgICAgICAgIFppcEZpbGUgemYgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgemYgPSBuZXcgWmlwRmlsZShhcmNoaXZlLCBDUDQzNywgZmFsc2UpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCh6Zi5nZXRFbnRyeShBU0NJSV9UWFQpKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoemYuZ2V0RW50cnkoRVVST19GT1JfRE9MTEFSX1RYVCkpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCh6Zi5nZXRFbnRyeShPSUxfQkFSUkVMX1RYVCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgWmlwRmlsZS5jbG9zZVF1aWV0bHkoemYpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVhZDdaaXBBcmNoaXZlRm9yU3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgRmlsZUlucHV0U3RyZWFtIGFyY2hpdmUgPQorICAgICAgICAgICAgbmV3IEZpbGVJbnB1dFN0cmVhbShnZXRGaWxlKCJ1dGY4LTd6aXAtdGVzdC56aXAiKSk7CisgICAgICAgIFppcEFyY2hpdmVJbnB1dFN0cmVhbSB6aSA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB6aSA9IG5ldyBaaXBBcmNoaXZlSW5wdXRTdHJlYW0oYXJjaGl2ZSwgQ1A0MzcsIGZhbHNlKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhBU0NJSV9UWFQsIHppLmdldE5leHRFbnRyeSgpLmdldE5hbWUoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoT0lMX0JBUlJFTF9UWFQsIHppLmdldE5leHRFbnRyeSgpLmdldE5hbWUoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoRVVST19GT1JfRE9MTEFSX1RYVCwgemkuZ2V0TmV4dEVudHJ5KCkuZ2V0TmFtZSgpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmICh6aSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgemkuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogV2luWklQIGNyZWF0ZWQgYXJjaGl2ZSwgdXNlcyBVbmljb2RlIEV4dHJhIEZpZWxkcyBidXQgb25seSBpbgorICAgICAqIHRoZSBjZW50cmFsIGRpcmVjdG9yeS4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RSZWFkV2luWmlwQXJjaGl2ZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGUgYXJjaGl2ZSA9IGdldEZpbGUoInV0Zjgtd2luemlwLXRlc3QuemlwIik7CisgICAgICAgIFppcEZpbGUgemYgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgemYgPSBuZXcgWmlwRmlsZShhcmNoaXZlLCBudWxsLCB0cnVlKTsKKyAgICAgICAgICAgIGFzc2VydENhblJlYWQoemYsIEFTQ0lJX1RYVCk7CisgICAgICAgICAgICBhc3NlcnRDYW5SZWFkKHpmLCBFVVJPX0ZPUl9ET0xMQVJfVFhUKTsKKyAgICAgICAgICAgIGFzc2VydENhblJlYWQoemYsIE9JTF9CQVJSRUxfVFhUKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIFppcEZpbGUuY2xvc2VRdWlldGx5KHpmKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhc3NlcnRDYW5SZWFkKGZpbmFsIFppcEZpbGUgemYsIGZpbmFsIFN0cmluZyBmaWxlTmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgWmlwQXJjaGl2ZUVudHJ5IGVudHJ5ID0gemYuZ2V0RW50cnkoZmlsZU5hbWUpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJFbnRyeSBkb2Vzbid0IGV4aXN0IiwgZW50cnkpOworICAgICAgICBmaW5hbCBJbnB1dFN0cmVhbSBpcyA9IHpmLmdldElucHV0U3RyZWFtKGVudHJ5KTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiSW5wdXRTdHJlYW0gaXMgbnVsbCIsIGlzKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlzLnJlYWQoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlzLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RSZWFkV2luWmlwQXJjaGl2ZUZvclN0cmVhbSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGVJbnB1dFN0cmVhbSBhcmNoaXZlID0KKyAgICAgICAgICAgIG5ldyBGaWxlSW5wdXRTdHJlYW0oZ2V0RmlsZSgidXRmOC13aW56aXAtdGVzdC56aXAiKSk7CisgICAgICAgIFppcEFyY2hpdmVJbnB1dFN0cmVhbSB6aSA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB6aSA9IG5ldyBaaXBBcmNoaXZlSW5wdXRTdHJlYW0oYXJjaGl2ZSwgbnVsbCwgdHJ1ZSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoRVVST19GT1JfRE9MTEFSX1RYVCwgemkuZ2V0TmV4dEVudHJ5KCkuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhPSUxfQkFSUkVMX1RYVCwgemkuZ2V0TmV4dEVudHJ5KCkuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhBU0NJSV9UWFQsIHppLmdldE5leHRFbnRyeSgpLmdldE5hbWUoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAoemkgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHppLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RaaXBGaWxlUmVhZHNVbmljb2RlRmllbGRzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgRmlsZSBmaWxlID0gRmlsZS5jcmVhdGVUZW1wRmlsZSgidW5pY29kZS10ZXN0IiwgIi56aXAiKTsKKyAgICAgICAgZmlsZS5kZWxldGVPbkV4aXQoKTsKKyAgICAgICAgWmlwQXJjaGl2ZUlucHV0U3RyZWFtIHppID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNyZWF0ZVRlc3RGaWxlKGZpbGUsIENoYXJzZXROYW1lcy5VU19BU0NJSSwgZmFsc2UsIHRydWUpOworICAgICAgICAgICAgZmluYWwgRmlsZUlucHV0U3RyZWFtIGFyY2hpdmUgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGUpOworICAgICAgICAgICAgemkgPSBuZXcgWmlwQXJjaGl2ZUlucHV0U3RyZWFtKGFyY2hpdmUsIENoYXJzZXROYW1lcy5VU19BU0NJSSwgdHJ1ZSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoT0lMX0JBUlJFTF9UWFQsIHppLmdldE5leHRFbnRyeSgpLmdldE5hbWUoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoRVVST19GT1JfRE9MTEFSX1RYVCwgemkuZ2V0TmV4dEVudHJ5KCkuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhBU0NJSV9UWFQsIHppLmdldE5leHRFbnRyeSgpLmdldE5hbWUoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAoemkgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHppLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnlIYXJkVG9EZWxldGUoZmlsZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RaaXBBcmNoaXZlSW5wdXRTdHJlYW1SZWFkc1VuaWNvZGVGaWVsZHMoKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlIGZpbGUgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKCJ1bmljb2RlLXRlc3QiLCAiLnppcCIpOworICAgICAgICBmaWxlLmRlbGV0ZU9uRXhpdCgpOworICAgICAgICBaaXBGaWxlIHpmID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNyZWF0ZVRlc3RGaWxlKGZpbGUsIENoYXJzZXROYW1lcy5VU19BU0NJSSwgZmFsc2UsIHRydWUpOworICAgICAgICAgICAgemYgPSBuZXcgWmlwRmlsZShmaWxlLCBDaGFyc2V0TmFtZXMuVVNfQVNDSUksIHRydWUpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCh6Zi5nZXRFbnRyeShBU0NJSV9UWFQpKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoemYuZ2V0RW50cnkoRVVST19GT1JfRE9MTEFSX1RYVCkpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCh6Zi5nZXRFbnRyeShPSUxfQkFSUkVMX1RYVCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgWmlwRmlsZS5jbG9zZVF1aWV0bHkoemYpOworICAgICAgICAgICAgdHJ5SGFyZFRvRGVsZXRlKGZpbGUpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmF3TmFtZVJlYWRGcm9tWmlwRmlsZSgpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGUgYXJjaGl2ZSA9IGdldEZpbGUoInV0ZjgtN3ppcC10ZXN0LnppcCIpOworICAgICAgICBaaXBGaWxlIHpmID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHpmID0gbmV3IFppcEZpbGUoYXJjaGl2ZSwgQ1A0MzcsIGZhbHNlKTsKKyAgICAgICAgICAgIGFzc2VydFJhd05hbWVPZkFjc2lpVHh0KHpmLmdldEVudHJ5KEFTQ0lJX1RYVCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgWmlwRmlsZS5jbG9zZVF1aWV0bHkoemYpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmF3TmFtZVJlYWRGcm9tU3RyZWFtKCkKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgRmlsZUlucHV0U3RyZWFtIGFyY2hpdmUgPQorICAgICAgICAgICAgbmV3IEZpbGVJbnB1dFN0cmVhbShnZXRGaWxlKCJ1dGY4LTd6aXAtdGVzdC56aXAiKSk7CisgICAgICAgIFppcEFyY2hpdmVJbnB1dFN0cmVhbSB6aSA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB6aSA9IG5ldyBaaXBBcmNoaXZlSW5wdXRTdHJlYW0oYXJjaGl2ZSwgQ1A0MzcsIGZhbHNlKTsKKyAgICAgICAgICAgIGFzc2VydFJhd05hbWVPZkFjc2lpVHh0KChaaXBBcmNoaXZlRW50cnkpIHppLmdldE5leHRFbnRyeSgpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmICh6aSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgemkuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgdGVzdEZpbGVSb3VuZHRyaXAoZmluYWwgU3RyaW5nIGVuY29kaW5nLCBmaW5hbCBib29sZWFuIHdpdGhFRlMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBib29sZWFuIHdpdGhFeHBsaWNpdFVuaWNvZGVFeHRyYSkKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKworICAgICAgICBmaW5hbCBGaWxlIGZpbGUgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKGVuY29kaW5nICsgIi10ZXN0IiwgIi56aXAiKTsKKyAgICAgICAgZmlsZS5kZWxldGVPbkV4aXQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNyZWF0ZVRlc3RGaWxlKGZpbGUsIGVuY29kaW5nLCB3aXRoRUZTLCB3aXRoRXhwbGljaXRVbmljb2RlRXh0cmEpOworICAgICAgICAgICAgdGVzdEZpbGUoZmlsZSwgZW5jb2RpbmcpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5SGFyZFRvRGVsZXRlKGZpbGUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBjcmVhdGVUZXN0RmlsZShmaW5hbCBGaWxlIGZpbGUsIGZpbmFsIFN0cmluZyBlbmNvZGluZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGJvb2xlYW4gd2l0aEVGUywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGJvb2xlYW4gd2l0aEV4cGxpY2l0VW5pY29kZUV4dHJhKQorICAgICAgICB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworCisgICAgICAgIGZpbmFsIFppcEVuY29kaW5nIHppcEVuY29kaW5nID0gWmlwRW5jb2RpbmdIZWxwZXIuZ2V0WmlwRW5jb2RpbmcoZW5jb2RpbmcpOworCisgICAgICAgIFppcEFyY2hpdmVPdXRwdXRTdHJlYW0gem9zID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHpvcyA9IG5ldyBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtKGZpbGUpOworICAgICAgICAgICAgem9zLnNldEVuY29kaW5nKGVuY29kaW5nKTsKKyAgICAgICAgICAgIHpvcy5zZXRVc2VMYW5ndWFnZUVuY29kaW5nRmxhZyh3aXRoRUZTKTsKKyAgICAgICAgICAgIHpvcy5zZXRDcmVhdGVVbmljb2RlRXh0cmFGaWVsZHMod2l0aEV4cGxpY2l0VW5pY29kZUV4dHJhID8KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWmlwQXJjaGl2ZU91dHB1dFN0cmVhbQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuVW5pY29kZUV4dHJhRmllbGRQb2xpY3kuTkVWRVIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5Vbmljb2RlRXh0cmFGaWVsZFBvbGljeS5BTFdBWVMpOworCisgICAgICAgICAgICBaaXBBcmNoaXZlRW50cnkgemUgPSBuZXcgWmlwQXJjaGl2ZUVudHJ5KE9JTF9CQVJSRUxfVFhUKTsKKyAgICAgICAgICAgIGlmICh3aXRoRXhwbGljaXRVbmljb2RlRXh0cmEKKyAgICAgICAgICAgICAgICAmJiAhemlwRW5jb2RpbmcuY2FuRW5jb2RlKHplLmdldE5hbWUoKSkpIHsKKworICAgICAgICAgICAgICAgIGZpbmFsIEJ5dGVCdWZmZXIgZW4gPSB6aXBFbmNvZGluZy5lbmNvZGUoemUuZ2V0TmFtZSgpKTsKKworICAgICAgICAgICAgICAgIHplLmFkZEV4dHJhRmllbGQobmV3IFVuaWNvZGVQYXRoRXh0cmFGaWVsZCh6ZS5nZXROYW1lKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuLmFycmF5KCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuLmFycmF5T2Zmc2V0KCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuLmxpbWl0KCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLSBlbi5wb3NpdGlvbigpKSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHpvcy5wdXRBcmNoaXZlRW50cnkoemUpOworICAgICAgICAgICAgem9zLndyaXRlKCJIZWxsbywgd29ybGQhIi5nZXRCeXRlcyhDaGFyc2V0TmFtZXMuVVNfQVNDSUkpKTsKKyAgICAgICAgICAgIHpvcy5jbG9zZUFyY2hpdmVFbnRyeSgpOworCisgICAgICAgICAgICB6ZSA9IG5ldyBaaXBBcmNoaXZlRW50cnkoRVVST19GT1JfRE9MTEFSX1RYVCk7CisgICAgICAgICAgICBpZiAod2l0aEV4cGxpY2l0VW5pY29kZUV4dHJhCisgICAgICAgICAgICAgICAgJiYgIXppcEVuY29kaW5nLmNhbkVuY29kZSh6ZS5nZXROYW1lKCkpKSB7CisKKyAgICAgICAgICAgICAgICBmaW5hbCBCeXRlQnVmZmVyIGVuID0gemlwRW5jb2RpbmcuZW5jb2RlKHplLmdldE5hbWUoKSk7CisKKyAgICAgICAgICAgICAgICB6ZS5hZGRFeHRyYUZpZWxkKG5ldyBVbmljb2RlUGF0aEV4dHJhRmllbGQoemUuZ2V0TmFtZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbi5hcnJheSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbi5hcnJheU9mZnNldCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbi5saW1pdCgpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0gZW4ucG9zaXRpb24oKSkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICB6b3MucHV0QXJjaGl2ZUVudHJ5KHplKTsKKyAgICAgICAgICAgIHpvcy53cml0ZSgiR2l2ZSBtZSB5b3VyIG1vbmV5ISIuZ2V0Qnl0ZXMoQ2hhcnNldE5hbWVzLlVTX0FTQ0lJKSk7CisgICAgICAgICAgICB6b3MuY2xvc2VBcmNoaXZlRW50cnkoKTsKKworICAgICAgICAgICAgemUgPSBuZXcgWmlwQXJjaGl2ZUVudHJ5KEFTQ0lJX1RYVCk7CisKKyAgICAgICAgICAgIGlmICh3aXRoRXhwbGljaXRVbmljb2RlRXh0cmEKKyAgICAgICAgICAgICAgICAmJiAhemlwRW5jb2RpbmcuY2FuRW5jb2RlKHplLmdldE5hbWUoKSkpIHsKKworICAgICAgICAgICAgICAgIGZpbmFsIEJ5dGVCdWZmZXIgZW4gPSB6aXBFbmNvZGluZy5lbmNvZGUoemUuZ2V0TmFtZSgpKTsKKworICAgICAgICAgICAgICAgIHplLmFkZEV4dHJhRmllbGQobmV3IFVuaWNvZGVQYXRoRXh0cmFGaWVsZCh6ZS5nZXROYW1lKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuLmFycmF5KCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuLmFycmF5T2Zmc2V0KCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuLmxpbWl0KCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLSBlbi5wb3NpdGlvbigpKSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHpvcy5wdXRBcmNoaXZlRW50cnkoemUpOworICAgICAgICAgICAgem9zLndyaXRlKCJhc2NpaSIuZ2V0Qnl0ZXMoQ2hhcnNldE5hbWVzLlVTX0FTQ0lJKSk7CisgICAgICAgICAgICB6b3MuY2xvc2VBcmNoaXZlRW50cnkoKTsKKworICAgICAgICAgICAgem9zLmZpbmlzaCgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKHpvcyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgem9zLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoZmluYWwgSU9FeGNlcHRpb24gZSkgeyAvKiBzd2FsbG93ICovIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgdGVzdEZpbGUoZmluYWwgRmlsZSBmaWxlLCBmaW5hbCBTdHJpbmcgZW5jb2RpbmcpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFppcEZpbGUgemYgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgemYgPSBuZXcgWmlwRmlsZShmaWxlLCBlbmNvZGluZywgZmFsc2UpOworCisgICAgICAgICAgICBmaW5hbCBFbnVtZXJhdGlvbjxaaXBBcmNoaXZlRW50cnk+IGUgPSB6Zi5nZXRFbnRyaWVzKCk7CisgICAgICAgICAgICB3aGlsZSAoZS5oYXNNb3JlRWxlbWVudHMoKSkgeworICAgICAgICAgICAgICAgIGZpbmFsIFppcEFyY2hpdmVFbnRyeSB6ZSA9IGUubmV4dEVsZW1lbnQoKTsKKworICAgICAgICAgICAgICAgIGlmICh6ZS5nZXROYW1lKCkuZW5kc1dpdGgoInNzZXIudHh0IikpIHsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VW5pY29kZU5hbWUoemUsIE9JTF9CQVJSRUxfVFhULCBlbmNvZGluZyk7CisKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHplLmdldE5hbWUoKS5lbmRzV2l0aCgiX2Zvcl9Eb2xsYXIudHh0IikpIHsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VW5pY29kZU5hbWUoemUsIEVVUk9fRk9SX0RPTExBUl9UWFQsIGVuY29kaW5nKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCF6ZS5nZXROYW1lKCkuZXF1YWxzKEFTQ0lJX1RYVCkpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJVbnJlY29nbml6ZWQgWklQIGVudHJ5IHdpdGggbmFtZSBbIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyB6ZS5nZXROYW1lKCkgKyAiXSBmb3VuZC4iKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBaaXBGaWxlLmNsb3NlUXVpZXRseSh6Zik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBVbmljb2RlUGF0aEV4dHJhRmllbGQgZmluZFVuaUNvZGVQYXRoKGZpbmFsIFppcEFyY2hpdmVFbnRyeSB6ZSkgeworICAgICAgICByZXR1cm4gKFVuaWNvZGVQYXRoRXh0cmFGaWVsZCkKKyAgICAgICAgICAgIHplLmdldEV4dHJhRmllbGQoVW5pY29kZVBhdGhFeHRyYUZpZWxkLlVQQVRIX0lEKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGFzc2VydFVuaWNvZGVOYW1lKGZpbmFsIFppcEFyY2hpdmVFbnRyeSB6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBleHBlY3RlZE5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgZW5jb2RpbmcpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICghZXhwZWN0ZWROYW1lLmVxdWFscyh6ZS5nZXROYW1lKCkpKSB7CisgICAgICAgICAgICBmaW5hbCBVbmljb2RlUGF0aEV4dHJhRmllbGQgdWNwZiA9IGZpbmRVbmlDb2RlUGF0aCh6ZSk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHVjcGYpOworCisgICAgICAgICAgICBmaW5hbCBaaXBFbmNvZGluZyBlbmMgPSBaaXBFbmNvZGluZ0hlbHBlci5nZXRaaXBFbmNvZGluZyhlbmNvZGluZyk7CisgICAgICAgICAgICBmaW5hbCBCeXRlQnVmZmVyIG5lID0gZW5jLmVuY29kZSh6ZS5nZXROYW1lKCkpOworCisgICAgICAgICAgICBmaW5hbCBDUkMzMiBjcmMgPSBuZXcgQ1JDMzIoKTsKKyAgICAgICAgICAgIGNyYy51cGRhdGUobmUuYXJyYXkoKSwgbmUuYXJyYXlPZmZzZXQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgbmUubGltaXQoKSAtIG5lLnBvc2l0aW9uKCkpOworCisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoY3JjLmdldFZhbHVlKCksIHVjcGYuZ2V0TmFtZUNSQzMyKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkTmFtZSwgbmV3IFN0cmluZyh1Y3BmLmdldFVuaWNvZGVOYW1lKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENoYXJzZXROYW1lcy5VVEZfOCkpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VXRmOEludGVyb3BlcmFiaWxpdHkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlIGZpbGUxID0gZ2V0RmlsZSgidXRmOC03emlwLXRlc3QuemlwIik7CisgICAgICAgIGZpbmFsIEZpbGUgZmlsZTIgPSBnZXRGaWxlKCJ1dGY4LXdpbnppcC10ZXN0LnppcCIpOworCisgICAgICAgIHRlc3RGaWxlKGZpbGUxLENQNDM3KTsKKyAgICAgICAgdGVzdEZpbGUoZmlsZTIsQ1A0MzcpOworCisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBhc3NlcnRSYXdOYW1lT2ZBY3NpaVR4dChmaW5hbCBaaXBBcmNoaXZlRW50cnkgemUpIHsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGIgPSB6ZS5nZXRSYXdOYW1lKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoYik7CisgICAgICAgIGZpbmFsIGludCBsZW4gPSBBU0NJSV9UWFQubGVuZ3RoKCk7CisgICAgICAgIGFzc2VydEVxdWFscyhsZW4sIGIubGVuZ3RoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW47IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJCeXRlICIgKyBpLCAoYnl0ZSkgQVNDSUlfVFhULmNoYXJBdChpKSwgYltpXSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0Tm90U2FtZShiLCB6ZS5nZXRSYXdOYW1lKCkpOworICAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9YMDAwQV9OVEZTVGVzdC5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9YMDAwQV9OVEZTVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI3N2QzNjAKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1gwMDBBX05URlNUZXN0LmphdmEKQEAgLTAsMCArMSw0MyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICoKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcDsKKworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworCitpbXBvcnQgamF2YS51dGlsLkRhdGU7CisKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRFcXVhbHM7CisKK3B1YmxpYyBjbGFzcyBYMDAwQV9OVEZTVGVzdCB7CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHNpbXBsZVJvdW50cmlwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFgwMDBBX05URlMgeGYgPSBuZXcgWDAwMEFfTlRGUygpOworICAgICAgICB4Zi5zZXRNb2RpZnlKYXZhVGltZShuZXcgRGF0ZSgwKSk7CisgICAgICAgIC8vIG9uZSBzZWNvbmQgcGFzdCBtaWRuaWdodAorICAgICAgICB4Zi5zZXRBY2Nlc3NKYXZhVGltZShuZXcgRGF0ZSgtMTE2NDQ0NzM2MDEwMDBsKSk7CisgICAgICAgIHhmLnNldENyZWF0ZUphdmFUaW1lKG51bGwpOworICAgICAgICBmaW5hbCBieXRlW10gYiA9IHhmLmdldExvY2FsRmlsZURhdGFEYXRhKCk7CisKKyAgICAgICAgZmluYWwgWDAwMEFfTlRGUyB4ZjIgPSBuZXcgWDAwMEFfTlRGUygpOworICAgICAgICB4ZjIucGFyc2VGcm9tTG9jYWxGaWxlRGF0YShiLCAwLCBiLmxlbmd0aCk7CisgICAgICAgIGFzc2VydEVxdWFscyhuZXcgRGF0ZSgwKSwgeGYyLmdldE1vZGlmeUphdmFUaW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobmV3IERhdGUoLTExNjQ0NDczNjAxMDAwbCksIHhmMi5nZXRBY2Nlc3NKYXZhVGltZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIHhmMi5nZXRDcmVhdGVKYXZhVGltZSgpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1g1NDU1X0V4dGVuZGVkVGltZXN0YW1wVGVzdC5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9YNTQ1NV9FeHRlbmRlZFRpbWVzdGFtcFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lM2JkNjBlCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9YNTQ1NV9FeHRlbmRlZFRpbWVzdGFtcFRlc3QuamF2YQpAQCAtMCwwICsxLDU1OCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICoKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcDsKKworaW1wb3J0IG9yZy5qdW5pdC5BZnRlcjsKK2ltcG9ydCBvcmcuanVuaXQuQmVmb3JlOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEudGV4dC5TaW1wbGVEYXRlRm9ybWF0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkNhbGVuZGFyOworaW1wb3J0IGphdmEudXRpbC5EYXRlOworaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuVGltZVpvbmU7CitpbXBvcnQgamF2YS51dGlsLnppcC5aaXBFeGNlcHRpb247CisKK2ltcG9ydCBzdGF0aWMgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLkFic3RyYWN0VGVzdENhc2UuZ2V0RmlsZTsKK2ltcG9ydCBzdGF0aWMgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLkFic3RyYWN0VGVzdENhc2UubWtkaXI7CitpbXBvcnQgc3RhdGljIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5BYnN0cmFjdFRlc3RDYXNlLnJtZGlyOworaW1wb3J0IHN0YXRpYyBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcC5YNTQ1NV9FeHRlbmRlZFRpbWVzdGFtcC5BQ0NFU1NfVElNRV9CSVQ7CitpbXBvcnQgc3RhdGljIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwLlg1NDU1X0V4dGVuZGVkVGltZXN0YW1wLkNSRUFURV9USU1FX0JJVDsKK2ltcG9ydCBzdGF0aWMgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXAuWDU0NTVfRXh0ZW5kZWRUaW1lc3RhbXAuTU9ESUZZX1RJTUVfQklUOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEVxdWFsczsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRGYWxzZTsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnROb3ROdWxsOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydE51bGw7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VHJ1ZTsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5mYWlsOworCitwdWJsaWMgY2xhc3MgWDU0NTVfRXh0ZW5kZWRUaW1lc3RhbXBUZXN0IHsKKyAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBaaXBTaG9ydCBYNTQ1NSA9IG5ldyBaaXBTaG9ydCgweDU0NTUpOworCisgICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgWmlwTG9uZyBaRVJPX1RJTUUgPSBuZXcgWmlwTG9uZygwKTsKKyAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBaaXBMb25nIE1BWF9USU1FX1NFQ09ORFMgPSBuZXcgWmlwTG9uZyhJbnRlZ2VyLk1BWF9WQUxVRSk7CisgICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU2ltcGxlRGF0ZUZvcm1hdCBEQVRFX0ZPUk1BVCA9IG5ldyBTaW1wbGVEYXRlRm9ybWF0KCJ5eXl5LU1NLWRkL0hIOm1tOnNzIFoiKTsKKworICAgIHN0YXRpYyB7CisgICAgICAgIERBVEVfRk9STUFULnNldFRpbWVab25lKFRpbWVab25lLmdldFRpbWVab25lKCJVVEMiKSk7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBUaGUgZXh0ZW5kZWQgZmllbGQgKHhmKSB3ZSBhcmUgdGVzdGluZy4KKyAgICAgKi8KKyAgICBwcml2YXRlIFg1NDU1X0V4dGVuZGVkVGltZXN0YW1wIHhmOworCisgICAgcHJpdmF0ZSBGaWxlIHRtcERpcjsKKworICAgIEBCZWZvcmUKKyAgICBwdWJsaWMgdm9pZCBiZWZvcmUoKSB7CisgICAgICAgIHhmID0gbmV3IFg1NDU1X0V4dGVuZGVkVGltZXN0YW1wKCk7CisgICAgfQorCisgICAgQEFmdGVyCisgICAgcHVibGljIHZvaWQgcmVtb3ZlVGVtcEZpbGVzKCkgeworICAgICAgICBpZiAodG1wRGlyICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJtZGlyKHRtcERpcik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RTYW1wbGVGaWxlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisKKyAgICAgICAgLyoKKyAgICAgICAgQ29udGFpbnMgZW50cmllcyB3aXRoIHppcFRpbWUsIGFjY2Vzc1RpbWUsIGFuZCBtb2RpZnlUaW1lLgorICAgICAgICBUaGUgZmlsZSBuYW1lIHRlbGxzIHlvdSB0aGUgeWVhciB3ZSB0cmllZCB0byBzZXQgdGhlIHRpbWUgdG8KKyAgICAgICAgKEphbiAxc3QsIE1pZG5pZ2h0LCBVVEMpLgorCisgICAgICAgIEZvciBleGFtcGxlOgorCisgICAgICAgIENPTVBSRVNTLTIxMF91bml4X3RpbWVfemlwX3Rlc3QvMTk5OQorICAgICAgICBDT01QUkVTUy0yMTBfdW5peF90aW1lX3ppcF90ZXN0LzIwMDAKKyAgICAgICAgQ09NUFJFU1MtMjEwX3VuaXhfdGltZV96aXBfdGVzdC8yMTA4CisKKyAgICAgICAgRmlsZSdzIGxhc3QtbW9kaWZpZWQgaXMgMXN0IHNlY29uZCBhZnRlciBtaWRuaWdodC4KKyAgICAgICAgWmlwLXRpbWUncyAyLXNlY29uZCBncmFudWxhcml0eSByb3VuZHMgdGhhdCB1cCB0byAybmQgc2Vjb25kLgorICAgICAgICBGaWxlJ3MgbGFzdC1hY2Nlc3MgaXMgM3JkIHNlY29uZCBhZnRlciBtaWRuaWdodC4KKworICAgICAgICBTbywgZnJvbSBleGFtcGxlIGFib3ZlOgorCisgICAgICAgIDE5OTkncyB6aXAgdGltZTogIEphbiAxc3QsIDE5OTktMDEtMDEvMDA6MDA6MDIKKyAgICAgICAgMTk5OSdzIG1vZCB0aW1lOiAgSmFuIDFzdCwgMTk5OS0wMS0wMS8wMDowMDowMQorICAgICAgICAxOTk5J3MgYWNjIHRpbWU6ICBKYW4gMXN0LCAxOTk5LTAxLTAxLzAwOjAwOjAzCisKKyAgICAgICAgU3RhcnRpbmcgd2l0aCBhIHBhdGNoIHJlbGVhc2Ugb2YgSmF2YTgsICJ6aXAgdGltZSIgYWN0dWFsbHkKKyAgICAgICAgdXNlcyB0aGUgZXh0ZW5kZWQgdGltZSBzdGFtcCBmaWVsZCBpdHNlbGYgYW5kIHNob3VsZCBiZSB0aGUKKyAgICAgICAgc2FtZSBhcyAibW9kIHRpbWUiLgorICAgICAgICBodHRwOi8vaGcub3Blbmpkay5qYXZhLm5ldC9qZGs4dS9qZGs4dS9qZGsvcmV2LzkwZGY2NzU2NDA2ZgorCisgICAgICAgIFN0YXJ0aW5nIHdpdGggSmF2YTkgdGhlIHBhcnNlciBmb3IgZXh0ZW5kZWQgdGltZSBzdGFtcHMgaGFzCisgICAgICAgIGJlZW4gZml4ZWQgdG8gdXNlIHNpZ25lZCBpbnRlZ2VycyB3aGljaCB3YXMgZGV0ZWN0ZWQgZHVyaW5nCisgICAgICAgIHRoZSB0cmlhZ2Ugb2YgQ09NUFJFU1MtNDE2LiBTaWduZWQgaW50ZWdlcnMgaXMgdGhlIGNvcnJlY3QKKyAgICAgICAgZm9ybWF0IGFuZCBDb21wcmVzcyAxLjE1IGhhcyBzdGFydGVkIHRvIHVzZSBzaWduZWQgaW50ZWdlcnMgYXMKKyAgICAgICAgd2VsbC4KKyAgICAgICAgICovCisKKyAgICAgICAgZmluYWwgRmlsZSBhcmNoaXZlID0gZ2V0RmlsZSgiQ09NUFJFU1MtMjEwX3VuaXhfdGltZV96aXBfdGVzdC56aXAiKTsKKyAgICAgICAgWmlwRmlsZSB6ZiA9IG51bGw7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHpmID0gbmV3IFppcEZpbGUoYXJjaGl2ZSk7CisgICAgICAgICAgICBmaW5hbCBFbnVtZXJhdGlvbjxaaXBBcmNoaXZlRW50cnk+IGVuID0gemYuZ2V0RW50cmllcygpOworCisgICAgICAgICAgICAvLyBXZSBleHBlY3QgRVZFUlkgZW50cnkgb2YgdGhpcyB6aXAgZmlsZQorICAgICAgICAgICAgLy8gdG8gY29udGFpbiBleHRyYSBmaWVsZCAweDU0NTUuCisgICAgICAgICAgICB3aGlsZSAoZW4uaGFzTW9yZUVsZW1lbnRzKCkpIHsKKworICAgICAgICAgICAgICAgIGZpbmFsIFppcEFyY2hpdmVFbnRyeSB6YWUgPSBlbi5uZXh0RWxlbWVudCgpOworICAgICAgICAgICAgICAgIGlmICh6YWUuaXNEaXJlY3RvcnkoKSkgeworICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIG5hbWUgPSB6YWUuZ2V0TmFtZSgpOworICAgICAgICAgICAgICAgIGZpbmFsIGludCB4ID0gbmFtZS5sYXN0SW5kZXhPZignLycpOworICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyB5ZWFyU3RyaW5nID0gbmFtZS5zdWJzdHJpbmcoeCArIDEpOworICAgICAgICAgICAgICAgIGludCB5ZWFyOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHllYXIgPSBJbnRlZ2VyLnBhcnNlSW50KHllYXJTdHJpbmcpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGZpbmFsIE51bWJlckZvcm1hdEV4Y2VwdGlvbiBuZmUpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gc2V0VGltZS5zaCwgc2tpcAorICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBmaW5hbCBYNTQ1NV9FeHRlbmRlZFRpbWVzdGFtcCB4ZiA9IChYNTQ1NV9FeHRlbmRlZFRpbWVzdGFtcCkgemFlLmdldEV4dHJhRmllbGQoWDU0NTUpOworICAgICAgICAgICAgICAgIGZpbmFsIERhdGUgcmF3WiA9IHphZS5nZXRMYXN0TW9kaWZpZWREYXRlKCk7CisgICAgICAgICAgICAgICAgZmluYWwgRGF0ZSBtID0geGYuZ2V0TW9kaWZ5SmF2YVRpbWUoKTsKKworICAgICAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgICAgICBXZSBtdXN0IGRpc3Rpbmd1aXNoIHRocmVlIGNhc2VzOgorICAgICAgICAgICAgICAgICAgLSBKYXZhIGhhcyByZWFkIHRoZSBleHRlbmRlZCB0aW1lIGZpZWxkIGl0c2VsZiBhbmQgYWdyZWVzIHdpdGggdXMgKEphdmE5IG9yIEphdmE4IGFuZCB5ZWFycyBwcmlvciB0bworICAgICAgICAgICAgICAgICAgICAyMDM4KQorICAgICAgICAgICAgICAgICAgLSBKYXZhIGhhcyByZWFkIHRoZSBleHRlbmRlZCB0aW1lIGZpZWxkIGJ1dCBmb3VuZCBhIHllYXIgPj0gMjAzOCAoSmF2YTgpCisgICAgICAgICAgICAgICAgICAtIEphdmEgaGFzbid0IHJlYWQgdGhlIGV4dGVuZGVkIHRpbWUgZmllbGQgYXQgYWxsIChKYXZhNy0gb3IgZWFybHkgSmF2YTgpCisgICAgICAgICAgICAgICAgKi8KKworICAgICAgICAgICAgICAgIGZpbmFsIGJvb2xlYW4gemlwVGltZVVzZXNFeHRlbmRlZFRpbWVzdGFtcENvcnJlY3RseSA9IHJhd1ouZXF1YWxzKG0pOworICAgICAgICAgICAgICAgIGZpbmFsIGJvb2xlYW4gemlwVGltZVVzZXNFeHRlbmRlZFRpbWVzdGFtcEJ1dFVuc2lnbmVkID0geWVhciA+IDIwMzcgJiYgcmF3Wi5nZXRTZWNvbmRzKCkgPT0gMTsKKyAgICAgICAgICAgICAgICBmaW5hbCBib29sZWFuIHppcFRpbWVVc2VzRXh0ZW5kZWRUaW1lc3RhbXAgPSB6aXBUaW1lVXNlc0V4dGVuZGVkVGltZXN0YW1wQ29ycmVjdGx5CisgICAgICAgICAgICAgICAgICAgIHx8IHppcFRpbWVVc2VzRXh0ZW5kZWRUaW1lc3RhbXBCdXRVbnNpZ25lZDsKKworICAgICAgICAgICAgICAgIGZpbmFsIERhdGUgeiA9IHppcFRpbWVVc2VzRXh0ZW5kZWRUaW1lc3RhbXAgPyByYXdaIDogYWRqdXN0RnJvbUdNVFRvRXhwZWN0ZWRPZmZzZXQocmF3Wik7CisgICAgICAgICAgICAgICAgZmluYWwgRGF0ZSBhID0geGYuZ2V0QWNjZXNzSmF2YVRpbWUoKTsKKworICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyB6aXBUaW1lID0gREFURV9GT1JNQVQuZm9ybWF0KHopOworICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBtb2RUaW1lID0gREFURV9GT1JNQVQuZm9ybWF0KG0pOworICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBhY2NUaW1lID0gREFURV9GT1JNQVQuZm9ybWF0KGEpOworCisgICAgICAgICAgICAgICAgc3dpdGNoICh5ZWFyKSB7CisgICAgICAgICAgICAgICAgY2FzZSAyMTA5OgorICAgICAgICAgICAgICAgICAgICAvLyBBbGwgdGhyZWUgdGltZXN0YW1wcyBoYXZlIG92ZXJmbG93ZWQgYnkgMjEwOS4KKyAgICAgICAgICAgICAgICAgICAgaWYgKCF6aXBUaW1lVXNlc0V4dGVuZGVkVGltZXN0YW1wKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIjE5ODEtMDEtMDEvMDA6MDA6MDIgKzAwMDAiLCB6aXBUaW1lKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgICAgICBpZiAoIXppcFRpbWVVc2VzRXh0ZW5kZWRUaW1lc3RhbXApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIFg1NDU1IHRpbWUgaXMgZ29vZCBmcm9tIGVwb2NoICgxOTcwKSB0byAyMDM3LgorICAgICAgICAgICAgICAgICAgICAgICAgLy8gWmlwIHRpbWUgaXMgZ29vZCBmcm9tIDE5ODAgdG8gMjEwNy4KKyAgICAgICAgICAgICAgICAgICAgICAgIGlmICh5ZWFyIDwgMTk4MCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiMTk4MC0wMS0wMS8wODowMDowMCArMDAwMCIsIHppcFRpbWUpOworICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoeWVhciArICItMDEtMDEvMDA6MDA6MDIgKzAwMDAiLCB6aXBUaW1lKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIGlmICh5ZWFyIDwgMjAzOCkgeworICAgICAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHllYXIgKyAiLTAxLTAxLzAwOjAwOjAxICswMDAwIiwgbW9kVGltZSk7CisgICAgICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoeWVhciArICItMDEtMDEvMDA6MDA6MDMgKzAwMDAiLCBhY2NUaW1lKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAoemYgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHpmLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdE1pc2MoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RmFsc2UoeGYuZXF1YWxzKG5ldyBPYmplY3QoKSkpOworICAgICAgICBhc3NlcnRUcnVlKHhmLnRvU3RyaW5nKCkuc3RhcnRzV2l0aCgiMHg1NDU1IFppcCBFeHRyYSBGaWVsZCIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgheGYudG9TdHJpbmcoKS5jb250YWlucygiIE1vZGlmeToiKSk7CisgICAgICAgIGFzc2VydFRydWUoIXhmLnRvU3RyaW5nKCkuY29udGFpbnMoIiBBY2Nlc3M6IikpOworICAgICAgICBhc3NlcnRUcnVlKCF4Zi50b1N0cmluZygpLmNvbnRhaW5zKCIgQ3JlYXRlOiIpKTsKKyAgICAgICAgT2JqZWN0IG8gPSB4Zi5jbG9uZSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoby5oYXNoQ29kZSgpLCB4Zi5oYXNoQ29kZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh4Zi5lcXVhbHMobykpOworCisgICAgICAgIHhmLnNldE1vZGlmeUphdmFUaW1lKG5ldyBEYXRlKDExMTEpKTsKKyAgICAgICAgeGYuc2V0QWNjZXNzSmF2YVRpbWUobmV3IERhdGUoMjIyMikpOworICAgICAgICB4Zi5zZXRDcmVhdGVKYXZhVGltZShuZXcgRGF0ZSgzMzMzKSk7CisgICAgICAgIHhmLnNldEZsYWdzKChieXRlKSA3KTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoeGYuZXF1YWxzKG8pKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh4Zi50b1N0cmluZygpLnN0YXJ0c1dpdGgoIjB4NTQ1NSBaaXAgRXh0cmEgRmllbGQiKSk7CisgICAgICAgIGFzc2VydFRydWUoeGYudG9TdHJpbmcoKS5jb250YWlucygiIE1vZGlmeToiKSk7CisgICAgICAgIGFzc2VydFRydWUoeGYudG9TdHJpbmcoKS5jb250YWlucygiIEFjY2VzczoiKSk7CisgICAgICAgIGFzc2VydFRydWUoeGYudG9TdHJpbmcoKS5jb250YWlucygiIENyZWF0ZToiKSk7CisgICAgICAgIG8gPSB4Zi5jbG9uZSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoby5oYXNoQ29kZSgpLCB4Zi5oYXNoQ29kZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh4Zi5lcXVhbHMobykpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEdldHRlcnNTZXR0ZXJzKCkgeworICAgICAgICAvLyBYNTQ1NSBpcyBjb25jZXJuZWQgd2l0aCB0aW1lLCBzbyBsZXQncworICAgICAgICAvLyBnZXQgYSB0aW1lc3RhbXAgdG8gcGxheSB3aXRoIChKYW4gMXN0LCAyMDAwKS4KKyAgICAgICAgZmluYWwgQ2FsZW5kYXIgY2FsID0gQ2FsZW5kYXIuZ2V0SW5zdGFuY2UoVGltZVpvbmUuZ2V0VGltZVpvbmUoIlVUQyIpKTsKKyAgICAgICAgY2FsLnNldChDYWxlbmRhci5ZRUFSLCAyMDAwKTsKKyAgICAgICAgY2FsLnNldChDYWxlbmRhci5NT05USCwgQ2FsZW5kYXIuSkFOVUFSWSk7CisgICAgICAgIGNhbC5zZXQoQ2FsZW5kYXIuREFURSwgMSk7CisgICAgICAgIGNhbC5zZXQoQ2FsZW5kYXIuSE9VUl9PRl9EQVksIDApOworICAgICAgICBjYWwuc2V0KENhbGVuZGFyLk1JTlVURSwgMCk7CisgICAgICAgIGNhbC5zZXQoQ2FsZW5kYXIuU0VDT05ELCAwKTsKKyAgICAgICAgY2FsLnNldChDYWxlbmRhci5NSUxMSVNFQ09ORCwgMCk7CisgICAgICAgIGZpbmFsIGxvbmcgdGltZU1pbGxpcyA9IGNhbC5nZXRUaW1lSW5NaWxsaXMoKTsKKyAgICAgICAgZmluYWwgWmlwTG9uZyB0aW1lID0gbmV3IFppcExvbmcodGltZU1pbGxpcyAvIDEwMDApOworCisgICAgICAgIC8vIHNldCB0b28gYmlnCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBKYXZhIHRpbWUgaXMgMTAwMCB4IGxhcmdlciAobWlsbGlzZWNvbmRzKS4KKyAgICAgICAgICAgIHhmLnNldE1vZGlmeUphdmFUaW1lKG5ldyBEYXRlKDEwMDBMICogKE1BWF9USU1FX1NFQ09ORFMuZ2V0VmFsdWUoKSArIDFMKSkpOworICAgICAgICAgICAgZmFpbCgiVGltZSB0b28gYmlnIGZvciAzMiBiaXRzISIpOworICAgICAgICB9IGNhdGNoIChmaW5hbCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7CisgICAgICAgICAgICAvLyBBbGwgaXMgZ29vZC4KKyAgICAgICAgfQorCisgICAgICAgIC8vIGdldC9zZXQgbW9kaWZ5IHRpbWUKKyAgICAgICAgeGYuc2V0TW9kaWZ5VGltZSh0aW1lKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRpbWUsIHhmLmdldE1vZGlmeVRpbWUoKSk7CisgICAgICAgIERhdGUgeGZNb2RpZnlKYXZhVGltZSA9IHhmLmdldE1vZGlmeUphdmFUaW1lKCk7CisgICAgICAgIGFzc2VydEVxdWFscyh0aW1lTWlsbGlzLCB4Zk1vZGlmeUphdmFUaW1lLmdldFRpbWUoKSk7CisgICAgICAgIHhmLnNldE1vZGlmeUphdmFUaW1lKG5ldyBEYXRlKHRpbWVNaWxsaXMpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRpbWUsIHhmLmdldE1vZGlmeVRpbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyh0aW1lTWlsbGlzLCB4Zi5nZXRNb2RpZnlKYXZhVGltZSgpLmdldFRpbWUoKSk7CisgICAgICAgIC8vIE1ha2Ugc3VyZSBtaWxsaXNlY29uZHMgZ2V0IHplcm9lZCBvdXQ6CisgICAgICAgIHhmLnNldE1vZGlmeUphdmFUaW1lKG5ldyBEYXRlKHRpbWVNaWxsaXMgKyAxMjMpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRpbWUsIHhmLmdldE1vZGlmeVRpbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyh0aW1lTWlsbGlzLCB4Zi5nZXRNb2RpZnlKYXZhVGltZSgpLmdldFRpbWUoKSk7CisgICAgICAgIC8vIE51bGwKKyAgICAgICAgeGYuc2V0TW9kaWZ5VGltZShudWxsKTsKKyAgICAgICAgYXNzZXJ0TnVsbCh4Zi5nZXRNb2RpZnlKYXZhVGltZSgpKTsKKyAgICAgICAgeGYuc2V0TW9kaWZ5SmF2YVRpbWUobnVsbCk7CisgICAgICAgIGFzc2VydE51bGwoeGYuZ2V0TW9kaWZ5VGltZSgpKTsKKworICAgICAgICAvLyBnZXQvc2V0IGFjY2VzcyB0aW1lCisgICAgICAgIHhmLnNldEFjY2Vzc1RpbWUodGltZSk7CisgICAgICAgIGFzc2VydEVxdWFscyh0aW1lLCB4Zi5nZXRBY2Nlc3NUaW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHModGltZU1pbGxpcywgeGYuZ2V0QWNjZXNzSmF2YVRpbWUoKS5nZXRUaW1lKCkpOworICAgICAgICB4Zi5zZXRBY2Nlc3NKYXZhVGltZShuZXcgRGF0ZSh0aW1lTWlsbGlzKSk7CisgICAgICAgIGFzc2VydEVxdWFscyh0aW1lLCB4Zi5nZXRBY2Nlc3NUaW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHModGltZU1pbGxpcywgeGYuZ2V0QWNjZXNzSmF2YVRpbWUoKS5nZXRUaW1lKCkpOworICAgICAgICAvLyBNYWtlIHN1cmUgbWlsbGlzZWNvbmRzIGdldCB6ZXJvZWQgb3V0OgorICAgICAgICB4Zi5zZXRBY2Nlc3NKYXZhVGltZShuZXcgRGF0ZSh0aW1lTWlsbGlzICsgMTIzKSk7CisgICAgICAgIGFzc2VydEVxdWFscyh0aW1lLCB4Zi5nZXRBY2Nlc3NUaW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHModGltZU1pbGxpcywgeGYuZ2V0QWNjZXNzSmF2YVRpbWUoKS5nZXRUaW1lKCkpOworICAgICAgICAvLyBOdWxsCisgICAgICAgIHhmLnNldEFjY2Vzc1RpbWUobnVsbCk7CisgICAgICAgIGFzc2VydE51bGwoeGYuZ2V0QWNjZXNzSmF2YVRpbWUoKSk7CisgICAgICAgIHhmLnNldEFjY2Vzc0phdmFUaW1lKG51bGwpOworICAgICAgICBhc3NlcnROdWxsKHhmLmdldEFjY2Vzc1RpbWUoKSk7CisKKyAgICAgICAgLy8gZ2V0L3NldCBjcmVhdGUgdGltZQorICAgICAgICB4Zi5zZXRDcmVhdGVUaW1lKHRpbWUpOworICAgICAgICBhc3NlcnRFcXVhbHModGltZSwgeGYuZ2V0Q3JlYXRlVGltZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRpbWVNaWxsaXMsIHhmLmdldENyZWF0ZUphdmFUaW1lKCkuZ2V0VGltZSgpKTsKKyAgICAgICAgeGYuc2V0Q3JlYXRlSmF2YVRpbWUobmV3IERhdGUodGltZU1pbGxpcykpOworICAgICAgICBhc3NlcnRFcXVhbHModGltZSwgeGYuZ2V0Q3JlYXRlVGltZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRpbWVNaWxsaXMsIHhmLmdldENyZWF0ZUphdmFUaW1lKCkuZ2V0VGltZSgpKTsKKyAgICAgICAgLy8gTWFrZSBzdXJlIG1pbGxpc2Vjb25kcyBnZXQgemVyb2VkIG91dDoKKyAgICAgICAgeGYuc2V0Q3JlYXRlSmF2YVRpbWUobmV3IERhdGUodGltZU1pbGxpcyArIDEyMykpOworICAgICAgICBhc3NlcnRFcXVhbHModGltZSwgeGYuZ2V0Q3JlYXRlVGltZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRpbWVNaWxsaXMsIHhmLmdldENyZWF0ZUphdmFUaW1lKCkuZ2V0VGltZSgpKTsKKyAgICAgICAgLy8gTnVsbAorICAgICAgICB4Zi5zZXRDcmVhdGVUaW1lKG51bGwpOworICAgICAgICBhc3NlcnROdWxsKHhmLmdldENyZWF0ZUphdmFUaW1lKCkpOworICAgICAgICB4Zi5zZXRDcmVhdGVKYXZhVGltZShudWxsKTsKKyAgICAgICAgYXNzZXJ0TnVsbCh4Zi5nZXRDcmVhdGVUaW1lKCkpOworCisKKyAgICAgICAgLy8gaW5pdGlhbGl6ZSBmb3IgZmxhZ3MKKyAgICAgICAgeGYuc2V0TW9kaWZ5VGltZSh0aW1lKTsKKyAgICAgICAgeGYuc2V0QWNjZXNzVGltZSh0aW1lKTsKKyAgICAgICAgeGYuc2V0Q3JlYXRlVGltZSh0aW1lKTsKKworICAgICAgICAvLyBnZXQvc2V0IGZsYWdzOiAwMDAKKyAgICAgICAgeGYuc2V0RmxhZ3MoKGJ5dGUpIDApOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgeGYuZ2V0RmxhZ3MoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKHhmLmlzQml0MF9tb2RpZnlUaW1lUHJlc2VudCgpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoeGYuaXNCaXQxX2FjY2Vzc1RpbWVQcmVzZW50KCkpOworICAgICAgICBhc3NlcnRGYWxzZSh4Zi5pc0JpdDJfY3JlYXRlVGltZVByZXNlbnQoKSk7CisgICAgICAgIC8vIExvY2FsIGxlbmd0aD0xLCBDZW50cmFsIGxlbmd0aD0xIChmbGFncyBvbmx5ISkKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIHhmLmdldExvY2FsRmlsZURhdGFMZW5ndGgoKS5nZXRWYWx1ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIHhmLmdldENlbnRyYWxEaXJlY3RvcnlMZW5ndGgoKS5nZXRWYWx1ZSgpKTsKKworICAgICAgICAvLyBnZXQvc2V0IGZsYWdzOiAwMDEKKyAgICAgICAgeGYuc2V0RmxhZ3MoKGJ5dGUpIDEpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgeGYuZ2V0RmxhZ3MoKSk7CisgICAgICAgIGFzc2VydFRydWUoeGYuaXNCaXQwX21vZGlmeVRpbWVQcmVzZW50KCkpOworICAgICAgICBhc3NlcnRGYWxzZSh4Zi5pc0JpdDFfYWNjZXNzVGltZVByZXNlbnQoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKHhmLmlzQml0Ml9jcmVhdGVUaW1lUHJlc2VudCgpKTsKKyAgICAgICAgLy8gTG9jYWwgbGVuZ3RoPTUsIENlbnRyYWwgbGVuZ3RoPTUgKGZsYWdzICsgbW9kKQorICAgICAgICBhc3NlcnRFcXVhbHMoNSwgeGYuZ2V0TG9jYWxGaWxlRGF0YUxlbmd0aCgpLmdldFZhbHVlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoNSwgeGYuZ2V0Q2VudHJhbERpcmVjdG9yeUxlbmd0aCgpLmdldFZhbHVlKCkpOworCisgICAgICAgIC8vIGdldC9zZXQgZmxhZ3M6IDAxMAorICAgICAgICB4Zi5zZXRGbGFncygoYnl0ZSkgMik7CisgICAgICAgIGFzc2VydEVxdWFscygyLCB4Zi5nZXRGbGFncygpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoeGYuaXNCaXQwX21vZGlmeVRpbWVQcmVzZW50KCkpOworICAgICAgICBhc3NlcnRUcnVlKHhmLmlzQml0MV9hY2Nlc3NUaW1lUHJlc2VudCgpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoeGYuaXNCaXQyX2NyZWF0ZVRpbWVQcmVzZW50KCkpOworICAgICAgICAvLyBMb2NhbCBsZW5ndGg9NSwgQ2VudHJhbCBsZW5ndGg9MQorICAgICAgICBhc3NlcnRFcXVhbHMoNSwgeGYuZ2V0TG9jYWxGaWxlRGF0YUxlbmd0aCgpLmdldFZhbHVlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgeGYuZ2V0Q2VudHJhbERpcmVjdG9yeUxlbmd0aCgpLmdldFZhbHVlKCkpOworCisgICAgICAgIC8vIGdldC9zZXQgZmxhZ3M6IDEwMAorICAgICAgICB4Zi5zZXRGbGFncygoYnl0ZSkgNCk7CisgICAgICAgIGFzc2VydEVxdWFscyg0LCB4Zi5nZXRGbGFncygpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoeGYuaXNCaXQwX21vZGlmeVRpbWVQcmVzZW50KCkpOworICAgICAgICBhc3NlcnRGYWxzZSh4Zi5pc0JpdDFfYWNjZXNzVGltZVByZXNlbnQoKSk7CisgICAgICAgIGFzc2VydFRydWUoeGYuaXNCaXQyX2NyZWF0ZVRpbWVQcmVzZW50KCkpOworICAgICAgICAvLyBMb2NhbCBsZW5ndGg9NSwgQ2VudHJhbCBsZW5ndGg9MQorICAgICAgICBhc3NlcnRFcXVhbHMoNSwgeGYuZ2V0TG9jYWxGaWxlRGF0YUxlbmd0aCgpLmdldFZhbHVlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgeGYuZ2V0Q2VudHJhbERpcmVjdG9yeUxlbmd0aCgpLmdldFZhbHVlKCkpOworCisgICAgICAgIC8vIGdldC9zZXQgZmxhZ3M6IDExMQorICAgICAgICB4Zi5zZXRGbGFncygoYnl0ZSkgNyk7CisgICAgICAgIGFzc2VydEVxdWFscyg3LCB4Zi5nZXRGbGFncygpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh4Zi5pc0JpdDBfbW9kaWZ5VGltZVByZXNlbnQoKSk7CisgICAgICAgIGFzc2VydFRydWUoeGYuaXNCaXQxX2FjY2Vzc1RpbWVQcmVzZW50KCkpOworICAgICAgICBhc3NlcnRUcnVlKHhmLmlzQml0Ml9jcmVhdGVUaW1lUHJlc2VudCgpKTsKKyAgICAgICAgLy8gTG9jYWwgbGVuZ3RoPTEzLCBDZW50cmFsIGxlbmd0aD01CisgICAgICAgIGFzc2VydEVxdWFscygxMywgeGYuZ2V0TG9jYWxGaWxlRGF0YUxlbmd0aCgpLmdldFZhbHVlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoNSwgeGYuZ2V0Q2VudHJhbERpcmVjdG9yeUxlbmd0aCgpLmdldFZhbHVlKCkpOworCisgICAgICAgIC8vIGdldC9zZXQgZmxhZ3M6IDExMTExMTExCisgICAgICAgIHhmLnNldEZsYWdzKChieXRlKSAtMSk7CisgICAgICAgIGFzc2VydEVxdWFscygtMSwgeGYuZ2V0RmxhZ3MoKSk7CisgICAgICAgIGFzc2VydFRydWUoeGYuaXNCaXQwX21vZGlmeVRpbWVQcmVzZW50KCkpOworICAgICAgICBhc3NlcnRUcnVlKHhmLmlzQml0MV9hY2Nlc3NUaW1lUHJlc2VudCgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh4Zi5pc0JpdDJfY3JlYXRlVGltZVByZXNlbnQoKSk7CisgICAgICAgIC8vIExvY2FsIGxlbmd0aD0xMywgQ2VudHJhbCBsZW5ndGg9NQorICAgICAgICBhc3NlcnRFcXVhbHMoMTMsIHhmLmdldExvY2FsRmlsZURhdGFMZW5ndGgoKS5nZXRWYWx1ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDUsIHhmLmdldENlbnRyYWxEaXJlY3RvcnlMZW5ndGgoKS5nZXRWYWx1ZSgpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRIZWFkZXJJZCgpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFg1NDU1LCB4Zi5nZXRIZWFkZXJJZCgpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RQYXJzZVJlcGFyc2UoKSB0aHJvd3MgWmlwRXhjZXB0aW9uIHsKKyAgICAgICAgLyoKKyAgICAgICAgICogUmVjYWxsIHRoZSBzcGVjOgorICAgICAgICAgKgorICAgICAgICAgKiAweDU0NTUgICAgICAgIFNob3J0ICAgICAgIHRhZyBmb3IgdGhpcyBleHRyYSBibG9jayB0eXBlICgiVVQiKQorICAgICAgICAgKiBUU2l6ZSAgICAgICAgIFNob3J0ICAgICAgIHRvdGFsIGRhdGEgc2l6ZSBmb3IgdGhpcyBibG9jaworICAgICAgICAgKiBGbGFncyAgICAgICAgIEJ5dGUgICAgICAgIGluZm8gYml0cworICAgICAgICAgKiAoTW9kVGltZSkgICAgIExvbmcgICAgICAgIHRpbWUgb2YgbGFzdCBtb2RpZmljYXRpb24gKFVUQy9HTVQpCisgICAgICAgICAqIChBY1RpbWUpICAgICAgTG9uZyAgICAgICAgdGltZSBvZiBsYXN0IGFjY2VzcyAoVVRDL0dNVCkKKyAgICAgICAgICogKENyVGltZSkgICAgICBMb25nICAgICAgICB0aW1lIG9mIG9yaWdpbmFsIGNyZWF0aW9uIChVVEMvR01UKQorICAgICAgICAgKi8KKyAgICAgICAgZmluYWwgYnl0ZVtdIE5VTExfRkxBR1MgPSB7MH07CisgICAgICAgIGZpbmFsIGJ5dGVbXSBBQ19DRU5UUkFMID0gezJ9OyAvLyBjZW50cmFsIGRhdGEgb25seSBjb250YWlucyB0aGUgQUMgZmxhZyBhbmQgbm8gYWN0dWFsIGRhdGEKKyAgICAgICAgZmluYWwgYnl0ZVtdIENSX0NFTlRSQUwgPSB7NH07IC8vIGNlbnRyYWwgZGF0YSBvbmx5IGRvbnRhaW5zIHRoZSBDUiBmbGFnIGFuZCBubyBhY3R1YWwgZGF0YQorCisgICAgICAgIGZpbmFsIGJ5dGVbXSBNT0RfWkVSTyA9IHsxLCAwLCAwLCAwLCAwfTsKKyAgICAgICAgZmluYWwgYnl0ZVtdIE1PRF9NQVggPSB7MSwgLTEsIC0xLCAtMSwgMHg3Zn07CisgICAgICAgIGZpbmFsIGJ5dGVbXSBBQ19aRVJPID0gezIsIDAsIDAsIDAsIDB9OworICAgICAgICBmaW5hbCBieXRlW10gQUNfTUFYID0gezIsIC0xLCAtMSwgLTEsIDB4N2Z9OworICAgICAgICBmaW5hbCBieXRlW10gQ1JfWkVSTyA9IHs0LCAwLCAwLCAwLCAwfTsKKyAgICAgICAgZmluYWwgYnl0ZVtdIENSX01BWCA9IHs0LCAtMSwgLTEsIC0xLCAweDdmfTsKKyAgICAgICAgZmluYWwgYnl0ZVtdIE1PRF9BQ19aRVJPID0gezMsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDB9OworICAgICAgICBmaW5hbCBieXRlW10gTU9EX0FDX01BWCA9IHszLCAtMSwgLTEsIC0xLCAweDdmLCAtMSwgLTEsIC0xLCAweDdmfTsKKyAgICAgICAgZmluYWwgYnl0ZVtdIE1PRF9BQ19DUl9aRVJPID0gezcsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDB9OworICAgICAgICBmaW5hbCBieXRlW10gTU9EX0FDX0NSX01BWCA9IHs3LCAtMSwgLTEsIC0xLCAweDdmLCAtMSwgLTEsIC0xLCAweDdmLCAtMSwgLTEsIC0xLCAweDdmfTsKKworICAgICAgICBwYXJzZVJlcGFyc2UobnVsbCwgTlVMTF9GTEFHUywgTlVMTF9GTEFHUyk7CisgICAgICAgIHBhcnNlUmVwYXJzZShaRVJPX1RJTUUsIE1PRF9aRVJPLCBNT0RfWkVSTyk7CisgICAgICAgIHBhcnNlUmVwYXJzZShNQVhfVElNRV9TRUNPTkRTLCBNT0RfTUFYLCBNT0RfTUFYKTsKKyAgICAgICAgcGFyc2VSZXBhcnNlKFpFUk9fVElNRSwgQUNfWkVSTywgQUNfQ0VOVFJBTCk7CisgICAgICAgIHBhcnNlUmVwYXJzZShNQVhfVElNRV9TRUNPTkRTLCBBQ19NQVgsIEFDX0NFTlRSQUwpOworICAgICAgICBwYXJzZVJlcGFyc2UoWkVST19USU1FLCBDUl9aRVJPLCBDUl9DRU5UUkFMKTsKKyAgICAgICAgcGFyc2VSZXBhcnNlKE1BWF9USU1FX1NFQ09ORFMsIENSX01BWCwgQ1JfQ0VOVFJBTCk7CisgICAgICAgIHBhcnNlUmVwYXJzZShaRVJPX1RJTUUsIE1PRF9BQ19aRVJPLCBNT0RfWkVSTyk7CisgICAgICAgIHBhcnNlUmVwYXJzZShNQVhfVElNRV9TRUNPTkRTLCBNT0RfQUNfTUFYLCBNT0RfTUFYKTsKKyAgICAgICAgcGFyc2VSZXBhcnNlKFpFUk9fVElNRSwgTU9EX0FDX0NSX1pFUk8sIE1PRF9aRVJPKTsKKyAgICAgICAgcGFyc2VSZXBhcnNlKE1BWF9USU1FX1NFQ09ORFMsIE1PRF9BQ19DUl9NQVgsIE1PRF9NQVgpOworCisgICAgICAgIC8vIEFzIGZhciBhcyB0aGUgc3BlYyBpcyBjb25jZXJuZWQgKERlY2VtYmVyIDIwMTIpIGFsbCBvZiB0aGVzZSBmbGFncworICAgICAgICAvLyBhcmUgc3B1cmlvdXMgdmVyc2lvbnMgb2YgNyAoYS5rLmEuIGJpbmFyeSAwMDAwMDExMSkuCisgICAgICAgIHBhcnNlUmVwYXJzZSgoYnl0ZSkgMTUsIE1BWF9USU1FX1NFQ09ORFMsIChieXRlKSA3LCBNT0RfQUNfQ1JfTUFYLCBNT0RfTUFYKTsKKyAgICAgICAgcGFyc2VSZXBhcnNlKChieXRlKSAzMSwgTUFYX1RJTUVfU0VDT05EUywgKGJ5dGUpIDcsIE1PRF9BQ19DUl9NQVgsIE1PRF9NQVgpOworICAgICAgICBwYXJzZVJlcGFyc2UoKGJ5dGUpIDYzLCBNQVhfVElNRV9TRUNPTkRTLCAoYnl0ZSkgNywgTU9EX0FDX0NSX01BWCwgTU9EX01BWCk7CisgICAgICAgIHBhcnNlUmVwYXJzZSgoYnl0ZSkgNzEsIE1BWF9USU1FX1NFQ09ORFMsIChieXRlKSA3LCBNT0RfQUNfQ1JfTUFYLCBNT0RfTUFYKTsKKyAgICAgICAgcGFyc2VSZXBhcnNlKChieXRlKSAxMjcsIE1BWF9USU1FX1NFQ09ORFMsIChieXRlKSA3LCBNT0RfQUNfQ1JfTUFYLCBNT0RfTUFYKTsKKyAgICAgICAgcGFyc2VSZXBhcnNlKChieXRlKSAtMSwgTUFYX1RJTUVfU0VDT05EUywgKGJ5dGUpIDcsIE1PRF9BQ19DUl9NQVgsIE1PRF9NQVgpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFdyaXRlUmVhZFJvdW5kdHJpcCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRtcERpciA9IG1rZGlyKCJYNTQ1NSIpOworICAgICAgICBmaW5hbCBGaWxlIG91dHB1dCA9IG5ldyBGaWxlKHRtcERpciwgIndyaXRlX3Jld3JpdGUuemlwIik7CisgICAgICAgIGZpbmFsIE91dHB1dFN0cmVhbSBvdXQgPSBuZXcgRmlsZU91dHB1dFN0cmVhbShvdXRwdXQpOworICAgICAgICBmaW5hbCBEYXRlIGQgPSBuZXcgRGF0ZSg5NywgOCwgMjQsIDE1LCAxMCwgMik7CisgICAgICAgIFppcEFyY2hpdmVPdXRwdXRTdHJlYW0gb3MgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgb3MgPSBuZXcgWmlwQXJjaGl2ZU91dHB1dFN0cmVhbShvdXQpOworICAgICAgICAgICAgZmluYWwgWmlwQXJjaGl2ZUVudHJ5IHplID0gbmV3IFppcEFyY2hpdmVFbnRyeSgiZm9vIik7CisgICAgICAgICAgICB4Zi5zZXRNb2RpZnlKYXZhVGltZShkKTsKKyAgICAgICAgICAgIHhmLnNldEZsYWdzKChieXRlKSAxKTsKKyAgICAgICAgICAgIHplLmFkZEV4dHJhRmllbGQoeGYpOworICAgICAgICAgICAgb3MucHV0QXJjaGl2ZUVudHJ5KHplKTsKKyAgICAgICAgICAgIG9zLmNsb3NlQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAob3MgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIG9zLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgb3V0LmNsb3NlKCk7CisKKyAgICAgICAgZmluYWwgWmlwRmlsZSB6ZiA9IG5ldyBaaXBGaWxlKG91dHB1dCk7CisgICAgICAgIGZpbmFsIFppcEFyY2hpdmVFbnRyeSB6ZSA9IHpmLmdldEVudHJ5KCJmb28iKTsKKyAgICAgICAgZmluYWwgWDU0NTVfRXh0ZW5kZWRUaW1lc3RhbXAgZXh0ID0KKyAgICAgICAgICAgIChYNTQ1NV9FeHRlbmRlZFRpbWVzdGFtcCkgemUuZ2V0RXh0cmFGaWVsZChYNTQ1NSk7CisgICAgICAgIGFzc2VydE5vdE51bGwoZXh0KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShleHQuaXNCaXQwX21vZGlmeVRpbWVQcmVzZW50KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoZCwgZXh0LmdldE1vZGlmeUphdmFUaW1lKCkpOworICAgICAgICB6Zi5jbG9zZSgpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEJpdHNBcmVTZXRXaXRoVGltZSgpIHsKKyAgICAgICAgeGYuc2V0TW9kaWZ5SmF2YVRpbWUobmV3IERhdGUoMTExMSkpOworICAgICAgICBhc3NlcnRUcnVlKHhmLmlzQml0MF9tb2RpZnlUaW1lUHJlc2VudCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIHhmLmdldEZsYWdzKCkpOworICAgICAgICB4Zi5zZXRBY2Nlc3NKYXZhVGltZShuZXcgRGF0ZSgyMjIyKSk7CisgICAgICAgIGFzc2VydFRydWUoeGYuaXNCaXQxX2FjY2Vzc1RpbWVQcmVzZW50KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMywgeGYuZ2V0RmxhZ3MoKSk7CisgICAgICAgIHhmLnNldENyZWF0ZUphdmFUaW1lKG5ldyBEYXRlKDMzMzMpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh4Zi5pc0JpdDJfY3JlYXRlVGltZVByZXNlbnQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg3LCB4Zi5nZXRGbGFncygpKTsKKyAgICAgICAgeGYuc2V0TW9kaWZ5SmF2YVRpbWUobnVsbCk7CisgICAgICAgIGFzc2VydEZhbHNlKHhmLmlzQml0MF9tb2RpZnlUaW1lUHJlc2VudCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDYsIHhmLmdldEZsYWdzKCkpOworICAgICAgICB4Zi5zZXRBY2Nlc3NKYXZhVGltZShudWxsKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoeGYuaXNCaXQxX2FjY2Vzc1RpbWVQcmVzZW50KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoNCwgeGYuZ2V0RmxhZ3MoKSk7CisgICAgICAgIHhmLnNldENyZWF0ZUphdmFUaW1lKG51bGwpOworICAgICAgICBhc3NlcnRGYWxzZSh4Zi5pc0JpdDJfY3JlYXRlVGltZVByZXNlbnQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCB4Zi5nZXRGbGFncygpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcGFyc2VSZXBhcnNlKAorICAgICAgICAgICAgZmluYWwgWmlwTG9uZyB0aW1lLAorICAgICAgICAgICAgZmluYWwgYnl0ZVtdIGV4cGVjdGVkTG9jYWwsCisgICAgICAgICAgICBmaW5hbCBieXRlW10gYWxtb3N0RXhwZWN0ZWRDZW50cmFsCisgICAgKSB0aHJvd3MgWmlwRXhjZXB0aW9uIHsKKyAgICAgICAgcGFyc2VSZXBhcnNlKGV4cGVjdGVkTG9jYWxbMF0sIHRpbWUsIGV4cGVjdGVkTG9jYWxbMF0sIGV4cGVjdGVkTG9jYWwsIGFsbW9zdEV4cGVjdGVkQ2VudHJhbCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHBhcnNlUmVwYXJzZSgKKyAgICAgICAgICAgIGZpbmFsIGJ5dGUgcHJvdmlkZWRGbGFncywKKyAgICAgICAgICAgIGZpbmFsIFppcExvbmcgdGltZSwKKyAgICAgICAgICAgIGZpbmFsIGJ5dGUgZXhwZWN0ZWRGbGFncywKKyAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBleHBlY3RlZExvY2FsLAorICAgICAgICAgICAgZmluYWwgYnl0ZVtdIGFsbW9zdEV4cGVjdGVkQ2VudHJhbAorICAgICkgdGhyb3dzIFppcEV4Y2VwdGlvbiB7CisKKyAgICAgICAgLy8gV2UncmUgcmVzcG9uc2libGUgZm9yIGV4cGVjdGVkQ2VudHJhbCdzIGZsYWdzLiAgVG9vIGFubm95aW5nIHRvIHNldCBpbiBjYWxsZXIuCisgICAgICAgIGZpbmFsIGJ5dGVbXSBleHBlY3RlZENlbnRyYWwgPSBuZXcgYnl0ZVthbG1vc3RFeHBlY3RlZENlbnRyYWwubGVuZ3RoXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShhbG1vc3RFeHBlY3RlZENlbnRyYWwsIDAsIGV4cGVjdGVkQ2VudHJhbCwgMCwgYWxtb3N0RXhwZWN0ZWRDZW50cmFsLmxlbmd0aCk7CisgICAgICAgIGV4cGVjdGVkQ2VudHJhbFswXSA9IGV4cGVjdGVkRmxhZ3M7CisKKyAgICAgICAgeGYuc2V0TW9kaWZ5VGltZSh0aW1lKTsKKyAgICAgICAgeGYuc2V0QWNjZXNzVGltZSh0aW1lKTsKKyAgICAgICAgeGYuc2V0Q3JlYXRlVGltZSh0aW1lKTsKKyAgICAgICAgeGYuc2V0RmxhZ3MocHJvdmlkZWRGbGFncyk7CisgICAgICAgIGJ5dGVbXSByZXN1bHQgPSB4Zi5nZXRMb2NhbEZpbGVEYXRhRGF0YSgpOworICAgICAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMoZXhwZWN0ZWRMb2NhbCwgcmVzdWx0KSk7CisKKyAgICAgICAgLy8gQW5kIG5vdyB3ZSByZS1wYXJzZToKKyAgICAgICAgeGYucGFyc2VGcm9tTG9jYWxGaWxlRGF0YShyZXN1bHQsIDAsIHJlc3VsdC5sZW5ndGgpOworICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWRGbGFncywgeGYuZ2V0RmxhZ3MoKSk7CisgICAgICAgIGlmIChpc0ZsYWdTZXQoZXhwZWN0ZWRGbGFncywgTU9ESUZZX1RJTUVfQklUKSkgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSh4Zi5pc0JpdDBfbW9kaWZ5VGltZVByZXNlbnQoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHModGltZSwgeGYuZ2V0TW9kaWZ5VGltZSgpKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoaXNGbGFnU2V0KGV4cGVjdGVkRmxhZ3MsIEFDQ0VTU19USU1FX0JJVCkpIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoeGYuaXNCaXQxX2FjY2Vzc1RpbWVQcmVzZW50KCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHRpbWUsIHhmLmdldEFjY2Vzc1RpbWUoKSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlzRmxhZ1NldChleHBlY3RlZEZsYWdzLCBDUkVBVEVfVElNRV9CSVQpKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKHhmLmlzQml0Ml9jcmVhdGVUaW1lUHJlc2VudCgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyh0aW1lLCB4Zi5nZXRDcmVhdGVUaW1lKCkpOworICAgICAgICB9CisKKyAgICAgICAgLy8gRG8gdGhlIHNhbWUgYXMgYWJvdmUsIGJ1dCB3aXRoIENlbnRyYWwgRGlyZWN0b3J5IGRhdGE6CisgICAgICAgIHhmLnNldE1vZGlmeVRpbWUodGltZSk7CisgICAgICAgIHhmLnNldEFjY2Vzc1RpbWUodGltZSk7CisgICAgICAgIHhmLnNldENyZWF0ZVRpbWUodGltZSk7CisgICAgICAgIHhmLnNldEZsYWdzKHByb3ZpZGVkRmxhZ3MpOworICAgICAgICByZXN1bHQgPSB4Zi5nZXRDZW50cmFsRGlyZWN0b3J5RGF0YSgpOworICAgICAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMoZXhwZWN0ZWRDZW50cmFsLCByZXN1bHQpKTsKKworICAgICAgICAvLyBBbmQgbm93IHdlIHJlLXBhcnNlOgorICAgICAgICB4Zi5wYXJzZUZyb21DZW50cmFsRGlyZWN0b3J5RGF0YShyZXN1bHQsIDAsIHJlc3VsdC5sZW5ndGgpOworICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWRGbGFncywgeGYuZ2V0RmxhZ3MoKSk7CisgICAgICAgIC8vIENlbnRyYWwgRGlyZWN0b3J5IG5ldmVyIGNvbnRhaW5zIEFDQ0VTUyBvciBDUkVBVEUsIGJ1dAorICAgICAgICAvLyBtYXkgY29udGFpbiBNT0RJRlkuCisgICAgICAgIGlmIChpc0ZsYWdTZXQoZXhwZWN0ZWRGbGFncywgTU9ESUZZX1RJTUVfQklUKSkgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSh4Zi5pc0JpdDBfbW9kaWZ5VGltZVByZXNlbnQoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHModGltZSwgeGYuZ2V0TW9kaWZ5VGltZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNGbGFnU2V0KGZpbmFsIGJ5dGUgZGF0YSwgZmluYWwgYnl0ZSBmbGFnKSB7IHJldHVybiAoZGF0YSAmIGZsYWcpID09IGZsYWc7IH0KKworICAgIC8qKgorICAgICAqIEluZm9aSVAgc2VlbXMgdG8gYWRqdXN0IHRoZSB0aW1lIHN0b3JlZCBpbnNpZGUgdGhlIExGSCBhbmQgQ0QKKyAgICAgKiB0byBHTVQgd2hlbiB3cml0aW5nIFpJUHMgd2hpbGUgamF2YS51dGlsLnppcC5aaXBFbnRyeSB0aGlua3MgaXQKKyAgICAgKiB3YXMgaW4gbG9jYWwgdGltZS4KKyAgICAgKgorICAgICAqIFRoZSBhcmNoaXZlIHJlYWQgaW4ge0BsaW5rICN0ZXN0U2FtcGxlRmlsZX0gaGFzIGJlZW4gY3JlYXRlZAorICAgICAqIHdpdGggR01ULTggc28gd2UgbmVlZCB0byBhZGp1c3QgZm9yIHRoZSBkaWZmZXJlbmNlLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIERhdGUgYWRqdXN0RnJvbUdNVFRvRXhwZWN0ZWRPZmZzZXQoZmluYWwgRGF0ZSBmcm9tKSB7CisgICAgICAgIGZpbmFsIENhbGVuZGFyIGNhbCA9IENhbGVuZGFyLmdldEluc3RhbmNlKCk7CisgICAgICAgIGNhbC5zZXRUaW1lKGZyb20pOworICAgICAgICBjYWwuYWRkKENhbGVuZGFyLk1JTExJU0VDT05ELCBjYWwuZ2V0KENhbGVuZGFyLlpPTkVfT0ZGU0VUKSk7CisgICAgICAgIGlmIChjYWwuZ2V0VGltZVpvbmUoKS5pbkRheWxpZ2h0VGltZShmcm9tKSkgeworICAgICAgICAgICAgY2FsLmFkZChDYWxlbmRhci5NSUxMSVNFQ09ORCwgY2FsLmdldChDYWxlbmRhci5EU1RfT0ZGU0VUKSk7CisgICAgICAgIH0KKyAgICAgICAgY2FsLmFkZChDYWxlbmRhci5IT1VSLCA4KTsKKyAgICAgICAgcmV0dXJuIGNhbC5nZXRUaW1lKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9YNzg3NV9OZXdVbml4VGVzdC5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9YNzg3NV9OZXdVbml4VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIxNDg4MDkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1g3ODc1X05ld1VuaXhUZXN0LmphdmEKQEAgLTAsMCArMSwyNDcgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcDsKKworaW1wb3J0IG9yZy5qdW5pdC5CZWZvcmU7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CisKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247CitpbXBvcnQgamF2YS51dGlsLnppcC5aaXBFeGNlcHRpb247CisKK2ltcG9ydCBzdGF0aWMgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLkFic3RyYWN0VGVzdENhc2UuZ2V0RmlsZTsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRBcnJheUVxdWFsczsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRFcXVhbHM7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0RmFsc2U7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VHJ1ZTsKKworcHVibGljIGNsYXNzIFg3ODc1X05ld1VuaXhUZXN0IHsKKworICAgIHByaXZhdGUgZmluYWwgc3RhdGljIFppcFNob3J0IFg3ODc1ID0gbmV3IFppcFNob3J0KDB4Nzg3NSk7CisKKyAgICBwcml2YXRlIFg3ODc1X05ld1VuaXggeGY7CisKKyAgICBAQmVmb3JlCisgICAgcHVibGljIHZvaWQgYmVmb3JlKCkgeworICAgICAgICB4ZiA9IG5ldyBYNzg3NV9OZXdVbml4KCk7CisgICAgfQorCisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RTYW1wbGVGaWxlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGUgYXJjaGl2ZSA9IGdldEZpbGUoIkNPTVBSRVNTLTIxMV91aWRfZ2lkX3ppcF90ZXN0LnppcCIpOworICAgICAgICBaaXBGaWxlIHpmID0gbnVsbDsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgemYgPSBuZXcgWmlwRmlsZShhcmNoaXZlKTsKKyAgICAgICAgICAgIGZpbmFsIEVudW1lcmF0aW9uPFppcEFyY2hpdmVFbnRyeT4gZW4gPSB6Zi5nZXRFbnRyaWVzKCk7CisKKyAgICAgICAgICAgIC8vIFdlIGV4cGVjdCBFVkVSWSBlbnRyeSBvZiB0aGlzIHppcCBmaWxlIChkaXIgJiBmaWxlKSB0bworICAgICAgICAgICAgLy8gY29udGFpbiBleHRyYSBmaWVsZCAweDc4NzUuCisgICAgICAgICAgICB3aGlsZSAoZW4uaGFzTW9yZUVsZW1lbnRzKCkpIHsKKworICAgICAgICAgICAgICAgIGZpbmFsIFppcEFyY2hpdmVFbnRyeSB6YWUgPSBlbi5uZXh0RWxlbWVudCgpOworICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBuYW1lID0gemFlLmdldE5hbWUoKTsKKyAgICAgICAgICAgICAgICBmaW5hbCBYNzg3NV9OZXdVbml4IHhmID0gKFg3ODc1X05ld1VuaXgpIHphZS5nZXRFeHRyYUZpZWxkKFg3ODc1KTsKKworICAgICAgICAgICAgICAgIC8vIFRoZSBkaXJlY3RvcnkgZW50cnkgaW4gdGhlIHRlc3QgemlwIGZpbGUgaXMgdWlkL2dpZCAxMDAwLgorICAgICAgICAgICAgICAgIGxvbmcgZXhwZWN0ZWQgPSAxMDAwOworICAgICAgICAgICAgICAgIGlmIChuYW1lLmNvbnRhaW5zKCJ1aWQ1NTVfZ2lkNTU1IikpIHsKKyAgICAgICAgICAgICAgICAgICAgZXhwZWN0ZWQgPSA1NTU7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChuYW1lLmNvbnRhaW5zKCJ1aWQ1NTU1X2dpZDU1NTUiKSkgeworICAgICAgICAgICAgICAgICAgICBleHBlY3RlZCA9IDU1NTU7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChuYW1lLmNvbnRhaW5zKCJ1aWQ1NTU1NV9naWQ1NTU1NSIpKSB7CisgICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkID0gNTU1NTU7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChuYW1lLmNvbnRhaW5zKCJ1aWQ1NTU1NTVfZ2lkNTU1NTU1IikpIHsKKyAgICAgICAgICAgICAgICAgICAgZXhwZWN0ZWQgPSA1NTU1NTU7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChuYW1lLmNvbnRhaW5zKCJtaW5fdW5peCIpKSB7CisgICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkID0gMDsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG5hbWUuY29udGFpbnMoIm1heF91bml4IikpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gMl4zMi0yIHdhcyB0aGUgYmlnZ2VzdCBVSUQvR0lEIEkgY291bGQgY3JlYXRlIG9uIG15IGxpbnV4IQorICAgICAgICAgICAgICAgICAgICAvLyAoRGVjZW1iZXIgMjAxMiwgbGludXgga2VybmVsIDMuNCkKKyAgICAgICAgICAgICAgICAgICAgZXhwZWN0ZWQgPSAweDEwMDAwMDAwMEwgLSAyOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWQsIHhmLmdldFVJRCgpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWQsIHhmLmdldEdJRCgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmICh6ZiAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgemYuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEdldEhlYWRlcklkKCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoWDc4NzUsIHhmLmdldEhlYWRlcklkKCkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdE1pc2MoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RmFsc2UoeGYuZXF1YWxzKG5ldyBPYmplY3QoKSkpOworICAgICAgICBhc3NlcnRUcnVlKHhmLnRvU3RyaW5nKCkuc3RhcnRzV2l0aCgiMHg3ODc1IFppcCBFeHRyYSBGaWVsZCIpKTsKKyAgICAgICAgZmluYWwgT2JqZWN0IG8gPSB4Zi5jbG9uZSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoby5oYXNoQ29kZSgpLCB4Zi5oYXNoQ29kZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh4Zi5lcXVhbHMobykpOworICAgICAgICB4Zi5zZXRVSUQoMTIzNDUpOworICAgICAgICBhc3NlcnRGYWxzZSh4Zi5lcXVhbHMobykpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFRyaW1MZWFkaW5nWmVyb2VzRm9yY2VNaW5MZW5ndGg0KCkgeworICAgICAgICBmaW5hbCBieXRlW10gTlVMTCA9IG51bGw7CisgICAgICAgIGZpbmFsIGJ5dGVbXSBFTVBUWSA9IG5ldyBieXRlWzBdOworICAgICAgICBmaW5hbCBieXRlW10gT05FX1pFUk8gPSB7MH07CisgICAgICAgIGZpbmFsIGJ5dGVbXSBUV09fWkVST0VTID0gezAsIDB9OworICAgICAgICBmaW5hbCBieXRlW10gRk9VUl9aRVJPRVMgPSB7MCwgMCwgMCwgMH07CisgICAgICAgIGZpbmFsIGJ5dGVbXSBTRVFVRU5DRSA9IHsxLCAyLCAzfTsKKyAgICAgICAgZmluYWwgYnl0ZVtdIFNFUVVFTkNFX0xFQURJTkdfWkVSTyA9IHswLCAxLCAyLCAzfTsKKyAgICAgICAgZmluYWwgYnl0ZVtdIFNFUVVFTkNFX0xFQURJTkdfWkVST0VTID0gezAsIDAsIDAsIDAsIDAsIDAsIDAsIDEsIDIsIDN9OworICAgICAgICBmaW5hbCBieXRlW10gVFJBSUxJTkdfWkVSTyA9IHsxLCAyLCAzLCAwfTsKKyAgICAgICAgZmluYWwgYnl0ZVtdIFBBRERJTkdfWkVSTyA9IHswLCAxLCAyLCAzLCAwfTsKKyAgICAgICAgZmluYWwgYnl0ZVtdIFNFUVVFTkNFNiA9IHsxLCAyLCAzLCA0LCA1LCA2fTsKKyAgICAgICAgZmluYWwgYnl0ZVtdIFNFUVVFTkNFNl9MRUFESU5HX1pFUk8gPSB7MCwgMSwgMiwgMywgNCwgNSwgNn07CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShOVUxMID09IHRyaW1UZXN0KE5VTEwpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKE9ORV9aRVJPLCB0cmltVGVzdChFTVBUWSkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKE9ORV9aRVJPLCB0cmltVGVzdChPTkVfWkVSTykpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKE9ORV9aRVJPLCB0cmltVGVzdChUV09fWkVST0VTKSkpOworICAgICAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMoT05FX1pFUk8sIHRyaW1UZXN0KEZPVVJfWkVST0VTKSkpOworICAgICAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMoU0VRVUVOQ0UsIHRyaW1UZXN0KFNFUVVFTkNFKSkpOworICAgICAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMoU0VRVUVOQ0UsIHRyaW1UZXN0KFNFUVVFTkNFX0xFQURJTkdfWkVSTykpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKFNFUVVFTkNFLCB0cmltVGVzdChTRVFVRU5DRV9MRUFESU5HX1pFUk9FUykpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKFRSQUlMSU5HX1pFUk8sIHRyaW1UZXN0KFRSQUlMSU5HX1pFUk8pKSk7CisgICAgICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhUUkFJTElOR19aRVJPLCB0cmltVGVzdChQQURESU5HX1pFUk8pKSk7CisgICAgICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhTRVFVRU5DRTYsIHRyaW1UZXN0KFNFUVVFTkNFNikpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKFNFUVVFTkNFNiwgdHJpbVRlc3QoU0VRVUVOQ0U2X0xFQURJTkdfWkVSTykpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBieXRlW10gdHJpbVRlc3QoZmluYWwgYnl0ZVtdIGIpIHsgcmV0dXJuIFg3ODc1X05ld1VuaXgudHJpbUxlYWRpbmdaZXJvZXNGb3JjZU1pbkxlbmd0aChiKTsgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UGFyc2VSZXBhcnNlKCkgdGhyb3dzIFppcEV4Y2VwdGlvbiB7CisKKyAgICAgICAgLy8gVmVyc2lvbj0xLCBMZW49MCwgTGVuPTAuCisgICAgICAgIGZpbmFsIGJ5dGVbXSBaRVJPX0xFTiA9IHsxLCAwLCAwfTsKKworICAgICAgICAvLyBWZXJzaW9uPTEsIExlbj0xLCB6ZXJvLCBMZW49MSwgemVyby4KKyAgICAgICAgZmluYWwgYnl0ZVtdIFpFUk9fVUlEX0dJRCA9IHsxLCAxLCAwLCAxLCAwfTsKKworICAgICAgICAvLyBWZXJzaW9uPTEsIExlbj0xLCBvbmUsIExlbj0xLCBvbmUKKyAgICAgICAgZmluYWwgYnl0ZVtdIE9ORV9VSURfR0lEID0gezEsIDEsIDEsIDEsIDF9OworCisgICAgICAgIC8vIFZlcnNpb249MSwgTGVuPTIsIG9uZSB0aG91c2FuZCwgTGVuPTIsIG9uZSB0aG91c2FuZAorICAgICAgICBmaW5hbCBieXRlW10gT05FX1RIT1VTQU5EX1VJRF9HSUQgPSB7MSwgMiwgLTI0LCAzLCAyLCAtMjQsIDN9OworCisgICAgICAgIC8vICgyXjMyIC0gMikuICAgSSBndWVzcyB0aGV5IGF2b2lkICgyXjMyIC0gMSkgc2luY2UgaXQncyBpZGVudGljYWwgdG8gLTEgaW4KKyAgICAgICAgLy8gdHdvJ3MgY29tcGxlbWVudCwgYW5kIC0xIG9mdGVuIGhhcyBhIHNwZWNpYWwgbWVhbmluZy4KKyAgICAgICAgZmluYWwgYnl0ZVtdIFVOSVhfTUFYX1VJRF9HSUQgPSB7MSwgNCwgLTIsIC0xLCAtMSwgLTEsIDQsIC0yLCAtMSwgLTEsIC0xfTsKKworICAgICAgICAvLyBWZXJzaW9uPTEsIExlbj01LCAyXjMyLCBMZW49NSwgMl4zMiArIDEKKyAgICAgICAgLy8gRXNvdGVyaWMgdGVzdDogIGNhbiB3ZSBoYW5kbGUgNDAgYml0IG51bWJlcnM/CisgICAgICAgIGZpbmFsIGJ5dGVbXSBMRU5HVEhfNSA9IHsxLCA1LCAwLCAwLCAwLCAwLCAxLCA1LCAxLCAwLCAwLCAwLCAxfTsKKworICAgICAgICAvLyBWZXJzaW9uPTEsIExlbj04LCAyXjYzIC0gMiwgTGVuPTgsIDJeNjMgLSAxCisgICAgICAgIC8vIEVzb3RlcmljIHRlc3Q6ICBjYW4gd2UgaGFuZGxlIDY0IGJpdCBudW1iZXJzPworICAgICAgICBmaW5hbCBieXRlW10gTEVOR1RIXzggPSB7MSwgOCwgLTIsIC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsIDEyNywgOCwgLTEsIC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsIDEyN307CisKKyAgICAgICAgZmluYWwgbG9uZyBUV09fVE9fMzIgPSAweDEwMDAwMDAwMEw7CisgICAgICAgIGZpbmFsIGxvbmcgTUFYID0gVFdPX1RPXzMyIC0gMjsKKworICAgICAgICBwYXJzZVJlcGFyc2UoMCwgMCwgWkVST19MRU4sIDAsIDApOworICAgICAgICBwYXJzZVJlcGFyc2UoMCwgMCwgWkVST19VSURfR0lELCAwLCAwKTsKKyAgICAgICAgcGFyc2VSZXBhcnNlKDEsIDEsIE9ORV9VSURfR0lELCAxLCAxKTsKKyAgICAgICAgcGFyc2VSZXBhcnNlKDEwMDAsIDEwMDAsIE9ORV9USE9VU0FORF9VSURfR0lELCAxMDAwLCAxMDAwKTsKKyAgICAgICAgcGFyc2VSZXBhcnNlKE1BWCwgTUFYLCBVTklYX01BWF9VSURfR0lELCBNQVgsIE1BWCk7CisgICAgICAgIHBhcnNlUmVwYXJzZSgtMiwgLTIsIFVOSVhfTUFYX1VJRF9HSUQsIE1BWCwgTUFYKTsKKyAgICAgICAgcGFyc2VSZXBhcnNlKFRXT19UT18zMiwgVFdPX1RPXzMyICsgMSwgTEVOR1RIXzUsIFRXT19UT18zMiwgVFdPX1RPXzMyICsgMSk7CisgICAgICAgIHBhcnNlUmVwYXJzZShMb25nLk1BWF9WQUxVRSAtIDEsIExvbmcuTUFYX1ZBTFVFLCBMRU5HVEhfOCwgTG9uZy5NQVhfVkFMVUUgLSAxLCBMb25nLk1BWF9WQUxVRSk7CisKKyAgICAgICAgLy8gV2UgbmV2ZXIgZW1pdCB0aGlzLCBidXQgd2Ugc2hvdWxkIGJlIGFibGUgdG8gcGFyc2UgaXQ6CisgICAgICAgIGZpbmFsIGJ5dGVbXSBTUFVSSU9VU19aRVJPRVNfMSA9IHsxLCA0LCAtMSwgMCwgMCwgMCwgNCwgLTEyOCwgMCwgMCwgMH07CisgICAgICAgIGZpbmFsIGJ5dGVbXSBFWFBFQ1RFRF8xID0gezEsIDEsIC0xLCAxLCAtMTI4fTsKKyAgICAgICAgeGYucGFyc2VGcm9tTG9jYWxGaWxlRGF0YShTUFVSSU9VU19aRVJPRVNfMSwgMCwgU1BVUklPVVNfWkVST0VTXzEubGVuZ3RoKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoMjU1LCB4Zi5nZXRVSUQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxMjgsIHhmLmdldEdJRCgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKEVYUEVDVEVEXzEsIHhmLmdldExvY2FsRmlsZURhdGFEYXRhKCkpKTsKKworICAgICAgICBmaW5hbCBieXRlW10gU1BVUklPVVNfWkVST0VTXzIgPSB7MSwgNCwgLTEsIC0xLCAwLCAwLCA0LCAxLCAyLCAwLCAwfTsKKyAgICAgICAgZmluYWwgYnl0ZVtdIEVYUEVDVEVEXzIgPSB7MSwgMiwgLTEsIC0xLCAyLCAxLCAyfTsKKyAgICAgICAgeGYucGFyc2VGcm9tTG9jYWxGaWxlRGF0YShTUFVSSU9VU19aRVJPRVNfMiwgMCwgU1BVUklPVVNfWkVST0VTXzIubGVuZ3RoKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoNjU1MzUsIHhmLmdldFVJRCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDUxMywgeGYuZ2V0R0lEKCkpOworICAgICAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMoRVhQRUNURURfMiwgeGYuZ2V0TG9jYWxGaWxlRGF0YURhdGEoKSkpOworICAgIH0KKworCisgICAgcHJpdmF0ZSB2b2lkIHBhcnNlUmVwYXJzZSgKKyAgICAgICAgICAgIGZpbmFsIGxvbmcgdWlkLAorICAgICAgICAgICAgZmluYWwgbG9uZyBnaWQsCisgICAgICAgICAgICBmaW5hbCBieXRlW10gZXhwZWN0ZWQsCisgICAgICAgICAgICBmaW5hbCBsb25nIGV4cGVjdGVkVUlELAorICAgICAgICAgICAgZmluYWwgbG9uZyBleHBlY3RlZEdJRAorICAgICkgdGhyb3dzIFppcEV4Y2VwdGlvbiB7CisKKyAgICAgICAgLy8gSW5pdGlhbCBsb2NhbCBwYXJzZSAoaW5pdCB3aXRoIGdhcmJhZ2UgdG8gYXZvaWQgZGVmYXVsdHMgY2F1c2luZyB0ZXN0IHRvIHBhc3MpLgorICAgICAgICB4Zi5zZXRVSUQoNTQzMjEpOworICAgICAgICB4Zi5zZXRHSUQoMTIzNDUpOworICAgICAgICB4Zi5wYXJzZUZyb21Mb2NhbEZpbGVEYXRhKGV4cGVjdGVkLCAwLCBleHBlY3RlZC5sZW5ndGgpOworICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWRVSUQsIHhmLmdldFVJRCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkR0lELCB4Zi5nZXRHSUQoKSk7CisKKyAgICAgICAgeGYuc2V0VUlEKHVpZCk7CisgICAgICAgIHhmLnNldEdJRChnaWQpOworICAgICAgICBpZiAoZXhwZWN0ZWQubGVuZ3RoIDwgNSkgeworICAgICAgICAgICAgLy8gV2UgbmV2ZXIgZW1pdCB6ZXJvLWxlbmd0aCBlbnRyaWVzLgorICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDUsIHhmLmdldExvY2FsRmlsZURhdGFMZW5ndGgoKS5nZXRWYWx1ZSgpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZC5sZW5ndGgsIHhmLmdldExvY2FsRmlsZURhdGFMZW5ndGgoKS5nZXRWYWx1ZSgpKTsKKyAgICAgICAgfQorICAgICAgICBieXRlW10gcmVzdWx0ID0geGYuZ2V0TG9jYWxGaWxlRGF0YURhdGEoKTsKKyAgICAgICAgaWYgKGV4cGVjdGVkLmxlbmd0aCA8IDUpIHsKKyAgICAgICAgICAgIC8vIFdlIG5ldmVyIGVtaXQgemVyby1sZW5ndGggZW50cmllcy4KKyAgICAgICAgICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhuZXcgYnl0ZVtdezEsMSwwLDEsMH0sIHJlc3VsdCkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKGV4cGVjdGVkLCByZXN1bHQpKTsKKyAgICAgICAgfQorCisKKworICAgICAgICAvLyBBbmQgbm93IHdlIHJlLXBhcnNlOgorICAgICAgICB4Zi5wYXJzZUZyb21Mb2NhbEZpbGVEYXRhKHJlc3VsdCwgMCwgcmVzdWx0Lmxlbmd0aCk7CisKKyAgICAgICAgLy8gRGlkIHVpZC9naWQgY2hhbmdlIGZyb20gcmUtcGFyc2U/ICBUaGV5IHNob3VsZG4ndCEKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkVUlELCB4Zi5nZXRVSUQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZEdJRCwgeGYuZ2V0R0lEKCkpOworCisgICAgICAgIGFzc2VydEVxdWFscygwLCB4Zi5nZXRDZW50cmFsRGlyZWN0b3J5TGVuZ3RoKCkuZ2V0VmFsdWUoKSk7CisgICAgICAgIHJlc3VsdCA9IHhmLmdldENlbnRyYWxEaXJlY3RvcnlEYXRhKCk7CisgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKG5ldyBieXRlWzBdLCByZXN1bHQpOworCisgICAgICAgIC8vIEFuZCBub3cgd2UgcmUtcGFyc2U6CisgICAgICAgIHhmLnBhcnNlRnJvbUNlbnRyYWxEaXJlY3RvcnlEYXRhKHJlc3VsdCwgMCwgcmVzdWx0Lmxlbmd0aCk7CisKKyAgICAgICAgLy8gRGlkIHVpZC9naWQgY2hhbmdlIGZyb20gMm5kIHJlLXBhcnNlPyAgVGhleSBzaG91bGRuJ3QhCisgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZFVJRCwgeGYuZ2V0VUlEKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWRHSUQsIHhmLmdldEdJRCgpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1ppcDY0RXh0ZW5kZWRJbmZvcm1hdGlvbkV4dHJhRmllbGRUZXN0LmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1ppcDY0RXh0ZW5kZWRJbmZvcm1hdGlvbkV4dHJhRmllbGRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTM2NmZmYQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvWmlwNjRFeHRlbmRlZEluZm9ybWF0aW9uRXh0cmFGaWVsZFRlc3QuamF2YQpAQCAtMCwwICsxLDI1MSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICoKKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwOworCitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuKjsKKworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGphdmEudXRpbC56aXAuWmlwRXhjZXB0aW9uOworCitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CisKK3B1YmxpYyBjbGFzcyBaaXA2NEV4dGVuZGVkSW5mb3JtYXRpb25FeHRyYUZpZWxkVGVzdCB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBaaXBFaWdodEJ5dGVJbnRlZ2VyIFNJWkUgPQorICAgICAgICBuZXcgWmlwRWlnaHRCeXRlSW50ZWdlcigweDEyMzQ1Njc4KTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBaaXBFaWdodEJ5dGVJbnRlZ2VyIENTSVpFID0KKyAgICAgICAgbmV3IFppcEVpZ2h0Qnl0ZUludGVnZXIoMHg5QUJDREVGKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBaaXBFaWdodEJ5dGVJbnRlZ2VyIE9GRiA9CisgICAgICAgIG5ldyBaaXBFaWdodEJ5dGVJbnRlZ2VyKEJpZ0ludGVnZXIudmFsdWVPZigweEFCQ0RFRjA5MTIzNDU2N2wpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zaGlmdExlZnQoNCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnNldEJpdCgzKSk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgWmlwTG9uZyBESVNLID0gbmV3IFppcExvbmcoMHgxMik7CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RXcml0ZUNET25seVNpemVzKCkgeworICAgICAgICBmaW5hbCBaaXA2NEV4dGVuZGVkSW5mb3JtYXRpb25FeHRyYUZpZWxkIGYgPQorICAgICAgICAgICAgbmV3IFppcDY0RXh0ZW5kZWRJbmZvcm1hdGlvbkV4dHJhRmllbGQoU0laRSwgQ1NJWkUpOworICAgICAgICBhc3NlcnRFcXVhbHMobmV3IFppcFNob3J0KDE2KSwgZi5nZXRDZW50cmFsRGlyZWN0b3J5TGVuZ3RoKCkpOworICAgICAgICBmaW5hbCBieXRlW10gYiA9IGYuZ2V0Q2VudHJhbERpcmVjdG9yeURhdGEoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDE2LCBiLmxlbmd0aCk7CisgICAgICAgIGNoZWNrU2l6ZXMoYik7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0V3JpdGVDRFNpemVBbmRPZmZzZXQoKSB7CisgICAgICAgIGZpbmFsIFppcDY0RXh0ZW5kZWRJbmZvcm1hdGlvbkV4dHJhRmllbGQgZiA9CisgICAgICAgICAgICBuZXcgWmlwNjRFeHRlbmRlZEluZm9ybWF0aW9uRXh0cmFGaWVsZChTSVpFLCBDU0laRSwgT0ZGLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBaaXBTaG9ydCgyNCksIGYuZ2V0Q2VudHJhbERpcmVjdG9yeUxlbmd0aCgpKTsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGIgPSBmLmdldENlbnRyYWxEaXJlY3RvcnlEYXRhKCk7CisgICAgICAgIGFzc2VydEVxdWFscygyNCwgYi5sZW5ndGgpOworICAgICAgICBjaGVja1NpemVzKGIpOworICAgICAgICBjaGVja09mZnNldChiLCAxNik7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0V3JpdGVDRFNpemVPZmZzZXRBbmREaXNrKCkgeworICAgICAgICBmaW5hbCBaaXA2NEV4dGVuZGVkSW5mb3JtYXRpb25FeHRyYUZpZWxkIGYgPQorICAgICAgICAgICAgbmV3IFppcDY0RXh0ZW5kZWRJbmZvcm1hdGlvbkV4dHJhRmllbGQoU0laRSwgQ1NJWkUsIE9GRiwgRElTSyk7CisgICAgICAgIGFzc2VydEVxdWFscyhuZXcgWmlwU2hvcnQoMjgpLCBmLmdldENlbnRyYWxEaXJlY3RvcnlMZW5ndGgoKSk7CisgICAgICAgIGZpbmFsIGJ5dGVbXSBiID0gZi5nZXRDZW50cmFsRGlyZWN0b3J5RGF0YSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoMjgsIGIubGVuZ3RoKTsKKyAgICAgICAgY2hlY2tTaXplcyhiKTsKKyAgICAgICAgY2hlY2tPZmZzZXQoYiwgMTYpOworICAgICAgICBjaGVja0Rpc2soYiwgMjQpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFdyaXRlQ0RTaXplQW5kRGlzaygpIHsKKyAgICAgICAgZmluYWwgWmlwNjRFeHRlbmRlZEluZm9ybWF0aW9uRXh0cmFGaWVsZCBmID0KKyAgICAgICAgICAgIG5ldyBaaXA2NEV4dGVuZGVkSW5mb3JtYXRpb25FeHRyYUZpZWxkKFNJWkUsIENTSVpFLCBudWxsLCBESVNLKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBaaXBTaG9ydCgyMCksIGYuZ2V0Q2VudHJhbERpcmVjdG9yeUxlbmd0aCgpKTsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGIgPSBmLmdldENlbnRyYWxEaXJlY3RvcnlEYXRhKCk7CisgICAgICAgIGFzc2VydEVxdWFscygyMCwgYi5sZW5ndGgpOworICAgICAgICBjaGVja1NpemVzKGIpOworICAgICAgICBjaGVja0Rpc2soYiwgMTYpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFJlYWRMRkhTaXplc09ubHkoKSB0aHJvd3MgWmlwRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgWmlwNjRFeHRlbmRlZEluZm9ybWF0aW9uRXh0cmFGaWVsZCBmID0KKyAgICAgICAgICAgIG5ldyBaaXA2NEV4dGVuZGVkSW5mb3JtYXRpb25FeHRyYUZpZWxkKCk7CisgICAgICAgIGZpbmFsIGJ5dGVbXSBiID0gbmV3IGJ5dGVbMTZdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KFNJWkUuZ2V0Qnl0ZXMoKSwgMCwgYiwgMCwgOCk7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoQ1NJWkUuZ2V0Qnl0ZXMoKSwgMCwgYiwgOCwgOCk7CisgICAgICAgIGYucGFyc2VGcm9tTG9jYWxGaWxlRGF0YShiLCAwLCBiLmxlbmd0aCk7CisgICAgICAgIGFzc2VydEVxdWFscyhTSVpFLCBmLmdldFNpemUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhDU0laRSwgZi5nZXRDb21wcmVzc2VkU2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChmLmdldFJlbGF0aXZlSGVhZGVyT2Zmc2V0KCkpOworICAgICAgICBhc3NlcnROdWxsKGYuZ2V0RGlza1N0YXJ0TnVtYmVyKCkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFJlYWRMRkhTaXplc0FuZE9mZnNldCgpIHRocm93cyBaaXBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBaaXA2NEV4dGVuZGVkSW5mb3JtYXRpb25FeHRyYUZpZWxkIGYgPQorICAgICAgICAgICAgbmV3IFppcDY0RXh0ZW5kZWRJbmZvcm1hdGlvbkV4dHJhRmllbGQoKTsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGIgPSBuZXcgYnl0ZVsyNF07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoU0laRS5nZXRCeXRlcygpLCAwLCBiLCAwLCA4KTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShDU0laRS5nZXRCeXRlcygpLCAwLCBiLCA4LCA4KTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShPRkYuZ2V0Qnl0ZXMoKSwgMCwgYiwgMTYsIDgpOworICAgICAgICBmLnBhcnNlRnJvbUxvY2FsRmlsZURhdGEoYiwgMCwgYi5sZW5ndGgpOworICAgICAgICBhc3NlcnRFcXVhbHMoU0laRSwgZi5nZXRTaXplKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoQ1NJWkUsIGYuZ2V0Q29tcHJlc3NlZFNpemUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhPRkYsIGYuZ2V0UmVsYXRpdmVIZWFkZXJPZmZzZXQoKSk7CisgICAgICAgIGFzc2VydE51bGwoZi5nZXREaXNrU3RhcnROdW1iZXIoKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVhZExGSFNpemVzT2Zmc2V0QW5kRGlzaygpIHRocm93cyBaaXBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBaaXA2NEV4dGVuZGVkSW5mb3JtYXRpb25FeHRyYUZpZWxkIGYgPQorICAgICAgICAgICAgbmV3IFppcDY0RXh0ZW5kZWRJbmZvcm1hdGlvbkV4dHJhRmllbGQoKTsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGIgPSBuZXcgYnl0ZVsyOF07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoU0laRS5nZXRCeXRlcygpLCAwLCBiLCAwLCA4KTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShDU0laRS5nZXRCeXRlcygpLCAwLCBiLCA4LCA4KTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShPRkYuZ2V0Qnl0ZXMoKSwgMCwgYiwgMTYsIDgpOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KERJU0suZ2V0Qnl0ZXMoKSwgMCwgYiwgMjQsIDQpOworICAgICAgICBmLnBhcnNlRnJvbUxvY2FsRmlsZURhdGEoYiwgMCwgYi5sZW5ndGgpOworICAgICAgICBhc3NlcnRFcXVhbHMoU0laRSwgZi5nZXRTaXplKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoQ1NJWkUsIGYuZ2V0Q29tcHJlc3NlZFNpemUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhPRkYsIGYuZ2V0UmVsYXRpdmVIZWFkZXJPZmZzZXQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhESVNLLCBmLmdldERpc2tTdGFydE51bWJlcigpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RSZWFkTEZIU2l6ZXNBbmREaXNrKCkgdGhyb3dzIFppcEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFppcDY0RXh0ZW5kZWRJbmZvcm1hdGlvbkV4dHJhRmllbGQgZiA9CisgICAgICAgICAgICBuZXcgWmlwNjRFeHRlbmRlZEluZm9ybWF0aW9uRXh0cmFGaWVsZCgpOworICAgICAgICBmaW5hbCBieXRlW10gYiA9IG5ldyBieXRlWzIwXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShTSVpFLmdldEJ5dGVzKCksIDAsIGIsIDAsIDgpOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KENTSVpFLmdldEJ5dGVzKCksIDAsIGIsIDgsIDgpOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KERJU0suZ2V0Qnl0ZXMoKSwgMCwgYiwgMTYsIDQpOworICAgICAgICBmLnBhcnNlRnJvbUxvY2FsRmlsZURhdGEoYiwgMCwgYi5sZW5ndGgpOworICAgICAgICBhc3NlcnRFcXVhbHMoU0laRSwgZi5nZXRTaXplKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoQ1NJWkUsIGYuZ2V0Q29tcHJlc3NlZFNpemUoKSk7CisgICAgICAgIGFzc2VydE51bGwoZi5nZXRSZWxhdGl2ZUhlYWRlck9mZnNldCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKERJU0ssIGYuZ2V0RGlza1N0YXJ0TnVtYmVyKCkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFJlYWRDRFNpemVzT2Zmc2V0QW5kRGlzaygpIHRocm93cyBaaXBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBaaXA2NEV4dGVuZGVkSW5mb3JtYXRpb25FeHRyYUZpZWxkIGYgPQorICAgICAgICAgICAgbmV3IFppcDY0RXh0ZW5kZWRJbmZvcm1hdGlvbkV4dHJhRmllbGQoKTsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGIgPSBuZXcgYnl0ZVsyOF07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoU0laRS5nZXRCeXRlcygpLCAwLCBiLCAwLCA4KTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShDU0laRS5nZXRCeXRlcygpLCAwLCBiLCA4LCA4KTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShPRkYuZ2V0Qnl0ZXMoKSwgMCwgYiwgMTYsIDgpOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KERJU0suZ2V0Qnl0ZXMoKSwgMCwgYiwgMjQsIDQpOworICAgICAgICBmLnBhcnNlRnJvbUNlbnRyYWxEaXJlY3RvcnlEYXRhKGIsIDAsIGIubGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFNJWkUsIGYuZ2V0U2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKENTSVpFLCBmLmdldENvbXByZXNzZWRTaXplKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoT0ZGLCBmLmdldFJlbGF0aXZlSGVhZGVyT2Zmc2V0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoRElTSywgZi5nZXREaXNrU3RhcnROdW1iZXIoKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVhZENEU2l6ZXNBbmRPZmZzZXQoKSB0aHJvd3MgWmlwRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgWmlwNjRFeHRlbmRlZEluZm9ybWF0aW9uRXh0cmFGaWVsZCBmID0KKyAgICAgICAgICAgIG5ldyBaaXA2NEV4dGVuZGVkSW5mb3JtYXRpb25FeHRyYUZpZWxkKCk7CisgICAgICAgIGZpbmFsIGJ5dGVbXSBiID0gbmV3IGJ5dGVbMjRdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KFNJWkUuZ2V0Qnl0ZXMoKSwgMCwgYiwgMCwgOCk7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoQ1NJWkUuZ2V0Qnl0ZXMoKSwgMCwgYiwgOCwgOCk7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoT0ZGLmdldEJ5dGVzKCksIDAsIGIsIDE2LCA4KTsKKyAgICAgICAgZi5wYXJzZUZyb21DZW50cmFsRGlyZWN0b3J5RGF0YShiLCAwLCBiLmxlbmd0aCk7CisgICAgICAgIGFzc2VydEVxdWFscyhTSVpFLCBmLmdldFNpemUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhDU0laRSwgZi5nZXRDb21wcmVzc2VkU2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKE9GRiwgZi5nZXRSZWxhdGl2ZUhlYWRlck9mZnNldCgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChmLmdldERpc2tTdGFydE51bWJlcigpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RSZWFkQ0RTb21ldGhpbmdBbmREaXNrKCkgdGhyb3dzIFppcEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFppcDY0RXh0ZW5kZWRJbmZvcm1hdGlvbkV4dHJhRmllbGQgZiA9CisgICAgICAgICAgICBuZXcgWmlwNjRFeHRlbmRlZEluZm9ybWF0aW9uRXh0cmFGaWVsZCgpOworICAgICAgICBmaW5hbCBieXRlW10gYiA9IG5ldyBieXRlWzEyXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShTSVpFLmdldEJ5dGVzKCksIDAsIGIsIDAsIDgpOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KERJU0suZ2V0Qnl0ZXMoKSwgMCwgYiwgOCwgNCk7CisgICAgICAgIGYucGFyc2VGcm9tQ2VudHJhbERpcmVjdG9yeURhdGEoYiwgMCwgYi5sZW5ndGgpOworICAgICAgICBhc3NlcnROdWxsKGYuZ2V0U2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChmLmdldENvbXByZXNzZWRTaXplKCkpOworICAgICAgICBhc3NlcnROdWxsKGYuZ2V0UmVsYXRpdmVIZWFkZXJPZmZzZXQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhESVNLLCBmLmdldERpc2tTdGFydE51bWJlcigpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RSZXBhcnNlQ0RTaW5nbGVFaWdodEJ5dGVEYXRhKCkgdGhyb3dzIFppcEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFppcDY0RXh0ZW5kZWRJbmZvcm1hdGlvbkV4dHJhRmllbGQgZiA9CisgICAgICAgICAgICBuZXcgWmlwNjRFeHRlbmRlZEluZm9ybWF0aW9uRXh0cmFGaWVsZCgpOworICAgICAgICBmaW5hbCBieXRlW10gYiA9IG5ldyBieXRlWzhdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KFNJWkUuZ2V0Qnl0ZXMoKSwgMCwgYiwgMCwgOCk7CisgICAgICAgIGYucGFyc2VGcm9tQ2VudHJhbERpcmVjdG9yeURhdGEoYiwgMCwgYi5sZW5ndGgpOworICAgICAgICBmLnJlcGFyc2VDZW50cmFsRGlyZWN0b3J5RGF0YSh0cnVlLCBmYWxzZSwgZmFsc2UsIGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFNJWkUsIGYuZ2V0U2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChmLmdldENvbXByZXNzZWRTaXplKCkpOworICAgICAgICBhc3NlcnROdWxsKGYuZ2V0UmVsYXRpdmVIZWFkZXJPZmZzZXQoKSk7CisgICAgICAgIGFzc2VydE51bGwoZi5nZXREaXNrU3RhcnROdW1iZXIoKSk7CisgICAgICAgIGYuc2V0U2l6ZShudWxsKTsKKyAgICAgICAgZi5yZXBhcnNlQ2VudHJhbERpcmVjdG9yeURhdGEoZmFsc2UsIHRydWUsIGZhbHNlLCBmYWxzZSk7CisgICAgICAgIGFzc2VydE51bGwoZi5nZXRTaXplKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoU0laRSwgZi5nZXRDb21wcmVzc2VkU2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChmLmdldFJlbGF0aXZlSGVhZGVyT2Zmc2V0KCkpOworICAgICAgICBhc3NlcnROdWxsKGYuZ2V0RGlza1N0YXJ0TnVtYmVyKCkpOworICAgICAgICBmLnNldENvbXByZXNzZWRTaXplKG51bGwpOworICAgICAgICBmLnJlcGFyc2VDZW50cmFsRGlyZWN0b3J5RGF0YShmYWxzZSwgZmFsc2UsIHRydWUsIGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0TnVsbChmLmdldFNpemUoKSk7CisgICAgICAgIGFzc2VydE51bGwoZi5nZXRDb21wcmVzc2VkU2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFNJWkUsIGYuZ2V0UmVsYXRpdmVIZWFkZXJPZmZzZXQoKSk7CisgICAgICAgIGFzc2VydE51bGwoZi5nZXREaXNrU3RhcnROdW1iZXIoKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBjaGVja1NpemVzKGZpbmFsIGJ5dGVbXSBiKSB7CisgICAgICAgIGFzc2VydEVxdWFscygweDc4LCBiWzBdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDB4NTYsIGJbMV0pOworICAgICAgICBhc3NlcnRFcXVhbHMoMHgzNCwgYlsyXSk7CisgICAgICAgIGFzc2VydEVxdWFscygweDEyLCBiWzNdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDB4MDAsIGJbNF0pOworICAgICAgICBhc3NlcnRFcXVhbHMoMHgwMCwgYls1XSk7CisgICAgICAgIGFzc2VydEVxdWFscygweDAwLCBiWzZdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDB4MDAsIGJbN10pOworICAgICAgICBhc3NlcnRFcXVhbHMoKGJ5dGUpIDB4RUYsIGJbOF0pOworICAgICAgICBhc3NlcnRFcXVhbHMoKGJ5dGUpIDB4Q0QsIGJbOV0pOworICAgICAgICBhc3NlcnRFcXVhbHMoKGJ5dGUpIDB4QUIsIGJbMTBdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDB4MDksIGJbMTFdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDB4MDAsIGJbMTJdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDB4MDAsIGJbMTNdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDB4MDAsIGJbMTRdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDB4MDAsIGJbMTVdKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGNoZWNrT2Zmc2V0KGZpbmFsIGJ5dGVbXSBiLCBmaW5hbCBpbnQgb2ZmKSB7CisgICAgICAgIGFzc2VydEVxdWFscygweDc4LCBiWzAgKyBvZmZdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDB4NTYsIGJbMSArIG9mZl0pOworICAgICAgICBhc3NlcnRFcXVhbHMoMHgzNCwgYlsyICsgb2ZmXSk7CisgICAgICAgIGFzc2VydEVxdWFscygweDEyLCBiWzMgKyBvZmZdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChieXRlKSAweDA5LCBiWzQgKyBvZmZdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChieXRlKSAweEVGLCBiWzUgKyBvZmZdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChieXRlKSAweENELCBiWzYgKyBvZmZdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChieXRlKSAweEFCLCBiWzcgKyBvZmZdKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGNoZWNrRGlzayhmaW5hbCBieXRlW10gYiwgZmluYWwgaW50IG9mZikgeworICAgICAgICBhc3NlcnRFcXVhbHMoMHgxMiwgYlswICsgb2ZmXSk7CisgICAgICAgIGFzc2VydEVxdWFscygweDAwLCBiWzEgKyBvZmZdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDB4MDAsIGJbMiArIG9mZl0pOworICAgICAgICBhc3NlcnRFcXVhbHMoMHgwMCwgYlszICsgb2ZmXSk7CisgICAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvWmlwNjRTdXBwb3J0SVQuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvWmlwNjRTdXBwb3J0SVQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iYTMwYzNmCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9aaXA2NFN1cHBvcnRJVC5qYXZhCkBAIC0wLDAgKzEsMjY2MiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICoKKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwOworCitpbXBvcnQgc3RhdGljIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5BYnN0cmFjdFRlc3RDYXNlLmdldEZpbGU7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0QXJyYXlFcXVhbHM7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0RXF1YWxzOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEZhbHNlOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydE5vdE51bGw7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0TnVsbDsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUcnVlOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmZhaWw7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3N1bWUuYXNzdW1lVHJ1ZTsKKworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5SYW5kb21BY2Nlc3NGaWxlOworaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuUmFuZG9tOworaW1wb3J0IGphdmEudXRpbC56aXAuWmlwRW50cnk7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuQWJzdHJhY3RUZXN0Q2FzZTsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworcHVibGljIGNsYXNzIFppcDY0U3VwcG9ydElUIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgRklWRV9CSUxMSU9OID0gNTAwMDAwMDAwMGw7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE9ORV9NSUxMSU9OID0gMTAwMDAwMDsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgT05FX0hVTkRSRURfVEhPVVNBTkQgPSAxMDAwMDA7CisKKyAgICBAVGVzdCBwdWJsaWMgdm9pZCByZWFkNUdCT2ZaZXJvc1VzaW5nSW5wdXRTdHJlYW0oKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgcmVhZDVHQk9mWmVyb3NJbXBsKGdldDVHQlplcm9zRmlsZSgpLCAiNUdCX29mX1plcm9zIik7CisgICAgfQorCisgICAgQFRlc3QgcHVibGljIHZvaWQgcmVhZDVHQk9mWmVyb3NHZW5lcmF0ZWRCeTdaSVBVc2luZ0lucHV0U3RyZWFtKCkKKyAgICAgICAgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIHJlYWQ1R0JPZlplcm9zSW1wbChnZXQ1R0JaZXJvc0ZpbGVHZW5lcmF0ZWRCeTdaSVAoKSwgIjVHQl9vZl9aZXJvcyIpOworICAgIH0KKworICAgIEBUZXN0IHB1YmxpYyB2b2lkIHJlYWQ1R0JPZlplcm9zR2VuZXJhdGVkQnlKYXZhN0phclVzaW5nSW5wdXRTdHJlYW0oKQorICAgICAgICB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgcmVhZDVHQk9mWmVyb3NJbXBsKGdldDVHQlplcm9zRmlsZUdlbmVyYXRlZEJ5SmF2YTdKYXIoKSwgIjVHQl9vZl9aZXJvcyIpOworICAgIH0KKworICAgIEBUZXN0IHB1YmxpYyB2b2lkIHJlYWQ1R0JPZlplcm9zR2VuZXJhdGVkQnlXaW5aSVBVc2luZ0lucHV0U3RyZWFtKCkKKyAgICAgICAgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIHJlYWQ1R0JPZlplcm9zSW1wbChnZXQ1R0JaZXJvc0ZpbGVHZW5lcmF0ZWRCeVdpblpJUCgpLCAiNUdCX29mX1plcm9zIik7CisgICAgfQorCisgICAgQFRlc3QgcHVibGljIHZvaWQgcmVhZDVHQk9mWmVyb3NHZW5lcmF0ZWRCeVBLWmlwVXNpbmdJbnB1dFN0cmVhbSgpCisgICAgICAgIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICByZWFkNUdCT2ZaZXJvc0ltcGwoZ2V0NUdCWmVyb3NGaWxlR2VuZXJhdGVkQnlQS1ppcCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgInppcDYvNUdCX29mX1plcm9zIik7CisgICAgfQorCisgICAgQFRlc3QgcHVibGljIHZvaWQgcmVhZDEwMEtGaWxlc1VzaW5nSW5wdXRTdHJlYW0oKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgcmVhZDEwMEtGaWxlc0ltcGwoZ2V0MTAwS0ZpbGVGaWxlKCkpOworICAgIH0KKworICAgIEBUZXN0IHB1YmxpYyB2b2lkIHJlYWQxMDBLRmlsZXNHZW5lcmF0ZWRCeTdaSVBVc2luZ0lucHV0U3RyZWFtKCkKKyAgICAgICAgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIHJlYWQxMDBLRmlsZXNJbXBsKGdldDEwMEtGaWxlRmlsZUdlbmVyYXRlZEJ5N1pJUCgpKTsKKyAgICB9CisKKyAgICBAVGVzdCBwdWJsaWMgdm9pZCByZWFkMTAwS0ZpbGVzR2VuZXJhdGVkQnlXaW5DRlVzaW5nSW5wdXRTdHJlYW0oKQorICAgICAgICB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgcmVhZDEwMEtGaWxlc0ltcGwoZ2V0MTAwS0ZpbGVGaWxlR2VuZXJhdGVkQnlXaW5DRigpKTsKKyAgICB9CisKKyAgICBAVGVzdCBwdWJsaWMgdm9pZCByZWFkMTAwS0ZpbGVzR2VuZXJhdGVkQnlKYXZhN0phclVzaW5nSW5wdXRTdHJlYW0oKQorICAgICAgICB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgcmVhZDEwMEtGaWxlc0ltcGwoZ2V0MTAwS0ZpbGVGaWxlR2VuZXJhdGVkQnlKYXZhN0phcigpKTsKKyAgICB9CisKKyAgICBAVGVzdCBwdWJsaWMgdm9pZCByZWFkMTAwS0ZpbGVzR2VuZXJhdGVkQnlXaW5aSVBVc2luZ0lucHV0U3RyZWFtKCkKKyAgICAgICAgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIHJlYWQxMDBLRmlsZXNJbXBsKGdldDEwMEtGaWxlRmlsZUdlbmVyYXRlZEJ5V2luWklQKCkpOworICAgIH0KKworICAgIEBUZXN0IHB1YmxpYyB2b2lkIHJlYWQxMDBLRmlsZXNHZW5lcmF0ZWRCeVBLWmlwVXNpbmdJbnB1dFN0cmVhbSgpCisgICAgICAgIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICByZWFkMTAwS0ZpbGVzSW1wbChnZXQxMDBLRmlsZUZpbGVHZW5lcmF0ZWRCeVBLWmlwKCkpOworICAgIH0KKworICAgIEBUZXN0IHB1YmxpYyB2b2lkIHJlYWQ1R0JPZlplcm9zVXNpbmdaaXBGaWxlKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIHJlYWQ1R0JPZlplcm9zVXNpbmdaaXBGaWxlSW1wbChnZXQ1R0JaZXJvc0ZpbGUoKSwgIjVHQl9vZl9aZXJvcyIpOworICAgIH0KKworICAgIEBUZXN0IHB1YmxpYyB2b2lkIHJlYWQ1R0JPZlplcm9zR2VuZXJhdGVkQnk3WklQVXNpbmdaaXBGaWxlKCkKKyAgICAgICAgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIHJlYWQ1R0JPZlplcm9zVXNpbmdaaXBGaWxlSW1wbChnZXQ1R0JaZXJvc0ZpbGVHZW5lcmF0ZWRCeTdaSVAoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI1R0Jfb2ZfWmVyb3MiKTsKKyAgICB9CisKKyAgICBAVGVzdCBwdWJsaWMgdm9pZCByZWFkNUdCT2ZaZXJvc0dlbmVyYXRlZEJ5SmF2YTdKYXJVc2luZ1ppcEZpbGUoKQorICAgICAgICB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgcmVhZDVHQk9mWmVyb3NVc2luZ1ppcEZpbGVJbXBsKGdldDVHQlplcm9zRmlsZUdlbmVyYXRlZEJ5SmF2YTdKYXIoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI1R0Jfb2ZfWmVyb3MiKTsKKyAgICB9CisKKyAgICBAVGVzdCBwdWJsaWMgdm9pZCByZWFkNUdCT2ZaZXJvc0dlbmVyYXRlZEJ5V2luWklQVXNpbmdaaXBGaWxlKCkKKyAgICAgICAgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIHJlYWQ1R0JPZlplcm9zVXNpbmdaaXBGaWxlSW1wbChnZXQ1R0JaZXJvc0ZpbGVHZW5lcmF0ZWRCeVdpblpJUCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjVHQl9vZl9aZXJvcyIpOworICAgIH0KKworICAgIEBUZXN0IHB1YmxpYyB2b2lkIHJlYWQ1R0JPZlplcm9zR2VuZXJhdGVkQnlQS1ppcFVzaW5nWmlwRmlsZSgpCisgICAgICAgIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICByZWFkNUdCT2ZaZXJvc1VzaW5nWmlwRmlsZUltcGwoZ2V0NUdCWmVyb3NGaWxlR2VuZXJhdGVkQnlQS1ppcCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInppcDYvNUdCX29mX1plcm9zIik7CisgICAgfQorCisgICAgQFRlc3QgcHVibGljIHZvaWQgd3JpdGVBbmRSZWFkNUdCT2ZaZXJvc1VzaW5nWmlwRmlsZSgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBGaWxlIGYgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZiA9IHdyaXRlNUdCWmVyb3NGaWxlKCJ3cml0ZUFuZFJlYWQ1R0JPZlplcm9zVXNpbmdaaXBGaWxlIik7CisgICAgICAgICAgICByZWFkNUdCT2ZaZXJvc1VzaW5nWmlwRmlsZUltcGwoZiwgIjVHQl9vZl9aZXJvcyIpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKGYgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIEFic3RyYWN0VGVzdENhc2UudHJ5SGFyZFRvRGVsZXRlKGYpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgRmlsZSB3cml0ZTVHQlplcm9zRmlsZShmaW5hbCBTdHJpbmcgdGVzdE5hbWUpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBmaW5hbCBGaWxlIGYgPSBnZXRUZW1wRmlsZSh0ZXN0TmFtZSk7CisgICAgICAgIGZpbmFsIFppcEFyY2hpdmVPdXRwdXRTdHJlYW0gem9zID0gbmV3IFppcEFyY2hpdmVPdXRwdXRTdHJlYW0oZik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB6b3Muc2V0VXNlWmlwNjQoWmlwNjRNb2RlLkFsd2F5cyk7CisgICAgICAgICAgICBmaW5hbCBieXRlW10gYnVmID0gbmV3IGJ5dGVbT05FX01JTExJT05dOworICAgICAgICAgICAgZmluYWwgWmlwQXJjaGl2ZUVudHJ5IHphZSA9IG5ldyBaaXBBcmNoaXZlRW50cnkoIjVHQl9vZl9aZXJvcyIpOworICAgICAgICAgICAgemFlLnNldFNpemUoRklWRV9CSUxMSU9OKTsKKyAgICAgICAgICAgIHphZS5zZXRNZXRob2QoWmlwRW50cnkuREVGTEFURUQpOworICAgICAgICAgICAgemFlLnNldENyYygweDhhNDA4ZjE2TCk7CisgICAgICAgICAgICB6b3MucHV0QXJjaGl2ZUVudHJ5KHphZSk7CisgICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IEZJVkVfQklMTElPTiAvIDEwMDAgLyAxMDAwOyBqKyspIHsKKyAgICAgICAgICAgICAgICB6b3Mud3JpdGUoYnVmKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHpvcy5jbG9zZUFyY2hpdmVFbnRyeSgpOworICAgICAgICAgICAgem9zLmNsb3NlKCk7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIElPRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkZhaWxlZCB0byB3cml0ZSBhcmNoaXZlIGJlY2F1c2Ugb2Y6ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGV4LmdldE1lc3NhZ2UoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiAtIGxpa2VseSBub3QgZW5vdWdoIGRpc2sgc3BhY2UuIik7CisgICAgICAgICAgICBhc3N1bWVUcnVlKGZhbHNlKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHpvcy5kZXN0cm95KCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGY7CisgICAgfQorCisgICAgQFRlc3QgcHVibGljIHZvaWQgcmVhZDEwMEtGaWxlc1VzaW5nWmlwRmlsZSgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICByZWFkMTAwS0ZpbGVzVXNpbmdaaXBGaWxlSW1wbChnZXQxMDBLRmlsZUZpbGUoKSk7CisgICAgfQorCisgICAgQFRlc3QgcHVibGljIHZvaWQgcmVhZDEwMEtGaWxlc0dlbmVyYXRlZEJ5N1pJUFVzaW5nWmlwRmlsZSgpCisgICAgICAgIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICByZWFkMTAwS0ZpbGVzVXNpbmdaaXBGaWxlSW1wbChnZXQxMDBLRmlsZUZpbGVHZW5lcmF0ZWRCeTdaSVAoKSk7CisgICAgfQorCisgICAgQFRlc3QgcHVibGljIHZvaWQgcmVhZDEwMEtGaWxlc0dlbmVyYXRlZEJ5V2luQ0ZVc2luZ1ppcEZpbGUoKQorICAgICAgICB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgcmVhZDEwMEtGaWxlc1VzaW5nWmlwRmlsZUltcGwoZ2V0MTAwS0ZpbGVGaWxlR2VuZXJhdGVkQnlXaW5DRigpKTsKKyAgICB9CisKKyAgICBAVGVzdCBwdWJsaWMgdm9pZCByZWFkMTAwS0ZpbGVzR2VuZXJhdGVkQnlKYXZhN0phclVzaW5nWmlwRmlsZSgpCisgICAgICAgIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICByZWFkMTAwS0ZpbGVzVXNpbmdaaXBGaWxlSW1wbChnZXQxMDBLRmlsZUZpbGVHZW5lcmF0ZWRCeUphdmE3SmFyKCkpOworICAgIH0KKworICAgIEBUZXN0IHB1YmxpYyB2b2lkIHJlYWQxMDBLRmlsZXNHZW5lcmF0ZWRCeVdpblpJUFVzaW5nWmlwRmlsZSgpCisgICAgICAgIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICByZWFkMTAwS0ZpbGVzVXNpbmdaaXBGaWxlSW1wbChnZXQxMDBLRmlsZUZpbGVHZW5lcmF0ZWRCeVdpblpJUCgpKTsKKyAgICB9CisKKyAgICBAVGVzdCBwdWJsaWMgdm9pZCByZWFkMTAwS0ZpbGVzR2VuZXJhdGVkQnlQS1ppcFVzaW5nWmlwRmlsZSgpCisgICAgICAgIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICByZWFkMTAwS0ZpbGVzVXNpbmdaaXBGaWxlSW1wbChnZXQxMDBLRmlsZUZpbGVHZW5lcmF0ZWRCeVBLWmlwKCkpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIFppcE91dHB1dFRlc3Qgd3JpdGUxMDBLRmlsZXMoKSB7CisgICAgICAgIHJldHVybiB3cml0ZTEwMEtGaWxlcyhaaXA2NE1vZGUuQXNOZWVkZWQpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIFppcE91dHB1dFRlc3Qgd3JpdGUxMDBLRmlsZXMoZmluYWwgWmlwNjRNb2RlIG1vZGUpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBaaXBPdXRwdXRUZXN0KCkgeworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgdm9pZCB0ZXN0KGZpbmFsIEZpbGUgZiwgZmluYWwgWmlwQXJjaGl2ZU91dHB1dFN0cmVhbSB6b3MpCisgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICBpZiAobW9kZSAhPSBaaXA2NE1vZGUuQXNOZWVkZWQpIHsKKyAgICAgICAgICAgICAgICAgICAgem9zLnNldFVzZVppcDY0KG1vZGUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB3cml0ZTEwMEtGaWxlc1RvU3RyZWFtKHpvcyk7CisgICAgICAgICAgICAgICAgdHJ5IChSYW5kb21BY2Nlc3NGaWxlIGEgPSBuZXcgUmFuZG9tQWNjZXNzRmlsZShmLCAiciIpKSB7CisgICAgICAgICAgICAgICAgICAgIGZpbmFsIGxvbmcgZW5kID0gYS5sZW5ndGgoKTsKKworICAgICAgICAgICAgICAgICAgICAvLyB2YWxpZGF0ZSAiZW5kIG9mIGNlbnRyYWwgZGlyZWN0b3J5IiBpcyBhdAorICAgICAgICAgICAgICAgICAgICAvLyB0aGUgZW5kIG9mIHRoZSBmaWxlIGFuZCBjb250YWlucyB0aGUgbWFnaWMKKyAgICAgICAgICAgICAgICAgICAgLy8gdmFsdWUgMHhGRkZGIGFzICJudW1iZXIgb2YgZW50cmllcyIuCisgICAgICAgICAgICAgICAgICAgIGEuc2VlayhlbmQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAtIDIyIC8qIGxlbmd0aCBvZiBFT0NEIHdpdGhvdXQgZmlsZSBjb21tZW50ICovKTsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgYnl0ZVtdIGVvY2QgPSBuZXcgYnl0ZVsxMl07CisgICAgICAgICAgICAgICAgICAgIGEucmVhZEZ1bGx5KGVvY2QpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRBcnJheUVxdWFscyhuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzaWcKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgMHg1MCwgKGJ5dGUpIDB4NGIsIDUsIDYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZGlzayBudW1iZXJzCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBlbnRyaWVzCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpIDB4ZmYsIChieXRlKSAweGZmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweGZmLCAoYnl0ZSkgMHhmZiwKKyAgICAgICAgICAgICAgICAgICAgfSwgZW9jZCk7CisKKyAgICAgICAgICAgICAgICAgICAgLy8gdmFsaWRhdGUgIlppcDY0IGVuZCBvZiBjZW50cmFsIGRpcmVjdG9yeQorICAgICAgICAgICAgICAgICAgICAvLyBsb2NhdG9yIiBpcyByaWdodCBpbiBmcm9udCBvZiB0aGUgRU9DRCBhbmQKKyAgICAgICAgICAgICAgICAgICAgLy8gdGhlIGxvY2F0aW9uIG9mIHRoZSAiWmlwNjQgZW5kIG9mIGNlbnRyYWwKKyAgICAgICAgICAgICAgICAgICAgLy8gZGlyZWN0b3J5IHJlY29yZCIgc2VlbXMgY29ycmVjdAorICAgICAgICAgICAgICAgICAgICBmaW5hbCBsb25nIGV4cGVjdGVkWjY0RW9jZE9mZnNldCA9IGVuZCAtIDIyIC8qIGVvY2QubGVuZ3RoICovCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLSAyMCAvKiB6NjQgZW9jZCBsb2NhdG9yLmxlbmd0aCAqLworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0gNTYgLyogejY0IGVvY2Qgd2l0aG91dCBleHRlbnNpYmxlIGRhdGEgc2VjdG9yICovOworICAgICAgICAgICAgICAgICAgICBmaW5hbCBieXRlW10gbG9jID0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBaaXBFaWdodEJ5dGVJbnRlZ2VyLmdldEJ5dGVzKGV4cGVjdGVkWjY0RW9jZE9mZnNldCk7CisgICAgICAgICAgICAgICAgICAgIGEuc2VlayhlbmQgLSAyMiAtIDIwKTsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgYnl0ZVtdIHo2NEVvY2RMb2MgPSBuZXcgYnl0ZVsyMF07CisgICAgICAgICAgICAgICAgICAgIGEucmVhZEZ1bGx5KHo2NEVvY2RMb2MpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRBcnJheUVxdWFscyhuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzaWcKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgMHg1MCwgKGJ5dGUpIDB4NGIsIDYsIDcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZGlzayBudW1iZXJzCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBsb2NhdGlvbiBvZiBaaXA2NCBFT0NELAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY1swXSwgbG9jWzFdLCBsb2NbMl0sIGxvY1szXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NbNF0sIGxvY1s1XSwgbG9jWzZdLCBsb2NbN10sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdG90YWwgbnVtYmVyIG9mIGRpc2tzCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMSwgMCwgMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgfSwgejY0RW9jZExvYyk7CisKKyAgICAgICAgICAgICAgICAgICAgLy8gdmFsaWRhdGUgIlppcDY0IGVuZCBvZiBjZW50cmFsIGRpcmVjdG9yeQorICAgICAgICAgICAgICAgICAgICAvLyByZWNvcmQiIGlzIHdoZXJlIGl0IGlzIHN1cHBvc2VkIHRvIGJlLCB0aGUKKyAgICAgICAgICAgICAgICAgICAgLy8ga25vd24gdmFsdWVzIGFyZSBmaW5lIGFuZCByZWFkIHRoZSBsb2NhdGlvbgorICAgICAgICAgICAgICAgICAgICAvLyBvZiB0aGUgY2VudHJhbCBkaXJlY3RvcnkgZnJvbSBpdAorICAgICAgICAgICAgICAgICAgICBhLnNlZWsoZXhwZWN0ZWRaNjRFb2NkT2Zmc2V0KTsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgYnl0ZVtdIHo2NEVvY2RTdGFydCA9IG5ldyBieXRlWzQwXTsKKyAgICAgICAgICAgICAgICAgICAgYS5yZWFkRnVsbHkoejY0RW9jZFN0YXJ0KTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMobmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2lnCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpIDB4NTAsIChieXRlKSAweDRiLCA2LCA2LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNpemUgb2YgejY0IEVPQ0QKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICA0NCwgMCwgMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAwLCAwLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHZlcnNpb24gbWFkZSBieQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDQ1LCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHZlcnNpb24gbmVlZGVkIHRvIGV4dHJhY3QKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICA0NSwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBkaXNrIG51bWJlcnMKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAwLCAwLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbnVtYmVyIG9mIGVudHJpZXMgMTAwayA9IDB4MTg2QTAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgMHhBMCwgKGJ5dGUpIDB4ODYsIDEsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgMHhBMCwgKGJ5dGUpIDB4ODYsIDEsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgfSwgejY0RW9jZFN0YXJ0KTsKKyAgICAgICAgICAgICAgICAgICAgYS5zZWVrKGV4cGVjdGVkWjY0RW9jZE9mZnNldCArIDQ4IC8qIHNraXAgc2l6ZSAqLyk7CisgICAgICAgICAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBjZE9mZnNldCA9IG5ldyBieXRlWzhdOworICAgICAgICAgICAgICAgICAgICBhLnJlYWRGdWxseShjZE9mZnNldCk7CisgICAgICAgICAgICAgICAgICAgIGZpbmFsIGxvbmcgY2RMb2MgPSBaaXBFaWdodEJ5dGVJbnRlZ2VyLmdldExvbmdWYWx1ZShjZE9mZnNldCk7CisKKyAgICAgICAgICAgICAgICAgICAgLy8gZmluYWxseSB2ZXJpZnkgdGhlcmUgcmVhbGx5IGlzIGEgY2VudHJhbAorICAgICAgICAgICAgICAgICAgICAvLyBkaXJlY3RvcnkgZW50cnkgd2hlcmUgdGhlIFppcDY0IEVPQ0QgY2xhaW1zCisgICAgICAgICAgICAgICAgICAgIGEuc2VlayhjZExvYyk7CisgICAgICAgICAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBzaWcgPSBuZXcgYnl0ZVs0XTsKKyAgICAgICAgICAgICAgICAgICAgYS5yZWFkRnVsbHkoc2lnKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMobmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpIDB4NTAsIChieXRlKSAweDRiLCAxLCAyLAorICAgICAgICAgICAgICAgICAgICB9LCBzaWcpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICB9CisKKyAgICBAVGVzdCBwdWJsaWMgdm9pZCB3cml0ZTEwMEtGaWxlc0ZpbGUoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgd2l0aFRlbXBvcmFyeUFyY2hpdmUoIndyaXRlMTAwS0ZpbGVzRmlsZSIsIHdyaXRlMTAwS0ZpbGVzKCksIHRydWUpOworICAgIH0KKworICAgIEBUZXN0IHB1YmxpYyB2b2lkIHdyaXRlMTAwS0ZpbGVzU3RyZWFtKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIHdpdGhUZW1wb3JhcnlBcmNoaXZlKCJ3cml0ZTEwMEtGaWxlc1N0cmVhbSIsIHdyaXRlMTAwS0ZpbGVzKCksIGZhbHNlKTsKKyAgICB9CisKKyAgICBAVGVzdCBwdWJsaWMgdm9pZCB3cml0ZTEwMEtGaWxlc0ZpbGVNb2RlQWx3YXlzKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIHdpdGhUZW1wb3JhcnlBcmNoaXZlKCJ3cml0ZTEwMEtGaWxlc0ZpbGVNb2RlQWx3YXlzIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGUxMDBLRmlsZXMoWmlwNjRNb2RlLkFsd2F5cyksIHRydWUpOworICAgIH0KKworICAgIEBUZXN0IHB1YmxpYyB2b2lkIHdyaXRlMTAwS0ZpbGVzU3RyZWFtTW9kZUFsd2F5cygpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICB3aXRoVGVtcG9yYXJ5QXJjaGl2ZSgid3JpdGUxMDBLRmlsZXNTdHJlYW1Nb2RlQWx3YXlzIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGUxMDBLRmlsZXMoWmlwNjRNb2RlLkFsd2F5cyksIGZhbHNlKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBaaXBPdXRwdXRUZXN0IHdyaXRlMTAwS0ZpbGVzTW9kZU5ldmVyID0KKyAgICAgICAgbmV3IFppcE91dHB1dFRlc3QoKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHRlc3QoZmluYWwgRmlsZSBmLCBmaW5hbCBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtIHpvcykKKyAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgICAgIHpvcy5zZXRVc2VaaXA2NChaaXA2NE1vZGUuTmV2ZXIpOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHdyaXRlMTAwS0ZpbGVzVG9TdHJlYW0oem9zKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgYSBaaXA2NFJlcXVpcmVkRXhjZXB0aW9uIik7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoZmluYWwgWmlwNjRSZXF1aXJlZEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoWmlwNjRSZXF1aXJlZEV4Y2VwdGlvbi5UT09fTUFOWV9FTlRSSUVTX01FU1NBR0UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleC5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgIEBUZXN0IHB1YmxpYyB2b2lkIHdyaXRlMTAwS0ZpbGVzRmlsZU1vZGVOZXZlcigpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICB3aXRoVGVtcG9yYXJ5QXJjaGl2ZSgid3JpdGUxMDBLRmlsZXNGaWxlTW9kZU5ldmVyIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGUxMDBLRmlsZXNNb2RlTmV2ZXIsIHRydWUpOworICAgIH0KKworICAgIEBUZXN0IHB1YmxpYyB2b2lkIHdyaXRlMTAwS0ZpbGVzU3RyZWFtTW9kZU5ldmVyKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIHdpdGhUZW1wb3JhcnlBcmNoaXZlKCJ3cml0ZTEwMEtGaWxlc1N0cmVhbU1vZGVOZXZlciIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlMTAwS0ZpbGVzTW9kZU5ldmVyLCBmYWxzZSk7CisgICAgfQorCisgICAgQFRlc3QgcHVibGljIHZvaWQgcmVhZFNlbGZHZW5lcmF0ZWQxMDBLRmlsZXNVc2luZ1ppcEZpbGUoKQorICAgICAgICB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgd2l0aFRlbXBvcmFyeUFyY2hpdmUoInJlYWRTZWxmR2VuZXJhdGVkMTAwS0ZpbGVzVXNpbmdaaXBGaWxlKCkiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgWmlwT3V0cHV0VGVzdCgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCB0ZXN0KGZpbmFsIEZpbGUgZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgWmlwQXJjaGl2ZU91dHB1dFN0cmVhbSB6b3MpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cml0ZTEwMEtGaWxlc1RvU3RyZWFtKHpvcyk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhZDEwMEtGaWxlc1VzaW5nWmlwRmlsZUltcGwoZik7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIFppcE91dHB1dFRlc3Qgd3JpdGUzRW50cmllc0NyZWF0aW5nQmlnQXJjaGl2ZSgpIHsKKyAgICAgICAgcmV0dXJuIHdyaXRlM0VudHJpZXNDcmVhdGluZ0JpZ0FyY2hpdmUoWmlwNjRNb2RlLkFzTmVlZGVkKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIEluZGl2aWR1YWwgc2l6ZXMgZG9uJ3QgcmVxdWlyZSBaSVA2NCBidXQgdGhlIG9mZnNldCBvZiB0aGUKKyAgICAgKiB0aGlyZCBlbnRyeSBpcyBiaWdnZXIgdGhhbiAweEZGRkZGRkZGIHNvIGEgWklQNjQgZXh0ZW5kZWQKKyAgICAgKiBpbmZvcm1hdGlvbiBpcyBuZWVkZWQgaW5zaWRlIHRoZSBjZW50cmFsIGRpcmVjdG9yeS4KKyAgICAgKgorICAgICAqIENyZWF0ZXMgYSB0ZW1wb3JhcnkgYXJjaGl2ZSBvZiBhcHByb3ggNUdCIGluIHNpemUKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBaaXBPdXRwdXRUZXN0CisgICAgICAgIHdyaXRlM0VudHJpZXNDcmVhdGluZ0JpZ0FyY2hpdmUoZmluYWwgWmlwNjRNb2RlIG1vZGUpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBaaXBPdXRwdXRUZXN0KCkgeworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgdm9pZCB0ZXN0KGZpbmFsIEZpbGUgZiwgZmluYWwgWmlwQXJjaGl2ZU91dHB1dFN0cmVhbSB6b3MpCisgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICBpZiAobW9kZSAhPSBaaXA2NE1vZGUuQXNOZWVkZWQpIHsKKyAgICAgICAgICAgICAgICAgICAgem9zLnNldFVzZVppcDY0KG1vZGUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB3cml0ZTNFbnRyaWVzQ3JlYXRpbmdCaWdBcmNoaXZlVG9TdHJlYW0oem9zKTsKKworICAgICAgICAgICAgICAgIHRyeSAoUmFuZG9tQWNjZXNzRmlsZSBhID0gbmV3IFJhbmRvbUFjY2Vzc0ZpbGUoZiwgInIiKSkgeworICAgICAgICAgICAgICAgICAgICBnZXRMZW5ndGhBbmRQb3NpdGlvbkF0Q2VudHJhbERpcmVjdG9yeShhKTsKKyAgICAgICAgICAgICAgICAgICAgLy8gc2tpcCBmaXJzdCB0d28gZW50cmllcworICAgICAgICAgICAgICAgICAgICBhLnNraXBCeXRlcygyICogNDcgLyogQ0QgZW50cnkgb2YgZmlsZSB3aXRoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlIG5hbWUgbGVuZ3RoIDEgYW5kIG5vCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRyYSBkYXRhICovCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIDIgKiAobW9kZSA9PSBaaXA2NE1vZGUuQWx3YXlzID8gMjggOiAwKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBaSVA2NCBleHRyYSBmaWVsZHMgaWYgbW9kZSBpcyBBbHdheXMgKi8KKyAgICAgICAgICAgICAgICAgICAgKTsKKworICAgICAgICAgICAgICAgICAgICAvLyBncmFiIHRoaXJkIGVudHJ5LCB2ZXJpZnkgb2Zmc2V0IGlzCisgICAgICAgICAgICAgICAgICAgIC8vIDB4RkZGRkZGRkYgYW5kIGl0IGhhcyBhIFpJUDY0IGV4dGVuZGVkCisgICAgICAgICAgICAgICAgICAgIC8vIGluZm9ybWF0aW9uIGV4dHJhIGZpZWxkCisgICAgICAgICAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBoZWFkZXIgPSBuZXcgYnl0ZVsxMl07CisgICAgICAgICAgICAgICAgICAgIGEucmVhZEZ1bGx5KGhlYWRlcik7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKCJDREggc3RhcnQiLCBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzaWcKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgMHg1MCwgKGJ5dGUpIDB4NGIsIDEsIDIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdmVyc2lvbiBtYWRlIGJ5CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgNDUsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdmVyc2lvbiBuZWVkZWQgdG8gZXh0cmFjdAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDQ1LCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEdQQiAoRUZTIGJpdCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCA4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1ldGhvZAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAKKyAgICAgICAgICAgICAgICAgICAgfSwgaGVhZGVyKTsKKyAgICAgICAgICAgICAgICAgICAgLy8gaWdub3JlIHRpbWVzdGFtcCwgQ1JDLCBjb21wcmVzc2VkIHNpemUKKyAgICAgICAgICAgICAgICAgICAgYS5za2lwQnl0ZXMoMTIpOworICAgICAgICAgICAgICAgICAgICAvLyBPcmlnaW5hbCBTaXplCisgICAgICAgICAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBvcmlnaW5hbFNpemUgPSBuZXcgYnl0ZVs0XTsKKyAgICAgICAgICAgICAgICAgICAgYS5yZWFkRnVsbHkob3JpZ2luYWxTaXplKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKG1vZGUgPT0gWmlwNjRNb2RlLkFsd2F5cykgeworICAgICAgICAgICAgICAgICAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMoIkNESCBvcmlnaW5hbCBzaXplIiwgbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweEZGLCAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4RkYsIChieXRlKSAweEZGLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sIG9yaWdpbmFsU2l6ZSk7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICBhc3NlcnRBcnJheUVxdWFscygiQ0RIIG9yaWdpbmFsIHNpemUiLCBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMSwgMCwgMCwgMAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sIG9yaWdpbmFsU2l6ZSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgZmluYWwgYnl0ZVtdIHJlc3QgPSBuZXcgYnl0ZVsxOV07CisgICAgICAgICAgICAgICAgICAgIGEucmVhZEZ1bGx5KHJlc3QpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRBcnJheUVxdWFscygiQ0RIIHJlc3QiLCBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBmaWxlIG5hbWUgbGVuZ3RoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMSwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBleHRyYSBmaWVsZCBsZW5ndGgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgKG1vZGUgPT0gWmlwNjRNb2RlLkFsd2F5cz8gMjggOiAxMiksIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY29tbWVudCBsZW5ndGgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGRpc2sgbnVtYmVyCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhdHRyaWJ1dGVzCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAwLCAwLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG9mZnNldAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweEZGLCAoYnl0ZSkgMHhGRiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4RkYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZmlsZSBuYW1lCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpICcyJworICAgICAgICAgICAgICAgICAgICB9LCByZXN0KTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKG1vZGUgPT0gWmlwNjRNb2RlLkFsd2F5cykgeworICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgYnl0ZVtdIGV4dHJhID0gbmV3IGJ5dGVbMTJdOworICAgICAgICAgICAgICAgICAgICAgICAgYS5yZWFkRnVsbHkoZXh0cmEpOworICAgICAgICAgICAgICAgICAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMoIkNESCBleHRyYSIsIG5ldyBieXRlW10geworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBIZWFkZXItSUQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMSwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2l6ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAyNCwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT3JpZ2luYWwgU2l6ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sIGV4dHJhKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNraXAgY29tcHJlc3NlZCBzaXplCisgICAgICAgICAgICAgICAgICAgICAgICBhLnNraXBCeXRlcyg4KTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBleHRyYSA9IG5ldyBieXRlWzRdOworICAgICAgICAgICAgICAgICAgICAgICAgYS5yZWFkRnVsbHkoZXh0cmEpOworICAgICAgICAgICAgICAgICAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMoIkNESCBleHRyYSIsIG5ldyBieXRlW10geworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBIZWFkZXItSUQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMSwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2l6ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA4LCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sIGV4dHJhKTsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIC8vIHJlYWQgb2Zmc2V0IG9mIExGSAorICAgICAgICAgICAgICAgICAgICBmaW5hbCBieXRlW10gb2Zmc2V0ID0gbmV3IGJ5dGVbOF07CisgICAgICAgICAgICAgICAgICAgIGEucmVhZEZ1bGx5KG9mZnNldCk7CisgICAgICAgICAgICAgICAgICAgIC8vIHZlcmlmeSB0aGVyZSBpcyBhIExGSCB3aGVyZSB0aGUgQ0QgY2xhaW1zIGl0CisgICAgICAgICAgICAgICAgICAgIGEuc2VlayhaaXBFaWdodEJ5dGVJbnRlZ2VyLmdldExvbmdWYWx1ZShvZmZzZXQpKTsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgYnl0ZVtdIHNpZyA9IG5ldyBieXRlWzRdOworICAgICAgICAgICAgICAgICAgICBhLnJlYWRGdWxseShzaWcpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRBcnJheUVxdWFscygiTEZIIHNpZ25hdHVyZSIsIG5ldyBieXRlW10geworICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweDUwLCAoYnl0ZSkgMHg0YiwgMywgNCwKKyAgICAgICAgICAgICAgICAgICAgfSwgc2lnKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH07CisgICAgfQorCisgICAgQFRlc3QgcHVibGljIHZvaWQgd3JpdGUzRW50cmllc0NyZWF0aW5nQmlnQXJjaGl2ZUZpbGUoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgd2l0aFRlbXBvcmFyeUFyY2hpdmUoIndyaXRlM0VudHJpZXNDcmVhdGluZ0JpZ0FyY2hpdmVGaWxlIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGUzRW50cmllc0NyZWF0aW5nQmlnQXJjaGl2ZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlKTsKKyAgICB9CisKKyAgICBAVGVzdCBwdWJsaWMgdm9pZCB3cml0ZTNFbnRyaWVzQ3JlYXRpbmdCaWdBcmNoaXZlU3RyZWFtKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIHdpdGhUZW1wb3JhcnlBcmNoaXZlKCJ3cml0ZTNFbnRyaWVzQ3JlYXRpbmdCaWdBcmNoaXZlU3RyZWFtIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGUzRW50cmllc0NyZWF0aW5nQmlnQXJjaGl2ZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSk7CisgICAgfQorCisgICAgQFRlc3QgcHVibGljIHZvaWQgd3JpdGUzRW50cmllc0NyZWF0aW5nQmlnQXJjaGl2ZUZpbGVNb2RlQWx3YXlzKCkKKyAgICAgICAgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIHdpdGhUZW1wb3JhcnlBcmNoaXZlKCJ3cml0ZTNFbnRyaWVzQ3JlYXRpbmdCaWdBcmNoaXZlRmlsZU1vZGVBbHdheXMiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cml0ZTNFbnRyaWVzQ3JlYXRpbmdCaWdBcmNoaXZlKFppcDY0TW9kZS5BbHdheXMpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlKTsKKyAgICB9CisKKyAgICBAVGVzdCBwdWJsaWMgdm9pZCB3cml0ZTNFbnRyaWVzQ3JlYXRpbmdCaWdBcmNoaXZlU3RyZWFtTW9kZUFsd2F5cygpCisgICAgICAgIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICB3aXRoVGVtcG9yYXJ5QXJjaGl2ZSgid3JpdGUzRW50cmllc0NyZWF0aW5nQmlnQXJjaGl2ZVN0cmVhbU1vZGVBbHdheXMiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cml0ZTNFbnRyaWVzQ3JlYXRpbmdCaWdBcmNoaXZlKFppcDY0TW9kZS5BbHdheXMpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgWmlwT3V0cHV0VGVzdCB3cml0ZTNFbnRyaWVzQ3JlYXRpbmdCaWdBcmNoaXZlTW9kZU5ldmVyID0KKyAgICAgICAgbmV3IFppcE91dHB1dFRlc3QoKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHRlc3QoZmluYWwgRmlsZSBmLCBmaW5hbCBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtIHpvcykKKyAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgICAgIHpvcy5zZXRVc2VaaXA2NChaaXA2NE1vZGUuTmV2ZXIpOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHdyaXRlM0VudHJpZXNDcmVhdGluZ0JpZ0FyY2hpdmVUb1N0cmVhbSh6b3MpOworICAgICAgICAgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBhIFppcDY0UmVxdWlyZWRFeGNlcHRpb24iKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChmaW5hbCBaaXA2NFJlcXVpcmVkRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhaaXA2NFJlcXVpcmVkRXhjZXB0aW9uLkFSQ0hJVkVfVE9PX0JJR19NRVNTQUdFLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXguZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH07CisKKyAgICBAVGVzdCBwdWJsaWMgdm9pZCB3cml0ZTNFbnRyaWVzQ3JlYXRpbmdCaWdBcmNoaXZlRmlsZU1vZGVOZXZlcigpCisgICAgICAgIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICB3aXRoVGVtcG9yYXJ5QXJjaGl2ZSgid3JpdGUzRW50cmllc0NyZWF0aW5nQmlnQXJjaGl2ZUZpbGVNb2RlTmV2ZXIiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cml0ZTNFbnRyaWVzQ3JlYXRpbmdCaWdBcmNoaXZlTW9kZU5ldmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlKTsKKyAgICB9CisKKyAgICBAVGVzdCBwdWJsaWMgdm9pZCB3cml0ZTNFbnRyaWVzQ3JlYXRpbmdCaWdBcmNoaXZlU3RyZWFtTW9kZU5ldmVyKCkKKyAgICAgICAgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIHdpdGhUZW1wb3JhcnlBcmNoaXZlKCJ3cml0ZTNFbnRyaWVzQ3JlYXRpbmdCaWdBcmNoaXZlU3RyZWFtTW9kZU5ldmVyIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGUzRW50cmllc0NyZWF0aW5nQmlnQXJjaGl2ZU1vZGVOZXZlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UpOworICAgIH0KKworICAgIEBUZXN0IHB1YmxpYyB2b2lkIHJlYWQzRW50cmllc0NyZWF0aW5nQmlnQXJjaGl2ZUZpbGVVc2luZ1ppcEZpbGUoKQorICAgICAgICB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgd2l0aFRlbXBvcmFyeUFyY2hpdmUoInJlYWQzRW50cmllc0NyZWF0aW5nQmlnQXJjaGl2ZUZpbGVVc2luZ1ppcEZpbGUiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgWmlwT3V0cHV0VGVzdCgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCB0ZXN0KGZpbmFsIEZpbGUgZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgWmlwQXJjaGl2ZU91dHB1dFN0cmVhbSB6b3MpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cml0ZTNFbnRyaWVzQ3JlYXRpbmdCaWdBcmNoaXZlVG9TdHJlYW0oem9zKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBaaXBGaWxlIHpmID0gbnVsbDsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB6ZiA9IG5ldyBaaXBGaWxlKGYpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaWR4ID0gMDsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChmaW5hbCBFbnVtZXJhdGlvbjxaaXBBcmNoaXZlRW50cnk+IGUgPQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB6Zi5nZXRFbnRyaWVzSW5QaHlzaWNhbE9yZGVyKCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZS5oYXNNb3JlRWxlbWVudHMoKTsgKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBaaXBBcmNoaXZlRW50cnkgemFlID0gZS5uZXh0RWxlbWVudCgpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKFN0cmluZy52YWx1ZU9mKGlkeCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgemFlLmdldE5hbWUoKSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaWR4KysgPCAyKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKEZJVkVfQklMTElPTiAvIDIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHphZS5nZXRTaXplKCkpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgemFlLmdldFNpemUoKSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBpID0gemYuZ2V0SW5wdXRTdHJlYW0oemFlKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGkpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoNDIsIGkucmVhZCgpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBaaXBGaWxlLmNsb3NlUXVpZXRseSh6Zik7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBaaXBPdXRwdXRUZXN0IHdyaXRlQmlnU3RvcmVkRW50cnkoZmluYWwgYm9vbGVhbiBrbm93blNpemUpIHsKKyAgICAgICAgcmV0dXJuIHdyaXRlQmlnU3RvcmVkRW50cnkoa25vd25TaXplLCBaaXA2NE1vZGUuQXNOZWVkZWQpOworICAgIH0KKworICAgIC8qCisgICAgICogT25lIGVudHJ5IG9mIGxlbmd0aCA1IGJpbGxpb24gYnl0ZXMsIHdyaXR0ZW4gd2l0aG91dAorICAgICAqIGNvbXByZXNzaW9uLgorICAgICAqCisgICAgICogTm8gQ29tcHJlc3Npb24gPT4gc2l6ZXMgYXJlIHN0b3JlZCBkaXJlY3RseSBpbnNpZGUgdGhlIExGSC4gIE5vCisgICAgICogRGF0YSBEZXNjcmlwdG9yIGF0IGFsbC4KKyAgICAgKgorICAgICAqIENyZWF0ZXMgYSB0ZW1wb3JhcnkgYXJjaGl2ZSBvZiBhcHByb3ggNUdCIGluIHNpemUKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBaaXBPdXRwdXRUZXN0IHdyaXRlQmlnU3RvcmVkRW50cnkoZmluYWwgYm9vbGVhbiBrbm93blNpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIFppcDY0TW9kZSBtb2RlKSB7CisgICAgICAgIHJldHVybiBuZXcgWmlwT3V0cHV0VGVzdCgpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIHZvaWQgdGVzdChmaW5hbCBGaWxlIGYsIGZpbmFsIFppcEFyY2hpdmVPdXRwdXRTdHJlYW0gem9zKQorICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgaWYgKG1vZGUgIT0gWmlwNjRNb2RlLkFzTmVlZGVkKSB7CisgICAgICAgICAgICAgICAgICAgIHpvcy5zZXRVc2VaaXA2NChtb2RlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZmluYWwgYnl0ZVtdIGJ1ZiA9IG5ldyBieXRlW09ORV9NSUxMSU9OXTsKKyAgICAgICAgICAgICAgICBmaW5hbCBaaXBBcmNoaXZlRW50cnkgemFlID0gbmV3IFppcEFyY2hpdmVFbnRyeSgiMCIpOworICAgICAgICAgICAgICAgIGlmIChrbm93blNpemUpIHsKKyAgICAgICAgICAgICAgICAgICAgemFlLnNldFNpemUoRklWRV9CSUxMSU9OKTsKKyAgICAgICAgICAgICAgICAgICAgemFlLnNldENyYygweDVjMzE2ZjUwTCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHphZS5zZXRNZXRob2QoWmlwRW50cnkuU1RPUkVEKTsKKyAgICAgICAgICAgICAgICB6b3MucHV0QXJjaGl2ZUVudHJ5KHphZSk7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBGSVZFX0JJTExJT04gLyAxMDAwIC8gMTAwMDsgaisrKSB7CisgICAgICAgICAgICAgICAgICAgIHpvcy53cml0ZShidWYpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB6b3MuY2xvc2VBcmNoaXZlRW50cnkoKTsKKyAgICAgICAgICAgICAgICB6b3MuY2xvc2UoKTsKKworICAgICAgICAgICAgICAgIHRyeSAoUmFuZG9tQWNjZXNzRmlsZSBhID0gbmV3IFJhbmRvbUFjY2Vzc0ZpbGUoZiwgInIiKSkgeworICAgICAgICAgICAgICAgICAgICBnZXRMZW5ndGhBbmRQb3NpdGlvbkF0Q2VudHJhbERpcmVjdG9yeShhKTsKKworICAgICAgICAgICAgICAgICAgICAvLyBncmFiIGZpcnN0IGVudHJ5LCB2ZXJpZnkgc2l6ZXMgYXJlIDB4RkZGRkZGRkYKKyAgICAgICAgICAgICAgICAgICAgLy8gYW5kIGl0IGhhcyBhIFpJUDY0IGV4dGVuZGVkIGluZm9ybWF0aW9uIGV4dHJhCisgICAgICAgICAgICAgICAgICAgIC8vIGZpZWxkCisgICAgICAgICAgICAgICAgICAgIGJ5dGVbXSBoZWFkZXIgPSBuZXcgYnl0ZVsxMl07CisgICAgICAgICAgICAgICAgICAgIGEucmVhZEZ1bGx5KGhlYWRlcik7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKCJDREggc3RhcnQiLCBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzaWcKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgMHg1MCwgKGJ5dGUpIDB4NGIsIDEsIDIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdmVyc2lvbiBtYWRlIGJ5CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgNDUsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdmVyc2lvbiBuZWVkZWQgdG8gZXh0cmFjdAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDQ1LCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEdQQiAoRUZTIGJpdCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCA4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1ldGhvZAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAKKyAgICAgICAgICAgICAgICAgICAgfSwgaGVhZGVyKTsKKyAgICAgICAgICAgICAgICAgICAgLy8gaWdub3JlIHRpbWVzdGFtcAorICAgICAgICAgICAgICAgICAgICBhLnNraXBCeXRlcyg0KTsKKyAgICAgICAgICAgICAgICAgICAgYnl0ZVtdIHJlc3QgPSBuZXcgYnl0ZVsyNl07CisgICAgICAgICAgICAgICAgICAgIGEucmVhZEZ1bGx5KHJlc3QpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRBcnJheUVxdWFscygiQ0RIIHJlc3QiLCBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBDUkMKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgMHg1MCwgKGJ5dGUpIDB4NkYsIChieXRlKSAweDMxLCAoYnl0ZSkgMHg1YywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBDb21wcmVzc2VkIFNpemUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4RkYsIChieXRlKSAweEZGLCAoYnl0ZSkgMHhGRiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPcmlnaW5hbCBTaXplCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpIDB4RkYsIChieXRlKSAweEZGLCAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4RkYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZmlsZSBuYW1lIGxlbmd0aAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZXh0cmEgZmllbGQgbGVuZ3RoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpIChtb2RlID09IFppcDY0TW9kZS5BbHdheXM/IDI4IDogMjApLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvbW1lbnQgbGVuZ3RoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBkaXNrIG51bWJlcgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYXR0cmlidXRlcworICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgfSwgcmVzdCk7CisgICAgICAgICAgICAgICAgICAgIGJ5dGVbXSBvZmZzZXQgPSBuZXcgYnl0ZVs0XTsKKyAgICAgICAgICAgICAgICAgICAgYS5yZWFkRnVsbHkob2Zmc2V0KTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKG1vZGUgPT0gWmlwNjRNb2RlLkFsd2F5cykgeworICAgICAgICAgICAgICAgICAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMoIm9mZnNldCIsIG5ldyBieXRlW10geworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4RkYsIChieXRlKSAweEZGLCAoYnl0ZSkgMHhGRiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LCBvZmZzZXQpOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMoIm9mZnNldCIsIG5ldyBieXRlW10geworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAwLCAwLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sIG9mZnNldCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCcwJywgYS5yZWFkKCkpOworICAgICAgICAgICAgICAgICAgICBmaW5hbCBieXRlW10gZXh0cmEgPSBuZXcgYnl0ZVsyMF07CisgICAgICAgICAgICAgICAgICAgIGEucmVhZEZ1bGx5KGV4dHJhKTsKKyAgICAgICAgICAgICAgICAgICAgLy8gNWU5ID09IDB4MTJBMDVGMjAwCisgICAgICAgICAgICAgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKCJDREggZXh0cmEiLCBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBIZWFkZXItSUQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAxLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNpemUgb2YgZXh0cmEKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgKG1vZGUgPT0gWmlwNjRNb2RlLkFsd2F5cz8gMjQgOiAxNiksIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gb3JpZ2luYWwgc2l6ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIChieXRlKSAweEYyLCA1LCAoYnl0ZSkgMHgyQSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAxLCAwLCAwLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvbXByZXNzZWQgc2l6ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIChieXRlKSAweEYyLCA1LCAoYnl0ZSkgMHgyQSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAxLCAwLCAwLCAwLAorICAgICAgICAgICAgICAgICAgICB9LCBleHRyYSk7CisgICAgICAgICAgICAgICAgICAgIGlmIChtb2RlID09IFppcDY0TW9kZS5BbHdheXMpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldCA9IG5ldyBieXRlWzhdOworICAgICAgICAgICAgICAgICAgICAgICAgYS5yZWFkRnVsbHkob2Zmc2V0KTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKCJleHRyYSBvZmZzZXQiLCBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LCBvZmZzZXQpOworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgLy8gYW5kIG5vdyB2YWxpZGF0ZSBsb2NhbCBmaWxlIGhlYWRlcgorICAgICAgICAgICAgICAgICAgICBhLnNlZWsoMCk7CisgICAgICAgICAgICAgICAgICAgIGhlYWRlciA9IG5ldyBieXRlWzEwXTsKKyAgICAgICAgICAgICAgICAgICAgYS5yZWFkRnVsbHkoaGVhZGVyKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMoIkxGSCBzdGFydCIsIG5ldyBieXRlW10geworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNpZworICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweDUwLCAoYnl0ZSkgMHg0YiwgMywgNCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB2ZXJzaW9uIG5lZWRlZCB0byBleHRyYWN0CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgNDUsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gR1BCIChFRlMgYml0KQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbWV0aG9kCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMAorICAgICAgICAgICAgICAgICAgICB9LCBoZWFkZXIpOworICAgICAgICAgICAgICAgICAgICAvLyBpZ25vcmUgdGltZXN0YW1wCisgICAgICAgICAgICAgICAgICAgIGEuc2tpcEJ5dGVzKDQpOworICAgICAgICAgICAgICAgICAgICByZXN0ID0gbmV3IGJ5dGVbMTddOworICAgICAgICAgICAgICAgICAgICBhLnJlYWRGdWxseShyZXN0KTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMoIkxGSCByZXN0IiwgbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ1JDCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpIDB4NTAsIChieXRlKSAweDZGLCAoYnl0ZSkgMHgzMSwgKGJ5dGUpIDB4NWMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ29tcHJlc3NlZCBTaXplCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpIDB4RkYsIChieXRlKSAweEZGLCAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4RkYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT3JpZ2luYWwgU2l6ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweEZGLCAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4RkYsIChieXRlKSAweEZGLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZpbGUgbmFtZSBsZW5ndGgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAxLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGV4dHJhIGZpZWxkIGxlbmd0aAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDIwLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZpbGUgbmFtZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAnMCcKKyAgICAgICAgICAgICAgICAgICAgfSwgcmVzdCk7CisgICAgICAgICAgICAgICAgICAgIGEucmVhZEZ1bGx5KGV4dHJhKTsKKyAgICAgICAgICAgICAgICAgICAgLy8gNWU5ID09IDB4MTJBMDVGMjAwCisgICAgICAgICAgICAgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKCJMRkggZXh0cmEiLCBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBIZWFkZXItSUQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAxLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNpemUgb2YgZXh0cmEKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAxNiwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBvcmlnaW5hbCBzaXplCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgKGJ5dGUpIDB4RjIsIDUsIChieXRlKSAweDJBLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEsIDAsIDAsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY29tcHJlc3NlZCBzaXplCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgKGJ5dGUpIDB4RjIsIDUsIChieXRlKSAweDJBLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEsIDAsIDAsIDAsCisgICAgICAgICAgICAgICAgICAgIH0sIGV4dHJhKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH07CisgICAgfQorCisgICAgLyoKKyAgICAgKiBObyBDb21wcmVzc2lvbiArIFN0cmVhbSA9PiBzaXplcyBtdXN0IGJlIGtub3duIGJlZm9yZSBkYXRhIGlzCisgICAgICogd3JpdHRlbi4KKyAgICAgKi8KKyAgICBAVGVzdCBwdWJsaWMgdm9pZCB3cml0ZUJpZ1N0b3JlZEVudHJ5VG9TdHJlYW0oKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgd2l0aFRlbXBvcmFyeUFyY2hpdmUoIndyaXRlQmlnU3RvcmVkRW50cnlUb1N0cmVhbSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlQmlnU3RvcmVkRW50cnkodHJ1ZSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlKTsKKyAgICB9CisKKyAgICBAVGVzdCBwdWJsaWMgdm9pZCB3cml0ZUJpZ1N0b3JlZEVudHJ5S25vd25TaXplVG9GaWxlKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIHdpdGhUZW1wb3JhcnlBcmNoaXZlKCJ3cml0ZUJpZ1N0b3JlZEVudHJ5S25vd25TaXplVG9GaWxlIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVCaWdTdG9yZWRFbnRyeSh0cnVlKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSk7CisgICAgfQorCisgICAgQFRlc3QgcHVibGljIHZvaWQgd3JpdGVCaWdTdG9yZWRFbnRyeVVubm93blNpemVUb0ZpbGUoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgd2l0aFRlbXBvcmFyeUFyY2hpdmUoIndyaXRlQmlnU3RvcmVkRW50cnlVbmtub3duU2l6ZVRvRmlsZSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlQmlnU3RvcmVkRW50cnkoZmFsc2UpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlKTsKKyAgICB9CisKKyAgICBAVGVzdCBwdWJsaWMgdm9pZCB3cml0ZUJpZ1N0b3JlZEVudHJ5VG9TdHJlYW1Nb2RlQWx3YXlzKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIHdpdGhUZW1wb3JhcnlBcmNoaXZlKCJ3cml0ZUJpZ1N0b3JlZEVudHJ5VG9TdHJlYW1Nb2RlQWx3YXlzIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVCaWdTdG9yZWRFbnRyeSh0cnVlLCBaaXA2NE1vZGUuQWx3YXlzKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UpOworICAgIH0KKworICAgIEBUZXN0IHB1YmxpYyB2b2lkIHdyaXRlQmlnU3RvcmVkRW50cnlLbm93blNpemVUb0ZpbGVNb2RlQWx3YXlzKCkKKyAgICAgICAgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIHdpdGhUZW1wb3JhcnlBcmNoaXZlKCJ3cml0ZUJpZ1N0b3JlZEVudHJ5S25vd25TaXplVG9GaWxlTW9kZUFsd2F5cyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlQmlnU3RvcmVkRW50cnkodHJ1ZSwgWmlwNjRNb2RlLkFsd2F5cyksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUpOworICAgIH0KKworICAgIEBUZXN0IHB1YmxpYyB2b2lkIHdyaXRlQmlnU3RvcmVkRW50cnlVbm5vd25TaXplVG9GaWxlTW9kZUFsd2F5cygpCisgICAgICAgIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICB3aXRoVGVtcG9yYXJ5QXJjaGl2ZSgid3JpdGVCaWdTdG9yZWRFbnRyeVVua25vd25TaXplVG9GaWxlTW9kZUFsd2F5cyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlQmlnU3RvcmVkRW50cnkoZmFsc2UsIFppcDY0TW9kZS5BbHdheXMpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBaaXBPdXRwdXRUZXN0CisgICAgICAgIHdyaXRlQmlnU3RvcmVkRW50cnlNb2RlTmV2ZXIoZmluYWwgYm9vbGVhbiBrbm93blNpemUpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBaaXBPdXRwdXRUZXN0KCkgeworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgdm9pZCB0ZXN0KGZpbmFsIEZpbGUgZiwgZmluYWwgWmlwQXJjaGl2ZU91dHB1dFN0cmVhbSB6b3MpCisgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICB6b3Muc2V0VXNlWmlwNjQoWmlwNjRNb2RlLk5ldmVyKTsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBmaW5hbCBieXRlW10gYnVmID0gbmV3IGJ5dGVbT05FX01JTExJT05dOworICAgICAgICAgICAgICAgICAgICBmaW5hbCBaaXBBcmNoaXZlRW50cnkgemFlID0gbmV3IFppcEFyY2hpdmVFbnRyeSgiMCIpOworICAgICAgICAgICAgICAgICAgICBpZiAoa25vd25TaXplKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB6YWUuc2V0U2l6ZShGSVZFX0JJTExJT04pOworICAgICAgICAgICAgICAgICAgICAgICAgemFlLnNldENyYygweDVjMzE2ZjUwTCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgemFlLnNldE1ldGhvZChaaXBFbnRyeS5TVE9SRUQpOworICAgICAgICAgICAgICAgICAgICB6b3MucHV0QXJjaGl2ZUVudHJ5KHphZSk7CisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgRklWRV9CSUxMSU9OIC8gMTAwMCAvIDEwMDA7IGorKykgeworICAgICAgICAgICAgICAgICAgICAgICAgem9zLndyaXRlKGJ1Zik7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgem9zLmNsb3NlQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIGEgWmlwNjRSZXF1aXJlZEV4Y2VwdGlvbiIpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGZpbmFsIFppcDY0UmVxdWlyZWRFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZShleC5nZXRNZXNzYWdlKCkuc3RhcnRzV2l0aCgiMCdzIHNpemUiKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9OworICAgIH0KKworICAgIEBUZXN0IHB1YmxpYyB2b2lkIHdyaXRlQmlnU3RvcmVkRW50cnlUb1N0cmVhbU1vZGVOZXZlcigpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICB3aXRoVGVtcG9yYXJ5QXJjaGl2ZSgid3JpdGVCaWdTdG9yZWRFbnRyeVRvU3RyZWFtTW9kZU5ldmVyIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVCaWdTdG9yZWRFbnRyeU1vZGVOZXZlcih0cnVlKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UpOworICAgIH0KKworICAgIEBUZXN0IHB1YmxpYyB2b2lkIHdyaXRlQmlnU3RvcmVkRW50cnlLbm93blNpemVUb0ZpbGVNb2RlTmV2ZXIoKQorICAgICAgICB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgd2l0aFRlbXBvcmFyeUFyY2hpdmUoIndyaXRlQmlnU3RvcmVkRW50cnlLbm93blNpemVUb0ZpbGVNb2RlTmV2ZXIiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cml0ZUJpZ1N0b3JlZEVudHJ5TW9kZU5ldmVyKHRydWUpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlKTsKKyAgICB9CisKKyAgICBAVGVzdCBwdWJsaWMgdm9pZCB3cml0ZUJpZ1N0b3JlZEVudHJ5VW5ub3duU2l6ZVRvRmlsZU1vZGVOZXZlcigpCisgICAgICAgIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICB3aXRoVGVtcG9yYXJ5QXJjaGl2ZSgid3JpdGVCaWdTdG9yZWRFbnRyeVVua25vd25TaXplVG9GaWxlTW9kZU5ldmVyIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVCaWdTdG9yZWRFbnRyeU1vZGVOZXZlcihmYWxzZSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUpOworICAgIH0KKworICAgIC8qCisgICAgICogT25lIGVudHJ5IG9mIGxlbmd0aCA1IGJpbGxpb24gYnl0ZXMsIHdyaXR0ZW4gd2l0aAorICAgICAqIGNvbXByZXNzaW9uIHRvIGEgc3RyZWFtLgorICAgICAqCisgICAgICogQ29tcHJlc3Npb24gKyBTdHJlYW0gPT4gc2l6ZXMgYXJlIHNldCB0byAwIGluIExGSCBhbmQgWklQNjQKKyAgICAgKiBlbnRyeSwgcmVhbCB2YWx1ZXMgYXJlIGluc2lkZSB0aGUgZGF0YSBkZXNjcmlwdG9yLgorICAgICAqCisgICAgICogQ3JlYXRlcyBhIHRlbXBvcmFyeSBhcmNoaXZlIG9mIGFwcHJveCA0TUIgaW4gc2l6ZQorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIFppcE91dHB1dFRlc3QKKyAgICAgICAgd3JpdGVCaWdEZWZsYXRlZEVudHJ5VG9TdHJlYW0oZmluYWwgYm9vbGVhbiBrbm93blNpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIFppcDY0TW9kZSBtb2RlKSB7CisgICAgICAgIHJldHVybiBuZXcgWmlwT3V0cHV0VGVzdCgpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIHZvaWQgdGVzdChmaW5hbCBGaWxlIGYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIFppcEFyY2hpdmVPdXRwdXRTdHJlYW0gem9zKQorICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgaWYgKG1vZGUgIT0gWmlwNjRNb2RlLkFzTmVlZGVkKSB7CisgICAgICAgICAgICAgICAgICAgIHpvcy5zZXRVc2VaaXA2NChtb2RlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZmluYWwgYnl0ZVtdIGJ1ZiA9IG5ldyBieXRlW09ORV9NSUxMSU9OXTsKKyAgICAgICAgICAgICAgICBmaW5hbCBaaXBBcmNoaXZlRW50cnkgemFlID0gbmV3IFppcEFyY2hpdmVFbnRyeSgiMCIpOworICAgICAgICAgICAgICAgIGlmIChrbm93blNpemUpIHsKKyAgICAgICAgICAgICAgICAgICAgemFlLnNldFNpemUoRklWRV9CSUxMSU9OKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgemFlLnNldE1ldGhvZChaaXBFbnRyeS5ERUZMQVRFRCk7CisgICAgICAgICAgICAgICAgem9zLnB1dEFyY2hpdmVFbnRyeSh6YWUpOworICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgRklWRV9CSUxMSU9OIC8gMTAwMCAvIDEwMDA7IGorKykgeworICAgICAgICAgICAgICAgICAgICB6b3Mud3JpdGUoYnVmKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgem9zLmNsb3NlQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgICAgICAgICAgem9zLmNsb3NlKCk7CisKKyAgICAgICAgICAgICAgICB0cnkgKFJhbmRvbUFjY2Vzc0ZpbGUgYSA9IG5ldyBSYW5kb21BY2Nlc3NGaWxlKGYsICJyIikpIHsKKyAgICAgICAgICAgICAgICAgICAgZ2V0TGVuZ3RoQW5kUG9zaXRpb25BdENlbnRyYWxEaXJlY3RvcnkoYSk7CisKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgbG9uZyBjZmhQb3MgPSBhLmdldEZpbGVQb2ludGVyKCk7CisgICAgICAgICAgICAgICAgICAgIC8vIGdyYWIgZmlyc3QgZW50cnksIHZlcmlmeQorICAgICAgICAgICAgICAgICAgICAvLyBzaXplcyBhcmUgMHhGRkZGRkZGRiBhbmQKKyAgICAgICAgICAgICAgICAgICAgLy8gaXQgaGFzIGEgWklQNjQgZXh0ZW5kZWQKKyAgICAgICAgICAgICAgICAgICAgLy8gaW5mb3JtYXRpb24gZXh0cmEgZmllbGQKKyAgICAgICAgICAgICAgICAgICAgYnl0ZVtdIGhlYWRlciA9IG5ldyBieXRlWzEyXTsKKyAgICAgICAgICAgICAgICAgICAgYS5yZWFkRnVsbHkoaGVhZGVyKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMoIkNESCBzdGFydCIsIG5ldyBieXRlW10geworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNpZworICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweDUwLCAoYnl0ZSkgMHg0YiwgMSwgMiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB2ZXJzaW9uIG1hZGUgYnkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICA0NSwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB2ZXJzaW9uIG5lZWRlZCB0byBleHRyYWN0CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgNDUsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gR1BCIChFRlMgKyBEYXRhIERlc2NyaXB0b3IpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgOCwgOCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBtZXRob2QKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICA4LCAwLAorICAgICAgICAgICAgICAgICAgICB9LCBoZWFkZXIpOworICAgICAgICAgICAgICAgICAgICAvLyBpZ25vcmUgdGltZXN0YW1wCisgICAgICAgICAgICAgICAgICAgIGEuc2tpcEJ5dGVzKDQpOworICAgICAgICAgICAgICAgICAgICBieXRlW10gcmVzdCA9IG5ldyBieXRlWzI2XTsKKyAgICAgICAgICAgICAgICAgICAgYS5yZWFkRnVsbHkocmVzdCk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKCJDREggcmVzdCIsIG5ldyBieXRlW10geworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENSQworICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweDUwLCAoYnl0ZSkgMHg2RiwgKGJ5dGUpIDB4MzEsIChieXRlKSAweDVjLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENvbXByZXNzZWQgU2l6ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweEZGLCAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4RkYsIChieXRlKSAweEZGLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9yaWdpbmFsIFNpemUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4RkYsIChieXRlKSAweEZGLCAoYnl0ZSkgMHhGRiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBmaWxlIG5hbWUgbGVuZ3RoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMSwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBleHRyYSBmaWVsZCBsZW5ndGgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgKG1vZGUgPT0gWmlwNjRNb2RlLkFsd2F5cz8gMjggOiAyMCksIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY29tbWVudCBsZW5ndGgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGRpc2sgbnVtYmVyCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhdHRyaWJ1dGVzCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAwLCAwLCAwLAorICAgICAgICAgICAgICAgICAgICB9LCByZXN0KTsKKyAgICAgICAgICAgICAgICAgICAgYnl0ZVtdIG9mZnNldCA9IG5ldyBieXRlWzRdOworICAgICAgICAgICAgICAgICAgICBhLnJlYWRGdWxseShvZmZzZXQpOworICAgICAgICAgICAgICAgICAgICBpZiAobW9kZSA9PSBaaXA2NE1vZGUuQWx3YXlzKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBhc3NlcnRBcnJheUVxdWFscygib2Zmc2V0IiwgbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweEZGLCAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4RkYsIChieXRlKSAweEZGLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sIG9mZnNldCk7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICBhc3NlcnRBcnJheUVxdWFscygib2Zmc2V0IiwgbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgb2Zmc2V0KTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoJzAnLCBhLnJlYWQoKSk7CisgICAgICAgICAgICAgICAgICAgIGJ5dGVbXSBleHRyYSA9IG5ldyBieXRlWzEyXTsKKyAgICAgICAgICAgICAgICAgICAgYS5yZWFkRnVsbHkoZXh0cmEpOworICAgICAgICAgICAgICAgICAgICAvLyA1ZTkgPT0gMHgxMkEwNUYyMDAKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMoIkNESCBleHRyYSIsIG5ldyBieXRlW10geworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEhlYWRlci1JRAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2l6ZSBvZiBleHRyYQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAobW9kZSA9PSBaaXA2NE1vZGUuQWx3YXlzPyAyNCA6IDE2KSwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBvcmlnaW5hbCBzaXplCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgKGJ5dGUpIDB4RjIsIDUsIChieXRlKSAweDJBLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEsIDAsIDAsIDAsCisgICAgICAgICAgICAgICAgICAgIH0sIGV4dHJhKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKG1vZGUgPT0gWmlwNjRNb2RlLkFsd2F5cykgeworICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2tpcCBjb21wcmVzc2VkIHNpemUKKyAgICAgICAgICAgICAgICAgICAgICAgIGEuc2tpcEJ5dGVzKDgpOworICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ID0gbmV3IGJ5dGVbOF07CisgICAgICAgICAgICAgICAgICAgICAgICBhLnJlYWRGdWxseShvZmZzZXQpOworICAgICAgICAgICAgICAgICAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMoImV4dHJhIG9mZnNldCIsIG5ldyBieXRlW10geworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sIG9mZnNldCk7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICAvLyB2YWxpZGF0ZSBkYXRhIGRlc2NyaXB0b3IKKyAgICAgICAgICAgICAgICAgICAgYS5zZWVrKGNmaFBvcyAtIDI0KTsKKyAgICAgICAgICAgICAgICAgICAgYnl0ZVtdIGRkID0gbmV3IGJ5dGVbOF07CisgICAgICAgICAgICAgICAgICAgIGEucmVhZEZ1bGx5KGRkKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMoIkREIiwgbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2lnCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpIDB4NTAsIChieXRlKSAweDRiLCA3LCA4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENSQworICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweDUwLCAoYnl0ZSkgMHg2RiwgKGJ5dGUpIDB4MzEsIChieXRlKSAweDVjLAorICAgICAgICAgICAgICAgICAgICB9LCBkZCk7CisgICAgICAgICAgICAgICAgICAgIC8vIHNraXAgY29tcHJlc3NlZCBzaXplCisgICAgICAgICAgICAgICAgICAgIGEuc2tpcEJ5dGVzKDgpOworICAgICAgICAgICAgICAgICAgICBkZCA9IG5ldyBieXRlWzhdOworICAgICAgICAgICAgICAgICAgICBhLnJlYWRGdWxseShkZCk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKCJERCBzaXplcyIsIG5ldyBieXRlW10geworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG9yaWdpbmFsIHNpemUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAoYnl0ZSkgMHhGMiwgNSwgKGJ5dGUpIDB4MkEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMSwgMCwgMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgfSwgZGQpOworCisgICAgICAgICAgICAgICAgICAgIC8vIGFuZCBub3cgdmFsaWRhdGUgbG9jYWwgZmlsZSBoZWFkZXIKKyAgICAgICAgICAgICAgICAgICAgYS5zZWVrKDApOworICAgICAgICAgICAgICAgICAgICBoZWFkZXIgPSBuZXcgYnl0ZVsxMF07CisgICAgICAgICAgICAgICAgICAgIGEucmVhZEZ1bGx5KGhlYWRlcik7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKCJMRkggc3RhcnQiLCBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzaWcKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgMHg1MCwgKGJ5dGUpIDB4NGIsIDMsIDQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdmVyc2lvbiBuZWVkZWQgdG8gZXh0cmFjdAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDQ1LCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEdQQiAoRUZTICsgRGF0YSBEZXNjcmlwdG9yKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDgsIDgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbWV0aG9kCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgOCwgMCwKKyAgICAgICAgICAgICAgICAgICAgfSwgaGVhZGVyKTsKKyAgICAgICAgICAgICAgICAgICAgLy8gaWdub3JlIHRpbWVzdGFtcAorICAgICAgICAgICAgICAgICAgICBhLnNraXBCeXRlcyg0KTsKKyAgICAgICAgICAgICAgICAgICAgcmVzdCA9IG5ldyBieXRlWzE3XTsKKyAgICAgICAgICAgICAgICAgICAgYS5yZWFkRnVsbHkocmVzdCk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKCJMRkggcmVzdCIsIG5ldyBieXRlW10geworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENSQworICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ29tcHJlc3NlZCBTaXplCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpIDB4RkYsIChieXRlKSAweEZGLCAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4RkYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT3JpZ2luYWwgU2l6ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweEZGLCAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4RkYsIChieXRlKSAweEZGLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZpbGUgbmFtZSBsZW5ndGgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAxLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGV4dHJhIGZpZWxkIGxlbmd0aAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDIwLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZpbGUgbmFtZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAnMCcKKyAgICAgICAgICAgICAgICAgICAgfSwgcmVzdCk7CisgICAgICAgICAgICAgICAgICAgIGV4dHJhID0gbmV3IGJ5dGVbMjBdOworICAgICAgICAgICAgICAgICAgICBhLnJlYWRGdWxseShleHRyYSk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKCJMRkggZXh0cmEiLCBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBIZWFkZXItSUQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAxLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNpemUgb2YgZXh0cmEKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAxNiwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBvcmlnaW5hbCBzaXplCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAwLCAwLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvbXByZXNzZWQgc2l6ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgfSwgZXh0cmEpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICB9CisKKyAgICBAVGVzdCBwdWJsaWMgdm9pZCB3cml0ZUJpZ0RlZmxhdGVkRW50cnlLbm93blNpemVUb1N0cmVhbSgpCisgICAgICAgIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICB3aXRoVGVtcG9yYXJ5QXJjaGl2ZSgid3JpdGVCaWdEZWZsYXRlZEVudHJ5S25vd25TaXplVG9TdHJlYW0iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cml0ZUJpZ0RlZmxhdGVkRW50cnlUb1N0cmVhbSh0cnVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBaaXA2NE1vZGUuQXNOZWVkZWQpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSk7CisgICAgfQorCisgICAgQFRlc3QgcHVibGljIHZvaWQgd3JpdGVCaWdEZWZsYXRlZEVudHJ5S25vd25TaXplVG9TdHJlYW1Nb2RlQWx3YXlzKCkKKyAgICAgICAgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIHdpdGhUZW1wb3JhcnlBcmNoaXZlKCJ3cml0ZUJpZ0RlZmxhdGVkRW50cnlLbm93blNpemVUb1N0cmVhbU1vZGVBbHdheXMiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cml0ZUJpZ0RlZmxhdGVkRW50cnlUb1N0cmVhbSh0cnVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBaaXA2NE1vZGUuQWx3YXlzKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UpOworICAgIH0KKworICAgIEBUZXN0IHB1YmxpYyB2b2lkIHdyaXRlQmlnRGVmbGF0ZWRFbnRyeVVua25vd25TaXplVG9TdHJlYW1Nb2RlQWx3YXlzKCkKKyAgICAgICAgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIHdpdGhUZW1wb3JhcnlBcmNoaXZlKCJ3cml0ZUJpZ0RlZmxhdGVkRW50cnlVbmtub3duU2l6ZVRvU3RyZWFtTW9kZUFsd2F5cyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlQmlnRGVmbGF0ZWRFbnRyeVRvU3RyZWFtKGZhbHNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBaaXA2NE1vZGUuQWx3YXlzKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIFppcE91dHB1dFRlc3QKKyAgICAgICAgd3JpdGVCaWdEZWZsYXRlZEVudHJ5VW5rbm93blNpemVUb1N0cmVhbShmaW5hbCBaaXA2NE1vZGUgbW9kZSkgeworICAgICAgICByZXR1cm4gbmV3IFppcE91dHB1dFRlc3QoKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHRlc3QoZmluYWwgRmlsZSBmLCBmaW5hbCBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtIHpvcykKKyAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChtb2RlICE9IFppcDY0TW9kZS5Bc05lZWRlZCkgeworICAgICAgICAgICAgICAgICAgICAgICAgem9zLnNldFVzZVppcDY0KG1vZGUpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBidWYgPSBuZXcgYnl0ZVtPTkVfTUlMTElPTl07CisgICAgICAgICAgICAgICAgICAgIGZpbmFsIFppcEFyY2hpdmVFbnRyeSB6YWUgPSBuZXcgWmlwQXJjaGl2ZUVudHJ5KCIwIik7CisgICAgICAgICAgICAgICAgICAgIHphZS5zZXRNZXRob2QoWmlwRW50cnkuREVGTEFURUQpOworICAgICAgICAgICAgICAgICAgICB6b3MucHV0QXJjaGl2ZUVudHJ5KHphZSk7CisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgRklWRV9CSUxMSU9OIC8gMTAwMCAvIDEwMDA7IGorKykgeworICAgICAgICAgICAgICAgICAgICAgICAgem9zLndyaXRlKGJ1Zik7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgem9zLmNsb3NlQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIGEgWmlwNjRSZXF1aXJlZEV4Y2VwdGlvbiIpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGZpbmFsIFppcDY0UmVxdWlyZWRFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZShleC5nZXRNZXNzYWdlKCkuc3RhcnRzV2l0aCgiMCdzIHNpemUiKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9OworICAgIH0KKworICAgIEBUZXN0IHB1YmxpYyB2b2lkIHdyaXRlQmlnRGVmbGF0ZWRFbnRyeVVua25vd25TaXplVG9TdHJlYW0oKQorICAgICAgICB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgd2l0aFRlbXBvcmFyeUFyY2hpdmUoIndyaXRlQmlnRGVmbGF0ZWRFbnRyeVVua25vd25TaXplVG9TdHJlYW0iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cml0ZUJpZ0RlZmxhdGVkRW50cnlVbmtub3duU2l6ZVRvU3RyZWFtKFppcDY0TW9kZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5Bc05lZWRlZCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlKTsKKyAgICB9CisKKyAgICBAVGVzdCBwdWJsaWMgdm9pZCB3cml0ZUJpZ0RlZmxhdGVkRW50cnlVbmtub3duU2l6ZVRvU3RyZWFtTW9kZU5ldmVyKCkKKyAgICAgICAgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIHdpdGhUZW1wb3JhcnlBcmNoaXZlKCJ3cml0ZUJpZ0RlZmxhdGVkRW50cnlVbmtub3duU2l6ZVRvU3RyZWFtTW9kZU5ldmVyIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVCaWdEZWZsYXRlZEVudHJ5VW5rbm93blNpemVUb1N0cmVhbShaaXA2NE1vZGUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuTmV2ZXIpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgWmlwT3V0cHV0VGVzdAorICAgICAgICB3cml0ZUJpZ0RlZmxhdGVkRW50cnlUb0ZpbGUoZmluYWwgYm9vbGVhbiBrbm93blNpemUpIHsKKyAgICAgICAgcmV0dXJuIHdyaXRlQmlnRGVmbGF0ZWRFbnRyeVRvRmlsZShrbm93blNpemUsIFppcDY0TW9kZS5Bc05lZWRlZCk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBPbmUgZW50cnkgb2YgbGVuZ3RoIDUgYmlsbGlvbiBieXRlcywgd3JpdHRlbiB3aXRoCisgICAgICogY29tcHJlc3Npb24gdG8gYSBmaWxlLgorICAgICAqCisgICAgICogV3JpdGluZyB0byBhIGZpbGUgPT4gc2l6ZXMgYXJlIHN0b3JlZCBkaXJlY3RseSBpbnNpZGUgdGhlIExGSC4KKyAgICAgKiBObyBEYXRhIERlc2NyaXB0b3IgYXQgYWxsLgorICAgICAqCisgICAgICogQ3JlYXRlcyBhIHRlbXBvcmFyeSBhcmNoaXZlIG9mIGFwcHJveCA0TUIgaW4gc2l6ZQorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIFppcE91dHB1dFRlc3QKKyAgICAgICAgd3JpdGVCaWdEZWZsYXRlZEVudHJ5VG9GaWxlKGZpbmFsIGJvb2xlYW4ga25vd25TaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgWmlwNjRNb2RlIG1vZGUpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBaaXBPdXRwdXRUZXN0KCkgeworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgdm9pZCB0ZXN0KGZpbmFsIEZpbGUgZiwgZmluYWwgWmlwQXJjaGl2ZU91dHB1dFN0cmVhbSB6b3MpCisgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICBpZiAobW9kZSAhPSBaaXA2NE1vZGUuQXNOZWVkZWQpIHsKKyAgICAgICAgICAgICAgICAgICAgem9zLnNldFVzZVppcDY0KG1vZGUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBmaW5hbCBieXRlW10gYnVmID0gbmV3IGJ5dGVbT05FX01JTExJT05dOworICAgICAgICAgICAgICAgIGZpbmFsIFppcEFyY2hpdmVFbnRyeSB6YWUgPSBuZXcgWmlwQXJjaGl2ZUVudHJ5KCIwIik7CisgICAgICAgICAgICAgICAgaWYgKGtub3duU2l6ZSkgeworICAgICAgICAgICAgICAgICAgICB6YWUuc2V0U2l6ZShGSVZFX0JJTExJT04pOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB6YWUuc2V0TWV0aG9kKFppcEVudHJ5LkRFRkxBVEVEKTsKKyAgICAgICAgICAgICAgICB6b3MucHV0QXJjaGl2ZUVudHJ5KHphZSk7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7CisgICAgICAgICAgICAgICAgICAgICBqIDwgRklWRV9CSUxMSU9OIC8gMTAwMCAvIDEwMDA7CisgICAgICAgICAgICAgICAgICAgICBqKyspIHsKKyAgICAgICAgICAgICAgICAgICAgem9zLndyaXRlKGJ1Zik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHpvcy5jbG9zZUFyY2hpdmVFbnRyeSgpOworICAgICAgICAgICAgICAgIHpvcy5jbG9zZSgpOworCisgICAgICAgICAgICAgICAgdHJ5IChSYW5kb21BY2Nlc3NGaWxlIGEgPSBuZXcgUmFuZG9tQWNjZXNzRmlsZShmLCAiciIpKSB7CisgICAgICAgICAgICAgICAgICAgIGdldExlbmd0aEFuZFBvc2l0aW9uQXRDZW50cmFsRGlyZWN0b3J5KGEpOworCisgICAgICAgICAgICAgICAgICAgIC8vIGdyYWIgZmlyc3QgZW50cnksIHZlcmlmeQorICAgICAgICAgICAgICAgICAgICAvLyBzaXplcyBhcmUgMHhGRkZGRkZGRiBhbmQKKyAgICAgICAgICAgICAgICAgICAgLy8gaXQgaGFzIGEgWklQNjQgZXh0ZW5kZWQKKyAgICAgICAgICAgICAgICAgICAgLy8gaW5mb3JtYXRpb24gZXh0cmEgZmllbGQKKyAgICAgICAgICAgICAgICAgICAgYnl0ZVtdIGhlYWRlciA9IG5ldyBieXRlWzEyXTsKKyAgICAgICAgICAgICAgICAgICAgYS5yZWFkRnVsbHkoaGVhZGVyKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMoIkNESCBzdGFydCIsIG5ldyBieXRlW10geworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNpZworICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweDUwLCAoYnl0ZSkgMHg0YiwgMSwgMiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB2ZXJzaW9uIG1hZGUgYnkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICA0NSwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB2ZXJzaW9uIG5lZWRlZCB0byBleHRyYWN0CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgNDUsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gR1BCIChFRlMgKyAqbm8qIERhdGEgRGVzY3JpcHRvcikKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCA4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1ldGhvZAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDgsIDAsCisgICAgICAgICAgICAgICAgICAgIH0sIGhlYWRlcik7CisgICAgICAgICAgICAgICAgICAgIC8vIGlnbm9yZSB0aW1lc3RhbXAKKyAgICAgICAgICAgICAgICAgICAgYS5za2lwQnl0ZXMoNCk7CisgICAgICAgICAgICAgICAgICAgIGJ5dGVbXSByZXN0ID0gbmV3IGJ5dGVbMjZdOworICAgICAgICAgICAgICAgICAgICBhLnJlYWRGdWxseShyZXN0KTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMoIkNESCByZXN0IiwgbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ1JDCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpIDB4NTAsIChieXRlKSAweDZGLCAoYnl0ZSkgMHgzMSwgKGJ5dGUpIDB4NWMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ29tcHJlc3NlZCBTaXplCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpIDB4RkYsIChieXRlKSAweEZGLCAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4RkYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT3JpZ2luYWwgU2l6ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweEZGLCAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4RkYsIChieXRlKSAweEZGLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZpbGUgbmFtZSBsZW5ndGgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAxLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGV4dHJhIGZpZWxkIGxlbmd0aAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAobW9kZSA9PSBaaXA2NE1vZGUuQWx3YXlzPyAyOCA6IDIwKSwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjb21tZW50IGxlbmd0aAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZGlzayBudW1iZXIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGF0dHJpYnV0ZXMKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAgICAgICAgIH0sIHJlc3QpOworICAgICAgICAgICAgICAgICAgICBieXRlW10gb2Zmc2V0ID0gbmV3IGJ5dGVbNF07CisgICAgICAgICAgICAgICAgICAgIGEucmVhZEZ1bGx5KG9mZnNldCk7CisgICAgICAgICAgICAgICAgICAgIGlmIChtb2RlID09IFppcDY0TW9kZS5BbHdheXMpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKCJvZmZzZXQiLCBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpIDB4RkYsIChieXRlKSAweEZGLCAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4RkYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgb2Zmc2V0KTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKCJvZmZzZXQiLCBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LCBvZmZzZXQpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygnMCcsIGEucmVhZCgpKTsKKyAgICAgICAgICAgICAgICAgICAgYnl0ZVtdIGV4dHJhID0gbmV3IGJ5dGVbMTJdOworICAgICAgICAgICAgICAgICAgICBhLnJlYWRGdWxseShleHRyYSk7CisgICAgICAgICAgICAgICAgICAgIC8vIDVlOSA9PSAweDEyQTA1RjIwMAorICAgICAgICAgICAgICAgICAgICBhc3NlcnRBcnJheUVxdWFscygiQ0RIIGV4dHJhIiwgbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSGVhZGVyLUlECisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMSwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzaXplIG9mIGV4dHJhCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpIChtb2RlID09IFppcDY0TW9kZS5BbHdheXM/IDI0IDogMTYpLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG9yaWdpbmFsIHNpemUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAoYnl0ZSkgMHhGMiwgNSwgKGJ5dGUpIDB4MkEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMSwgMCwgMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgfSwgZXh0cmEpOworICAgICAgICAgICAgICAgICAgICBpZiAobW9kZSA9PSBaaXA2NE1vZGUuQWx3YXlzKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyBza2lwIGNvbXByZXNzZWQgc2l6ZQorICAgICAgICAgICAgICAgICAgICAgICAgYS5za2lwQnl0ZXMoOCk7CisgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQgPSBuZXcgYnl0ZVs4XTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGEucmVhZEZ1bGx5KG9mZnNldCk7CisgICAgICAgICAgICAgICAgICAgICAgICBhc3NlcnRBcnJheUVxdWFscygiZXh0cmEgb2Zmc2V0IiwgbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgb2Zmc2V0KTsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIC8vIGFuZCBub3cgdmFsaWRhdGUgbG9jYWwgZmlsZSBoZWFkZXIKKyAgICAgICAgICAgICAgICAgICAgYS5zZWVrKDApOworICAgICAgICAgICAgICAgICAgICBoZWFkZXIgPSBuZXcgYnl0ZVsxMF07CisgICAgICAgICAgICAgICAgICAgIGEucmVhZEZ1bGx5KGhlYWRlcik7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKCJMRkggc3RhcnQiLCBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzaWcKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgMHg1MCwgKGJ5dGUpIDB4NGIsIDMsIDQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdmVyc2lvbiBuZWVkZWQgdG8gZXh0cmFjdAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDQ1LCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEdQQiAoRUZTIGJpdCwgbm8gREQpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgOCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBtZXRob2QKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICA4LCAwLAorICAgICAgICAgICAgICAgICAgICB9LCBoZWFkZXIpOworICAgICAgICAgICAgICAgICAgICAvLyBpZ25vcmUgdGltZXN0YW1wCisgICAgICAgICAgICAgICAgICAgIGEuc2tpcEJ5dGVzKDQpOworICAgICAgICAgICAgICAgICAgICByZXN0ID0gbmV3IGJ5dGVbMTddOworICAgICAgICAgICAgICAgICAgICBhLnJlYWRGdWxseShyZXN0KTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMobmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ1JDCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpIDB4NTAsIChieXRlKSAweDZGLCAoYnl0ZSkgMHgzMSwgKGJ5dGUpIDB4NWMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ29tcHJlc3NlZCBTaXplCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpIDB4RkYsIChieXRlKSAweEZGLCAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4RkYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT3JpZ2luYWwgU2l6ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweEZGLCAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4RkYsIChieXRlKSAweEZGLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZpbGUgbmFtZSBsZW5ndGgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAxLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGV4dHJhIGZpZWxkIGxlbmd0aAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDIwLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZpbGUgbmFtZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAnMCcKKyAgICAgICAgICAgICAgICAgICAgfSwgcmVzdCk7CisgICAgICAgICAgICAgICAgICAgIGV4dHJhID0gbmV3IGJ5dGVbMTJdOworICAgICAgICAgICAgICAgICAgICBhLnJlYWRGdWxseShleHRyYSk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKG5ldyBieXRlW10geworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEhlYWRlci1JRAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2l6ZSBvZiBleHRyYQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDE2LCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG9yaWdpbmFsIHNpemUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAoYnl0ZSkgMHhGMiwgNSwgKGJ5dGUpIDB4MkEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMSwgMCwgMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBza2lwIGNvbXByZXNzZWQgc2l6ZQorICAgICAgICAgICAgICAgICAgICB9LCBleHRyYSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9OworICAgIH0KKworICAgIEBUZXN0IHB1YmxpYyB2b2lkIHdyaXRlQmlnRGVmbGF0ZWRFbnRyeUtub3duU2l6ZVRvRmlsZSgpCisgICAgICAgIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICB3aXRoVGVtcG9yYXJ5QXJjaGl2ZSgid3JpdGVCaWdEZWZsYXRlZEVudHJ5S25vd25TaXplVG9GaWxlIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVCaWdEZWZsYXRlZEVudHJ5VG9GaWxlKHRydWUpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlKTsKKyAgICB9CisKKyAgICBAVGVzdCBwdWJsaWMgdm9pZCB3cml0ZUJpZ0RlZmxhdGVkRW50cnlVbmtub3duU2l6ZVRvRmlsZSgpCisgICAgICAgIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICB3aXRoVGVtcG9yYXJ5QXJjaGl2ZSgid3JpdGVCaWdEZWZsYXRlZEVudHJ5VW5rbm93blNpemVUb0ZpbGUiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cml0ZUJpZ0RlZmxhdGVkRW50cnlUb0ZpbGUoZmFsc2UpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlKTsKKyAgICB9CisKKyAgICBAVGVzdCBwdWJsaWMgdm9pZCB3cml0ZUJpZ0RlZmxhdGVkRW50cnlLbm93blNpemVUb0ZpbGVNb2RlQWx3YXlzKCkKKyAgICAgICAgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIHdpdGhUZW1wb3JhcnlBcmNoaXZlKCJ3cml0ZUJpZ0RlZmxhdGVkRW50cnlLbm93blNpemVUb0ZpbGVNb2RlQWx3YXlzIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVCaWdEZWZsYXRlZEVudHJ5VG9GaWxlKHRydWUsIFppcDY0TW9kZS5BbHdheXMpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlKTsKKyAgICB9CisKKyAgICBAVGVzdCBwdWJsaWMgdm9pZCB3cml0ZUJpZ0RlZmxhdGVkRW50cnlVbmtub3duU2l6ZVRvRmlsZU1vZGVBbHdheXMoKQorICAgICAgICB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgd2l0aFRlbXBvcmFyeUFyY2hpdmUoIndyaXRlQmlnRGVmbGF0ZWRFbnRyeVVua25vd25TaXplVG9GaWxlTW9kZUFsd2F5cyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlQmlnRGVmbGF0ZWRFbnRyeVRvRmlsZShmYWxzZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFppcDY0TW9kZS5BbHdheXMpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlKTsKKyAgICB9CisKKyAgICBAVGVzdCBwdWJsaWMgdm9pZCB3cml0ZUJpZ0RlZmxhdGVkRW50cnlLbm93blNpemVUb1N0cmVhbU1vZGVOZXZlcigpCisgICAgICAgIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICB3aXRoVGVtcG9yYXJ5QXJjaGl2ZSgid3JpdGVCaWdEZWZsYXRlZEVudHJ5S25vd25TaXplVG9TdHJlYW1Nb2RlTmV2ZXIiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgWmlwT3V0cHV0VGVzdCgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCB0ZXN0KGZpbmFsIEZpbGUgZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgWmlwQXJjaGl2ZU91dHB1dFN0cmVhbSB6b3MpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB6b3Muc2V0VXNlWmlwNjQoWmlwNjRNb2RlLk5ldmVyKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBaaXBBcmNoaXZlRW50cnkgemFlID0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBaaXBBcmNoaXZlRW50cnkoIjAiKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgemFlLnNldFNpemUoRklWRV9CSUxMSU9OKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgemFlLnNldE1ldGhvZChaaXBFbnRyeS5ERUZMQVRFRCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHpvcy5wdXRBcmNoaXZlRW50cnkoemFlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgYSIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgWmlwNjRSZXF1aXJlZEV4Y2VwdGlvbiIpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGZpbmFsIFppcDY0UmVxdWlyZWRFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZShleC5nZXRNZXNzYWdlKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc3RhcnRzV2l0aCgiMCdzIHNpemUiKSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBPbmUgZW50cnkgb2YgbGVuZ3RoIDUgYmlsbGlvbiBieXRlcywgd3JpdHRlbiB3aXRoCisgICAgICogY29tcHJlc3Npb24gdG8gYSBmaWxlLgorICAgICAqCisgICAgICogV3JpdGluZyB0byBhIGZpbGUgPT4gc2l6ZXMgYXJlIHN0b3JlZCBkaXJlY3RseSBpbnNpZGUgdGhlIExGSC4KKyAgICAgKiBObyBEYXRhIERlc2NyaXB0b3IgYXQgYWxsLgorICAgICAqCisgICAgICogQ3JlYXRlcyBhIHRlbXBvcmFyeSBhcmNoaXZlIG9mIGFwcHJveCA0TUIgaW4gc2l6ZQorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIFppcE91dHB1dFRlc3QKKyAgICAgICAgd3JpdGVCaWdEZWZsYXRlZEVudHJ5VG9GaWxlTW9kZU5ldmVyKGZpbmFsIGJvb2xlYW4ga25vd25TaXplKSB7CisgICAgICAgIHJldHVybiBuZXcgWmlwT3V0cHV0VGVzdCgpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIHZvaWQgdGVzdChmaW5hbCBGaWxlIGYsIGZpbmFsIFppcEFyY2hpdmVPdXRwdXRTdHJlYW0gem9zKQorICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgem9zLnNldFVzZVppcDY0KFppcDY0TW9kZS5OZXZlcik7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgYnl0ZVtdIGJ1ZiA9IG5ldyBieXRlW09ORV9NSUxMSU9OXTsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgWmlwQXJjaGl2ZUVudHJ5IHphZSA9IG5ldyBaaXBBcmNoaXZlRW50cnkoIjAiKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGtub3duU2l6ZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgemFlLnNldFNpemUoRklWRV9CSUxMSU9OKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB6YWUuc2V0TWV0aG9kKFppcEVudHJ5LkRFRkxBVEVEKTsKKyAgICAgICAgICAgICAgICAgICAgem9zLnB1dEFyY2hpdmVFbnRyeSh6YWUpOworICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBqID0gMDsKKyAgICAgICAgICAgICAgICAgICAgICAgICBqIDwgRklWRV9CSUxMSU9OIC8gMTAwMCAvIDEwMDA7CisgICAgICAgICAgICAgICAgICAgICAgICAgaisrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB6b3Mud3JpdGUoYnVmKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB6b3MuY2xvc2VBcmNoaXZlRW50cnkoKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgYSBaaXA2NFJlcXVpcmVkRXhjZXB0aW9uIik7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoZmluYWwgWmlwNjRSZXF1aXJlZEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKGV4LmdldE1lc3NhZ2UoKS5zdGFydHNXaXRoKCIwJ3Mgc2l6ZSIpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH07CisgICAgfQorCisgICAgQFRlc3QgcHVibGljIHZvaWQgd3JpdGVCaWdEZWZsYXRlZEVudHJ5S25vd25TaXplVG9GaWxlTW9kZU5ldmVyKCkKKyAgICAgICAgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIHdpdGhUZW1wb3JhcnlBcmNoaXZlKCJ3cml0ZUJpZ0RlZmxhdGVkRW50cnlLbm93blNpemVUb0ZpbGVNb2RlTmV2ZXIiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cml0ZUJpZ0RlZmxhdGVkRW50cnlUb0ZpbGVNb2RlTmV2ZXIodHJ1ZSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUpOworICAgIH0KKworICAgIEBUZXN0IHB1YmxpYyB2b2lkIHdyaXRlQmlnRGVmbGF0ZWRFbnRyeVVua25vd25TaXplVG9GaWxlTW9kZU5ldmVyKCkKKyAgICAgICAgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIHdpdGhUZW1wb3JhcnlBcmNoaXZlKCJ3cml0ZUJpZ0RlZmxhdGVkRW50cnlVbmtub3duU2l6ZVRvRmlsZU1vZGVOZXZlciIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlQmlnRGVmbGF0ZWRFbnRyeVRvRmlsZU1vZGVOZXZlcihmYWxzZSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIFppcE91dHB1dFRlc3Qgd3JpdGVTbWFsbFN0b3JlZEVudHJ5KGZpbmFsIGJvb2xlYW4ga25vd25TaXplKSB7CisgICAgICAgIHJldHVybiB3cml0ZVNtYWxsU3RvcmVkRW50cnkoa25vd25TaXplLCBaaXA2NE1vZGUuQXNOZWVkZWQpOworICAgIH0KKworICAgIC8qCisgICAgICogT25lIGVudHJ5IG9mIGxlbmd0aCAxIG1pbGxpb24gYnl0ZXMsIHdyaXR0ZW4gd2l0aG91dCBjb21wcmVzc2lvbi4KKyAgICAgKgorICAgICAqIE5vIENvbXByZXNzaW9uID0+IHNpemVzIGFyZSBzdG9yZWQgZGlyZWN0bHkgaW5zaWRlIHRoZSBMRkguICBObworICAgICAqIERhdGEgRGVzY3JpcHRvciBhdCBhbGwuICBTaG91bGRuJ3QgY29udGFpbiBhbnkgWklQNjQgZXh0cmEKKyAgICAgKiBmaWVsZCBpZiBzaXplIHdhcyBrbm93bi4KKyAgICAgKgorICAgICAqIENyZWF0ZXMgYSB0ZW1wb3JhcnkgYXJjaGl2ZSBvZiBhcHByb3ggMU1CIGluIHNpemUKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBaaXBPdXRwdXRUZXN0IHdyaXRlU21hbGxTdG9yZWRFbnRyeShmaW5hbCBib29sZWFuIGtub3duU2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBaaXA2NE1vZGUgbW9kZSkgeworICAgICAgICByZXR1cm4gbmV3IFppcE91dHB1dFRlc3QoKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHRlc3QoZmluYWwgRmlsZSBmLCBmaW5hbCBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtIHpvcykKKyAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgICAgIGlmIChtb2RlICE9IFppcDY0TW9kZS5Bc05lZWRlZCkgeworICAgICAgICAgICAgICAgICAgICB6b3Muc2V0VXNlWmlwNjQobW9kZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBidWYgPSBuZXcgYnl0ZVtPTkVfTUlMTElPTl07CisgICAgICAgICAgICAgICAgZmluYWwgWmlwQXJjaGl2ZUVudHJ5IHphZSA9IG5ldyBaaXBBcmNoaXZlRW50cnkoIjAiKTsKKyAgICAgICAgICAgICAgICBpZiAoa25vd25TaXplKSB7CisgICAgICAgICAgICAgICAgICAgIHphZS5zZXRTaXplKE9ORV9NSUxMSU9OKTsKKyAgICAgICAgICAgICAgICAgICAgemFlLnNldENyYygweDEyNzlDQjlFTCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHphZS5zZXRNZXRob2QoWmlwRW50cnkuU1RPUkVEKTsKKyAgICAgICAgICAgICAgICB6b3MucHV0QXJjaGl2ZUVudHJ5KHphZSk7CisgICAgICAgICAgICAgICAgem9zLndyaXRlKGJ1Zik7CisgICAgICAgICAgICAgICAgem9zLmNsb3NlQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgICAgICAgICAgem9zLmNsb3NlKCk7CisKKyAgICAgICAgICAgICAgICB0cnkgKFJhbmRvbUFjY2Vzc0ZpbGUgYSA9IG5ldyBSYW5kb21BY2Nlc3NGaWxlKGYsICJyIikpIHsKKyAgICAgICAgICAgICAgICAgICAgZ2V0TGVuZ3RoQW5kUG9zaXRpb25BdENlbnRyYWxEaXJlY3RvcnkoYSk7CisKKyAgICAgICAgICAgICAgICAgICAgLy8gZ3JhYiBmaXJzdCBDRiBlbnRyeSwgdmVyaWZ5IHNpemVzIGFyZSAxZTYgYW5kIGl0CisgICAgICAgICAgICAgICAgICAgIC8vIGhhcyBubyBaSVA2NCBleHRlbmRlZCBpbmZvcm1hdGlvbiBleHRyYSBmaWVsZAorICAgICAgICAgICAgICAgICAgICAvLyBhdCBhbGwKKyAgICAgICAgICAgICAgICAgICAgYnl0ZVtdIGhlYWRlciA9IG5ldyBieXRlWzEyXTsKKyAgICAgICAgICAgICAgICAgICAgYS5yZWFkRnVsbHkoaGVhZGVyKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMoIkNESCBzdGFydCIsIG5ldyBieXRlW10geworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNpZworICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweDUwLCAoYnl0ZSkgMHg0YiwgMSwgMiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB2ZXJzaW9uIG1hZGUgYnkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAyMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB2ZXJzaW9uIG5lZWRlZCB0byBleHRyYWN0CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMTAsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gR1BCIChFRlMgYml0KQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbWV0aG9kCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMAorICAgICAgICAgICAgICAgICAgICB9LCBoZWFkZXIpOworICAgICAgICAgICAgICAgICAgICAvLyBpZ25vcmUgdGltZXN0YW1wCisgICAgICAgICAgICAgICAgICAgIGEuc2tpcEJ5dGVzKDQpOworICAgICAgICAgICAgICAgICAgICBieXRlW10gcmVzdCA9IG5ldyBieXRlWzMxXTsKKyAgICAgICAgICAgICAgICAgICAgYS5yZWFkRnVsbHkocmVzdCk7CisgICAgICAgICAgICAgICAgICAgIC8vIDFlNiA9PSAweEY0MjQwCisgICAgICAgICAgICAgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKCJDREggcmVzdCIsIG5ldyBieXRlW10geworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENSQworICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweDlFLCAoYnl0ZSkgMHhDQiwgKGJ5dGUpIDB4NzksIChieXRlKSAweDEyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENvbXByZXNzZWQgU2l6ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweDQwLCAoYnl0ZSkgMHg0MiwgKGJ5dGUpIDB4MEYsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT3JpZ2luYWwgU2l6ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweDQwLCAoYnl0ZSkgMHg0MiwgKGJ5dGUpIDB4MEYsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZmlsZSBuYW1lIGxlbmd0aAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZXh0cmEgZmllbGQgbGVuZ3RoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjb21tZW50IGxlbmd0aAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZGlzayBudW1iZXIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGF0dHJpYnV0ZXMKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gb2Zmc2V0CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBmaWxlIG5hbWUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgJzAnCisgICAgICAgICAgICAgICAgICAgIH0sIHJlc3QpOworCisgICAgICAgICAgICAgICAgICAgIC8vIGFuZCBub3cgdmFsaWRhdGUgbG9jYWwgZmlsZSBoZWFkZXI6IHRoaXMgb25lCisgICAgICAgICAgICAgICAgICAgIC8vIGhhcyBhIFpJUDY0IGV4dHJhIGZpZWxkIGlmIGFuZCBvbmx5IGlmIHNpemUgd2FzCisgICAgICAgICAgICAgICAgICAgIC8vIHVua25vd24gYW5kIG1vZGUgd2FzIG5vdCBOZXZlciBvciB0aGUgbW9kZSB3YXMKKyAgICAgICAgICAgICAgICAgICAgLy8gQWx3YXlzIChyZWdhcmRsZXNzIG9mIHNpemUpCisgICAgICAgICAgICAgICAgICAgIGZpbmFsIGJvb2xlYW4gaGFzRXh0cmEgPSBtb2RlID09IFppcDY0TW9kZS5BbHdheXMKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCAobW9kZSA9PSBaaXA2NE1vZGUuQXNOZWVkZWQgJiYgIWtub3duU2l6ZSk7CisgICAgICAgICAgICAgICAgICAgIGEuc2VlaygwKTsKKyAgICAgICAgICAgICAgICAgICAgaGVhZGVyID0gbmV3IGJ5dGVbMTBdOworICAgICAgICAgICAgICAgICAgICBhLnJlYWRGdWxseShoZWFkZXIpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRBcnJheUVxdWFscygiTEZIIHN0YXJ0IiwgbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2lnCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpIDB4NTAsIChieXRlKSAweDRiLCAzLCA0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHZlcnNpb24gbmVlZGVkIHRvIGV4dHJhY3QKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAxMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBHUEIgKEVGUyBiaXQpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgOCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBtZXRob2QKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAwCisgICAgICAgICAgICAgICAgICAgIH0sIGhlYWRlcik7CisgICAgICAgICAgICAgICAgICAgIC8vIGlnbm9yZSB0aW1lc3RhbXAKKyAgICAgICAgICAgICAgICAgICAgYS5za2lwQnl0ZXMoNCk7CisgICAgICAgICAgICAgICAgICAgIHJlc3QgPSBuZXcgYnl0ZVsxN107CisgICAgICAgICAgICAgICAgICAgIGEucmVhZEZ1bGx5KHJlc3QpOworICAgICAgICAgICAgICAgICAgICAvLyAxZTYgPT0gMHhGNDI0MAorICAgICAgICAgICAgICAgICAgICBhc3NlcnRBcnJheUVxdWFscygiTEZIIHJlc3QiLCBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBDUkMKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgMHg5RSwgKGJ5dGUpIDB4Q0IsIChieXRlKSAweDc5LCAoYnl0ZSkgMHgxMiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBDb21wcmVzc2VkIFNpemUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgMHg0MCwgKGJ5dGUpIDB4NDIsIChieXRlKSAweDBGLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9yaWdpbmFsIFNpemUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgMHg0MCwgKGJ5dGUpIDB4NDIsIChieXRlKSAweDBGLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZpbGUgbmFtZSBsZW5ndGgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAxLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGV4dHJhIGZpZWxkIGxlbmd0aAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAoIWhhc0V4dHJhID8gMCA6IDIwKSwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBmaWxlIG5hbWUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgJzAnCisgICAgICAgICAgICAgICAgICAgIH0sIHJlc3QpOworICAgICAgICAgICAgICAgICAgICBpZiAoaGFzRXh0cmEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBleHRyYSA9IG5ldyBieXRlWzIwXTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGEucmVhZEZ1bGx5KGV4dHJhKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKCJaSVA2NCBleHRyYSBmaWVsZCIsIG5ldyBieXRlW10geworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBIZWFkZXItSUQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMSwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2l6ZSBvZiBleHRyYQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxNiwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gb3JpZ2luYWwgc2l6ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgMHg0MCwgKGJ5dGUpIDB4NDIsIChieXRlKSAweDBGLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAwLCAwLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjb21wcmVzc2VkIHNpemUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpIDB4NDAsIChieXRlKSAweDQyLCAoYnl0ZSkgMHgwRiwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgIH0sIGV4dHJhKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICB9CisKKyAgICBAVGVzdCBwdWJsaWMgdm9pZCB3cml0ZVNtYWxsU3RvcmVkRW50cnlUb1N0cmVhbSgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICB3aXRoVGVtcG9yYXJ5QXJjaGl2ZSgid3JpdGVTbWFsbFN0b3JlZEVudHJ5VG9TdHJlYW0iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cml0ZVNtYWxsU3RvcmVkRW50cnkodHJ1ZSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlKTsKKyAgICB9CisKKyAgICBAVGVzdCBwdWJsaWMgdm9pZCB3cml0ZVNtYWxsU3RvcmVkRW50cnlLbm93blNpemVUb0ZpbGUoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgd2l0aFRlbXBvcmFyeUFyY2hpdmUoIndyaXRlU21hbGxTdG9yZWRFbnRyeUtub3duU2l6ZVRvRmlsZSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlU21hbGxTdG9yZWRFbnRyeSh0cnVlKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSk7CisgICAgfQorCisgICAgQFRlc3QgcHVibGljIHZvaWQgd3JpdGVTbWFsbFN0b3JlZEVudHJ5VW5ub3duU2l6ZVRvRmlsZSgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICB3aXRoVGVtcG9yYXJ5QXJjaGl2ZSgid3JpdGVTbWFsbFN0b3JlZEVudHJ5VW5rbm93blNpemVUb0ZpbGUiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cml0ZVNtYWxsU3RvcmVkRW50cnkoZmFsc2UpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlKTsKKyAgICB9CisKKyAgICBAVGVzdCBwdWJsaWMgdm9pZCB3cml0ZVNtYWxsU3RvcmVkRW50cnlUb1N0cmVhbU1vZGVOZXZlcigpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICB3aXRoVGVtcG9yYXJ5QXJjaGl2ZSgid3JpdGVTbWFsbFN0b3JlZEVudHJ5VG9TdHJlYW1Nb2RlTmV2ZXIiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cml0ZVNtYWxsU3RvcmVkRW50cnkodHJ1ZSwgWmlwNjRNb2RlLk5ldmVyKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UpOworICAgIH0KKworICAgIEBUZXN0IHB1YmxpYyB2b2lkIHdyaXRlU21hbGxTdG9yZWRFbnRyeUtub3duU2l6ZVRvRmlsZU1vZGVOZXZlcigpCisgICAgICAgIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICB3aXRoVGVtcG9yYXJ5QXJjaGl2ZSgid3JpdGVTbWFsbFN0b3JlZEVudHJ5S25vd25TaXplVG9GaWxlTW9kZU5ldmVyIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVTbWFsbFN0b3JlZEVudHJ5KHRydWUsIFppcDY0TW9kZS5OZXZlciksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUpOworICAgIH0KKworICAgIEBUZXN0IHB1YmxpYyB2b2lkIHdyaXRlU21hbGxTdG9yZWRFbnRyeVVubm93blNpemVUb0ZpbGVNb2RlTmV2ZXIoKQorICAgICAgICB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgd2l0aFRlbXBvcmFyeUFyY2hpdmUoIndyaXRlU21hbGxTdG9yZWRFbnRyeVVua25vd25TaXplVG9GaWxlTW9kZU5ldmVyIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVTbWFsbFN0b3JlZEVudHJ5KGZhbHNlLCBaaXA2NE1vZGUuTmV2ZXIpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIE9uZSBlbnRyeSBvZiBsZW5ndGggMSBtaWxsaW9uIGJ5dGVzLCB3cml0dGVuIHdpdGhvdXQgY29tcHJlc3Npb24uCisgICAgICoKKyAgICAgKiBObyBDb21wcmVzc2lvbiA9PiBzaXplcyBhcmUgc3RvcmVkIGRpcmVjdGx5IGluc2lkZSB0aGUgTEZILiAgTm8KKyAgICAgKiBEYXRhIERlc2NyaXB0b3IgYXQgYWxsLiBDb250YWlucyBaSVA2NCBleHRyYSBmaWVsZHMgYmVjYXVzZQorICAgICAqIG1vZGUgaXMgQWx3YXlzCisgICAgICoKKyAgICAgKiBDcmVhdGVzIGEgdGVtcG9yYXJ5IGFyY2hpdmUgb2YgYXBwcm94IDFNQiBpbiBzaXplCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgWmlwT3V0cHV0VGVzdAorICAgICAgICB3cml0ZVNtYWxsU3RvcmVkRW50cnlNb2RlQWx3YXlzKGZpbmFsIGJvb2xlYW4ga25vd25TaXplKSB7CisgICAgICAgIHJldHVybiBuZXcgWmlwT3V0cHV0VGVzdCgpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIHZvaWQgdGVzdChmaW5hbCBGaWxlIGYsIGZpbmFsIFppcEFyY2hpdmVPdXRwdXRTdHJlYW0gem9zKQorICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgem9zLnNldFVzZVppcDY0KFppcDY0TW9kZS5BbHdheXMpOworICAgICAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBidWYgPSBuZXcgYnl0ZVtPTkVfTUlMTElPTl07CisgICAgICAgICAgICAgICAgZmluYWwgWmlwQXJjaGl2ZUVudHJ5IHphZSA9IG5ldyBaaXBBcmNoaXZlRW50cnkoIjAiKTsKKyAgICAgICAgICAgICAgICBpZiAoa25vd25TaXplKSB7CisgICAgICAgICAgICAgICAgICAgIHphZS5zZXRTaXplKE9ORV9NSUxMSU9OKTsKKyAgICAgICAgICAgICAgICAgICAgemFlLnNldENyYygweDEyNzlDQjlFTCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHphZS5zZXRNZXRob2QoWmlwRW50cnkuU1RPUkVEKTsKKyAgICAgICAgICAgICAgICB6b3MucHV0QXJjaGl2ZUVudHJ5KHphZSk7CisgICAgICAgICAgICAgICAgem9zLndyaXRlKGJ1Zik7CisgICAgICAgICAgICAgICAgem9zLmNsb3NlQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgICAgICAgICAgem9zLmNsb3NlKCk7CisKKyAgICAgICAgICAgICAgICB0cnkgKFJhbmRvbUFjY2Vzc0ZpbGUgYSA9IG5ldyBSYW5kb21BY2Nlc3NGaWxlKGYsICJyIikpIHsKKyAgICAgICAgICAgICAgICAgICAgZ2V0TGVuZ3RoQW5kUG9zaXRpb25BdENlbnRyYWxEaXJlY3RvcnkoYSk7CisKKyAgICAgICAgICAgICAgICAgICAgLy8gZ3JhYiBmaXJzdCBDRiBlbnRyeSwgdmVyaWZ5IHNpemVzIGFyZSAxZTYgYW5kIGl0CisgICAgICAgICAgICAgICAgICAgIC8vIGhhcyBhbiBlbXB0eSBaSVA2NCBleHRlbmRlZCBpbmZvcm1hdGlvbiBleHRyYSBmaWVsZAorICAgICAgICAgICAgICAgICAgICBieXRlW10gaGVhZGVyID0gbmV3IGJ5dGVbMTJdOworICAgICAgICAgICAgICAgICAgICBhLnJlYWRGdWxseShoZWFkZXIpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRBcnJheUVxdWFscygiQ0RIIHN0YXJ0IiwgbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2lnCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpIDB4NTAsIChieXRlKSAweDRiLCAxLCAyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHZlcnNpb24gbWFkZSBieQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDQ1LCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHZlcnNpb24gbmVlZGVkIHRvIGV4dHJhY3QKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICA0NSwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBHUEIgKEVGUyBiaXQpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgOCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBtZXRob2QKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAwCisgICAgICAgICAgICAgICAgICAgIH0sIGhlYWRlcik7CisgICAgICAgICAgICAgICAgICAgIC8vIGlnbm9yZSB0aW1lc3RhbXAKKyAgICAgICAgICAgICAgICAgICAgYS5za2lwQnl0ZXMoNCk7CisgICAgICAgICAgICAgICAgICAgIGJ5dGVbXSByZXN0ID0gbmV3IGJ5dGVbMzFdOworICAgICAgICAgICAgICAgICAgICBhLnJlYWRGdWxseShyZXN0KTsKKyAgICAgICAgICAgICAgICAgICAgLy8gMWU2ID09IDB4RjQyNDAKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMoIkNESCByZXN0IiwgbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ1JDCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpIDB4OUUsIChieXRlKSAweENCLCAoYnl0ZSkgMHg3OSwgKGJ5dGUpIDB4MTIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ29tcHJlc3NlZCBTaXplCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpIDB4RkYsIChieXRlKSAweEZGLCAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4RkYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT3JpZ2luYWwgU2l6ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweEZGLCAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4RkYsIChieXRlKSAweEZGLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZpbGUgbmFtZSBsZW5ndGgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAxLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGV4dHJhIGZpZWxkIGxlbmd0aAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDI4LCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvbW1lbnQgbGVuZ3RoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBkaXNrIG51bWJlcgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYXR0cmlidXRlcworICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBvZmZzZXQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4RkYsIChieXRlKSAweEZGLCAoYnl0ZSkgMHhGRiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBmaWxlIG5hbWUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgJzAnCisgICAgICAgICAgICAgICAgICAgIH0sIHJlc3QpOworCisgICAgICAgICAgICAgICAgICAgIGJ5dGVbXSBleHRyYSA9IG5ldyBieXRlWzI4XTsKKyAgICAgICAgICAgICAgICAgICAgYS5yZWFkRnVsbHkoZXh0cmEpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRBcnJheUVxdWFscygiQ0RIIGV4dHJhIiwgbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSGVhZGVyLUlECisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMSwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzaXplIG9mIGV4dHJhCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMjQsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gb3JpZ2luYWwgc2l6ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweDQwLCAoYnl0ZSkgMHg0MiwgKGJ5dGUpIDB4MEYsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjb21wcmVzc2VkIHNpemUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgMHg0MCwgKGJ5dGUpIDB4NDIsIChieXRlKSAweDBGLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgfSwgZXh0cmEpOworCisgICAgICAgICAgICAgICAgICAgIC8vIGFuZCBub3cgdmFsaWRhdGUgbG9jYWwgZmlsZSBoZWFkZXI6IHRoaXMgb25lCisgICAgICAgICAgICAgICAgICAgIC8vIGhhcyBhIFpJUDY0IGV4dHJhIGZpZWxkIGFzIHRoZSBtb2RlIHdhcworICAgICAgICAgICAgICAgICAgICAvLyBBbHdheXMKKyAgICAgICAgICAgICAgICAgICAgYS5zZWVrKDApOworICAgICAgICAgICAgICAgICAgICBoZWFkZXIgPSBuZXcgYnl0ZVsxMF07CisgICAgICAgICAgICAgICAgICAgIGEucmVhZEZ1bGx5KGhlYWRlcik7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKCJMRkggc3RhcnQiLCBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzaWcKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgMHg1MCwgKGJ5dGUpIDB4NGIsIDMsIDQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdmVyc2lvbiBuZWVkZWQgdG8gZXh0cmFjdAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDQ1LCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEdQQiAoRUZTIGJpdCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCA4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1ldGhvZAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAKKyAgICAgICAgICAgICAgICAgICAgfSwgaGVhZGVyKTsKKyAgICAgICAgICAgICAgICAgICAgLy8gaWdub3JlIHRpbWVzdGFtcAorICAgICAgICAgICAgICAgICAgICBhLnNraXBCeXRlcyg0KTsKKyAgICAgICAgICAgICAgICAgICAgcmVzdCA9IG5ldyBieXRlWzE3XTsKKyAgICAgICAgICAgICAgICAgICAgYS5yZWFkRnVsbHkocmVzdCk7CisgICAgICAgICAgICAgICAgICAgIC8vIDFlNiA9PSAweEY0MjQwCisgICAgICAgICAgICAgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKCJMRkggcmVzdCIsIG5ldyBieXRlW10geworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENSQworICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweDlFLCAoYnl0ZSkgMHhDQiwgKGJ5dGUpIDB4NzksIChieXRlKSAweDEyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENvbXByZXNzZWQgU2l6ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweEZGLCAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4RkYsIChieXRlKSAweEZGLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9yaWdpbmFsIFNpemUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4RkYsIChieXRlKSAweEZGLCAoYnl0ZSkgMHhGRiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBmaWxlIG5hbWUgbGVuZ3RoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMSwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBleHRyYSBmaWVsZCBsZW5ndGgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAyMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBmaWxlIG5hbWUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgJzAnCisgICAgICAgICAgICAgICAgICAgIH0sIHJlc3QpOworCisgICAgICAgICAgICAgICAgICAgIGV4dHJhID0gbmV3IGJ5dGVbMjBdOworICAgICAgICAgICAgICAgICAgICBhLnJlYWRGdWxseShleHRyYSk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKCJMRkggZXh0cmEiLCBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBIZWFkZXItSUQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAxLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNpemUgb2YgZXh0cmEKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAxNiwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBvcmlnaW5hbCBzaXplCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpIDB4NDAsIChieXRlKSAweDQyLCAoYnl0ZSkgMHgwRiwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAwLCAwLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvbXByZXNzZWQgc2l6ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweDQwLCAoYnl0ZSkgMHg0MiwgKGJ5dGUpIDB4MEYsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgfSwgZXh0cmEpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICB9CisKKyAgICBAVGVzdCBwdWJsaWMgdm9pZCB3cml0ZVNtYWxsU3RvcmVkRW50cnlUb1N0cmVhbU1vZGVBbHdheXMoKQorICAgICAgICB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgd2l0aFRlbXBvcmFyeUFyY2hpdmUoIndyaXRlU21hbGxTdG9yZWRFbnRyeVRvU3RyZWFtTW9kZUFsd2F5cyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlU21hbGxTdG9yZWRFbnRyeU1vZGVBbHdheXModHJ1ZSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlKTsKKyAgICB9CisKKyAgICBAVGVzdCBwdWJsaWMgdm9pZCB3cml0ZVNtYWxsU3RvcmVkRW50cnlLbm93blNpemVUb0ZpbGVNb2RlQWx3YXlzKCkKKyAgICAgICAgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIHdpdGhUZW1wb3JhcnlBcmNoaXZlKCJ3cml0ZVNtYWxsU3RvcmVkRW50cnlLbm93blNpemVUb0ZpbGVNb2RlQWx3YXlzIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVTbWFsbFN0b3JlZEVudHJ5TW9kZUFsd2F5cyh0cnVlKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSk7CisgICAgfQorCisgICAgQFRlc3QgcHVibGljIHZvaWQgd3JpdGVTbWFsbFN0b3JlZEVudHJ5VW5ub3duU2l6ZVRvRmlsZU1vZGVBbHdheXMoKQorICAgICAgICB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgd2l0aFRlbXBvcmFyeUFyY2hpdmUoIndyaXRlU21hbGxTdG9yZWRFbnRyeVVua25vd25TaXplVG9GaWxlTW9kZUFsd2F5cyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlU21hbGxTdG9yZWRFbnRyeU1vZGVBbHdheXMoZmFsc2UpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIE9uZSBlbnRyeSBvZiBsZW5ndGggMSBtaWxsaW9uIGJ5dGVzLCB3cml0dGVuIHdpdGggY29tcHJlc3Npb24KKyAgICAgKiB0byBhIHN0cmVhbS4KKyAgICAgKgorICAgICAqIENvbXByZXNzaW9uICsgU3RyZWFtID0+IHNpemVzIGFyZSBzZXQgdG8gMCBpbiBMRkgsIHJlYWwgdmFsdWVzCisgICAgICogYXJlIGluc2lkZSB0aGUgZGF0YSBkZXNjcmlwdG9yLiAgTm8gWklQNjQgZXh0cmEgZmllbGQgYXQgYWxsLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIFppcE91dHB1dFRlc3QKKyAgICAgICAgd3JpdGVTbWFsbERlZmxhdGVkRW50cnlUb1N0cmVhbShmaW5hbCBib29sZWFuIGtub3duU2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBaaXA2NE1vZGUgbW9kZSkgeworICAgICAgICByZXR1cm4gbmV3IFppcE91dHB1dFRlc3QoKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHRlc3QoZmluYWwgRmlsZSBmLCBmaW5hbCBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtIHpvcykKKyAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgICAgIGlmIChtb2RlICE9IFppcDY0TW9kZS5Bc05lZWRlZCkgeworICAgICAgICAgICAgICAgICAgICB6b3Muc2V0VXNlWmlwNjQobW9kZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBidWYgPSBuZXcgYnl0ZVtPTkVfTUlMTElPTl07CisgICAgICAgICAgICAgICAgZmluYWwgWmlwQXJjaGl2ZUVudHJ5IHphZSA9IG5ldyBaaXBBcmNoaXZlRW50cnkoIjAiKTsKKyAgICAgICAgICAgICAgICBpZiAoa25vd25TaXplKSB7CisgICAgICAgICAgICAgICAgICAgIHphZS5zZXRTaXplKE9ORV9NSUxMSU9OKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgemFlLnNldE1ldGhvZChaaXBFbnRyeS5ERUZMQVRFRCk7CisgICAgICAgICAgICAgICAgem9zLnB1dEFyY2hpdmVFbnRyeSh6YWUpOworICAgICAgICAgICAgICAgIHpvcy53cml0ZShidWYpOworICAgICAgICAgICAgICAgIHpvcy5jbG9zZUFyY2hpdmVFbnRyeSgpOworICAgICAgICAgICAgICAgIHpvcy5jbG9zZSgpOworCisgICAgICAgICAgICAgICAgdHJ5IChSYW5kb21BY2Nlc3NGaWxlIGEgPSBuZXcgUmFuZG9tQWNjZXNzRmlsZShmLCAiciIpKSB7CisgICAgICAgICAgICAgICAgICAgIGdldExlbmd0aEFuZFBvc2l0aW9uQXRDZW50cmFsRGlyZWN0b3J5KGEpOworCisgICAgICAgICAgICAgICAgICAgIGZpbmFsIGxvbmcgY2ZoUG9zID0gYS5nZXRGaWxlUG9pbnRlcigpOworICAgICAgICAgICAgICAgICAgICAvLyBncmFiIGZpcnN0IGVudHJ5LCB2ZXJpZnkgc2l6ZXMgYXJlIG5vdAorICAgICAgICAgICAgICAgICAgICAvLyAweEZGRkZGRkYgYW5kIGl0IGhhcyBubyBaSVA2NCBleHRlbmRlZAorICAgICAgICAgICAgICAgICAgICAvLyBpbmZvcm1hdGlvbiBleHRyYSBmaWVsZAorICAgICAgICAgICAgICAgICAgICBieXRlW10gaGVhZGVyID0gbmV3IGJ5dGVbMTJdOworICAgICAgICAgICAgICAgICAgICBhLnJlYWRGdWxseShoZWFkZXIpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRBcnJheUVxdWFscyhuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzaWcKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgMHg1MCwgKGJ5dGUpIDB4NGIsIDEsIDIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdmVyc2lvbiBtYWRlIGJ5CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMjAsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdmVyc2lvbiBuZWVkZWQgdG8gZXh0cmFjdAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDIwLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEdQQiAoRUZTICsgRGF0YSBEZXNjcmlwdG9yKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDgsIDgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbWV0aG9kCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgOCwgMCwKKyAgICAgICAgICAgICAgICAgICAgfSwgaGVhZGVyKTsKKyAgICAgICAgICAgICAgICAgICAgLy8gaWdub3JlIHRpbWVzdGFtcAorICAgICAgICAgICAgICAgICAgICBhLnNraXBCeXRlcyg0KTsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgYnl0ZVtdIGNyYyA9IG5ldyBieXRlWzRdOworICAgICAgICAgICAgICAgICAgICBhLnJlYWRGdWxseShjcmMpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRBcnJheUVxdWFscyhuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgMHg5RSwgKGJ5dGUpIDB4Q0IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpIDB4NzksIChieXRlKSAweDEyLAorICAgICAgICAgICAgICAgICAgICB9LCBjcmMpOworICAgICAgICAgICAgICAgICAgICAvLyBza2lwIGNvbXByZXNzZWQgc2l6ZQorICAgICAgICAgICAgICAgICAgICBhLnNraXBCeXRlcyg0KTsKKyAgICAgICAgICAgICAgICAgICAgYnl0ZVtdIHJlc3QgPSBuZXcgYnl0ZVsyM107CisgICAgICAgICAgICAgICAgICAgIGEucmVhZEZ1bGx5KHJlc3QpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRBcnJheUVxdWFscyhuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPcmlnaW5hbCBTaXplCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpIDB4NDAsIChieXRlKSAweDQyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweDBGLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZpbGUgbmFtZSBsZW5ndGgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAxLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGV4dHJhIGZpZWxkIGxlbmd0aAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY29tbWVudCBsZW5ndGgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGRpc2sgbnVtYmVyCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhdHRyaWJ1dGVzCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAwLCAwLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG9mZnNldAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZmlsZSBuYW1lCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpICcwJworICAgICAgICAgICAgICAgICAgICB9LCByZXN0KTsKKworICAgICAgICAgICAgICAgICAgICAvLyB2YWxpZGF0ZSBkYXRhIGRlc2NyaXB0b3IKKyAgICAgICAgICAgICAgICAgICAgYS5zZWVrKGNmaFBvcyAtIDE2KTsKKyAgICAgICAgICAgICAgICAgICAgYnl0ZVtdIGRkID0gbmV3IGJ5dGVbOF07CisgICAgICAgICAgICAgICAgICAgIGEucmVhZEZ1bGx5KGRkKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMobmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2lnCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpIDB4NTAsIChieXRlKSAweDRiLCA3LCA4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENSQworICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweDlFLCAoYnl0ZSkgMHhDQiwgKGJ5dGUpIDB4NzksIChieXRlKSAweDEyLAorICAgICAgICAgICAgICAgICAgICB9LCBkZCk7CisgICAgICAgICAgICAgICAgICAgIC8vIHNraXAgdW5jb21wcmVzc2VkIHNpemUKKyAgICAgICAgICAgICAgICAgICAgYS5za2lwQnl0ZXMoNCk7CisgICAgICAgICAgICAgICAgICAgIGRkID0gbmV3IGJ5dGVbNF07CisgICAgICAgICAgICAgICAgICAgIGEucmVhZEZ1bGx5KGRkKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMobmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gb3JpZ2luYWwgc2l6ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweDQwLCAoYnl0ZSkgMHg0MiwgKGJ5dGUpIDB4MEYsIDAsCisgICAgICAgICAgICAgICAgICAgIH0sIGRkKTsKKworICAgICAgICAgICAgICAgICAgICAvLyBhbmQgbm93IHZhbGlkYXRlIGxvY2FsIGZpbGUgaGVhZGVyCisgICAgICAgICAgICAgICAgICAgIGEuc2VlaygwKTsKKyAgICAgICAgICAgICAgICAgICAgaGVhZGVyID0gbmV3IGJ5dGVbMTBdOworICAgICAgICAgICAgICAgICAgICBhLnJlYWRGdWxseShoZWFkZXIpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRBcnJheUVxdWFscyhuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzaWcKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgMHg1MCwgKGJ5dGUpIDB4NGIsIDMsIDQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdmVyc2lvbiBuZWVkZWQgdG8gZXh0cmFjdAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDIwLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEdQQiAoRUZTICsgRGF0YSBEZXNjcmlwdG9yKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDgsIDgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbWV0aG9kCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgOCwgMCwKKyAgICAgICAgICAgICAgICAgICAgfSwgaGVhZGVyKTsKKyAgICAgICAgICAgICAgICAgICAgLy8gaWdub3JlIHRpbWVzdGFtcAorICAgICAgICAgICAgICAgICAgICBhLnNraXBCeXRlcyg0KTsKKyAgICAgICAgICAgICAgICAgICAgcmVzdCA9IG5ldyBieXRlWzE3XTsKKyAgICAgICAgICAgICAgICAgICAgYS5yZWFkRnVsbHkocmVzdCk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKG5ldyBieXRlW10geworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENSQworICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ29tcHJlc3NlZCBTaXplCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPcmlnaW5hbCBTaXplCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBmaWxlIG5hbWUgbGVuZ3RoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMSwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBleHRyYSBmaWVsZCBsZW5ndGgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZpbGUgbmFtZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAnMCcKKyAgICAgICAgICAgICAgICAgICAgfSwgcmVzdCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9OworCisgICAgfQorCisgICAgQFRlc3QgcHVibGljIHZvaWQgd3JpdGVTbWFsbERlZmxhdGVkRW50cnlLbm93blNpemVUb1N0cmVhbSgpCisgICAgICAgIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICB3aXRoVGVtcG9yYXJ5QXJjaGl2ZSgid3JpdGVTbWFsbERlZmxhdGVkRW50cnlLbm93blNpemVUb1N0cmVhbSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlU21hbGxEZWZsYXRlZEVudHJ5VG9TdHJlYW0odHJ1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBaaXA2NE1vZGUuQXNOZWVkZWQpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSk7CisgICAgfQorCisgICAgQFRlc3QgcHVibGljIHZvaWQgd3JpdGVTbWFsbERlZmxhdGVkRW50cnlLbm93blNpemVUb1N0cmVhbU1vZGVOZXZlcigpCisgICAgICAgIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICB3aXRoVGVtcG9yYXJ5QXJjaGl2ZSgid3JpdGVTbWFsbERlZmxhdGVkRW50cnlLbm93blNpemVUb1N0cmVhbU1vZGVOZXZlciIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlU21hbGxEZWZsYXRlZEVudHJ5VG9TdHJlYW0odHJ1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBaaXA2NE1vZGUuTmV2ZXIpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSk7CisgICAgfQorCisgICAgQFRlc3QgcHVibGljIHZvaWQgd3JpdGVTbWFsbERlZmxhdGVkRW50cnlVbmtub3duU2l6ZVRvU3RyZWFtKCkKKyAgICAgICAgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIHdpdGhUZW1wb3JhcnlBcmNoaXZlKCJ3cml0ZVNtYWxsRGVmbGF0ZWRFbnRyeVVua25vd25TaXplVG9TdHJlYW0iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cml0ZVNtYWxsRGVmbGF0ZWRFbnRyeVRvU3RyZWFtKGZhbHNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFppcDY0TW9kZS5Bc05lZWRlZCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlKTsKKyAgICB9CisKKyAgICBAVGVzdCBwdWJsaWMgdm9pZCB3cml0ZVNtYWxsRGVmbGF0ZWRFbnRyeVVua25vd25TaXplVG9TdHJlYW1Nb2RlTmV2ZXIoKQorICAgICAgICB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgd2l0aFRlbXBvcmFyeUFyY2hpdmUoIndyaXRlU21hbGxEZWZsYXRlZEVudHJ5VW5rbm93blNpemVUb1N0cmVhbU1vZGVOZXZlciIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlU21hbGxEZWZsYXRlZEVudHJ5VG9TdHJlYW0oZmFsc2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWmlwNjRNb2RlLk5ldmVyKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UpOworICAgIH0KKworICAgIC8qCisgICAgICogT25lIGVudHJ5IG9mIGxlbmd0aCAxIG1pbGxpb24gYnl0ZXMsIHdyaXR0ZW4gd2l0aCBjb21wcmVzc2lvbgorICAgICAqIHRvIGEgc3RyZWFtLgorICAgICAqCisgICAgICogQ29tcHJlc3Npb24gKyBTdHJlYW0gPT4gc2l6ZXMgYXJlIHNldCB0byAwIGluIExGSCwgcmVhbCB2YWx1ZXMKKyAgICAgKiBhcmUgaW5zaWRlIHRoZSBkYXRhIGRlc2NyaXB0b3IuICBaSVA2NCBleHRyYSBmaWVsZCBhcyBtb2RlIGlzIEFsd2F5cy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBaaXBPdXRwdXRUZXN0CisgICAgICAgIHdyaXRlU21hbGxEZWZsYXRlZEVudHJ5VG9TdHJlYW1Nb2RlQWx3YXlzKGZpbmFsIGJvb2xlYW4ga25vd25TaXplKSB7CisgICAgICAgIHJldHVybiBuZXcgWmlwT3V0cHV0VGVzdCgpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIHZvaWQgdGVzdChmaW5hbCBGaWxlIGYsIGZpbmFsIFppcEFyY2hpdmVPdXRwdXRTdHJlYW0gem9zKQorICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgem9zLnNldFVzZVppcDY0KFppcDY0TW9kZS5BbHdheXMpOworICAgICAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBidWYgPSBuZXcgYnl0ZVtPTkVfTUlMTElPTl07CisgICAgICAgICAgICAgICAgZmluYWwgWmlwQXJjaGl2ZUVudHJ5IHphZSA9IG5ldyBaaXBBcmNoaXZlRW50cnkoIjAiKTsKKyAgICAgICAgICAgICAgICBpZiAoa25vd25TaXplKSB7CisgICAgICAgICAgICAgICAgICAgIHphZS5zZXRTaXplKE9ORV9NSUxMSU9OKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgemFlLnNldE1ldGhvZChaaXBFbnRyeS5ERUZMQVRFRCk7CisgICAgICAgICAgICAgICAgem9zLnB1dEFyY2hpdmVFbnRyeSh6YWUpOworICAgICAgICAgICAgICAgIHpvcy53cml0ZShidWYpOworICAgICAgICAgICAgICAgIHpvcy5jbG9zZUFyY2hpdmVFbnRyeSgpOworICAgICAgICAgICAgICAgIHpvcy5jbG9zZSgpOworCisgICAgICAgICAgICAgICAgdHJ5IChSYW5kb21BY2Nlc3NGaWxlIGEgPSBuZXcgUmFuZG9tQWNjZXNzRmlsZShmLCAiciIpKSB7CisgICAgICAgICAgICAgICAgICAgIGdldExlbmd0aEFuZFBvc2l0aW9uQXRDZW50cmFsRGlyZWN0b3J5KGEpOworCisgICAgICAgICAgICAgICAgICAgIGZpbmFsIGxvbmcgY2ZoUG9zID0gYS5nZXRGaWxlUG9pbnRlcigpOworICAgICAgICAgICAgICAgICAgICAvLyBncmFiIGZpcnN0IGVudHJ5LCB2ZXJpZnkgc2l6ZXMgYXJlIG5vdAorICAgICAgICAgICAgICAgICAgICAvLyAweEZGRkZGRkYgYW5kIGl0IGhhcyBhbiBlbXB0eSBaSVA2NCBleHRlbmRlZAorICAgICAgICAgICAgICAgICAgICAvLyBpbmZvcm1hdGlvbiBleHRyYSBmaWVsZAorICAgICAgICAgICAgICAgICAgICBieXRlW10gaGVhZGVyID0gbmV3IGJ5dGVbMTJdOworICAgICAgICAgICAgICAgICAgICBhLnJlYWRGdWxseShoZWFkZXIpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRBcnJheUVxdWFscygiQ0RIIHN0YXJ0IiwgbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2lnCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpIDB4NTAsIChieXRlKSAweDRiLCAxLCAyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHZlcnNpb24gbWFkZSBieQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDQ1LCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHZlcnNpb24gbmVlZGVkIHRvIGV4dHJhY3QKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICA0NSwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBHUEIgKEVGUyArIERhdGEgRGVzY3JpcHRvcikKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICA4LCA4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1ldGhvZAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDgsIDAsCisgICAgICAgICAgICAgICAgICAgIH0sIGhlYWRlcik7CisgICAgICAgICAgICAgICAgICAgIC8vIGlnbm9yZSB0aW1lc3RhbXAKKyAgICAgICAgICAgICAgICAgICAgYS5za2lwQnl0ZXMoNCk7CisgICAgICAgICAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBjcmMgPSBuZXcgYnl0ZVs0XTsKKyAgICAgICAgICAgICAgICAgICAgYS5yZWFkRnVsbHkoY3JjKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMobmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpIDB4OUUsIChieXRlKSAweENCLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweDc5LCAoYnl0ZSkgMHgxMiwKKyAgICAgICAgICAgICAgICAgICAgfSwgY3JjKTsKKyAgICAgICAgICAgICAgICAgICAgLy8gc2tpcCBjb21wcmVzc2VkIHNpemUKKyAgICAgICAgICAgICAgICAgICAgYS5za2lwQnl0ZXMoNCk7CisgICAgICAgICAgICAgICAgICAgIGJ5dGVbXSByZXN0ID0gbmV3IGJ5dGVbMjNdOworICAgICAgICAgICAgICAgICAgICBhLnJlYWRGdWxseShyZXN0KTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMoIkNESCByZXN0IiwgbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT3JpZ2luYWwgU2l6ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweEZGLCAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4RkYsIChieXRlKSAweEZGLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZpbGUgbmFtZSBsZW5ndGgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAxLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGV4dHJhIGZpZWxkIGxlbmd0aAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDI4LCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvbW1lbnQgbGVuZ3RoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBkaXNrIG51bWJlcgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYXR0cmlidXRlcworICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBvZmZzZXQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4RkYsIChieXRlKSAweEZGLCAoYnl0ZSkgMHhGRiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBmaWxlIG5hbWUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgJzAnCisgICAgICAgICAgICAgICAgICAgIH0sIHJlc3QpOworICAgICAgICAgICAgICAgICAgICBieXRlW10gZXh0cmEgPSBuZXcgYnl0ZVsxMl07CisgICAgICAgICAgICAgICAgICAgIGEucmVhZEZ1bGx5KGV4dHJhKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMoIkNESCBleHRyYSIsIG5ldyBieXRlW10geworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEhlYWRlci1JRAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2l6ZSBvZiBleHRyYQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDI0LCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG9yaWdpbmFsIHNpemUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgMHg0MCwgKGJ5dGUpIDB4NDIsIChieXRlKSAweDBGLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAgICAgICAgIH0sIGV4dHJhKTsKKyAgICAgICAgICAgICAgICAgICAgLy8gc2tpcCBjb21wcmVzc2VkIHNpemUKKyAgICAgICAgICAgICAgICAgICAgYS5za2lwQnl0ZXMoOCk7CisgICAgICAgICAgICAgICAgICAgIGJ5dGVbXSBvZmZzZXQgPSBuZXcgYnl0ZVs4XTsKKyAgICAgICAgICAgICAgICAgICAgYS5yZWFkRnVsbHkob2Zmc2V0KTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMoImV4dHJhIG9mZnNldCIsIG5ldyBieXRlW10geworICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICB9LCBvZmZzZXQpOworCisgICAgICAgICAgICAgICAgICAgIC8vIHZhbGlkYXRlIGRhdGEgZGVzY3JpcHRvcgorICAgICAgICAgICAgICAgICAgICBhLnNlZWsoY2ZoUG9zIC0gMjQpOworICAgICAgICAgICAgICAgICAgICBieXRlW10gZGQgPSBuZXcgYnl0ZVs4XTsKKyAgICAgICAgICAgICAgICAgICAgYS5yZWFkRnVsbHkoZGQpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRBcnJheUVxdWFscygiREQiLCBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzaWcKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgMHg1MCwgKGJ5dGUpIDB4NGIsIDcsIDgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ1JDCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpIDB4OUUsIChieXRlKSAweENCLCAoYnl0ZSkgMHg3OSwgKGJ5dGUpIDB4MTIsCisgICAgICAgICAgICAgICAgICAgIH0sIGRkKTsKKyAgICAgICAgICAgICAgICAgICAgLy8gc2tpcCBjb21wcmVzc2VkIHNpemUKKyAgICAgICAgICAgICAgICAgICAgYS5za2lwQnl0ZXMoOCk7CisgICAgICAgICAgICAgICAgICAgIGRkID0gbmV3IGJ5dGVbOF07CisgICAgICAgICAgICAgICAgICAgIGEucmVhZEZ1bGx5KGRkKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMoIkREIHNpemUiLCBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBvcmlnaW5hbCBzaXplCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpIDB4NDAsIChieXRlKSAweDQyLCAoYnl0ZSkgMHgwRiwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAwLCAwLCAwCisgICAgICAgICAgICAgICAgICAgIH0sIGRkKTsKKworICAgICAgICAgICAgICAgICAgICAvLyBhbmQgbm93IHZhbGlkYXRlIGxvY2FsIGZpbGUgaGVhZGVyCisgICAgICAgICAgICAgICAgICAgIGEuc2VlaygwKTsKKyAgICAgICAgICAgICAgICAgICAgaGVhZGVyID0gbmV3IGJ5dGVbMTBdOworICAgICAgICAgICAgICAgICAgICBhLnJlYWRGdWxseShoZWFkZXIpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRBcnJheUVxdWFscygiTEZIIHN0YXJ0IiwgbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2lnCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpIDB4NTAsIChieXRlKSAweDRiLCAzLCA0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHZlcnNpb24gbmVlZGVkIHRvIGV4dHJhY3QKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICA0NSwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBHUEIgKEVGUyArIERhdGEgRGVzY3JpcHRvcikKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICA4LCA4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1ldGhvZAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDgsIDAsCisgICAgICAgICAgICAgICAgICAgIH0sIGhlYWRlcik7CisgICAgICAgICAgICAgICAgICAgIC8vIGlnbm9yZSB0aW1lc3RhbXAKKyAgICAgICAgICAgICAgICAgICAgYS5za2lwQnl0ZXMoNCk7CisgICAgICAgICAgICAgICAgICAgIHJlc3QgPSBuZXcgYnl0ZVsxN107CisgICAgICAgICAgICAgICAgICAgIGEucmVhZEZ1bGx5KHJlc3QpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRBcnJheUVxdWFscygiTEZIIHJlc3QiLCBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBDUkMKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAwLCAwLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENvbXByZXNzZWQgU2l6ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweEZGLCAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4RkYsIChieXRlKSAweEZGLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9yaWdpbmFsIFNpemUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4RkYsIChieXRlKSAweEZGLCAoYnl0ZSkgMHhGRiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBmaWxlIG5hbWUgbGVuZ3RoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMSwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBleHRyYSBmaWVsZCBsZW5ndGgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAyMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBmaWxlIG5hbWUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgJzAnCisgICAgICAgICAgICAgICAgICAgIH0sIHJlc3QpOworCisgICAgICAgICAgICAgICAgICAgIGV4dHJhID0gbmV3IGJ5dGVbMjBdOworICAgICAgICAgICAgICAgICAgICBhLnJlYWRGdWxseShleHRyYSk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKCJMRkggZXh0cmEiLCBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBIZWFkZXItSUQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAxLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNpemUgb2YgZXh0cmEKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAxNiwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBvcmlnaW5hbCBzaXplCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAwLCAwLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvbXByZXNzZWQgc2l6ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgfSwgZXh0cmEpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgIH0KKworICAgIEBUZXN0IHB1YmxpYyB2b2lkIHdyaXRlU21hbGxEZWZsYXRlZEVudHJ5S25vd25TaXplVG9TdHJlYW1Nb2RlQWx3YXlzKCkKKyAgICAgICAgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIHdpdGhUZW1wb3JhcnlBcmNoaXZlKCJ3cml0ZVNtYWxsRGVmbGF0ZWRFbnRyeUtub3duU2l6ZVRvU3RyZWFtTW9kZUFsd2F5cyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlU21hbGxEZWZsYXRlZEVudHJ5VG9TdHJlYW1Nb2RlQWx3YXlzKHRydWUpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSk7CisgICAgfQorCisgICAgQFRlc3QgcHVibGljIHZvaWQgd3JpdGVTbWFsbERlZmxhdGVkRW50cnlVbmtub3duU2l6ZVRvU3RyZWFtTW9kZUFsd2F5cygpCisgICAgICAgIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICB3aXRoVGVtcG9yYXJ5QXJjaGl2ZSgid3JpdGVTbWFsbERlZmxhdGVkRW50cnlVbmtub3duU2l6ZVRvU3RyZWFtTW9kZUFsd2F5cyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlU21hbGxEZWZsYXRlZEVudHJ5VG9TdHJlYW1Nb2RlQWx3YXlzKGZhbHNlKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIFppcE91dHB1dFRlc3Qgd3JpdGVTbWFsbERlZmxhdGVkRW50cnlUb0ZpbGUoZmluYWwgYm9vbGVhbiBrbm93blNpemUpIHsKKyAgICAgICAgcmV0dXJuIHdyaXRlU21hbGxEZWZsYXRlZEVudHJ5VG9GaWxlKGtub3duU2l6ZSwgWmlwNjRNb2RlLkFzTmVlZGVkKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIE9uZSBlbnRyeSBvZiBsZW5ndGggMSBtaWxsaW9uIGJ5dGVzLCB3cml0dGVuIHdpdGggY29tcHJlc3Npb24KKyAgICAgKiB0byBhIGZpbGUuCisgICAgICoKKyAgICAgKiBXcml0aW5nIHRvIGEgZmlsZSA9PiBzaXplcyBhcmUgc3RvcmVkIGRpcmVjdGx5IGluc2lkZSB0aGUgTEZILgorICAgICAqIE5vIERhdGEgRGVzY3JpcHRvciBhdCBhbGwuICBTaG91bGRuJ3QgY29udGFpbiBhbnkgWklQNjQgZXh0cmEKKyAgICAgKiBmaWVsZCBpZiBzaXplIHdhcyBrbm93bi4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBaaXBPdXRwdXRUZXN0CisgICAgICAgIHdyaXRlU21hbGxEZWZsYXRlZEVudHJ5VG9GaWxlKGZpbmFsIGJvb2xlYW4ga25vd25TaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBaaXA2NE1vZGUgbW9kZSkgeworICAgICAgICByZXR1cm4gbmV3IFppcE91dHB1dFRlc3QoKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHRlc3QoZmluYWwgRmlsZSBmLCBmaW5hbCBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtIHpvcykKKyAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgICAgIGlmIChtb2RlICE9IFppcDY0TW9kZS5Bc05lZWRlZCkgeworICAgICAgICAgICAgICAgICAgICB6b3Muc2V0VXNlWmlwNjQobW9kZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBidWYgPSBuZXcgYnl0ZVtPTkVfTUlMTElPTl07CisgICAgICAgICAgICAgICAgZmluYWwgWmlwQXJjaGl2ZUVudHJ5IHphZSA9IG5ldyBaaXBBcmNoaXZlRW50cnkoIjAiKTsKKyAgICAgICAgICAgICAgICBpZiAoa25vd25TaXplKSB7CisgICAgICAgICAgICAgICAgICAgIHphZS5zZXRTaXplKE9ORV9NSUxMSU9OKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgemFlLnNldE1ldGhvZChaaXBFbnRyeS5ERUZMQVRFRCk7CisgICAgICAgICAgICAgICAgem9zLnB1dEFyY2hpdmVFbnRyeSh6YWUpOworICAgICAgICAgICAgICAgIHpvcy53cml0ZShidWYpOworICAgICAgICAgICAgICAgIHpvcy5jbG9zZUFyY2hpdmVFbnRyeSgpOworICAgICAgICAgICAgICAgIHpvcy5jbG9zZSgpOworCisgICAgICAgICAgICAgICAgdHJ5IChSYW5kb21BY2Nlc3NGaWxlIGEgPSBuZXcgUmFuZG9tQWNjZXNzRmlsZShmLCAiciIpKSB7CisgICAgICAgICAgICAgICAgICAgIGdldExlbmd0aEFuZFBvc2l0aW9uQXRDZW50cmFsRGlyZWN0b3J5KGEpOworCisgICAgICAgICAgICAgICAgICAgIC8vIGdyYWIgZmlyc3QgQ0QgZW50cnksIHZlcmlmeSBzaXplcyBhcmUgbm90CisgICAgICAgICAgICAgICAgICAgIC8vIDB4RkZGRkZGRkYgYW5kIGl0IGhhcyBhIG5vIFpJUDY0IGV4dGVuZGVkCisgICAgICAgICAgICAgICAgICAgIC8vIGluZm9ybWF0aW9uIGV4dHJhIGZpZWxkCisgICAgICAgICAgICAgICAgICAgIGJ5dGVbXSBoZWFkZXIgPSBuZXcgYnl0ZVsxMl07CisgICAgICAgICAgICAgICAgICAgIGEucmVhZEZ1bGx5KGhlYWRlcik7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKG5ldyBieXRlW10geworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNpZworICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweDUwLCAoYnl0ZSkgMHg0YiwgMSwgMiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB2ZXJzaW9uIG1hZGUgYnkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAyMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB2ZXJzaW9uIG5lZWRlZCB0byBleHRyYWN0CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMjAsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gR1BCIChFRlMgKyAqbm8qIERhdGEgRGVzY3JpcHRvcikKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCA4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1ldGhvZAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDgsIDAsCisgICAgICAgICAgICAgICAgICAgIH0sIGhlYWRlcik7CisgICAgICAgICAgICAgICAgICAgIC8vIGlnbm9yZSB0aW1lc3RhbXAKKyAgICAgICAgICAgICAgICAgICAgYS5za2lwQnl0ZXMoNCk7CisgICAgICAgICAgICAgICAgICAgIGJ5dGVbXSBjcmMgPSBuZXcgYnl0ZVs0XTsKKyAgICAgICAgICAgICAgICAgICAgYS5yZWFkRnVsbHkoY3JjKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMobmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpIDB4OUUsIChieXRlKSAweENCLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweDc5LCAoYnl0ZSkgMHgxMiwKKyAgICAgICAgICAgICAgICAgICAgfSwgY3JjKTsKKyAgICAgICAgICAgICAgICAgICAgLy8gc2tpcCBjb21wcmVzc2VkIHNpemUKKyAgICAgICAgICAgICAgICAgICAgYS5za2lwQnl0ZXMoNCk7CisgICAgICAgICAgICAgICAgICAgIGJ5dGVbXSByZXN0ID0gbmV3IGJ5dGVbMjNdOworICAgICAgICAgICAgICAgICAgICBhLnJlYWRGdWxseShyZXN0KTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMobmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT3JpZ2luYWwgU2l6ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweDQwLCAoYnl0ZSkgMHg0MiwgKGJ5dGUpIDB4MEYsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZmlsZSBuYW1lIGxlbmd0aAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZXh0cmEgZmllbGQgbGVuZ3RoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjb21tZW50IGxlbmd0aAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZGlzayBudW1iZXIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGF0dHJpYnV0ZXMKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gb2Zmc2V0CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBmaWxlIG5hbWUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgJzAnCisgICAgICAgICAgICAgICAgICAgIH0sIHJlc3QpOworCisgICAgICAgICAgICAgICAgICAgIC8vIGFuZCBub3cgdmFsaWRhdGUgbG9jYWwgZmlsZSBoZWFkZXIKKyAgICAgICAgICAgICAgICAgICAgYS5zZWVrKDApOworICAgICAgICAgICAgICAgICAgICBoZWFkZXIgPSBuZXcgYnl0ZVsxMF07CisgICAgICAgICAgICAgICAgICAgIGEucmVhZEZ1bGx5KGhlYWRlcik7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKG5ldyBieXRlW10geworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNpZworICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweDUwLCAoYnl0ZSkgMHg0YiwgMywgNCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB2ZXJzaW9uIG5lZWRlZCB0byBleHRyYWN0CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMjAsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gR1BCIChFRlMgYml0LCBubyBERCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCA4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1ldGhvZAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDgsIDAsCisgICAgICAgICAgICAgICAgICAgIH0sIGhlYWRlcik7CisgICAgICAgICAgICAgICAgICAgIC8vIGlnbm9yZSB0aW1lc3RhbXAKKyAgICAgICAgICAgICAgICAgICAgYS5za2lwQnl0ZXMoNCk7CisgICAgICAgICAgICAgICAgICAgIGNyYyA9IG5ldyBieXRlWzRdOworICAgICAgICAgICAgICAgICAgICBhLnJlYWRGdWxseShjcmMpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRBcnJheUVxdWFscyhuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgMHg5RSwgKGJ5dGUpIDB4Q0IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpIDB4NzksIChieXRlKSAweDEyLAorICAgICAgICAgICAgICAgICAgICB9LCBjcmMpOworICAgICAgICAgICAgICAgICAgICAvLyBza2lwIGNvbXByZXNzZWQgc2l6ZQorICAgICAgICAgICAgICAgICAgICBhLnNraXBCeXRlcyg0KTsKKyAgICAgICAgICAgICAgICAgICAgcmVzdCA9IG5ldyBieXRlWzldOworICAgICAgICAgICAgICAgICAgICBhLnJlYWRGdWxseShyZXN0KTsKKworICAgICAgICAgICAgICAgICAgICBmaW5hbCBib29sZWFuIGhhc0V4dHJhID0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2RlID09IFppcDY0TW9kZS5Bc05lZWRlZCAmJiAha25vd25TaXplOworCisgICAgICAgICAgICAgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKG5ldyBieXRlW10geworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9yaWdpbmFsIFNpemUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgMHg0MCwgKGJ5dGUpIDB4NDIsIChieXRlKSAweDBGLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZpbGUgbmFtZSBsZW5ndGgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAxLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGV4dHJhIGZpZWxkIGxlbmd0aAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAoIWhhc0V4dHJhID8gMCA6IDIwKSwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBmaWxlIG5hbWUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgJzAnCisgICAgICAgICAgICAgICAgICAgIH0sIHJlc3QpOworICAgICAgICAgICAgICAgICAgICBpZiAoaGFzRXh0cmEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBleHRyYSA9IG5ldyBieXRlWzEyXTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGEucmVhZEZ1bGx5KGV4dHJhKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKG5ldyBieXRlW10geworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBIZWFkZXItSUQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMSwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2l6ZSBvZiBleHRyYQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxNiwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gb3JpZ2luYWwgc2l6ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgMHg0MCwgKGJ5dGUpIDB4NDIsIChieXRlKSAweDBGLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAwLCAwLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBkb24ndCBrbm93IHRoZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjb21wcmVzc2VkIHNpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGRvbid0IHdhbnQgdG8KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaGFyZC1jb2RlIGl0CisgICAgICAgICAgICAgICAgICAgICAgICB9LCBleHRyYSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH07CisgICAgfQorCisgICAgQFRlc3QgcHVibGljIHZvaWQgd3JpdGVTbWFsbERlZmxhdGVkRW50cnlLbm93blNpemVUb0ZpbGUoKQorICAgICAgICB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgd2l0aFRlbXBvcmFyeUFyY2hpdmUoIndyaXRlU21hbGxEZWZsYXRlZEVudHJ5S25vd25TaXplVG9GaWxlIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVTbWFsbERlZmxhdGVkRW50cnlUb0ZpbGUodHJ1ZSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUpOworICAgIH0KKworICAgIEBUZXN0IHB1YmxpYyB2b2lkIHdyaXRlU21hbGxEZWZsYXRlZEVudHJ5VW5rbm93blNpemVUb0ZpbGUoKQorICAgICAgICB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgd2l0aFRlbXBvcmFyeUFyY2hpdmUoIndyaXRlU21hbGxEZWZsYXRlZEVudHJ5VW5rbm93blNpemVUb0ZpbGUiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cml0ZVNtYWxsRGVmbGF0ZWRFbnRyeVRvRmlsZShmYWxzZSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUpOworICAgIH0KKworICAgIEBUZXN0IHB1YmxpYyB2b2lkIHdyaXRlU21hbGxEZWZsYXRlZEVudHJ5S25vd25TaXplVG9GaWxlTW9kZU5ldmVyKCkKKyAgICAgICAgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIHdpdGhUZW1wb3JhcnlBcmNoaXZlKCJ3cml0ZVNtYWxsRGVmbGF0ZWRFbnRyeUtub3duU2l6ZVRvRmlsZU1vZGVOZXZlciIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlU21hbGxEZWZsYXRlZEVudHJ5VG9GaWxlKHRydWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFppcDY0TW9kZS5OZXZlciksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUpOworICAgIH0KKworICAgIEBUZXN0IHB1YmxpYyB2b2lkIHdyaXRlU21hbGxEZWZsYXRlZEVudHJ5VW5rbm93blNpemVUb0ZpbGVNb2RlTmV2ZXIoKQorICAgICAgICB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgd2l0aFRlbXBvcmFyeUFyY2hpdmUoIndyaXRlU21hbGxEZWZsYXRlZEVudHJ5VW5rbm93blNpemVUb0ZpbGVNb2RlTmV2ZXIiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cml0ZVNtYWxsRGVmbGF0ZWRFbnRyeVRvRmlsZShmYWxzZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWmlwNjRNb2RlLk5ldmVyKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBPbmUgZW50cnkgb2YgbGVuZ3RoIDEgbWlsbGlvbiBieXRlcywgd3JpdHRlbiB3aXRoIGNvbXByZXNzaW9uCisgICAgICogdG8gYSBmaWxlLgorICAgICAqCisgICAgICogV3JpdGluZyB0byBhIGZpbGUgPT4gc2l6ZXMgYXJlIHN0b3JlZCBkaXJlY3RseSBpbnNpZGUgdGhlIExGSC4KKyAgICAgKiBObyBEYXRhIERlc2NyaXB0b3IgYXQgYWxsLiAgTXVzdCBjb250YWluIFpJUDY0IGV4dHJhIGZpZWxkIGFzCisgICAgICogbW9kZSBpcyBBbHdheXMuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgWmlwT3V0cHV0VGVzdAorICAgICAgICB3cml0ZVNtYWxsRGVmbGF0ZWRFbnRyeVRvRmlsZU1vZGVBbHdheXMoZmluYWwgYm9vbGVhbiBrbm93blNpemUpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBaaXBPdXRwdXRUZXN0KCkgeworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgdm9pZCB0ZXN0KGZpbmFsIEZpbGUgZiwgZmluYWwgWmlwQXJjaGl2ZU91dHB1dFN0cmVhbSB6b3MpCisgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICB6b3Muc2V0VXNlWmlwNjQoWmlwNjRNb2RlLkFsd2F5cyk7CisgICAgICAgICAgICAgICAgZmluYWwgYnl0ZVtdIGJ1ZiA9IG5ldyBieXRlW09ORV9NSUxMSU9OXTsKKyAgICAgICAgICAgICAgICBmaW5hbCBaaXBBcmNoaXZlRW50cnkgemFlID0gbmV3IFppcEFyY2hpdmVFbnRyeSgiMCIpOworICAgICAgICAgICAgICAgIGlmIChrbm93blNpemUpIHsKKyAgICAgICAgICAgICAgICAgICAgemFlLnNldFNpemUoT05FX01JTExJT04pOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB6YWUuc2V0TWV0aG9kKFppcEVudHJ5LkRFRkxBVEVEKTsKKyAgICAgICAgICAgICAgICB6b3MucHV0QXJjaGl2ZUVudHJ5KHphZSk7CisgICAgICAgICAgICAgICAgem9zLndyaXRlKGJ1Zik7CisgICAgICAgICAgICAgICAgem9zLmNsb3NlQXJjaGl2ZUVudHJ5KCk7CisgICAgICAgICAgICAgICAgem9zLmNsb3NlKCk7CisKKyAgICAgICAgICAgICAgICB0cnkgKFJhbmRvbUFjY2Vzc0ZpbGUgYSA9IG5ldyBSYW5kb21BY2Nlc3NGaWxlKGYsICJyIikpIHsKKyAgICAgICAgICAgICAgICAgICAgZ2V0TGVuZ3RoQW5kUG9zaXRpb25BdENlbnRyYWxEaXJlY3RvcnkoYSk7CisKKyAgICAgICAgICAgICAgICAgICAgLy8gZ3JhYiBmaXJzdCBDRCBlbnRyeSwgdmVyaWZ5IHNpemVzIGFyZSBub3QKKyAgICAgICAgICAgICAgICAgICAgLy8gMHhGRkZGRkZGRiBhbmQgaXQgaGFzIGEgYW4gZW1wdHkgWklQNjQgZXh0ZW5kZWQKKyAgICAgICAgICAgICAgICAgICAgLy8gaW5mb3JtYXRpb24gZXh0cmEgZmllbGQKKyAgICAgICAgICAgICAgICAgICAgYnl0ZVtdIGhlYWRlciA9IG5ldyBieXRlWzEyXTsKKyAgICAgICAgICAgICAgICAgICAgYS5yZWFkRnVsbHkoaGVhZGVyKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMoIkNESCBzdGFydCIsIG5ldyBieXRlW10geworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNpZworICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweDUwLCAoYnl0ZSkgMHg0YiwgMSwgMiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB2ZXJzaW9uIG1hZGUgYnkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICA0NSwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB2ZXJzaW9uIG5lZWRlZCB0byBleHRyYWN0CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgNDUsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gR1BCIChFRlMgKyAqbm8qIERhdGEgRGVzY3JpcHRvcikKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCA4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1ldGhvZAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDgsIDAsCisgICAgICAgICAgICAgICAgICAgIH0sIGhlYWRlcik7CisgICAgICAgICAgICAgICAgICAgIC8vIGlnbm9yZSB0aW1lc3RhbXAKKyAgICAgICAgICAgICAgICAgICAgYS5za2lwQnl0ZXMoNCk7CisgICAgICAgICAgICAgICAgICAgIGJ5dGVbXSBjcmMgPSBuZXcgYnl0ZVs0XTsKKyAgICAgICAgICAgICAgICAgICAgYS5yZWFkRnVsbHkoY3JjKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMoIkNESCBDUkMiLCBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgMHg5RSwgKGJ5dGUpIDB4Q0IsIChieXRlKSAweDc5LCAoYnl0ZSkgMHgxMiwKKyAgICAgICAgICAgICAgICAgICAgfSwgY3JjKTsKKyAgICAgICAgICAgICAgICAgICAgLy8gc2tpcCBjb21wcmVzc2VkIHNpemUKKyAgICAgICAgICAgICAgICAgICAgYS5za2lwQnl0ZXMoNCk7CisgICAgICAgICAgICAgICAgICAgIGJ5dGVbXSByZXN0ID0gbmV3IGJ5dGVbMjNdOworICAgICAgICAgICAgICAgICAgICBhLnJlYWRGdWxseShyZXN0KTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMoIkNESCByZXN0IiwgbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT3JpZ2luYWwgU2l6ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweGZmLCAoYnl0ZSkgMHhmZiwgKGJ5dGUpIDB4ZmYsIChieXRlKSAweGZmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZpbGUgbmFtZSBsZW5ndGgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAxLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGV4dHJhIGZpZWxkIGxlbmd0aAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDI4LCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvbW1lbnQgbGVuZ3RoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBkaXNrIG51bWJlcgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYXR0cmlidXRlcworICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBvZmZzZXQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgMHhmZiwgKGJ5dGUpIDB4ZmYsIChieXRlKSAweGZmLCAoYnl0ZSkgMHhmZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBmaWxlIG5hbWUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgJzAnCisgICAgICAgICAgICAgICAgICAgIH0sIHJlc3QpOworICAgICAgICAgICAgICAgICAgICBieXRlW10gZXh0cmEgPSBuZXcgYnl0ZVsxMl07CisgICAgICAgICAgICAgICAgICAgIGEucmVhZEZ1bGx5KGV4dHJhKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMoIkNESCBleHRyYSIsIG5ldyBieXRlW10geworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEhlYWRlci1JRAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2l6ZSBvZiBleHRyYQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDI0LCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG9yaWdpbmFsIHNpemUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgMHg0MCwgKGJ5dGUpIDB4NDIsIChieXRlKSAweDBGLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAgICAgICAgIH0sIGV4dHJhKTsKKyAgICAgICAgICAgICAgICAgICAgLy8gc2tpcCBjb21wcmVzc2VkIHNpemUKKyAgICAgICAgICAgICAgICAgICAgYS5za2lwQnl0ZXMoOCk7CisgICAgICAgICAgICAgICAgICAgIGJ5dGVbXSBvZmZzZXQgPSBuZXcgYnl0ZVs4XTsKKyAgICAgICAgICAgICAgICAgICAgYS5yZWFkRnVsbHkob2Zmc2V0KTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMoImV4dHJhIG9mZnNldCIsIG5ldyBieXRlW10geworICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICB9LCBvZmZzZXQpOworCisgICAgICAgICAgICAgICAgICAgIC8vIGFuZCBub3cgdmFsaWRhdGUgbG9jYWwgZmlsZSBoZWFkZXIKKyAgICAgICAgICAgICAgICAgICAgYS5zZWVrKDApOworICAgICAgICAgICAgICAgICAgICBoZWFkZXIgPSBuZXcgYnl0ZVsxMF07CisgICAgICAgICAgICAgICAgICAgIGEucmVhZEZ1bGx5KGhlYWRlcik7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKCJMRkggc3RhcnQiLCBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzaWcKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgMHg1MCwgKGJ5dGUpIDB4NGIsIDMsIDQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdmVyc2lvbiBuZWVkZWQgdG8gZXh0cmFjdAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDQ1LCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEdQQiAoRUZTIGJpdCwgbm8gREQpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgOCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBtZXRob2QKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICA4LCAwLAorICAgICAgICAgICAgICAgICAgICB9LCBoZWFkZXIpOworICAgICAgICAgICAgICAgICAgICAvLyBpZ25vcmUgdGltZXN0YW1wCisgICAgICAgICAgICAgICAgICAgIGEuc2tpcEJ5dGVzKDQpOworICAgICAgICAgICAgICAgICAgICBjcmMgPSBuZXcgYnl0ZVs0XTsKKyAgICAgICAgICAgICAgICAgICAgYS5yZWFkRnVsbHkoY3JjKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMoIkxGSCBDUkMiLCBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgMHg5RSwgKGJ5dGUpIDB4Q0IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpIDB4NzksIChieXRlKSAweDEyLAorICAgICAgICAgICAgICAgICAgICB9LCBjcmMpOworICAgICAgICAgICAgICAgICAgICByZXN0ID0gbmV3IGJ5dGVbMTNdOworICAgICAgICAgICAgICAgICAgICBhLnJlYWRGdWxseShyZXN0KTsKKworICAgICAgICAgICAgICAgICAgICBhc3NlcnRBcnJheUVxdWFscygiTEZIIHJlc3QiLCBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBDb21wcmVzc2VkIFNpemUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4RkYsIChieXRlKSAweEZGLCAoYnl0ZSkgMHhGRiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPcmlnaW5hbCBTaXplCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpIDB4RkYsIChieXRlKSAweEZGLCAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4RkYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZmlsZSBuYW1lIGxlbmd0aAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZXh0cmEgZmllbGQgbGVuZ3RoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMjAsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZmlsZSBuYW1lCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpICcwJworICAgICAgICAgICAgICAgICAgICB9LCByZXN0KTsKKworICAgICAgICAgICAgICAgICAgICBleHRyYSA9IG5ldyBieXRlWzEyXTsKKyAgICAgICAgICAgICAgICAgICAgYS5yZWFkRnVsbHkoZXh0cmEpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRBcnJheUVxdWFscygiTEZIIGV4dHJhIiwgbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSGVhZGVyLUlECisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMSwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzaXplIG9mIGV4dHJhCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMTYsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gb3JpZ2luYWwgc2l6ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweDQwLCAoYnl0ZSkgMHg0MiwgKGJ5dGUpIDB4MEYsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBkb24ndCBrbm93IHRoZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvbXByZXNzZWQgc2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBkb24ndCB3YW50IHRvCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaGFyZC1jb2RlIGl0CisgICAgICAgICAgICAgICAgICAgIH0sIGV4dHJhKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH07CisgICAgfQorCisgICAgQFRlc3QgcHVibGljIHZvaWQgd3JpdGVTbWFsbERlZmxhdGVkRW50cnlLbm93blNpemVUb0ZpbGVNb2RlQWx3YXlzKCkKKyAgICAgICAgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIHdpdGhUZW1wb3JhcnlBcmNoaXZlKCJ3cml0ZVNtYWxsRGVmbGF0ZWRFbnRyeUtub3duU2l6ZVRvRmlsZU1vZGVBbHdheXMiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cml0ZVNtYWxsRGVmbGF0ZWRFbnRyeVRvRmlsZU1vZGVBbHdheXModHJ1ZSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUpOworICAgIH0KKworICAgIEBUZXN0IHB1YmxpYyB2b2lkIHdyaXRlU21hbGxEZWZsYXRlZEVudHJ5VW5rbm93blNpemVUb0ZpbGVNb2RlQWx3YXlzKCkKKyAgICAgICAgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIHdpdGhUZW1wb3JhcnlBcmNoaXZlKCJ3cml0ZVNtYWxsRGVmbGF0ZWRFbnRyeVVua25vd25TaXplVG9GaWxlTW9kZUFsd2F5cyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlU21hbGxEZWZsYXRlZEVudHJ5VG9GaWxlTW9kZUFsd2F5cyhmYWxzZSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUpOworICAgIH0KKworICAgIHN0YXRpYyBpbnRlcmZhY2UgWmlwT3V0cHV0VGVzdCB7CisgICAgICAgIHZvaWQgdGVzdChGaWxlIGYsIFppcEFyY2hpdmVPdXRwdXRTdHJlYW0gem9zKSB0aHJvd3MgSU9FeGNlcHRpb247CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCB3aXRoVGVtcG9yYXJ5QXJjaGl2ZShmaW5hbCBTdHJpbmcgdGVzdE5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBaaXBPdXRwdXRUZXN0IHRlc3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBib29sZWFuIHVzZVJhbmRvbUFjY2Vzc0ZpbGUpCisgICAgICAgIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBmaW5hbCBGaWxlIGYgPSBnZXRUZW1wRmlsZSh0ZXN0TmFtZSk7CisgICAgICAgIEJ1ZmZlcmVkT3V0cHV0U3RyZWFtIG9zID0gbnVsbDsKKyAgICAgICAgZmluYWwgWmlwQXJjaGl2ZU91dHB1dFN0cmVhbSB6b3MgPSB1c2VSYW5kb21BY2Nlc3NGaWxlCisgICAgICAgICAgICA/IG5ldyBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtKGYpCisgICAgICAgICAgICA6IG5ldyBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtKG9zID0gbmV3IEJ1ZmZlcmVkT3V0cHV0U3RyZWFtKG5ldyBGaWxlT3V0cHV0U3RyZWFtKGYpKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0ZXN0LnRlc3QoZiwgem9zKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgSU9FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiRmFpbGVkIHRvIHdyaXRlIGFyY2hpdmUgYmVjYXVzZSBvZjogIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgZXguZ2V0TWVzc2FnZSgpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIC0gbGlrZWx5IG5vdCBlbm91Z2ggZGlzayBzcGFjZS4iKTsKKyAgICAgICAgICAgIGFzc3VtZVRydWUoZmFsc2UpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICB6b3MuZGVzdHJveSgpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBpZiAob3MgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBvcy5jbG9zZSgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBBYnN0cmFjdFRlc3RDYXNlLnRyeUhhcmRUb0RlbGV0ZShmKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIEZpbGUgZ2V0NUdCWmVyb3NGaWxlKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIHJldHVybiBnZXRGaWxlKCI1R0Jfb2ZfWmVyb3MuemlwIik7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgRmlsZSBnZXQ1R0JaZXJvc0ZpbGVHZW5lcmF0ZWRCeTdaSVAoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgcmV0dXJuIGdldEZpbGUoIjVHQl9vZl9aZXJvc183WklQLnppcCIpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIEZpbGUgZ2V0NUdCWmVyb3NGaWxlR2VuZXJhdGVkQnlKYXZhN0phcigpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICByZXR1cm4gZ2V0RmlsZSgiNUdCX29mX1plcm9zX2phci56aXAiKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBGaWxlIGdldDVHQlplcm9zRmlsZUdlbmVyYXRlZEJ5V2luWklQKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIHJldHVybiBnZXRGaWxlKCI1R0Jfb2ZfWmVyb3NfV2luWmlwLnppcCIpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIEZpbGUgZ2V0NUdCWmVyb3NGaWxlR2VuZXJhdGVkQnlQS1ppcCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICByZXR1cm4gZ2V0RmlsZSgiNUdCX29mX1plcm9zX1BLWmlwLnppcCIpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIEZpbGUgZ2V0MTAwS0ZpbGVGaWxlKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIHJldHVybiBnZXRGaWxlKCIxMDBrX0ZpbGVzLnppcCIpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIEZpbGUgZ2V0MTAwS0ZpbGVGaWxlR2VuZXJhdGVkQnk3WklQKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIHJldHVybiBnZXRGaWxlKCIxMDBrX0ZpbGVzXzdaSVAuemlwIik7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgRmlsZSBnZXQxMDBLRmlsZUZpbGVHZW5lcmF0ZWRCeVdpbkNGKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIHJldHVybiBnZXRGaWxlKCIxMDBrX0ZpbGVzX1dpbmRvd3NDb21wcmVzc2VkRm9sZGVycy56aXAiKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBGaWxlIGdldDEwMEtGaWxlRmlsZUdlbmVyYXRlZEJ5SmF2YTdKYXIoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgcmV0dXJuIGdldEZpbGUoIjEwMGtfRmlsZXNfamFyLnppcCIpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIEZpbGUgZ2V0MTAwS0ZpbGVGaWxlR2VuZXJhdGVkQnlXaW5aSVAoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgcmV0dXJuIGdldEZpbGUoIjEwMGtfRmlsZXNfV2luWklQLnppcCIpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIEZpbGUgZ2V0MTAwS0ZpbGVGaWxlR2VuZXJhdGVkQnlQS1ppcCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICByZXR1cm4gZ2V0RmlsZSgiMTAwa19GaWxlc19QS1ppcC56aXAiKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBGaWxlIGdldFRlbXBGaWxlKGZpbmFsIFN0cmluZyB0ZXN0TmFtZSkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIGZpbmFsIEZpbGUgZiA9IEZpbGUuY3JlYXRlVGVtcEZpbGUoImNvbW1vbnMtY29tcHJlc3MtIiArIHRlc3ROYW1lLCAiLnppcCIpOworICAgICAgICBmLmRlbGV0ZU9uRXhpdCgpOworICAgICAgICByZXR1cm4gZjsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHJlYWQ1R0JPZlplcm9zSW1wbChmaW5hbCBGaWxlIGYsIGZpbmFsIFN0cmluZyBleHBlY3RlZE5hbWUpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGVJbnB1dFN0cmVhbSBmaW4gPSBuZXcgRmlsZUlucHV0U3RyZWFtKGYpOworICAgICAgICBaaXBBcmNoaXZlSW5wdXRTdHJlYW0gemluID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHppbiA9IG5ldyBaaXBBcmNoaXZlSW5wdXRTdHJlYW0oZmluKTsKKyAgICAgICAgICAgIFppcEFyY2hpdmVFbnRyeSB6YWUgPSB6aW4uZ2V0TmV4dFppcEVudHJ5KCk7CisgICAgICAgICAgICB3aGlsZSAoemFlLmlzRGlyZWN0b3J5KCkpIHsKKyAgICAgICAgICAgICAgICB6YWUgPSB6aW4uZ2V0TmV4dFppcEVudHJ5KCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWROYW1lLCB6YWUuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBidWYgPSBuZXcgYnl0ZVsxMDI0ICogMTAyNF07CisgICAgICAgICAgICBsb25nIHJlYWQgPSAwOworICAgICAgICAgICAgZmluYWwgUmFuZG9tIHIgPSBuZXcgUmFuZG9tKFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpKTsKKyAgICAgICAgICAgIGludCByZWFkTm93OworICAgICAgICAgICAgd2hpbGUgKChyZWFkTm93ID0gemluLnJlYWQoYnVmLCAwLCBidWYubGVuZ3RoKSkgPiAwKSB7CisgICAgICAgICAgICAgICAgLy8gdGVzdGluZyBhbGwgYnl0ZXMgZm9yIGEgdmFsdWUgb2YgMCBpcyBnb2luZyB0byB0YWtlCisgICAgICAgICAgICAgICAgLy8gdG9vIGxvbmcsIGp1c3QgcGljayBhIGZldyBvbmVzIHJhbmRvbWx5CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDI0OyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGlkeCA9IHIubmV4dEludChyZWFkTm93KTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0ZXN0aW5nIGJ5dGUgIiArIChyZWFkICsgaWR4KSwgMCwgYnVmW2lkeF0pOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZWFkICs9IHJlYWROb3c7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoRklWRV9CSUxMSU9OLCByZWFkKTsKKyAgICAgICAgICAgIGFzc2VydE51bGwoemluLmdldE5leHRaaXBFbnRyeSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhGSVZFX0JJTExJT04sIHphZS5nZXRTaXplKCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKHppbiAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgemluLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmaW4uY2xvc2UoKTsgLy8gZmluIGNhbm5vdCBiZSBudWxsIGhlcmUKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgcmVhZDVHQk9mWmVyb3NVc2luZ1ppcEZpbGVJbXBsKGZpbmFsIEZpbGUgZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgZXhwZWN0ZWROYW1lKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBaaXBGaWxlIHpmID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHpmID0gbmV3IFppcEZpbGUoZik7CisgICAgICAgICAgICBmaW5hbCBFbnVtZXJhdGlvbjxaaXBBcmNoaXZlRW50cnk+IGUgPSB6Zi5nZXRFbnRyaWVzKCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKGUuaGFzTW9yZUVsZW1lbnRzKCkpOworICAgICAgICAgICAgWmlwQXJjaGl2ZUVudHJ5IHphZSA9IGUubmV4dEVsZW1lbnQoKTsKKyAgICAgICAgICAgIHdoaWxlICh6YWUuaXNEaXJlY3RvcnkoKSkgeworICAgICAgICAgICAgICAgIHphZSA9IGUubmV4dEVsZW1lbnQoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZE5hbWUsIHphZS5nZXROYW1lKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKEZJVkVfQklMTElPTiwgemFlLmdldFNpemUoKSk7CisgICAgICAgICAgICBmaW5hbCBieXRlW10gYnVmID0gbmV3IGJ5dGVbMTAyNCAqIDEwMjRdOworICAgICAgICAgICAgbG9uZyByZWFkID0gMDsKKyAgICAgICAgICAgIGZpbmFsIFJhbmRvbSByID0gbmV3IFJhbmRvbShTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSk7CisgICAgICAgICAgICBpbnQgcmVhZE5vdzsKKyAgICAgICAgICAgIHRyeSAoSW5wdXRTdHJlYW0gemluID0gemYuZ2V0SW5wdXRTdHJlYW0oemFlKSkgeworICAgICAgICAgICAgICAgIHdoaWxlICgocmVhZE5vdyA9IHppbi5yZWFkKGJ1ZiwgMCwgYnVmLmxlbmd0aCkpID4gMCkgeworICAgICAgICAgICAgICAgICAgICAvLyB0ZXN0aW5nIGFsbCBieXRlcyBmb3IgYSB2YWx1ZSBvZiAwIGlzIGdvaW5nIHRvIHRha2UKKyAgICAgICAgICAgICAgICAgICAgLy8gdG9vIGxvbmcsIGp1c3QgcGljayBhIGZldyBvbmVzIHJhbmRvbWx5CisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTAyNDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgaWR4ID0gci5uZXh0SW50KHJlYWROb3cpOworICAgICAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0ZXN0aW5nIGJ5dGUgIiArIChyZWFkICsgaWR4KSwgMCwgYnVmW2lkeF0pOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHJlYWQgKz0gcmVhZE5vdzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoRklWRV9CSUxMSU9OLCByZWFkKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGUuaGFzTW9yZUVsZW1lbnRzKCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgWmlwRmlsZS5jbG9zZVF1aWV0bHkoemYpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCByZWFkMTAwS0ZpbGVzSW1wbChmaW5hbCBGaWxlIGYpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGVJbnB1dFN0cmVhbSBmaW4gPSBuZXcgRmlsZUlucHV0U3RyZWFtKGYpOworICAgICAgICBaaXBBcmNoaXZlSW5wdXRTdHJlYW0gemluID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHppbiA9IG5ldyBaaXBBcmNoaXZlSW5wdXRTdHJlYW0oZmluKTsKKyAgICAgICAgICAgIGludCBmaWxlcyA9IDA7CisgICAgICAgICAgICBaaXBBcmNoaXZlRW50cnkgemFlID0gbnVsbDsKKyAgICAgICAgICAgIHdoaWxlICgoemFlID0gemluLmdldE5leHRaaXBFbnRyeSgpKSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgaWYgKCF6YWUuaXNEaXJlY3RvcnkoKSkgeworICAgICAgICAgICAgICAgICAgICBmaWxlcysrOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMCwgemFlLmdldFNpemUoKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKE9ORV9IVU5EUkVEX1RIT1VTQU5ELCBmaWxlcyk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAoemluICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICB6aW4uY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZpbi5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCByZWFkMTAwS0ZpbGVzVXNpbmdaaXBGaWxlSW1wbChmaW5hbCBGaWxlIGYpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFppcEZpbGUgemYgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgemYgPSBuZXcgWmlwRmlsZShmKTsKKyAgICAgICAgICAgIGludCBmaWxlcyA9IDA7CisgICAgICAgICAgICBmb3IgKGZpbmFsIEVudW1lcmF0aW9uPFppcEFyY2hpdmVFbnRyeT4gZSA9IHpmLmdldEVudHJpZXMoKTsgZS5oYXNNb3JlRWxlbWVudHMoKTsgKSB7CisgICAgICAgICAgICAgICAgZmluYWwgWmlwQXJjaGl2ZUVudHJ5IHphZSA9IGUubmV4dEVsZW1lbnQoKTsKKyAgICAgICAgICAgICAgICBpZiAoIXphZS5pc0RpcmVjdG9yeSgpKSB7CisgICAgICAgICAgICAgICAgICAgIGZpbGVzKys7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygwLCB6YWUuZ2V0U2l6ZSgpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoT05FX0hVTkRSRURfVEhPVVNBTkQsIGZpbGVzKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIFppcEZpbGUuY2xvc2VRdWlldGx5KHpmKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGxvbmcgZ2V0TGVuZ3RoQW5kUG9zaXRpb25BdENlbnRyYWxEaXJlY3RvcnkoZmluYWwgUmFuZG9tQWNjZXNzRmlsZSBhKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBsb25nIGVuZCA9IGEubGVuZ3RoKCk7CisgICAgICAgIGEuc2VlayhlbmQgLSAyMiAtIDIwKTsKKyAgICAgICAgZmluYWwgYnl0ZVtdIHNpZyA9IG5ldyBieXRlWzRdOworICAgICAgICBhLnJlYWRGdWxseShzaWcpOworICAgICAgICBpZiAoc2lnWzBdICE9IChieXRlKSAweDUwIHx8IHNpZ1sxXSAhPSAoYnl0ZSkgMHg0YgorICAgICAgICAgICAgfHwgc2lnWzJdICE9IDYgfHwgc2lnWzNdICE9IDcpIHsKKyAgICAgICAgICAgIC8vIG5vdCBhIFpJUDY0IGFyY2hpdmUKKyAgICAgICAgICAgIHJldHVybiBnZXRMZW5ndGhBbmRQb3NpdGlvbkF0Q2VudHJhbERpcmVjdG9yeTMyKGEsIGVuZCk7CisgICAgICAgIH0KKworICAgICAgICBmaW5hbCBsb25nIGNkT2Zmc2V0TG9jID0gZW5kIC0gMjIgLSAyMCAtIDU2ICsgNDg7CisgICAgICAgIC8vIHNlZWsgdG8gY2VudHJhbCBkaXJlY3RvcnkgbG9jYXRvcgorICAgICAgICBhLnNlZWsoY2RPZmZzZXRMb2MpOworICAgICAgICBmaW5hbCBieXRlW10gY2RPZmZzZXQgPSBuZXcgYnl0ZVs4XTsKKyAgICAgICAgYS5yZWFkRnVsbHkoY2RPZmZzZXQpOworICAgICAgICBhLnNlZWsoWmlwRWlnaHRCeXRlSW50ZWdlci5nZXRMb25nVmFsdWUoY2RPZmZzZXQpKTsKKyAgICAgICAgcmV0dXJuIGVuZDsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBsb25nIGdldExlbmd0aEFuZFBvc2l0aW9uQXRDZW50cmFsRGlyZWN0b3J5MzIoZmluYWwgUmFuZG9tQWNjZXNzRmlsZSBhLCBmaW5hbCBsb25nIGVuZCkKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYS5zZWVrKGVuZCAtIDIyICsgMTYpOworICAgICAgICBmaW5hbCBieXRlW10gY2RPZmZzZXQgPSBuZXcgYnl0ZVs0XTsKKyAgICAgICAgYS5yZWFkRnVsbHkoY2RPZmZzZXQpOworICAgICAgICBhLnNlZWsoWmlwTG9uZy5nZXRWYWx1ZShjZE9mZnNldCkpOworICAgICAgICByZXR1cm4gZW5kOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgd3JpdGUxMDBLRmlsZXNUb1N0cmVhbShmaW5hbCBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtIHpvcykKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBPTkVfSFVORFJFRF9USE9VU0FORDsgaSsrKSB7CisgICAgICAgICAgICBmaW5hbCBaaXBBcmNoaXZlRW50cnkgemFlID0gbmV3IFppcEFyY2hpdmVFbnRyeShTdHJpbmcudmFsdWVPZihpKSk7CisgICAgICAgICAgICB6YWUuc2V0U2l6ZSgwKTsKKyAgICAgICAgICAgIHpvcy5wdXRBcmNoaXZlRW50cnkoemFlKTsKKyAgICAgICAgICAgIHpvcy5jbG9zZUFyY2hpdmVFbnRyeSgpOworICAgICAgICB9CisgICAgICAgIHpvcy5jbG9zZSgpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQKKyAgICAgICAgd3JpdGUzRW50cmllc0NyZWF0aW5nQmlnQXJjaGl2ZVRvU3RyZWFtKGZpbmFsIFppcEFyY2hpdmVPdXRwdXRTdHJlYW0gem9zKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBieXRlW10gYnVmID0gbmV3IGJ5dGVbT05FX01JTExJT05dOworICAgICAgICBaaXBBcmNoaXZlRW50cnkgemFlID0gbnVsbDsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAyOyBpKyspIHsKKyAgICAgICAgICAgIHphZSA9IG5ldyBaaXBBcmNoaXZlRW50cnkoU3RyaW5nLnZhbHVlT2YoaSkpOworICAgICAgICAgICAgemFlLnNldFNpemUoRklWRV9CSUxMSU9OIC8gMik7CisgICAgICAgICAgICB6YWUuc2V0TWV0aG9kKFppcEVudHJ5LlNUT1JFRCk7CisgICAgICAgICAgICB6YWUuc2V0Q3JjKDB4OGE0MDhmMTZMKTsKKyAgICAgICAgICAgIHpvcy5wdXRBcmNoaXZlRW50cnkoemFlKTsKKyAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgRklWRV9CSUxMSU9OIC8gMiAvIDEwMDAgLyAxMDAwOworICAgICAgICAgICAgICAgICBqKyspIHsKKyAgICAgICAgICAgICAgICB6b3Mud3JpdGUoYnVmKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHpvcy5jbG9zZUFyY2hpdmVFbnRyeSgpOworICAgICAgICB9CisgICAgICAgIHphZSA9IG5ldyBaaXBBcmNoaXZlRW50cnkoU3RyaW5nLnZhbHVlT2YoMikpOworICAgICAgICB6YWUuc2V0U2l6ZSgxKTsKKyAgICAgICAgemFlLnNldE1ldGhvZChaaXBFbnRyeS5TVE9SRUQpOworICAgICAgICB6YWUuc2V0Q3JjKDB4OWI5MjY1YkwpOworICAgICAgICB6b3MucHV0QXJjaGl2ZUVudHJ5KHphZSk7CisgICAgICAgIHpvcy53cml0ZShuZXcgYnl0ZVtdIHsgNDIgfSk7CisgICAgICAgIHpvcy5jbG9zZUFyY2hpdmVFbnRyeSgpOworICAgICAgICB6b3MuY2xvc2UoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1ppcEFyY2hpdmVFbnRyeVRlc3QuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvWmlwQXJjaGl2ZUVudHJ5VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdiZGY1NGMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1ppcEFyY2hpdmVFbnRyeVRlc3QuamF2YQpAQCAtMCwwICsxLDI5MyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICoKKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwOworCitpbXBvcnQgc3RhdGljIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5BYnN0cmFjdFRlc3RDYXNlLmdldEZpbGU7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuKjsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC56aXAuWmlwRW50cnk7CisKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworLyoqCisgKiBKVW5pdCB0ZXN0Y2FzZXMgZm9yIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwLlppcEVudHJ5LgorICoKKyAqLworcHVibGljIGNsYXNzIFppcEFyY2hpdmVFbnRyeVRlc3QgeworCisgICAgLyoqCisgICAgICogdGVzdCBoYW5kbGluZyBvZiBleHRyYSBmaWVsZHMKKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RFeHRyYUZpZWxkcygpIHsKKyAgICAgICAgZmluYWwgQXNpRXh0cmFGaWVsZCBhID0gbmV3IEFzaUV4dHJhRmllbGQoKTsKKyAgICAgICAgYS5zZXREaXJlY3RvcnkodHJ1ZSk7CisgICAgICAgIGEuc2V0TW9kZSgwNzU1KTsKKyAgICAgICAgZmluYWwgVW5yZWNvZ25pemVkRXh0cmFGaWVsZCB1ID0gbmV3IFVucmVjb2duaXplZEV4dHJhRmllbGQoKTsKKyAgICAgICAgdS5zZXRIZWFkZXJJZChFeHRyYUZpZWxkVXRpbHNUZXN0LlVOUkVDT0dOSVpFRF9IRUFERVIpOworICAgICAgICB1LnNldExvY2FsRmlsZURhdGFEYXRhKG5ldyBieXRlWzBdKTsKKworICAgICAgICBmaW5hbCBaaXBBcmNoaXZlRW50cnkgemUgPSBuZXcgWmlwQXJjaGl2ZUVudHJ5KCJ0ZXN0LyIpOworICAgICAgICB6ZS5zZXRFeHRyYUZpZWxkcyhuZXcgWmlwRXh0cmFGaWVsZFtdIHthLCB1fSk7CisgICAgICAgIGZpbmFsIGJ5dGVbXSBkYXRhMSA9IHplLmdldEV4dHJhKCk7CisgICAgICAgIFppcEV4dHJhRmllbGRbXSByZXN1bHQgPSB6ZS5nZXRFeHRyYUZpZWxkcygpOworICAgICAgICBhc3NlcnRFcXVhbHMoImZpcnN0IHBhc3MiLCAyLCByZXN1bHQubGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0U2FtZShhLCByZXN1bHRbMF0pOworICAgICAgICBhc3NlcnRTYW1lKHUsIHJlc3VsdFsxXSk7CisKKyAgICAgICAgZmluYWwgVW5yZWNvZ25pemVkRXh0cmFGaWVsZCB1MiA9IG5ldyBVbnJlY29nbml6ZWRFeHRyYUZpZWxkKCk7CisgICAgICAgIHUyLnNldEhlYWRlcklkKEV4dHJhRmllbGRVdGlsc1Rlc3QuVU5SRUNPR05JWkVEX0hFQURFUik7CisgICAgICAgIHUyLnNldExvY2FsRmlsZURhdGFEYXRhKG5ldyBieXRlW10gezF9KTsKKworICAgICAgICB6ZS5hZGRFeHRyYUZpZWxkKHUyKTsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGRhdGEyID0gemUuZ2V0RXh0cmEoKTsKKyAgICAgICAgcmVzdWx0ID0gemUuZ2V0RXh0cmFGaWVsZHMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJzZWNvbmQgcGFzcyIsIDIsIHJlc3VsdC5sZW5ndGgpOworICAgICAgICBhc3NlcnRTYW1lKGEsIHJlc3VsdFswXSk7CisgICAgICAgIGFzc2VydFNhbWUodTIsIHJlc3VsdFsxXSk7CisgICAgICAgIGFzc2VydEVxdWFscygibGVuZ3RoIHNlY29uZCBwYXNzIiwgZGF0YTEubGVuZ3RoKzEsIGRhdGEyLmxlbmd0aCk7CisKKyAgICAgICAgZmluYWwgVW5yZWNvZ25pemVkRXh0cmFGaWVsZCB1MyA9IG5ldyBVbnJlY29nbml6ZWRFeHRyYUZpZWxkKCk7CisgICAgICAgIHUzLnNldEhlYWRlcklkKG5ldyBaaXBTaG9ydCgyKSk7CisgICAgICAgIHUzLnNldExvY2FsRmlsZURhdGFEYXRhKG5ldyBieXRlW10gezF9KTsKKyAgICAgICAgemUuYWRkRXh0cmFGaWVsZCh1Myk7CisgICAgICAgIHJlc3VsdCA9IHplLmdldEV4dHJhRmllbGRzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygidGhpcmQgcGFzcyIsIDMsIHJlc3VsdC5sZW5ndGgpOworCisgICAgICAgIHplLnJlbW92ZUV4dHJhRmllbGQoRXh0cmFGaWVsZFV0aWxzVGVzdC5VTlJFQ09HTklaRURfSEVBREVSKTsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGRhdGEzID0gemUuZ2V0RXh0cmEoKTsKKyAgICAgICAgcmVzdWx0ID0gemUuZ2V0RXh0cmFGaWVsZHMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmb3VydGggcGFzcyIsIDIsIHJlc3VsdC5sZW5ndGgpOworICAgICAgICBhc3NlcnRTYW1lKGEsIHJlc3VsdFswXSk7CisgICAgICAgIGFzc2VydFNhbWUodTMsIHJlc3VsdFsxXSk7CisgICAgICAgIGFzc2VydEVxdWFscygibGVuZ3RoIGZvdXJ0aCBwYXNzIiwgZGF0YTIubGVuZ3RoLCBkYXRhMy5sZW5ndGgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB6ZS5yZW1vdmVFeHRyYUZpZWxkKEV4dHJhRmllbGRVdGlsc1Rlc3QuVU5SRUNPR05JWkVEX0hFQURFUik7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgYmUgbm8gc3VjaCBlbGVtZW50Iik7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIGphdmEudXRpbC5Ob1N1Y2hFbGVtZW50RXhjZXB0aW9uIG5zZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogdGVzdCBoYW5kbGluZyBvZiBleHRyYSBmaWVsZHMgdmlhIGNlbnRyYWwgZGlyZWN0b3J5CisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RXh0cmFGaWVsZE1lcmdpbmcoKSB7CisgICAgICAgIGZpbmFsIEFzaUV4dHJhRmllbGQgYSA9IG5ldyBBc2lFeHRyYUZpZWxkKCk7CisgICAgICAgIGEuc2V0RGlyZWN0b3J5KHRydWUpOworICAgICAgICBhLnNldE1vZGUoMDc1NSk7CisgICAgICAgIGZpbmFsIFVucmVjb2duaXplZEV4dHJhRmllbGQgdSA9IG5ldyBVbnJlY29nbml6ZWRFeHRyYUZpZWxkKCk7CisgICAgICAgIHUuc2V0SGVhZGVySWQoRXh0cmFGaWVsZFV0aWxzVGVzdC5VTlJFQ09HTklaRURfSEVBREVSKTsKKyAgICAgICAgdS5zZXRMb2NhbEZpbGVEYXRhRGF0YShuZXcgYnl0ZVswXSk7CisKKyAgICAgICAgZmluYWwgWmlwQXJjaGl2ZUVudHJ5IHplID0gbmV3IFppcEFyY2hpdmVFbnRyeSgidGVzdC8iKTsKKyAgICAgICAgemUuc2V0RXh0cmFGaWVsZHMobmV3IFppcEV4dHJhRmllbGRbXSB7YSwgdX0pOworCisgICAgICAgIC8vIG1lcmdlCisgICAgICAgIC8vIEhlYWRlci1JRCAxICsgbGVuZ3RoIDEgKyBvbmUgYnl0ZSBvZiBkYXRhCisgICAgICAgIGZpbmFsIGJ5dGVbXSBiID0gRXh0cmFGaWVsZFV0aWxzVGVzdC5VTlJFQ09HTklaRURfSEVBREVSLmdldEJ5dGVzKCk7CisgICAgICAgIHplLnNldENlbnRyYWxEaXJlY3RvcnlFeHRyYShuZXcgYnl0ZVtdIHtiWzBdLCBiWzFdLCAxLCAwLCAxMjd9KTsKKworICAgICAgICBaaXBFeHRyYUZpZWxkW10gcmVzdWx0ID0gemUuZ2V0RXh0cmFGaWVsZHMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmaXJzdCBwYXNzIiwgMiwgcmVzdWx0Lmxlbmd0aCk7CisgICAgICAgIGFzc2VydFNhbWUoYSwgcmVzdWx0WzBdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEV4dHJhRmllbGRVdGlsc1Rlc3QuVU5SRUNPR05JWkVEX0hFQURFUiwKKyAgICAgICAgICAgICAgICAgICAgIHJlc3VsdFsxXS5nZXRIZWFkZXJJZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBaaXBTaG9ydCgwKSwgcmVzdWx0WzFdLmdldExvY2FsRmlsZURhdGFMZW5ndGgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhuZXcgWmlwU2hvcnQoMSksIHJlc3VsdFsxXS5nZXRDZW50cmFsRGlyZWN0b3J5TGVuZ3RoKCkpOworCisgICAgICAgIC8vIGFkZCBuZXcKKyAgICAgICAgLy8gSGVhZGVyLUlEIDIgKyBsZW5ndGggMAorICAgICAgICB6ZS5zZXRDZW50cmFsRGlyZWN0b3J5RXh0cmEobmV3IGJ5dGVbXSB7MiwgMCwgMCwgMH0pOworCisgICAgICAgIHJlc3VsdCA9IHplLmdldEV4dHJhRmllbGRzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygic2Vjb25kIHBhc3MiLCAzLCByZXN1bHQubGVuZ3RoKTsKKworICAgICAgICAvLyBtZXJnZQorICAgICAgICAvLyBIZWFkZXItSUQgMiArIGxlbmd0aCAxICsgb25lIGJ5dGUgb2YgZGF0YQorICAgICAgICB6ZS5zZXRFeHRyYShuZXcgYnl0ZVtdIHsyLCAwLCAxLCAwLCAxMjd9KTsKKworICAgICAgICByZXN1bHQgPSB6ZS5nZXRFeHRyYUZpZWxkcygpOworICAgICAgICBhc3NlcnRFcXVhbHMoInRoaXJkIHBhc3MiLCAzLCByZXN1bHQubGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0U2FtZShhLCByZXN1bHRbMF0pOworICAgICAgICBhc3NlcnRFcXVhbHMobmV3IFppcFNob3J0KDIpLCByZXN1bHRbMl0uZ2V0SGVhZGVySWQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhuZXcgWmlwU2hvcnQoMSksIHJlc3VsdFsyXS5nZXRMb2NhbEZpbGVEYXRhTGVuZ3RoKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobmV3IFppcFNob3J0KDApLCByZXN1bHRbMl0uZ2V0Q2VudHJhbERpcmVjdG9yeUxlbmd0aCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB0ZXN0IGhhbmRsaW5nIG9mIGV4dHJhIGZpZWxkcworICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEFkZEFzRmlyc3RFeHRyYUZpZWxkKCkgeworICAgICAgICBmaW5hbCBBc2lFeHRyYUZpZWxkIGEgPSBuZXcgQXNpRXh0cmFGaWVsZCgpOworICAgICAgICBhLnNldERpcmVjdG9yeSh0cnVlKTsKKyAgICAgICAgYS5zZXRNb2RlKDA3NTUpOworICAgICAgICBmaW5hbCBVbnJlY29nbml6ZWRFeHRyYUZpZWxkIHUgPSBuZXcgVW5yZWNvZ25pemVkRXh0cmFGaWVsZCgpOworICAgICAgICB1LnNldEhlYWRlcklkKEV4dHJhRmllbGRVdGlsc1Rlc3QuVU5SRUNPR05JWkVEX0hFQURFUik7CisgICAgICAgIHUuc2V0TG9jYWxGaWxlRGF0YURhdGEobmV3IGJ5dGVbMF0pOworCisgICAgICAgIGZpbmFsIFppcEFyY2hpdmVFbnRyeSB6ZSA9IG5ldyBaaXBBcmNoaXZlRW50cnkoInRlc3QvIik7CisgICAgICAgIHplLnNldEV4dHJhRmllbGRzKG5ldyBaaXBFeHRyYUZpZWxkW10ge2EsIHV9KTsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGRhdGExID0gemUuZ2V0RXh0cmEoKTsKKworICAgICAgICBmaW5hbCBVbnJlY29nbml6ZWRFeHRyYUZpZWxkIHUyID0gbmV3IFVucmVjb2duaXplZEV4dHJhRmllbGQoKTsKKyAgICAgICAgdTIuc2V0SGVhZGVySWQoRXh0cmFGaWVsZFV0aWxzVGVzdC5VTlJFQ09HTklaRURfSEVBREVSKTsKKyAgICAgICAgdTIuc2V0TG9jYWxGaWxlRGF0YURhdGEobmV3IGJ5dGVbXSB7MX0pOworCisgICAgICAgIHplLmFkZEFzRmlyc3RFeHRyYUZpZWxkKHUyKTsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGRhdGEyID0gemUuZ2V0RXh0cmEoKTsKKyAgICAgICAgWmlwRXh0cmFGaWVsZFtdIHJlc3VsdCA9IHplLmdldEV4dHJhRmllbGRzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygic2Vjb25kIHBhc3MiLCAyLCByZXN1bHQubGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0U2FtZSh1MiwgcmVzdWx0WzBdKTsKKyAgICAgICAgYXNzZXJ0U2FtZShhLCByZXN1bHRbMV0pOworICAgICAgICBhc3NlcnRFcXVhbHMoImxlbmd0aCBzZWNvbmQgcGFzcyIsIGRhdGExLmxlbmd0aCArIDEsIGRhdGEyLmxlbmd0aCk7CisKKyAgICAgICAgZmluYWwgVW5yZWNvZ25pemVkRXh0cmFGaWVsZCB1MyA9IG5ldyBVbnJlY29nbml6ZWRFeHRyYUZpZWxkKCk7CisgICAgICAgIHUzLnNldEhlYWRlcklkKG5ldyBaaXBTaG9ydCgyKSk7CisgICAgICAgIHUzLnNldExvY2FsRmlsZURhdGFEYXRhKG5ldyBieXRlW10gezF9KTsKKyAgICAgICAgemUuYWRkQXNGaXJzdEV4dHJhRmllbGQodTMpOworICAgICAgICByZXN1bHQgPSB6ZS5nZXRFeHRyYUZpZWxkcygpOworICAgICAgICBhc3NlcnRFcXVhbHMoInRoaXJkIHBhc3MiLCAzLCByZXN1bHQubGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0U2FtZSh1MywgcmVzdWx0WzBdKTsKKyAgICAgICAgYXNzZXJ0U2FtZSh1MiwgcmVzdWx0WzFdKTsKKyAgICAgICAgYXNzZXJ0U2FtZShhLCByZXN1bHRbMl0pOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFVuaXhNb2RlKCkgeworICAgICAgICBaaXBBcmNoaXZlRW50cnkgemUgPSBuZXcgWmlwQXJjaGl2ZUVudHJ5KCJmb28iKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIHplLmdldFBsYXRmb3JtKCkpOworICAgICAgICB6ZS5zZXRVbml4TW9kZSgwNzU1KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIHplLmdldFBsYXRmb3JtKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMDc1NSwKKyAgICAgICAgICAgICAgICAgICAgICh6ZS5nZXRFeHRlcm5hbEF0dHJpYnV0ZXMoKSA+PiAxNikgJiAweEZGRkYpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgemUuZ2V0RXh0ZXJuYWxBdHRyaWJ1dGVzKCkgICYgMHhGRkZGKTsKKworICAgICAgICB6ZS5zZXRVbml4TW9kZSgwNDQ0KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIHplLmdldFBsYXRmb3JtKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMDQ0NCwKKyAgICAgICAgICAgICAgICAgICAgICh6ZS5nZXRFeHRlcm5hbEF0dHJpYnV0ZXMoKSA+PiAxNikgJiAweEZGRkYpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgemUuZ2V0RXh0ZXJuYWxBdHRyaWJ1dGVzKCkgICYgMHhGRkZGKTsKKworICAgICAgICB6ZSA9IG5ldyBaaXBBcmNoaXZlRW50cnkoImZvby8iKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIHplLmdldFBsYXRmb3JtKCkpOworICAgICAgICB6ZS5zZXRVbml4TW9kZSgwNzc3KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIHplLmdldFBsYXRmb3JtKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMDc3NywKKyAgICAgICAgICAgICAgICAgICAgICh6ZS5nZXRFeHRlcm5hbEF0dHJpYnV0ZXMoKSA+PiAxNikgJiAweEZGRkYpOworICAgICAgICBhc3NlcnRFcXVhbHMoMHgxMCwgemUuZ2V0RXh0ZXJuYWxBdHRyaWJ1dGVzKCkgICYgMHhGRkZGKTsKKworICAgICAgICB6ZS5zZXRVbml4TW9kZSgwNTc3KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIHplLmdldFBsYXRmb3JtKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMDU3NywKKyAgICAgICAgICAgICAgICAgICAgICh6ZS5nZXRFeHRlcm5hbEF0dHJpYnV0ZXMoKSA+PiAxNikgJiAweEZGRkYpOworICAgICAgICBhc3NlcnRFcXVhbHMoMHgxMSwgemUuZ2V0RXh0ZXJuYWxBdHRyaWJ1dGVzKCkgICYgMHhGRkZGKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGNhc2UgZm9yCisgICAgICogPGEgaHJlZj0iaHR0cHM6Ly9pc3N1ZXMuYXBhY2hlLm9yZy9qaXJhL2Jyb3dzZS9DT01QUkVTUy05MyIKKyAgICAgKiA+Q09NUFJFU1MtOTM8L2E+LgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdENvbXByZXNzaW9uTWV0aG9kKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFppcEFyY2hpdmVPdXRwdXRTdHJlYW0gem9zID0KKyAgICAgICAgICAgIG5ldyBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKSk7CisgICAgICAgIGZpbmFsIFppcEFyY2hpdmVFbnRyeSBlbnRyeSA9IG5ldyBaaXBBcmNoaXZlRW50cnkoImZvbyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIGVudHJ5LmdldE1ldGhvZCgpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2Uoem9zLmNhbldyaXRlRW50cnlEYXRhKGVudHJ5KSk7CisKKyAgICAgICAgZW50cnkuc2V0TWV0aG9kKFppcEVudHJ5LlNUT1JFRCk7CisgICAgICAgIGFzc2VydEVxdWFscyhaaXBFbnRyeS5TVE9SRUQsIGVudHJ5LmdldE1ldGhvZCgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh6b3MuY2FuV3JpdGVFbnRyeURhdGEoZW50cnkpKTsKKworICAgICAgICBlbnRyeS5zZXRNZXRob2QoWmlwRW50cnkuREVGTEFURUQpOworICAgICAgICBhc3NlcnRFcXVhbHMoWmlwRW50cnkuREVGTEFURUQsIGVudHJ5LmdldE1ldGhvZCgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh6b3MuY2FuV3JpdGVFbnRyeURhdGEoZW50cnkpKTsKKworICAgICAgICAvLyBUZXN0IHRoZSB1bnN1cHBvcnRlZCAiaW1wbG9kZWQiIGNvbXByZXNzaW9uIG1ldGhvZCAoNikKKyAgICAgICAgZW50cnkuc2V0TWV0aG9kKDYpOworICAgICAgICBhc3NlcnRFcXVhbHMoNiwgZW50cnkuZ2V0TWV0aG9kKCkpOworICAgICAgICBhc3NlcnRGYWxzZSh6b3MuY2FuV3JpdGVFbnRyeURhdGEoZW50cnkpKTsKKyAgICAgICAgem9zLmNsb3NlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBjYXNlIGZvcgorICAgICAqIDxhIGhyZWY9Imh0dHBzOi8vaXNzdWVzLmFwYWNoZS5vcmcvamlyYS9icm93c2UvQ09NUFJFU1MtOTQiCisgICAgICogPkNPTVBSRVNTLTk0PC9hPi4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3ROb3RFcXVhbHMoKSB7CisgICAgICAgIGZpbmFsIFppcEFyY2hpdmVFbnRyeSBlbnRyeTEgPSBuZXcgWmlwQXJjaGl2ZUVudHJ5KCJmb28iKTsKKyAgICAgICAgZmluYWwgWmlwQXJjaGl2ZUVudHJ5IGVudHJ5MiA9IG5ldyBaaXBBcmNoaXZlRW50cnkoImJhciIpOworICAgICAgICBhc3NlcnRGYWxzZShlbnRyeTEuZXF1YWxzKGVudHJ5MikpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3RzIGNvbW1lbnQncyBpbmZsdWVuY2Ugb24gZXF1YWxzIGNvbXBhcmlzb25zLgorICAgICAqIEBzZWUgImh0dHBzOi8vaXNzdWVzLmFwYWNoZS5vcmcvamlyYS9icm93c2UvQ09NUFJFU1MtMTg3IgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdE51bGxDb21tZW50RXF1YWxzRW1wdHlDb21tZW50KCkgeworICAgICAgICBmaW5hbCBaaXBBcmNoaXZlRW50cnkgZW50cnkxID0gbmV3IFppcEFyY2hpdmVFbnRyeSgiZm9vIik7CisgICAgICAgIGZpbmFsIFppcEFyY2hpdmVFbnRyeSBlbnRyeTIgPSBuZXcgWmlwQXJjaGl2ZUVudHJ5KCJmb28iKTsKKyAgICAgICAgZmluYWwgWmlwQXJjaGl2ZUVudHJ5IGVudHJ5MyA9IG5ldyBaaXBBcmNoaXZlRW50cnkoImZvbyIpOworICAgICAgICBlbnRyeTEuc2V0Q29tbWVudChudWxsKTsKKyAgICAgICAgZW50cnkyLnNldENvbW1lbnQoIiIpOworICAgICAgICBlbnRyeTMuc2V0Q29tbWVudCgiYmFyIik7CisgICAgICAgIGFzc2VydEVxdWFscyhlbnRyeTEsIGVudHJ5Mik7CisgICAgICAgIGFzc2VydEZhbHNlKGVudHJ5MS5lcXVhbHMoZW50cnkzKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGVudHJ5Mi5lcXVhbHMoZW50cnkzKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29weUNvbnN0cnVjdG9yKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFppcEFyY2hpdmVFbnRyeSBhcmNoaXZlRW50cnkgPSBuZXcgWmlwQXJjaGl2ZUVudHJ5KCJmcmVkIik7CisgICAgICAgIGFyY2hpdmVFbnRyeS5zZXRVbml4TW9kZSgwNjY0KTsKKyAgICAgICAgYXJjaGl2ZUVudHJ5LnNldE1ldGhvZChaaXBFbnRyeS5ERUZMQVRFRCk7CisgICAgICAgIGFyY2hpdmVFbnRyeS5nZXRHZW5lcmFsUHVycG9zZUJpdCgpLnVzZVN0cm9uZ0VuY3J5cHRpb24odHJ1ZSk7CisgICAgICAgIGZpbmFsIFppcEFyY2hpdmVFbnRyeSBjb3B5ID0gbmV3IFppcEFyY2hpdmVFbnRyeShhcmNoaXZlRW50cnkpOworICAgICAgICBhc3NlcnRFcXVhbHMoYXJjaGl2ZUVudHJ5LCBjb3B5KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlICJodHRwczovL2lzc3Vlcy5hcGFjaGUub3JnL2ppcmEvYnJvd3NlL0NPTVBSRVNTLTM3OSIKKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIGlzVW5peFN5bWxpbmtJc0ZhbHNlSWZNb3JlVGhhbk9uZUZsYWdJc1NldCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgKFppcEZpbGUgemYgPSBuZXcgWmlwRmlsZShnZXRGaWxlKCJDT01QUkVTUy0zNzkuamFyIikpKSB7CisgICAgICAgICAgICBaaXBBcmNoaXZlRW50cnkgemUgPSB6Zi5nZXRFbnRyeSgiTUVUQS1JTkYvbWF2ZW4vIik7CisgICAgICAgICAgICBhc3NlcnRGYWxzZSh6ZS5pc1VuaXhTeW1saW5rKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SXNVbml4U3ltbGluaygpIHsKKyAgICAgICAgWmlwQXJjaGl2ZUVudHJ5IHplID0gbmV3IFppcEFyY2hpdmVFbnRyeSgiZm9vIik7CisgICAgICAgIHplLnNldFVuaXhNb2RlKFVuaXhTdGF0LkxJTktfRkxBRyk7CisgICAgICAgIGFzc2VydFRydWUoemUuaXNVbml4U3ltbGluaygpKTsKKyAgICAgICAgemUuc2V0VW5peE1vZGUoVW5peFN0YXQuTElOS19GTEFHIHwgVW5peFN0YXQuRElSX0ZMQUcpOworICAgICAgICBhc3NlcnRGYWxzZSh6ZS5pc1VuaXhTeW1saW5rKCkpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9aaXBBcmNoaXZlSW5wdXRTdHJlYW1UZXN0LmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1ppcEFyY2hpdmVJbnB1dFN0cmVhbVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iOTM5NWZiCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9aaXBBcmNoaXZlSW5wdXRTdHJlYW1UZXN0LmphdmEKQEAgLTAsMCArMSw1MTYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcDsKKworaW1wb3J0IHN0YXRpYyBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuQWJzdHJhY3RUZXN0Q2FzZS5nZXRGaWxlOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEFycmF5RXF1YWxzOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEVxdWFsczsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRGYWxzZTsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUcnVlOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmZhaWw7CisKK2ltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkVPRkV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLnppcC5aaXBFeGNlcHRpb247CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLkFyY2hpdmVFbnRyeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuSU9VdGlsczsKK2ltcG9ydCBvcmcuanVuaXQuQXNzZXJ0OworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworCitwdWJsaWMgY2xhc3MgWmlwQXJjaGl2ZUlucHV0U3RyZWFtVGVzdCB7CisKKyAgICAvKioKKyAgICAgKiBAc2VlICJodHRwczovL2lzc3Vlcy5hcGFjaGUub3JnL2ppcmEvYnJvd3NlL0NPTVBSRVNTLTE3NiIKKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHdpbnppcEJhY2tTbGFzaFdvcmthcm91bmQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgWmlwQXJjaGl2ZUlucHV0U3RyZWFtIGluID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGluID0gbmV3IFppcEFyY2hpdmVJbnB1dFN0cmVhbShuZXcgRmlsZUlucHV0U3RyZWFtKGdldEZpbGUoInRlc3Qtd2luemlwLnppcCIpKSk7CisgICAgICAgICAgICBaaXBBcmNoaXZlRW50cnkgemFlID0gaW4uZ2V0TmV4dFppcEVudHJ5KCk7CisgICAgICAgICAgICB6YWUgPSBpbi5nZXROZXh0WmlwRW50cnkoKTsKKyAgICAgICAgICAgIHphZSA9IGluLmdldE5leHRaaXBFbnRyeSgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJcdTAwZTQvIiwgemFlLmdldE5hbWUoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAoaW4gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGluLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlICJodHRwczovL2lzc3Vlcy5hcGFjaGUub3JnL2ppcmEvYnJvd3NlL0NPTVBSRVNTLTE4OSIKKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHByb3BlclVzZU9mSW5mbGF0ZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgWmlwRmlsZSB6ZiA9IG51bGw7CisgICAgICAgIFppcEFyY2hpdmVJbnB1dFN0cmVhbSBpbiA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB6ZiA9IG5ldyBaaXBGaWxlKGdldEZpbGUoIkNPTVBSRVNTLTE4OS56aXAiKSk7CisgICAgICAgICAgICBmaW5hbCBaaXBBcmNoaXZlRW50cnkgemFlID0gemYuZ2V0RW50cnkoIlVTRDA1NTg2ODItMjAwODAxMDEuWklQIik7CisgICAgICAgICAgICBpbiA9IG5ldyBaaXBBcmNoaXZlSW5wdXRTdHJlYW0obmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0oemYuZ2V0SW5wdXRTdHJlYW0oemFlKSkpOworICAgICAgICAgICAgWmlwQXJjaGl2ZUVudHJ5IGlubmVyRW50cnk7CisgICAgICAgICAgICB3aGlsZSAoKGlubmVyRW50cnkgPSBpbi5nZXROZXh0WmlwRW50cnkoKSkgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGlmIChpbm5lckVudHJ5LmdldE5hbWUoKS5lbmRzV2l0aCgiWE1MIikpIHsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgwIDwgaW4ucmVhZCgpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAoemYgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHpmLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoaW4gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGluLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHNob3VsZENvbnN1bWVBcmNoaXZlQ29tcGxldGVseSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBJbnB1dFN0cmVhbSBpcyA9IFppcEFyY2hpdmVJbnB1dFN0cmVhbVRlc3QuY2xhc3MKKyAgICAgICAgICAgIC5nZXRSZXNvdXJjZUFzU3RyZWFtKCIvYXJjaGl2ZV93aXRoX3RyYWlsZXIuemlwIik7CisgICAgICAgIGZpbmFsIFppcEFyY2hpdmVJbnB1dFN0cmVhbSB6aXAgPSBuZXcgWmlwQXJjaGl2ZUlucHV0U3RyZWFtKGlzKTsKKyAgICAgICAgd2hpbGUgKHppcC5nZXROZXh0WmlwRW50cnkoKSAhPSBudWxsKSB7CisgICAgICAgICAgICAvLyBqdXN0IGNvbnN1bWUgdGhlIGFyY2hpdmUKKyAgICAgICAgfQorICAgICAgICBmaW5hbCBieXRlW10gZXhwZWN0ZWQgPSBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICdIJywgJ2UnLCAnbCcsICdsJywgJ28nLCAnLCcsICcgJywgJ3cnLCAnbycsICdyJywgJ2wnLCAnZCcsICchJywgJ1xuJworICAgICAgICB9OworICAgICAgICBmaW5hbCBieXRlW10gYWN0dWFsID0gbmV3IGJ5dGVbZXhwZWN0ZWQubGVuZ3RoXTsKKyAgICAgICAgaXMucmVhZChhY3R1YWwpOworICAgICAgICBhc3NlcnRBcnJheUVxdWFscyhleHBlY3RlZCwgYWN0dWFsKTsKKyAgICAgICAgemlwLmNsb3NlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSAiaHR0cHM6Ly9pc3N1ZXMuYXBhY2hlLm9yZy9qaXJhL2Jyb3dzZS9DT01QUkVTUy0yMTkiCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBzaG91bGRSZWFkTmVzdGVkWmlwKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgWmlwQXJjaGl2ZUlucHV0U3RyZWFtIGluID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGluID0gbmV3IFppcEFyY2hpdmVJbnB1dFN0cmVhbShuZXcgRmlsZUlucHV0U3RyZWFtKGdldEZpbGUoIkNPTVBSRVNTLTIxOS56aXAiKSkpOworICAgICAgICAgICAgZXh0cmFjdFppcElucHV0U3RyZWFtKGluKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmIChpbiAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBleHRyYWN0WmlwSW5wdXRTdHJlYW0oZmluYWwgWmlwQXJjaGl2ZUlucHV0U3RyZWFtIGluKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBaaXBBcmNoaXZlRW50cnkgemFlID0gaW4uZ2V0TmV4dFppcEVudHJ5KCk7CisgICAgICAgIHdoaWxlICh6YWUgIT0gbnVsbCkgeworICAgICAgICAgICAgaWYgKHphZS5nZXROYW1lKCkuZW5kc1dpdGgoIi56aXAiKSkgeworICAgICAgICAgICAgICAgIGV4dHJhY3RaaXBJbnB1dFN0cmVhbShuZXcgWmlwQXJjaGl2ZUlucHV0U3RyZWFtKGluKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB6YWUgPSBpbi5nZXROZXh0WmlwRW50cnkoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFVuc2hyaW5rRW50cnkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgWmlwQXJjaGl2ZUlucHV0U3RyZWFtIGluID0gbmV3IFppcEFyY2hpdmVJbnB1dFN0cmVhbShuZXcgRmlsZUlucHV0U3RyZWFtKGdldEZpbGUoIlNIUlVOSy5aSVAiKSkpOworCisgICAgICAgIFppcEFyY2hpdmVFbnRyeSBlbnRyeSA9IGluLmdldE5leHRaaXBFbnRyeSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm1ldGhvZCIsIFppcE1ldGhvZC5VTlNIUklOS0lORy5nZXRDb2RlKCksIGVudHJ5LmdldE1ldGhvZCgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShpbi5jYW5SZWFkRW50cnlEYXRhKGVudHJ5KSk7CisKKyAgICAgICAgRmlsZUlucHV0U3RyZWFtIG9yaWdpbmFsID0gbmV3IEZpbGVJbnB1dFN0cmVhbShnZXRGaWxlKCJ0ZXN0MS54bWwiKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc3NlcnRBcnJheUVxdWFscyhJT1V0aWxzLnRvQnl0ZUFycmF5KG9yaWdpbmFsKSwgSU9VdGlscy50b0J5dGVBcnJheShpbikpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgb3JpZ2luYWwuY2xvc2UoKTsKKyAgICAgICAgfQorCisgICAgICAgIGVudHJ5ID0gaW4uZ2V0TmV4dFppcEVudHJ5KCk7CisgICAgICAgIGFzc2VydEVxdWFscygibWV0aG9kIiwgWmlwTWV0aG9kLlVOU0hSSU5LSU5HLmdldENvZGUoKSwgZW50cnkuZ2V0TWV0aG9kKCkpOworICAgICAgICBhc3NlcnRUcnVlKGluLmNhblJlYWRFbnRyeURhdGEoZW50cnkpKTsKKworICAgICAgICBvcmlnaW5hbCA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oZ2V0RmlsZSgidGVzdDIueG1sIikpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMoSU9VdGlscy50b0J5dGVBcnJheShvcmlnaW5hbCksIElPVXRpbHMudG9CeXRlQXJyYXkoaW4pKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIG9yaWdpbmFsLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFRlc3QgY2FzZSBmb3IKKyAgICAgKiA8YSBocmVmPSJodHRwczovL2lzc3Vlcy5hcGFjaGUub3JnL2ppcmEvYnJvd3NlL0NPTVBSRVNTLTI2NCIKKyAgICAgKiA+Q09NUFJFU1MtMjY0PC9hPi4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RSZWFkaW5nT2ZGaXJzdFN0b3JlZEVudHJ5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisKKyAgICAgICAgdHJ5IChaaXBBcmNoaXZlSW5wdXRTdHJlYW0gaW4gPSBuZXcgWmlwQXJjaGl2ZUlucHV0U3RyZWFtKG5ldyBGaWxlSW5wdXRTdHJlYW0oZ2V0RmlsZSgiQ09NUFJFU1MtMjY0LnppcCIpKSkpIHsKKyAgICAgICAgICAgIGZpbmFsIFppcEFyY2hpdmVFbnRyeSB6ZSA9IGluLmdldE5leHRaaXBFbnRyeSgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDUsIHplLmdldFNpemUoKSk7CisgICAgICAgICAgICBhc3NlcnRBcnJheUVxdWFscyhuZXcgYnl0ZVtdIHsgJ2QnLCAnYScsICd0JywgJ2EnLCAnXG4nIH0sCisgICAgICAgICAgICAgICAgICAgIElPVXRpbHMudG9CeXRlQXJyYXkoaW4pKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgY2FzZSBmb3IKKyAgICAgKiA8YSBocmVmPSJodHRwczovL2lzc3Vlcy5hcGFjaGUub3JnL2ppcmEvYnJvd3NlL0NPTVBSRVNTLTM1MSIKKyAgICAgKiA+Q09NUFJFU1MtMzUxPC9hPi4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RNZXNzYWdlV2l0aENvcnJ1cHRGaWxlTmFtZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgKFppcEFyY2hpdmVJbnB1dFN0cmVhbSBpbiA9IG5ldyBaaXBBcmNoaXZlSW5wdXRTdHJlYW0obmV3IEZpbGVJbnB1dFN0cmVhbShnZXRGaWxlKCJDT01QUkVTUy0zNTEuemlwIikpKSkgeworICAgICAgICAgICAgWmlwQXJjaGl2ZUVudHJ5IHplID0gaW4uZ2V0TmV4dFppcEVudHJ5KCk7CisgICAgICAgICAgICB3aGlsZSAoemUgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHplID0gaW4uZ2V0TmV4dFppcEVudHJ5KCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBFT0ZFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgRU9GRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBmaW5hbCBTdHJpbmcgbSA9IGV4LmdldE1lc3NhZ2UoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUobS5zdGFydHNXaXRoKCJUcnVuY2F0ZWQgWklQIGVudHJ5OiA/MjAxNiIpKTsgLy8gdGhlIGZpcnN0IGNoYXJhY3RlciBpcyBub3QgcHJpbnRhYmxlCisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RVbnppcEJaaXAyQ29tcHJlc3NlZEVudHJ5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisKKyAgICAgICAgdHJ5IChaaXBBcmNoaXZlSW5wdXRTdHJlYW0gaW4gPSBuZXcgWmlwQXJjaGl2ZUlucHV0U3RyZWFtKG5ldyBGaWxlSW5wdXRTdHJlYW0oZ2V0RmlsZSgiYnppcDItemlwLnppcCIpKSkpIHsKKyAgICAgICAgICAgIGZpbmFsIFppcEFyY2hpdmVFbnRyeSB6ZSA9IGluLmdldE5leHRaaXBFbnRyeSgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDQyLCB6ZS5nZXRTaXplKCkpOworICAgICAgICAgICAgZmluYWwgYnl0ZVtdIGV4cGVjdGVkID0gbmV3IGJ5dGVbNDJdOworICAgICAgICAgICAgQXJyYXlzLmZpbGwoZXhwZWN0ZWQsIChieXRlKSAnYScpOworICAgICAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMoZXhwZWN0ZWQsIElPVXRpbHMudG9CeXRlQXJyYXkoaW4pKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgImh0dHBzOi8vaXNzdWVzLmFwYWNoZS5vcmcvamlyYS9icm93c2UvQ09NUFJFU1MtMzgwIgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgcmVhZERlZmxhdGU2NENvbXByZXNzZWRTdHJlYW0oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgRmlsZSBpbnB1dCA9IGdldEZpbGUoIkNPTVBSRVNTLTM4MC9DT01QUkVTUy0zODAtaW5wdXQiKTsKKyAgICAgICAgZmluYWwgRmlsZSBhcmNoaXZlID0gZ2V0RmlsZSgiQ09NUFJFU1MtMzgwL0NPTVBSRVNTLTM4MC56aXAiKTsKKyAgICAgICAgdHJ5IChGaWxlSW5wdXRTdHJlYW0gaW4gPSBuZXcgRmlsZUlucHV0U3RyZWFtKGlucHV0KTsKKyAgICAgICAgICAgICBaaXBBcmNoaXZlSW5wdXRTdHJlYW0gemluID0gbmV3IFppcEFyY2hpdmVJbnB1dFN0cmVhbShuZXcgRmlsZUlucHV0U3RyZWFtKGFyY2hpdmUpKSkgeworICAgICAgICAgICAgYnl0ZVtdIG9yaWcgPSBJT1V0aWxzLnRvQnl0ZUFycmF5KGluKTsKKyAgICAgICAgICAgIFppcEFyY2hpdmVFbnRyeSBlID0gemluLmdldE5leHRaaXBFbnRyeSgpOworICAgICAgICAgICAgYnl0ZVtdIGZyb21aaXAgPSBJT1V0aWxzLnRvQnl0ZUFycmF5KHppbik7CisgICAgICAgICAgICBhc3NlcnRBcnJheUVxdWFscyhvcmlnLCBmcm9tWmlwKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgcmVhZERlZmxhdGU2NENvbXByZXNzZWRTdHJlYW1XaXRoRGF0YURlc2NyaXB0b3IoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gdGhpcyBpcyBhIGNvcHkgb2YgYmxhLmphciB3aXRoIE1FVEEtSU5GL01BTklGRVNULk1GJ3MgbWV0aG9kIG1hbnVhbGx5IGNoYW5nZWQgdG8gRU5IQU5DRURfREVGTEFURUQKKyAgICAgICAgZmluYWwgRmlsZSBhcmNoaXZlID0gZ2V0RmlsZSgiQ09NUFJFU1MtMzgwL0NPTVBSRVNTLTM4MC1kZC56aXAiKTsKKyAgICAgICAgdHJ5IChaaXBBcmNoaXZlSW5wdXRTdHJlYW0gemluID0gbmV3IFppcEFyY2hpdmVJbnB1dFN0cmVhbShuZXcgRmlsZUlucHV0U3RyZWFtKGFyY2hpdmUpKSkgeworICAgICAgICAgICAgWmlwQXJjaGl2ZUVudHJ5IGUgPSB6aW4uZ2V0TmV4dFppcEVudHJ5KCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIGUuZ2V0U2l6ZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhaaXBNZXRob2QuRU5IQU5DRURfREVGTEFURUQuZ2V0Q29kZSgpLCBlLmdldE1ldGhvZCgpKTsKKyAgICAgICAgICAgIGJ5dGVbXSBmcm9tWmlwID0gSU9VdGlscy50b0J5dGVBcnJheSh6aW4pOworICAgICAgICAgICAgYnl0ZVtdIGV4cGVjdGVkID0gbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAgICAgJ00nLCAnYScsICduJywgJ2knLCAnZicsICdlJywgJ3MnLCAndCcsICctJywgJ1YnLCAnZScsICdyJywgJ3MnLCAnaScsICdvJywgJ24nLCAnOicsICcgJywgJzEnLCAnLicsICcwJywKKyAgICAgICAgICAgICAgICAnXHInLCAnXG4nLCAnXHInLCAnXG4nCisgICAgICAgICAgICB9OworICAgICAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMoZXhwZWN0ZWQsIGZyb21aaXApOworICAgICAgICAgICAgemluLmdldE5leHRaaXBFbnRyeSgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDI1LCBlLmdldFNpemUoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGNhc2UgZm9yCisgICAgICogPGEgaHJlZj0iaHR0cHM6Ly9pc3N1ZXMuYXBhY2hlLm9yZy9qaXJhL2Jyb3dzZS9DT01QUkVTUy0zNjQiCisgICAgICogPkNPTVBSRVNTLTM2NDwvYT4uCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0V2l0aEJ5dGVzQWZ0ZXJEYXRhKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIGludCBleHBlY3RlZE51bUVudHJpZXMgPSAyOworICAgICAgICBmaW5hbCBJbnB1dFN0cmVhbSBpcyA9IFppcEFyY2hpdmVJbnB1dFN0cmVhbVRlc3QuY2xhc3MKKyAgICAgICAgICAgICAgICAuZ2V0UmVzb3VyY2VBc1N0cmVhbSgiL2FyY2hpdmVfd2l0aF9ieXRlc19hZnRlcl9kYXRhLnppcCIpOworICAgICAgICBmaW5hbCBaaXBBcmNoaXZlSW5wdXRTdHJlYW0gemlwID0gbmV3IFppcEFyY2hpdmVJbnB1dFN0cmVhbShpcyk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGludCBhY3R1YWxOdW1FbnRyaWVzID0gMDsKKyAgICAgICAgICAgIFppcEFyY2hpdmVFbnRyeSB6YWUgPSB6aXAuZ2V0TmV4dFppcEVudHJ5KCk7CisgICAgICAgICAgICB3aGlsZSAoemFlICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBhY3R1YWxOdW1FbnRyaWVzKys7CisgICAgICAgICAgICAgICAgcmVhZEVudHJ5KHppcCwgemFlKTsKKyAgICAgICAgICAgICAgICB6YWUgPSB6aXAuZ2V0TmV4dFppcEVudHJ5KCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWROdW1FbnRyaWVzLCBhY3R1YWxOdW1FbnRyaWVzKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHppcC5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogPGNvZGU+Z2V0TmV4dFppcEVudHJ5KCk8L2NvZGU+IHNob3VsZCB0aHJvdyBhIDxjb2RlPlppcEV4Y2VwdGlvbjwvY29kZT4gcmF0aGVyIHRoYW4gcmV0dXJuCisgICAgICogPGNvZGU+bnVsbDwvY29kZT4gd2hlbiBhbiB1bmV4cGVjdGVkIHN0cnVjdHVyZSBpcyBlbmNvdW50ZXJlZC4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RUaHJvd09uSW52YWxpZEVudHJ5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIElucHV0U3RyZWFtIGlzID0gWmlwQXJjaGl2ZUlucHV0U3RyZWFtVGVzdC5jbGFzcworICAgICAgICAgICAgICAgIC5nZXRSZXNvdXJjZUFzU3RyZWFtKCIvaW52YWxpZC16aXAuemlwIik7CisgICAgICAgIGZpbmFsIFppcEFyY2hpdmVJbnB1dFN0cmVhbSB6aXAgPSBuZXcgWmlwQXJjaGl2ZUlucHV0U3RyZWFtKGlzKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgemlwLmdldE5leHRaaXBFbnRyeSgpOworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoWmlwRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKGV4cGVjdGVkLmdldE1lc3NhZ2UoKS5jb250YWlucygiVW5leHBlY3RlZCByZWNvcmQgc2lnbmF0dXJlIikpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgemlwLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGNvcnJlY3QgcG9wdWxhdGlvbiBvZiBoZWFkZXIgYW5kIGRhdGEgb2Zmc2V0cy4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RPZmZzZXRzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIG1peGVkLnppcCBjb250YWlucyBib3RoIGluZmxhdGVkIGFuZCBzdG9yZWQgZmlsZXMKKyAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBhcmNoaXZlU3RyZWFtID0gWmlwQXJjaGl2ZUlucHV0U3RyZWFtLmNsYXNzLmdldFJlc291cmNlQXNTdHJlYW0oIi9taXhlZC56aXAiKTsKKyAgICAgICAgICAgICBaaXBBcmNoaXZlSW5wdXRTdHJlYW0gemlwU3RyZWFtID0gIG5ldyBaaXBBcmNoaXZlSW5wdXRTdHJlYW0oKGFyY2hpdmVTdHJlYW0pKQorICAgICAgICApIHsKKyAgICAgICAgICAgIFppcEFyY2hpdmVFbnRyeSBpbmZsYXRlZEVudHJ5ID0gemlwU3RyZWFtLmdldE5leHRaaXBFbnRyeSgpOworICAgICAgICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygiaW5mbGF0ZWQudHh0IiwgaW5mbGF0ZWRFbnRyeS5nZXROYW1lKCkpOworICAgICAgICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygweDAwMDAsIGluZmxhdGVkRW50cnkuZ2V0TG9jYWxIZWFkZXJPZmZzZXQoKSk7CisgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDB4MDA0NiwgaW5mbGF0ZWRFbnRyeS5nZXREYXRhT2Zmc2V0KCkpOworICAgICAgICAgICAgWmlwQXJjaGl2ZUVudHJ5IHN0b3JlZEVudHJ5ID0gemlwU3RyZWFtLmdldE5leHRaaXBFbnRyeSgpOworICAgICAgICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygic3RvcmVkLnR4dCIsIHN0b3JlZEVudHJ5LmdldE5hbWUoKSk7CisgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDB4NTg5Miwgc3RvcmVkRW50cnkuZ2V0TG9jYWxIZWFkZXJPZmZzZXQoKSk7CisgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDB4NThkNiwgc3RvcmVkRW50cnkuZ2V0RGF0YU9mZnNldCgpKTsKKyAgICAgICAgICAgIEFzc2VydC5hc3NlcnROdWxsKHppcFN0cmVhbS5nZXROZXh0WmlwRW50cnkoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIG5hbWVTb3VyY2VEZWZhdWx0c1RvTmFtZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBuYW1lU291cmNlKCJibGEuemlwIiwgInRlc3QxLnhtbCIsIFppcEFyY2hpdmVFbnRyeS5OYW1lU291cmNlLk5BTUUpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgbmFtZVNvdXJjZUlzU2V0VG9Vbmljb2RlRXh0cmFGaWVsZCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBuYW1lU291cmNlKCJ1dGY4LXdpbnppcC10ZXN0LnppcCIsICJcdTIwQUNfZm9yX0RvbGxhci50eHQiLAorICAgICAgICAgICAgICAgICAgIFppcEFyY2hpdmVFbnRyeS5OYW1lU291cmNlLlVOSUNPREVfRVhUUkFfRklFTEQpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgbmFtZVNvdXJjZUlzU2V0VG9FRlMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgbmFtZVNvdXJjZSgidXRmOC03emlwLXRlc3QuemlwIiwgIlx1MjBBQ19mb3JfRG9sbGFyLnR4dCIsIDMsCisgICAgICAgICAgICAgICAgICAgWmlwQXJjaGl2ZUVudHJ5Lk5hbWVTb3VyY2UuTkFNRV9XSVRIX0VGU19GTEFHKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHByb3Blcmx5TWFya3NFbnRyaWVzQXNVbnJlYWRhYmxlSWZVbmNvbXByZXNzZWRTaXplSXNVbmtub3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIHdlIG5ldmVyIHJlYWQgYW55IGRhdGEKKyAgICAgICAgdHJ5IChaaXBBcmNoaXZlSW5wdXRTdHJlYW0gemlzID0gbmV3IFppcEFyY2hpdmVJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0obmV3IGJ5dGVbMF0pKSkgeworICAgICAgICAgICAgWmlwQXJjaGl2ZUVudHJ5IGUgPSBuZXcgWmlwQXJjaGl2ZUVudHJ5KCJ0ZXN0Iik7CisgICAgICAgICAgICBlLnNldE1ldGhvZChaaXBNZXRob2QuREVGTEFURUQuZ2V0Q29kZSgpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoemlzLmNhblJlYWRFbnRyeURhdGEoZSkpOworICAgICAgICAgICAgZS5zZXRNZXRob2QoWmlwTWV0aG9kLkVOSEFOQ0VEX0RFRkxBVEVELmdldENvZGUoKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKHppcy5jYW5SZWFkRW50cnlEYXRhKGUpKTsKKyAgICAgICAgICAgIGUuc2V0TWV0aG9kKFppcE1ldGhvZC5CWklQMi5nZXRDb2RlKCkpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoemlzLmNhblJlYWRFbnRyeURhdGEoZSkpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBzaW5nbGVCeXRlUmVhZENvbnNpc3RlbnRseVJldHVybnNNaW51c09uZUF0RW9mVXNpbmdEZWZsYXRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHNpbmdsZUJ5dGVSZWFkQ29uc2lzdGVudGx5UmV0dXJuc01pbnVzT25lQXRFb2YoZ2V0RmlsZSgiYmxhLnppcCIpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHNpbmdsZUJ5dGVSZWFkQ29uc2lzdGVudGx5UmV0dXJuc01pbnVzT25lQXRFb2ZVc2luZ1N0b3JlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHNpbmdsZUJ5dGVSZWFkQ29uc2lzdGVudGx5UmV0dXJuc01pbnVzT25lQXRFb2YoZ2V0RmlsZSgiQ09NUFJFU1MtMjY0LnppcCIpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHNpbmdsZUJ5dGVSZWFkQ29uc2lzdGVudGx5UmV0dXJuc01pbnVzT25lQXRFb2ZVc2luZ1Vuc2hyaW5rKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHNpbmdsZUJ5dGVSZWFkQ29uc2lzdGVudGx5UmV0dXJuc01pbnVzT25lQXRFb2YoZ2V0RmlsZSgiU0hSVU5LLlpJUCIpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHNpbmdsZUJ5dGVSZWFkQ29uc2lzdGVudGx5UmV0dXJuc01pbnVzT25lQXRFb2ZVc2luZ0V4cGxvZGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc2luZ2xlQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZihnZXRGaWxlKCJpbXBsb2RpbmctOEtkaWN0LTN0cmVlcy56aXAiKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBzaW5nbGVCeXRlUmVhZENvbnNpc3RlbnRseVJldHVybnNNaW51c09uZUF0RW9mVXNpbmdEZWZsYXRlNjQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc2luZ2xlQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZihnZXRGaWxlKCJDT01QUkVTUy0zODAvQ09NUFJFU1MtMzgwLnppcCIpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHNpbmdsZUJ5dGVSZWFkQ29uc2lzdGVudGx5UmV0dXJuc01pbnVzT25lQXRFb2ZVc2luZ0J6aXAyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHNpbmdsZUJ5dGVSZWFkQ29uc2lzdGVudGx5UmV0dXJuc01pbnVzT25lQXRFb2YoZ2V0RmlsZSgiYnppcDItemlwLnppcCIpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgc2luZ2xlQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZihGaWxlIGZpbGUpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgKEZpbGVJbnB1dFN0cmVhbSBpbiA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oZmlsZSk7CisgICAgICAgICAgICAgWmlwQXJjaGl2ZUlucHV0U3RyZWFtIGFyY2hpdmUgPSBuZXcgWmlwQXJjaGl2ZUlucHV0U3RyZWFtKGluKSkgeworICAgICAgICAgICAgQXJjaGl2ZUVudHJ5IGUgPSBhcmNoaXZlLmdldE5leHRFbnRyeSgpOworICAgICAgICAgICAgSU9VdGlscy50b0J5dGVBcnJheShhcmNoaXZlKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygtMSwgYXJjaGl2ZS5yZWFkKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBhcmNoaXZlLnJlYWQoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIG11bHRpQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZlVzaW5nRGVmbGF0ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBtdWx0aUJ5dGVSZWFkQ29uc2lzdGVudGx5UmV0dXJuc01pbnVzT25lQXRFb2YoZ2V0RmlsZSgiYmxhLnppcCIpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIG11bHRpQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZlVzaW5nU3RvcmUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgbXVsdGlCeXRlUmVhZENvbnNpc3RlbnRseVJldHVybnNNaW51c09uZUF0RW9mKGdldEZpbGUoIkNPTVBSRVNTLTI2NC56aXAiKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBtdWx0aUJ5dGVSZWFkQ29uc2lzdGVudGx5UmV0dXJuc01pbnVzT25lQXRFb2ZVc2luZ1Vuc2hyaW5rKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIG11bHRpQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZihnZXRGaWxlKCJTSFJVTksuWklQIikpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgbXVsdGlCeXRlUmVhZENvbnNpc3RlbnRseVJldHVybnNNaW51c09uZUF0RW9mVXNpbmdFeHBsb2RlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIG11bHRpQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZihnZXRGaWxlKCJpbXBsb2RpbmctOEtkaWN0LTN0cmVlcy56aXAiKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBtdWx0aUJ5dGVSZWFkQ29uc2lzdGVudGx5UmV0dXJuc01pbnVzT25lQXRFb2ZVc2luZ0RlZmxhdGU2NCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBtdWx0aUJ5dGVSZWFkQ29uc2lzdGVudGx5UmV0dXJuc01pbnVzT25lQXRFb2YoZ2V0RmlsZSgiQ09NUFJFU1MtMzgwL0NPTVBSRVNTLTM4MC56aXAiKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBtdWx0aUJ5dGVSZWFkQ29uc2lzdGVudGx5UmV0dXJuc01pbnVzT25lQXRFb2ZVc2luZ0J6aXAyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIG11bHRpQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZihnZXRGaWxlKCJiemlwMi16aXAuemlwIikpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBtdWx0aUJ5dGVSZWFkQ29uc2lzdGVudGx5UmV0dXJuc01pbnVzT25lQXRFb2YoRmlsZSBmaWxlKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGJ1ZiA9IG5ldyBieXRlWzJdOworICAgICAgICB0cnkgKEZpbGVJbnB1dFN0cmVhbSBpbiA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oZ2V0RmlsZSgiYmxhLnppcCIpKTsKKyAgICAgICAgICAgICBaaXBBcmNoaXZlSW5wdXRTdHJlYW0gYXJjaGl2ZSA9IG5ldyBaaXBBcmNoaXZlSW5wdXRTdHJlYW0oaW4pKSB7CisgICAgICAgICAgICBBcmNoaXZlRW50cnkgZSA9IGFyY2hpdmUuZ2V0TmV4dEVudHJ5KCk7CisgICAgICAgICAgICBJT1V0aWxzLnRvQnl0ZUFycmF5KGFyY2hpdmUpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBhcmNoaXZlLnJlYWQoYnVmKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIGFyY2hpdmUucmVhZChidWYpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgc2luZ2xlQnl0ZVJlYWRUaHJvd3NBdEVvZkZvckNvcnJ1cHRlZFN0b3JlZEVudHJ5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBjb250ZW50OworICAgICAgICB0cnkgKEZpbGVJbnB1dFN0cmVhbSBmcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oZ2V0RmlsZSgiQ09NUFJFU1MtMjY0LnppcCIpKSkgeworICAgICAgICAgICAgY29udGVudCA9IElPVXRpbHMudG9CeXRlQXJyYXkoZnMpOworICAgICAgICB9CisgICAgICAgIC8vIG1ha2Ugc2l6ZSBtdWNoIGJpZ2dlciB0aGFuIGVudHJ5J3MgcmVhbCBzaXplCisgICAgICAgIGZvciAoaW50IGkgPSAxNzsgaSA8IDI2OyBpKyspIHsKKyAgICAgICAgICAgIGNvbnRlbnRbaV0gPSAoYnl0ZSkgMHhmZjsKKyAgICAgICAgfQorICAgICAgICB0cnkgKEJ5dGVBcnJheUlucHV0U3RyZWFtIGluID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGNvbnRlbnQpOworICAgICAgICAgICAgIFppcEFyY2hpdmVJbnB1dFN0cmVhbSBhcmNoaXZlID0gbmV3IFppcEFyY2hpdmVJbnB1dFN0cmVhbShpbikpIHsKKyAgICAgICAgICAgIEFyY2hpdmVFbnRyeSBlID0gYXJjaGl2ZS5nZXROZXh0RW50cnkoKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgSU9VdGlscy50b0J5dGVBcnJheShhcmNoaXZlKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBleGNlcHRpb24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJUcnVuY2F0ZWQgWklQIGZpbGUiLCBleC5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBhcmNoaXZlLnJlYWQoKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBleGNlcHRpb24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJUcnVuY2F0ZWQgWklQIGZpbGUiLCBleC5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBhcmNoaXZlLnJlYWQoKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBleGNlcHRpb24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJUcnVuY2F0ZWQgWklQIGZpbGUiLCBleC5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBtdWx0aUJ5dGVSZWFkVGhyb3dzQXRFb2ZGb3JDb3JydXB0ZWRTdG9yZWRFbnRyeSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBieXRlW10gY29udGVudDsKKyAgICAgICAgdHJ5IChGaWxlSW5wdXRTdHJlYW0gZnMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGdldEZpbGUoIkNPTVBSRVNTLTI2NC56aXAiKSkpIHsKKyAgICAgICAgICAgIGNvbnRlbnQgPSBJT1V0aWxzLnRvQnl0ZUFycmF5KGZzKTsKKyAgICAgICAgfQorICAgICAgICAvLyBtYWtlIHNpemUgbXVjaCBiaWdnZXIgdGhhbiBlbnRyeSdzIHJlYWwgc2l6ZQorICAgICAgICBmb3IgKGludCBpID0gMTc7IGkgPCAyNjsgaSsrKSB7CisgICAgICAgICAgICBjb250ZW50W2ldID0gKGJ5dGUpIDB4ZmY7CisgICAgICAgIH0KKyAgICAgICAgYnl0ZVtdIGJ1ZiA9IG5ldyBieXRlWzJdOworICAgICAgICB0cnkgKEJ5dGVBcnJheUlucHV0U3RyZWFtIGluID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGNvbnRlbnQpOworICAgICAgICAgICAgIFppcEFyY2hpdmVJbnB1dFN0cmVhbSBhcmNoaXZlID0gbmV3IFppcEFyY2hpdmVJbnB1dFN0cmVhbShpbikpIHsKKyAgICAgICAgICAgIEFyY2hpdmVFbnRyeSBlID0gYXJjaGl2ZS5nZXROZXh0RW50cnkoKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgSU9VdGlscy50b0J5dGVBcnJheShhcmNoaXZlKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBleGNlcHRpb24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJUcnVuY2F0ZWQgWklQIGZpbGUiLCBleC5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBhcmNoaXZlLnJlYWQoYnVmKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBleGNlcHRpb24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJUcnVuY2F0ZWQgWklQIGZpbGUiLCBleC5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBhcmNoaXZlLnJlYWQoYnVmKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBleGNlcHRpb24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJUcnVuY2F0ZWQgWklQIGZpbGUiLCBleC5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgYnl0ZVtdIHJlYWRFbnRyeShaaXBBcmNoaXZlSW5wdXRTdHJlYW0gemlwLCBaaXBBcmNoaXZlRW50cnkgemFlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBpbnQgbGVuID0gKGludCl6YWUuZ2V0U2l6ZSgpOworICAgICAgICBmaW5hbCBieXRlW10gYnVmZiA9IG5ldyBieXRlW2xlbl07CisgICAgICAgIHppcC5yZWFkKGJ1ZmYsIDAsIGxlbik7CisKKyAgICAgICAgcmV0dXJuIGJ1ZmY7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBuYW1lU291cmNlKFN0cmluZyBhcmNoaXZlLCBTdHJpbmcgZW50cnksIFppcEFyY2hpdmVFbnRyeS5OYW1lU291cmNlIGV4cGVjdGVkKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgbmFtZVNvdXJjZShhcmNoaXZlLCBlbnRyeSwgMSwgZXhwZWN0ZWQpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgbmFtZVNvdXJjZShTdHJpbmcgYXJjaGl2ZSwgU3RyaW5nIGVudHJ5LCBpbnQgZW50cnlObywgWmlwQXJjaGl2ZUVudHJ5Lk5hbWVTb3VyY2UgZXhwZWN0ZWQpCisgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgKFppcEFyY2hpdmVJbnB1dFN0cmVhbSB6aXMgPSBuZXcgWmlwQXJjaGl2ZUlucHV0U3RyZWFtKG5ldyBGaWxlSW5wdXRTdHJlYW0oZ2V0RmlsZShhcmNoaXZlKSkpKSB7CisgICAgICAgICAgICBaaXBBcmNoaXZlRW50cnkgemU7CisgICAgICAgICAgICBkbyB7CisgICAgICAgICAgICAgICAgemUgPSB6aXMuZ2V0TmV4dFppcEVudHJ5KCk7CisgICAgICAgICAgICB9IHdoaWxlICgtLWVudHJ5Tm8gPiAwKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhlbnRyeSwgemUuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZCwgemUuZ2V0TmFtZVNvdXJjZSgpKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvWmlwQ2xhc3NDb3ZlcmFnZVRlc3QuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvWmlwQ2xhc3NDb3ZlcmFnZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wNTk1ODc3Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9aaXBDbGFzc0NvdmVyYWdlVGVzdC5qYXZhCkBAIC0wLDAgKzEsNTkgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcDsKKworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEVxdWFsczsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRGYWxzZTsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnROb3ROdWxsOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydFRoYXQ7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5JbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uOworaW1wb3J0IG9yZy5oYW1jcmVzdC5jb3JlLklzSW5zdGFuY2VPZjsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworcHVibGljIGNsYXNzIFppcENsYXNzQ292ZXJhZ2VUZXN0IHsKKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdENvbnN0cnVjdFppcDY0UmVxdWlyZWRFeGNlcHRpb24oKSB7CisgICAgICAgIFppcDY0UmVxdWlyZWRFeGNlcHRpb24gZSA9IG5ldyBaaXA2NFJlcXVpcmVkRXhjZXB0aW9uKCJjcml0aXF1ZSBvZiBwdXJlIik7CisgICAgICAgIGFzc2VydE5vdE51bGwoZSk7CisgICAgfQorICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdE1lc3NhZ2VFeGNlcHRpb24oKSB7CisgICAgICAgIFppcEFyY2hpdmVFbnRyeSB6ZSA9IG5ldyBaaXBBcmNoaXZlRW50cnkoImhlbGxvIik7CisgICAgICAgIFN0cmluZyBlbnRyeVRvb0JpZ01lc3NhZ2UgPSBaaXA2NFJlcXVpcmVkRXhjZXB0aW9uLmdldEVudHJ5VG9vQmlnTWVzc2FnZSh6ZSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaGVsbG8ncyBzaXplIGV4Y2VlZHMgdGhlIGxpbWl0IG9mIDRHQnl0ZS4iLAorICAgICAgICAgICAgZW50cnlUb29CaWdNZXNzYWdlKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RDb25zdGFudENvbnN0cnVjdG9yKCkKKyAgICAgICAgdGhyb3dzIE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiwgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiwgSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbiwgSW5zdGFudGlhdGlvbkV4Y2VwdGlvbiB7CisgICAgICAgIENsYXNzPFppcENvbnN0YW50cz4gY2xhenogPSBaaXBDb25zdGFudHMuY2xhc3M7CisgICAgICAgIENvbnN0cnVjdG9yPFppcENvbnN0YW50cz4gY29uc3RydWN0b3IgPSBjbGF6ei5nZXREZWNsYXJlZENvbnN0cnVjdG9yKCk7CisgICAgICAgIGFzc2VydEZhbHNlKGNvbnN0cnVjdG9yLmlzQWNjZXNzaWJsZSgpKTsKKyAgICAgICAgY29uc3RydWN0b3Iuc2V0QWNjZXNzaWJsZSh0cnVlKTsKKyAgICAgICAgT2JqZWN0IG8gPSBjb25zdHJ1Y3Rvci5uZXdJbnN0YW5jZSgpOworICAgICAgICBhc3NlcnRUaGF0KG8sIElzSW5zdGFuY2VPZi5pbnN0YW5jZU9mKGNsYXp6KSk7CisgICAgICAgIGNvbnN0cnVjdG9yLnNldEFjY2Vzc2libGUoZmFsc2UpOworCisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1ppcEVpZ2h0Qnl0ZUludGVnZXJUZXN0LmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1ppcEVpZ2h0Qnl0ZUludGVnZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTM4ZjgxOQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvWmlwRWlnaHRCeXRlSW50ZWdlclRlc3QuamF2YQpAQCAtMCwwICsxLDEyMiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICoKKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwOworCitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuKjsKKworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworCitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CisKKy8qKgorICogSlVuaXQgdGVzdGNhc2VzIGZvciBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcC5aaXBFaWdodEJ5dGVJbnRlZ2VyLgorICoKKyAqLworcHVibGljIGNsYXNzIFppcEVpZ2h0Qnl0ZUludGVnZXJUZXN0IHsKKworICAgIC8qKgorICAgICAqIFRlc3QgY29udmVyc2lvbiB0byBieXRlcy4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RMb25nVG9CeXRlcygpIHsKKyAgICAgICAgZmluYWwgWmlwRWlnaHRCeXRlSW50ZWdlciB6bCA9IG5ldyBaaXBFaWdodEJ5dGVJbnRlZ2VyKDB4QUIxMjM0NTY3OGwpOworICAgICAgICBmaW5hbCBieXRlW10gcmVzdWx0ID0gemwuZ2V0Qnl0ZXMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJsZW5ndGggZ2V0Qnl0ZXMiLCA4LCByZXN1bHQubGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmaXJzdCBieXRlIGdldEJ5dGVzIiwgMHg3OCwgcmVzdWx0WzBdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJzZWNvbmQgYnl0ZSBnZXRCeXRlcyIsIDB4NTYsIHJlc3VsdFsxXSk7CisgICAgICAgIGFzc2VydEVxdWFscygidGhpcmQgYnl0ZSBnZXRCeXRlcyIsIDB4MzQsIHJlc3VsdFsyXSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZm91cnRoIGJ5dGUgZ2V0Qnl0ZXMiLCAweDEyLCByZXN1bHRbM10pOworICAgICAgICBhc3NlcnRFcXVhbHMoImZpZnRoIGJ5dGUgZ2V0Qnl0ZXMiLCAoYnl0ZSkgMHhBQiwgcmVzdWx0WzRdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJzaXh0aCBieXRlIGdldEJ5dGVzIiwgMCwgcmVzdWx0WzVdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJzZXZlbnRoIGJ5dGUgZ2V0Qnl0ZXMiLCAwLCByZXN1bHRbNl0pOworICAgICAgICBhc3NlcnRFcXVhbHMoImVpZ2h0aCBieXRlIGdldEJ5dGVzIiwgMCwgcmVzdWx0WzddKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGNvbnZlcnNpb24gZnJvbSBieXRlcy4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RMb25nRnJvbUJ5dGVzKCkgeworICAgICAgICBmaW5hbCBieXRlW10gdmFsID0gbmV3IGJ5dGVbXSB7MHg3OCwgMHg1NiwgMHgzNCwgMHgxMiwgKGJ5dGUpIDB4QUIsIDB4MDAsIDB4MDAsIDB4MDB9OworICAgICAgICBmaW5hbCBaaXBFaWdodEJ5dGVJbnRlZ2VyIHpsID0gbmV3IFppcEVpZ2h0Qnl0ZUludGVnZXIodmFsKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJsb25nVmFsdWUgZnJvbSBieXRlcyIsIDB4QUIxMjM0NTY3OGwsIHpsLmdldExvbmdWYWx1ZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGNvbnZlcnNpb24gdG8gYnl0ZXMuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QklUb0J5dGVzKCkgeworICAgICAgICBmaW5hbCBaaXBFaWdodEJ5dGVJbnRlZ2VyIHpsID0KKyAgICAgICAgICAgIG5ldyBaaXBFaWdodEJ5dGVJbnRlZ2VyKEJpZ0ludGVnZXIudmFsdWVPZihMb25nLk1BWF9WQUxVRSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zaGlmdExlZnQoMSkpOworICAgICAgICBmaW5hbCBieXRlW10gcmVzdWx0ID0gemwuZ2V0Qnl0ZXMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJsZW5ndGggZ2V0Qnl0ZXMiLCA4LCByZXN1bHQubGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmaXJzdCBieXRlIGdldEJ5dGVzIiwgKGJ5dGUpIDB4RkUsIHJlc3VsdFswXSk7CisgICAgICAgIGFzc2VydEVxdWFscygic2Vjb25kIGJ5dGUgZ2V0Qnl0ZXMiLCAoYnl0ZSkgMHhGRiwgcmVzdWx0WzFdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0aGlyZCBieXRlIGdldEJ5dGVzIiwgKGJ5dGUpIDB4RkYsIHJlc3VsdFsyXSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZm91cnRoIGJ5dGUgZ2V0Qnl0ZXMiLCAoYnl0ZSkgMHhGRiwgcmVzdWx0WzNdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmaWZ0aCBieXRlIGdldEJ5dGVzIiwgKGJ5dGUpIDB4RkYsIHJlc3VsdFs0XSk7CisgICAgICAgIGFzc2VydEVxdWFscygic2l4dGggYnl0ZSBnZXRCeXRlcyIsIChieXRlKSAweEZGLCByZXN1bHRbNV0pOworICAgICAgICBhc3NlcnRFcXVhbHMoInNldmVudGggYnl0ZSBnZXRCeXRlcyIsIChieXRlKSAweEZGLCByZXN1bHRbNl0pOworICAgICAgICBhc3NlcnRFcXVhbHMoImVpZ2h0aCBieXRlIGdldEJ5dGVzIiwgKGJ5dGUpIDB4RkYsIHJlc3VsdFs3XSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBjb252ZXJzaW9uIGZyb20gYnl0ZXMuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QklGcm9tQnl0ZXMoKSB7CisgICAgICAgIGZpbmFsIGJ5dGVbXSB2YWwgPSBuZXcgYnl0ZVtdIHsoYnl0ZSkgMHhGRSwgKGJ5dGUpIDB4RkYsIChieXRlKSAweEZGLCAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4RkYsIChieXRlKSAweEZGLCAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4RkZ9OworICAgICAgICBmaW5hbCBaaXBFaWdodEJ5dGVJbnRlZ2VyIHpsID0gbmV3IFppcEVpZ2h0Qnl0ZUludGVnZXIodmFsKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ2YWx1ZSBmcm9tIGJ5dGVzIiwKKyAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIudmFsdWVPZihMb25nLk1BWF9WQUxVRSkuc2hpZnRMZWZ0KDEpLAorICAgICAgICAgICAgICAgICAgICAgemwuZ2V0VmFsdWUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB0aGUgY29udHJhY3Qgb2YgdGhlIGVxdWFscyBtZXRob2QuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RXF1YWxzKCkgeworICAgICAgICBmaW5hbCBaaXBFaWdodEJ5dGVJbnRlZ2VyIHpsID0gbmV3IFppcEVpZ2h0Qnl0ZUludGVnZXIoMHgxMjM0NTY3OCk7CisgICAgICAgIGZpbmFsIFppcEVpZ2h0Qnl0ZUludGVnZXIgemwyID0gbmV3IFppcEVpZ2h0Qnl0ZUludGVnZXIoMHgxMjM0NTY3OCk7CisgICAgICAgIGZpbmFsIFppcEVpZ2h0Qnl0ZUludGVnZXIgemwzID0gbmV3IFppcEVpZ2h0Qnl0ZUludGVnZXIoMHg4NzY1NDMyMSk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgicmVmbGV4aXZlIiwgemwuZXF1YWxzKHpsKSk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgid29ya3MiLCB6bC5lcXVhbHMoemwyKSk7CisgICAgICAgIGFzc2VydFRydWUoIndvcmtzLCBwYXJ0IHR3byIsICF6bC5lcXVhbHMoemwzKSk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgic3ltbWV0cmljIiwgemwyLmVxdWFscyh6bCkpOworCisgICAgICAgIGFzc2VydFRydWUoIm51bGwgaGFuZGxpbmciLCAhemwuZXF1YWxzKG51bGwpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgibm9uIFppcEVpZ2h0Qnl0ZUludGVnZXIgaGFuZGxpbmciLCAhemwuZXF1YWxzKG5ldyBJbnRlZ2VyKDB4MTIzNCkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHNpZ24gaGFuZGxpbmcuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2lnbigpIHsKKyAgICAgICAgZmluYWwgWmlwRWlnaHRCeXRlSW50ZWdlciB6bCA9IG5ldyBaaXBFaWdodEJ5dGVJbnRlZ2VyKG5ldyBieXRlW10geyhieXRlKTB4RkYsIChieXRlKTB4RkYsIChieXRlKTB4RkYsIChieXRlKTB4RkYsIChieXRlKTB4RkYsIChieXRlKTB4RkYsIChieXRlKTB4RkYsIChieXRlKTB4RkZ9KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEJpZ0ludGVnZXIudmFsdWVPZihMb25nLk1BWF9WQUxVRSkuc2hpZnRMZWZ0KDEpLnNldEJpdCgwKSwKKyAgICAgICAgICAgICAgICAgICAgIHpsLmdldFZhbHVlKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvWmlwRW5jb2RpbmdUZXN0LmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1ppcEVuY29kaW5nVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFmNzk4ZDAKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1ppcEVuY29kaW5nVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTk0IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcDsKKworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEZhbHNlOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydE5vdE51bGw7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VGhhdDsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUcnVlOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldDsKK2ltcG9ydCBvcmcuaGFtY3Jlc3QuY29yZS5Jc0luc3RhbmNlT2Y7CitpbXBvcnQgb3JnLmp1bml0LkFzc2VydDsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworLyoqCisgKiBUZXN0IHppcCBlbmNvZGluZ3MuCisgKi8KK3B1YmxpYyBjbGFzcyBaaXBFbmNvZGluZ1Rlc3QgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFVORU5DX1NUUklORyA9ICJcdTIwMTYiOworCisgICAgLy8gc3RyZXNzIHRlc3QgZm9yIGludGVybmFsIGdyb3cgbWV0aG9kLgorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBCQURfU1RSSU5HID0KKyAgICAgICAgIlx1MjAxNlx1MjAxNVx1MjAxNlx1MjAxNVx1MjAxNlx1MjAxNVx1MjAxNlx1MjAxNVx1MjAxNlx1MjAxNVx1MjAxNiI7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQkFEX1NUUklOR19FTkMgPQorICAgICAgICAiJVUyMDE2JVUyMDE1JVUyMDE2JVUyMDE1JVUyMDE2JVUyMDE1JVUyMDE2JVUyMDE1JVUyMDE2JVUyMDE1JVUyMDE2IjsKKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdE5vdGhpbmdUb01ha2VDb3ZlcmFsbHNIYXBwaWVyKCkgeworICAgICAgICBPYmplY3QgbyA9IG5ldyBaaXBFbmNvZGluZ0hlbHBlcigpIHsKKyAgICAgICAgfTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChvKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXROb25leGlzdGVudEVuY29kbmcoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBaaXBFbmNvZGluZyB6ZSA9IFppcEVuY29kaW5nSGVscGVyLmdldFppcEVuY29kaW5nKCJJLWFtLWEtYmFuYW5hIik7CisgICAgICAgIGFzc2VydE5vdE51bGwoemUpOworICAgICAgICBpZiAoemUgaW5zdGFuY2VvZiBDaGFyc2V0QWNjZXNzb3IpIHsKKyAgICAgICAgICAgIENoYXJzZXRBY2Nlc3NvciBoYXNDaGFyc2V0ID0gKENoYXJzZXRBY2Nlc3NvcikgemU7CisgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKENoYXJzZXQuZGVmYXVsdENoYXJzZXQoKSwgaGFzQ2hhcnNldC5nZXRDaGFyc2V0KCkpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SXNVVEY4KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICBhc3NlcnRUcnVlKFppcEVuY29kaW5nSGVscGVyLmlzVVRGOCgiVVRGLTgiKSk7CisgICAgICAgYXNzZXJ0VHJ1ZShaaXBFbmNvZGluZ0hlbHBlci5pc1VURjgoIlVURjgiKSk7CisgICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyhDaGFyc2V0LmRlZmF1bHRDaGFyc2V0KCkubmFtZSgpLmVxdWFscygiVVRGLTgiKSwgWmlwRW5jb2RpbmdIZWxwZXIuaXNVVEY4KG51bGwpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RTaW1wbGVDcDQzN0VuY29kaW5nKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZG9TaW1wbGVFbmNvZGluZ3NUZXN0KDQzNyk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2ltcGxlQ3A4NTBFbmNvZGluZygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGRvU2ltcGxlRW5jb2RpbmdzVGVzdCg4NTApOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEViY2lkaWMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCisgICAgICAgIGRvU2ltcGxlRW5jb2RpbmdUZXN0KCJJQk0xMDQ3IiwgbnVsbCk7CisgICAgfQorCisKKyAgICBwcml2YXRlIHZvaWQgZG9TaW1wbGVFbmNvZGluZ3NUZXN0KGludCBuKSB0aHJvd3MgSU9FeGNlcHRpb24geworCisgICAgICAgIGRvU2ltcGxlRW5jb2RpbmdUZXN0KCJDcCIgKyBuLCBudWxsKTsKKyAgICAgICAgZG9TaW1wbGVFbmNvZGluZ1Rlc3QoImNwIiArIG4sIG51bGwpOworICAgICAgICBkb1NpbXBsZUVuY29kaW5nVGVzdCgiQ1AiICsgbiwgbnVsbCk7CisgICAgICAgIGRvU2ltcGxlRW5jb2RpbmdUZXN0KCJJQk0iICsgbiwgbnVsbCk7CisgICAgICAgIGRvU2ltcGxlRW5jb2RpbmdUZXN0KCJpYm0iICsgbiwgbnVsbCk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TmlvQ3AxMjUyRW5jb2RpbmcoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBDUDEyNTIgaGFzIHNvbWUgdW5kZWZpbmVkIGNvZGUgcG9pbnRzLCB0aGVzZSBhcmUKKyAgICAgICAgLy8gdGhlIGRlZmluZWQgb25lcworICAgICAgICAvLyByZXRyaWV2ZWQgYnkKKyAgICAgICAgLy8gICAgYXdrICcvXjB4LyAmJiBORj4yIHtwcmludCAkMTt9JyBDUDEyNTIuVFhUCisgICAgICAgIGZpbmFsIGJ5dGVbXSBiID0KKyAgICAgICAgICAgIG5ldyBieXRlW10geyAweDAwLCAweDAxLCAweDAyLCAweDAzLCAweDA0LCAweDA1LCAweDA2LCAweDA3LAorICAgICAgICAgICAgICAgICAgICAgICAgIDB4MDgsIDB4MDksIDB4MEEsIDB4MEIsIDB4MEMsIDB4MEQsIDB4MEUsIDB4MEYsCisgICAgICAgICAgICAgICAgICAgICAgICAgMHgxMCwgMHgxMSwgMHgxMiwgMHgxMywgMHgxNCwgMHgxNSwgMHgxNiwgMHgxNywKKyAgICAgICAgICAgICAgICAgICAgICAgICAweDE4LCAweDE5LCAweDFBLCAweDFCLCAweDFDLCAweDFELCAweDFFLCAweDFGLAorICAgICAgICAgICAgICAgICAgICAgICAgIDB4MjAsIDB4MjEsIDB4MjIsIDB4MjMsIDB4MjQsIDB4MjUsIDB4MjYsIDB4MjcsCisgICAgICAgICAgICAgICAgICAgICAgICAgMHgyOCwgMHgyOSwgMHgyQSwgMHgyQiwgMHgyQywgMHgyRCwgMHgyRSwgMHgyRiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAweDMwLCAweDMxLCAweDMyLCAweDMzLCAweDM0LCAweDM1LCAweDM2LCAweDM3LAorICAgICAgICAgICAgICAgICAgICAgICAgIDB4MzgsIDB4MzksIDB4M0EsIDB4M0IsIDB4M0MsIDB4M0QsIDB4M0UsIDB4M0YsCisgICAgICAgICAgICAgICAgICAgICAgICAgMHg0MCwgMHg0MSwgMHg0MiwgMHg0MywgMHg0NCwgMHg0NSwgMHg0NiwgMHg0NywKKyAgICAgICAgICAgICAgICAgICAgICAgICAweDQ4LCAweDQ5LCAweDRBLCAweDRCLCAweDRDLCAweDRELCAweDRFLCAweDRGLAorICAgICAgICAgICAgICAgICAgICAgICAgIDB4NTAsIDB4NTEsIDB4NTIsIDB4NTMsIDB4NTQsIDB4NTUsIDB4NTYsIDB4NTcsCisgICAgICAgICAgICAgICAgICAgICAgICAgMHg1OCwgMHg1OSwgMHg1QSwgMHg1QiwgMHg1QywgMHg1RCwgMHg1RSwgMHg1RiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAweDYwLCAweDYxLCAweDYyLCAweDYzLCAweDY0LCAweDY1LCAweDY2LCAweDY3LAorICAgICAgICAgICAgICAgICAgICAgICAgIDB4NjgsIDB4NjksIDB4NkEsIDB4NkIsIDB4NkMsIDB4NkQsIDB4NkUsIDB4NkYsCisgICAgICAgICAgICAgICAgICAgICAgICAgMHg3MCwgMHg3MSwgMHg3MiwgMHg3MywgMHg3NCwgMHg3NSwgMHg3NiwgMHg3NywKKyAgICAgICAgICAgICAgICAgICAgICAgICAweDc4LCAweDc5LCAweDdBLCAweDdCLCAweDdDLCAweDdELCAweDdFLCAweDdGLAorICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweDgwLCAoYnl0ZSkgMHg4MiwgKGJ5dGUpIDB4ODMsIChieXRlKSAweDg0LAorICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweDg1LCAoYnl0ZSkgMHg4NiwgKGJ5dGUpIDB4ODcsIChieXRlKSAweDg4LAorICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweDg5LCAoYnl0ZSkgMHg4QSwgKGJ5dGUpIDB4OEIsIChieXRlKSAweDhDLAorICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweDhFLCAoYnl0ZSkgMHg5MSwgKGJ5dGUpIDB4OTIsIChieXRlKSAweDkzLAorICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweDk0LCAoYnl0ZSkgMHg5NSwgKGJ5dGUpIDB4OTYsIChieXRlKSAweDk3LAorICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweDk4LCAoYnl0ZSkgMHg5OSwgKGJ5dGUpIDB4OUEsIChieXRlKSAweDlCLAorICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweDlDLCAoYnl0ZSkgMHg5RSwgKGJ5dGUpIDB4OUYsIChieXRlKSAweEEwLAorICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweEExLCAoYnl0ZSkgMHhBMiwgKGJ5dGUpIDB4QTMsIChieXRlKSAweEE0LAorICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweEE1LCAoYnl0ZSkgMHhBNiwgKGJ5dGUpIDB4QTcsIChieXRlKSAweEE4LAorICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweEE5LCAoYnl0ZSkgMHhBQSwgKGJ5dGUpIDB4QUIsIChieXRlKSAweEFDLAorICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweEFELCAoYnl0ZSkgMHhBRSwgKGJ5dGUpIDB4QUYsIChieXRlKSAweEIwLAorICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweEIxLCAoYnl0ZSkgMHhCMiwgKGJ5dGUpIDB4QjMsIChieXRlKSAweEI0LAorICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweEI1LCAoYnl0ZSkgMHhCNiwgKGJ5dGUpIDB4QjcsIChieXRlKSAweEI4LAorICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweEI5LCAoYnl0ZSkgMHhCQSwgKGJ5dGUpIDB4QkIsIChieXRlKSAweEJDLAorICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweEJELCAoYnl0ZSkgMHhCRSwgKGJ5dGUpIDB4QkYsIChieXRlKSAweEMwLAorICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweEMxLCAoYnl0ZSkgMHhDMiwgKGJ5dGUpIDB4QzMsIChieXRlKSAweEM0LAorICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweEM1LCAoYnl0ZSkgMHhDNiwgKGJ5dGUpIDB4QzcsIChieXRlKSAweEM4LAorICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweEM5LCAoYnl0ZSkgMHhDQSwgKGJ5dGUpIDB4Q0IsIChieXRlKSAweENDLAorICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweENELCAoYnl0ZSkgMHhDRSwgKGJ5dGUpIDB4Q0YsIChieXRlKSAweEQwLAorICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweEQxLCAoYnl0ZSkgMHhEMiwgKGJ5dGUpIDB4RDMsIChieXRlKSAweEQ0LAorICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweEQ1LCAoYnl0ZSkgMHhENiwgKGJ5dGUpIDB4RDcsIChieXRlKSAweEQ4LAorICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweEQ5LCAoYnl0ZSkgMHhEQSwgKGJ5dGUpIDB4REIsIChieXRlKSAweERDLAorICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweERELCAoYnl0ZSkgMHhERSwgKGJ5dGUpIDB4REYsIChieXRlKSAweEUwLAorICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweEUxLCAoYnl0ZSkgMHhFMiwgKGJ5dGUpIDB4RTMsIChieXRlKSAweEU0LAorICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweEU1LCAoYnl0ZSkgMHhFNiwgKGJ5dGUpIDB4RTcsIChieXRlKSAweEU4LAorICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweEU5LCAoYnl0ZSkgMHhFQSwgKGJ5dGUpIDB4RUIsIChieXRlKSAweEVDLAorICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweEVELCAoYnl0ZSkgMHhFRSwgKGJ5dGUpIDB4RUYsIChieXRlKSAweEYwLAorICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweEYxLCAoYnl0ZSkgMHhGMiwgKGJ5dGUpIDB4RjMsIChieXRlKSAweEY0LAorICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweEY1LCAoYnl0ZSkgMHhGNiwgKGJ5dGUpIDB4RjcsIChieXRlKSAweEY4LAorICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweEY5LCAoYnl0ZSkgMHhGQSwgKGJ5dGUpIDB4RkIsIChieXRlKSAweEZDLAorICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAweEZELCAoYnl0ZSkgMHhGRSwgKGJ5dGUpIDB4RkYgfTsKKworICAgICAgICBkb1NpbXBsZUVuY29kaW5nVGVzdCgiQ3AxMjUyIixiKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGFzc2VydEVxdWFscyhmaW5hbCBieXRlW10gZXhwZWN0ZWQsIGZpbmFsIEJ5dGVCdWZmZXIgYWN0dWFsKSB7CisKKyAgICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyhleHBlY3RlZC5sZW5ndGgsIGFjdHVhbC5saW1pdCgpKTsKKworICAgICAgICBmb3IgKGZpbmFsIGJ5dGUgYW5FeHBlY3RlZCA6IGV4cGVjdGVkKSB7CisgICAgICAgICAgICBmaW5hbCBieXRlIGEgPSBhY3R1YWwuZ2V0KCk7CisgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKGFuRXhwZWN0ZWQsIGEpOworICAgICAgICB9CisKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgZG9TaW1wbGVFbmNvZGluZ1Rlc3QoZmluYWwgU3RyaW5nIG5hbWUsIGJ5dGVbXSB0ZXN0Qnl0ZXMpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisKKyAgICAgICAgZmluYWwgWmlwRW5jb2RpbmcgZW5jID0gWmlwRW5jb2RpbmdIZWxwZXIuZ2V0WmlwRW5jb2RpbmcobmFtZSk7CisgICAgICAgIGFzc2VydFRoYXQoZW5jLCBJc0luc3RhbmNlT2YuaW5zdGFuY2VPZihOaW9aaXBFbmNvZGluZy5jbGFzcykpOworICAgICAgICBpZiAodGVzdEJ5dGVzID09IG51bGwpIHsKKworICAgICAgICAgICAgdGVzdEJ5dGVzID0gbmV3IGJ5dGVbMjU2XTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMjU2OyArK2kpIHsKKyAgICAgICAgICAgICAgICB0ZXN0Qnl0ZXNbaV0gPSAoYnl0ZSkgaTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIFN0cmluZyBkZWNvZGVkID0gZW5jLmRlY29kZSh0ZXN0Qnl0ZXMpOworCisgICAgICAgIGFzc2VydFRydWUoZW5jLmNhbkVuY29kZShkZWNvZGVkKSk7CisKKyAgICAgICAgZmluYWwgQnl0ZUJ1ZmZlciBlbmNvZGVkID0gZW5jLmVuY29kZShkZWNvZGVkKTsKKworICAgICAgICBhc3NlcnRFcXVhbHModGVzdEJ5dGVzLCBlbmNvZGVkKTsKKworICAgICAgICBhc3NlcnRGYWxzZShlbmMuY2FuRW5jb2RlKFVORU5DX1NUUklORykpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiVVMjAxNiIuZ2V0Qnl0ZXMobmFtZSksIGVuYy5lbmNvZGUoVU5FTkNfU1RSSU5HKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGVuYy5jYW5FbmNvZGUoQkFEX1NUUklORykpOworICAgICAgICBhc3NlcnRFcXVhbHMoQkFEX1NUUklOR19FTkMuZ2V0Qnl0ZXMobmFtZSksIGVuYy5lbmNvZGUoQkFEX1NUUklORykpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9aaXBGaWxlVGVzdC5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9aaXBGaWxlVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNiNmQxOTcKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1ppcEZpbGVUZXN0LmphdmEKQEAgLTAsMCArMSw4MDIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcDsKKworaW1wb3J0IHN0YXRpYyBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuQWJzdHJhY3RUZXN0Q2FzZS5nZXRGaWxlOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0Lio7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXQ7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKK2ltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuVHJlZU1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5hdG9taWMuQXRvbWljSW50ZWdlcjsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLkNSQzMyOworaW1wb3J0IGphdmEudXRpbC56aXAuWmlwRW50cnk7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuSU9VdGlsczsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuU2Vla2FibGVJbk1lbW9yeUJ5dGVDaGFubmVsOworaW1wb3J0IG9yZy5qdW5pdC5BZnRlcjsKK2ltcG9ydCBvcmcuanVuaXQuQXNzZXJ0OworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworCitwdWJsaWMgY2xhc3MgWmlwRmlsZVRlc3QgeworICAgIHByaXZhdGUgWmlwRmlsZSB6ZiA9IG51bGw7CisKKyAgICBAQWZ0ZXIKKyAgICBwdWJsaWMgdm9pZCB0ZWFyRG93bigpIHsKKyAgICAgICAgWmlwRmlsZS5jbG9zZVF1aWV0bHkoemYpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdENET3JkZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgcmVhZE9yZGVyVGVzdCgpOworICAgICAgICBmaW5hbCBBcnJheUxpc3Q8WmlwQXJjaGl2ZUVudHJ5PiBsID0gQ29sbGVjdGlvbnMubGlzdCh6Zi5nZXRFbnRyaWVzKCkpOworICAgICAgICBhc3NlcnRFbnRyeU5hbWUobCwgMCwgIkFic3RyYWN0VW5pY29kZUV4dHJhRmllbGQiKTsKKyAgICAgICAgYXNzZXJ0RW50cnlOYW1lKGwsIDEsICJBc2lFeHRyYUZpZWxkIik7CisgICAgICAgIGFzc2VydEVudHJ5TmFtZShsLCAyLCAiRXh0cmFGaWVsZFV0aWxzIik7CisgICAgICAgIGFzc2VydEVudHJ5TmFtZShsLCAzLCAiRmFsbGJhY2taaXBFbmNvZGluZyIpOworICAgICAgICBhc3NlcnRFbnRyeU5hbWUobCwgNCwgIkdlbmVyYWxQdXJwb3NlQml0Iik7CisgICAgICAgIGFzc2VydEVudHJ5TmFtZShsLCA1LCAiSmFyTWFya2VyIik7CisgICAgICAgIGFzc2VydEVudHJ5TmFtZShsLCA2LCAiTmlvWmlwRW5jb2RpbmciKTsKKyAgICAgICAgYXNzZXJ0RW50cnlOYW1lKGwsIDcsICJTaW1wbGU4Qml0WmlwRW5jb2RpbmciKTsKKyAgICAgICAgYXNzZXJ0RW50cnlOYW1lKGwsIDgsICJVbmljb2RlQ29tbWVudEV4dHJhRmllbGQiKTsKKyAgICAgICAgYXNzZXJ0RW50cnlOYW1lKGwsIDksICJVbmljb2RlUGF0aEV4dHJhRmllbGQiKTsKKyAgICAgICAgYXNzZXJ0RW50cnlOYW1lKGwsIDEwLCAiVW5peFN0YXQiKTsKKyAgICAgICAgYXNzZXJ0RW50cnlOYW1lKGwsIDExLCAiVW5wYXJzZWFibGVFeHRyYUZpZWxkRGF0YSIpOworICAgICAgICBhc3NlcnRFbnRyeU5hbWUobCwgMTIsICJVbnJlY29nbml6ZWRFeHRyYUZpZWxkIik7CisgICAgICAgIGFzc2VydEVudHJ5TmFtZShsLCAxMywgIlppcEFyY2hpdmVFbnRyeSIpOworICAgICAgICBhc3NlcnRFbnRyeU5hbWUobCwgMTQsICJaaXBBcmNoaXZlSW5wdXRTdHJlYW0iKTsKKyAgICAgICAgYXNzZXJ0RW50cnlOYW1lKGwsIDE1LCAiWmlwQXJjaGl2ZU91dHB1dFN0cmVhbSIpOworICAgICAgICBhc3NlcnRFbnRyeU5hbWUobCwgMTYsICJaaXBFbmNvZGluZyIpOworICAgICAgICBhc3NlcnRFbnRyeU5hbWUobCwgMTcsICJaaXBFbmNvZGluZ0hlbHBlciIpOworICAgICAgICBhc3NlcnRFbnRyeU5hbWUobCwgMTgsICJaaXBFeHRyYUZpZWxkIik7CisgICAgICAgIGFzc2VydEVudHJ5TmFtZShsLCAxOSwgIlppcFV0aWwiKTsKKyAgICAgICAgYXNzZXJ0RW50cnlOYW1lKGwsIDIwLCAiWmlwTG9uZyIpOworICAgICAgICBhc3NlcnRFbnRyeU5hbWUobCwgMjEsICJaaXBTaG9ydCIpOworICAgICAgICBhc3NlcnRFbnRyeU5hbWUobCwgMjIsICJaaXBGaWxlIik7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q0RPcmRlckluTWVtb3J5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBkYXRhID0gbnVsbDsKKyAgICAgICAgdHJ5IChGaWxlSW5wdXRTdHJlYW0gZmlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShnZXRGaWxlKCJvcmRlcnRlc3QuemlwIikpKSB7CisgICAgICAgICAgICBkYXRhID0gSU9VdGlscy50b0J5dGVBcnJheShmaXMpOworICAgICAgICB9CisKKyAgICAgICAgemYgPSBuZXcgWmlwRmlsZShuZXcgU2Vla2FibGVJbk1lbW9yeUJ5dGVDaGFubmVsKGRhdGEpLCBaaXBFbmNvZGluZ0hlbHBlci5VVEY4KTsKKyAgICAgICAgZmluYWwgQXJyYXlMaXN0PFppcEFyY2hpdmVFbnRyeT4gbCA9IENvbGxlY3Rpb25zLmxpc3QoemYuZ2V0RW50cmllcygpKTsKKyAgICAgICAgYXNzZXJ0RW50cnlOYW1lKGwsIDAsICJBYnN0cmFjdFVuaWNvZGVFeHRyYUZpZWxkIik7CisgICAgICAgIGFzc2VydEVudHJ5TmFtZShsLCAxLCAiQXNpRXh0cmFGaWVsZCIpOworICAgICAgICBhc3NlcnRFbnRyeU5hbWUobCwgMiwgIkV4dHJhRmllbGRVdGlscyIpOworICAgICAgICBhc3NlcnRFbnRyeU5hbWUobCwgMywgIkZhbGxiYWNrWmlwRW5jb2RpbmciKTsKKyAgICAgICAgYXNzZXJ0RW50cnlOYW1lKGwsIDQsICJHZW5lcmFsUHVycG9zZUJpdCIpOworICAgICAgICBhc3NlcnRFbnRyeU5hbWUobCwgNSwgIkphck1hcmtlciIpOworICAgICAgICBhc3NlcnRFbnRyeU5hbWUobCwgNiwgIk5pb1ppcEVuY29kaW5nIik7CisgICAgICAgIGFzc2VydEVudHJ5TmFtZShsLCA3LCAiU2ltcGxlOEJpdFppcEVuY29kaW5nIik7CisgICAgICAgIGFzc2VydEVudHJ5TmFtZShsLCA4LCAiVW5pY29kZUNvbW1lbnRFeHRyYUZpZWxkIik7CisgICAgICAgIGFzc2VydEVudHJ5TmFtZShsLCA5LCAiVW5pY29kZVBhdGhFeHRyYUZpZWxkIik7CisgICAgICAgIGFzc2VydEVudHJ5TmFtZShsLCAxMCwgIlVuaXhTdGF0Iik7CisgICAgICAgIGFzc2VydEVudHJ5TmFtZShsLCAxMSwgIlVucGFyc2VhYmxlRXh0cmFGaWVsZERhdGEiKTsKKyAgICAgICAgYXNzZXJ0RW50cnlOYW1lKGwsIDEyLCAiVW5yZWNvZ25pemVkRXh0cmFGaWVsZCIpOworICAgICAgICBhc3NlcnRFbnRyeU5hbWUobCwgMTMsICJaaXBBcmNoaXZlRW50cnkiKTsKKyAgICAgICAgYXNzZXJ0RW50cnlOYW1lKGwsIDE0LCAiWmlwQXJjaGl2ZUlucHV0U3RyZWFtIik7CisgICAgICAgIGFzc2VydEVudHJ5TmFtZShsLCAxNSwgIlppcEFyY2hpdmVPdXRwdXRTdHJlYW0iKTsKKyAgICAgICAgYXNzZXJ0RW50cnlOYW1lKGwsIDE2LCAiWmlwRW5jb2RpbmciKTsKKyAgICAgICAgYXNzZXJ0RW50cnlOYW1lKGwsIDE3LCAiWmlwRW5jb2RpbmdIZWxwZXIiKTsKKyAgICAgICAgYXNzZXJ0RW50cnlOYW1lKGwsIDE4LCAiWmlwRXh0cmFGaWVsZCIpOworICAgICAgICBhc3NlcnRFbnRyeU5hbWUobCwgMTksICJaaXBVdGlsIik7CisgICAgICAgIGFzc2VydEVudHJ5TmFtZShsLCAyMCwgIlppcExvbmciKTsKKyAgICAgICAgYXNzZXJ0RW50cnlOYW1lKGwsIDIxLCAiWmlwU2hvcnQiKTsKKyAgICAgICAgYXNzZXJ0RW50cnlOYW1lKGwsIDIyLCAiWmlwRmlsZSIpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFBoeXNpY2FsT3JkZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgcmVhZE9yZGVyVGVzdCgpOworICAgICAgICBmaW5hbCBBcnJheUxpc3Q8WmlwQXJjaGl2ZUVudHJ5PiBsID0gQ29sbGVjdGlvbnMubGlzdCh6Zi5nZXRFbnRyaWVzSW5QaHlzaWNhbE9yZGVyKCkpOworICAgICAgICBhc3NlcnRFbnRyeU5hbWUobCwgMCwgIkFic3RyYWN0VW5pY29kZUV4dHJhRmllbGQiKTsKKyAgICAgICAgYXNzZXJ0RW50cnlOYW1lKGwsIDEsICJBc2lFeHRyYUZpZWxkIik7CisgICAgICAgIGFzc2VydEVudHJ5TmFtZShsLCAyLCAiRXh0cmFGaWVsZFV0aWxzIik7CisgICAgICAgIGFzc2VydEVudHJ5TmFtZShsLCAzLCAiRmFsbGJhY2taaXBFbmNvZGluZyIpOworICAgICAgICBhc3NlcnRFbnRyeU5hbWUobCwgNCwgIkdlbmVyYWxQdXJwb3NlQml0Iik7CisgICAgICAgIGFzc2VydEVudHJ5TmFtZShsLCA1LCAiSmFyTWFya2VyIik7CisgICAgICAgIGFzc2VydEVudHJ5TmFtZShsLCA2LCAiTmlvWmlwRW5jb2RpbmciKTsKKyAgICAgICAgYXNzZXJ0RW50cnlOYW1lKGwsIDcsICJTaW1wbGU4Qml0WmlwRW5jb2RpbmciKTsKKyAgICAgICAgYXNzZXJ0RW50cnlOYW1lKGwsIDgsICJVbmljb2RlQ29tbWVudEV4dHJhRmllbGQiKTsKKyAgICAgICAgYXNzZXJ0RW50cnlOYW1lKGwsIDksICJVbmljb2RlUGF0aEV4dHJhRmllbGQiKTsKKyAgICAgICAgYXNzZXJ0RW50cnlOYW1lKGwsIDEwLCAiVW5peFN0YXQiKTsKKyAgICAgICAgYXNzZXJ0RW50cnlOYW1lKGwsIDExLCAiVW5wYXJzZWFibGVFeHRyYUZpZWxkRGF0YSIpOworICAgICAgICBhc3NlcnRFbnRyeU5hbWUobCwgMTIsICJVbnJlY29nbml6ZWRFeHRyYUZpZWxkIik7CisgICAgICAgIGFzc2VydEVudHJ5TmFtZShsLCAxMywgIlppcEFyY2hpdmVFbnRyeSIpOworICAgICAgICBhc3NlcnRFbnRyeU5hbWUobCwgMTQsICJaaXBBcmNoaXZlSW5wdXRTdHJlYW0iKTsKKyAgICAgICAgYXNzZXJ0RW50cnlOYW1lKGwsIDE1LCAiWmlwQXJjaGl2ZU91dHB1dFN0cmVhbSIpOworICAgICAgICBhc3NlcnRFbnRyeU5hbWUobCwgMTYsICJaaXBFbmNvZGluZyIpOworICAgICAgICBhc3NlcnRFbnRyeU5hbWUobCwgMTcsICJaaXBFbmNvZGluZ0hlbHBlciIpOworICAgICAgICBhc3NlcnRFbnRyeU5hbWUobCwgMTgsICJaaXBFeHRyYUZpZWxkIik7CisgICAgICAgIGFzc2VydEVudHJ5TmFtZShsLCAxOSwgIlppcEZpbGUiKTsKKyAgICAgICAgYXNzZXJ0RW50cnlOYW1lKGwsIDIwLCAiWmlwTG9uZyIpOworICAgICAgICBhc3NlcnRFbnRyeU5hbWUobCwgMjEsICJaaXBTaG9ydCIpOworICAgICAgICBhc3NlcnRFbnRyeU5hbWUobCwgMjIsICJaaXBVdGlsIik7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RG91YmxlQ2xvc2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgcmVhZE9yZGVyVGVzdCgpOworICAgICAgICB6Zi5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgemYuY2xvc2UoKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBmYWlsKCJDYXVnaHQgZXhjZXB0aW9uIG9mIHNlY29uZCBjbG9zZSIpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVhZGluZ09mU3RvcmVkRW50cnkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgRmlsZSBmID0gRmlsZS5jcmVhdGVUZW1wRmlsZSgiY29tbW9ucy1jb21wcmVzcy16aXBmaWxldGVzdCIsICIuemlwIik7CisgICAgICAgIGYuZGVsZXRlT25FeGl0KCk7CisgICAgICAgIE91dHB1dFN0cmVhbSBvID0gbnVsbDsKKyAgICAgICAgSW5wdXRTdHJlYW0gaSA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0oZik7CisgICAgICAgICAgICBmaW5hbCBaaXBBcmNoaXZlT3V0cHV0U3RyZWFtIHpvID0gbmV3IFppcEFyY2hpdmVPdXRwdXRTdHJlYW0obyk7CisgICAgICAgICAgICBaaXBBcmNoaXZlRW50cnkgemUgPSBuZXcgWmlwQXJjaGl2ZUVudHJ5KCJmb28iKTsKKyAgICAgICAgICAgIHplLnNldE1ldGhvZChaaXBFbnRyeS5TVE9SRUQpOworICAgICAgICAgICAgemUuc2V0U2l6ZSg0KTsKKyAgICAgICAgICAgIHplLnNldENyYygweGI2M2NmYmNkbCk7CisgICAgICAgICAgICB6by5wdXRBcmNoaXZlRW50cnkoemUpOworICAgICAgICAgICAgem8ud3JpdGUobmV3IGJ5dGVbXSB7IDEsIDIsIDMsIDQgfSk7CisgICAgICAgICAgICB6by5jbG9zZUFyY2hpdmVFbnRyeSgpOworICAgICAgICAgICAgem8uY2xvc2UoKTsKKyAgICAgICAgICAgIG8uY2xvc2UoKTsKKyAgICAgICAgICAgIG8gID0gbnVsbDsKKworICAgICAgICAgICAgemYgPSBuZXcgWmlwRmlsZShmKTsKKyAgICAgICAgICAgIHplID0gemYuZ2V0RW50cnkoImZvbyIpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCh6ZSk7CisgICAgICAgICAgICBpID0gemYuZ2V0SW5wdXRTdHJlYW0oemUpOworICAgICAgICAgICAgZmluYWwgYnl0ZVtdIGIgPSBuZXcgYnl0ZVs0XTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyg0LCBpLnJlYWQoYikpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBpLnJlYWQoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAobyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgby5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGkgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGkuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGYuZGVsZXRlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlICJodHRwczovL2lzc3Vlcy5hcGFjaGUub3JnL2ppcmEvYnJvd3NlL0NPTVBSRVNTLTE3NiIKKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RXaW56aXBCYWNrU2xhc2hXb3JrYXJvdW5kKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGUgYXJjaGl2ZSA9IGdldEZpbGUoInRlc3Qtd2luemlwLnppcCIpOworICAgICAgICB6ZiA9IG5ldyBaaXBGaWxlKGFyY2hpdmUpOworICAgICAgICBhc3NlcnROdWxsKHpmLmdldEVudHJ5KCJcdTAwZTRcXFx1MDBmYy50eHQiKSk7CisgICAgICAgIGFzc2VydE5vdE51bGwoemYuZ2V0RW50cnkoIlx1MDBlNC9cdTAwZmMudHh0IikpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgY2FzZSBmb3IKKyAgICAgKiA8YSBocmVmPSJodHRwczovL2lzc3Vlcy5hcGFjaGUub3JnL2ppcmEvYnJvd3NlL0NPTVBSRVNTLTIwOCIKKyAgICAgKiA+Q09NUFJFU1MtMjA4PC9hPi4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RTa2lwc1BLMDBQcmVmaXgoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgRmlsZSBhcmNoaXZlID0gZ2V0RmlsZSgiQ09NUFJFU1MtMjA4LnppcCIpOworICAgICAgICB6ZiA9IG5ldyBaaXBGaWxlKGFyY2hpdmUpOworICAgICAgICBhc3NlcnROb3ROdWxsKHpmLmdldEVudHJ5KCJ0ZXN0MS54bWwiKSk7CisgICAgICAgIGFzc2VydE5vdE51bGwoemYuZ2V0RW50cnkoInRlc3QyLnhtbCIpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RVbml4U3ltbGlua1NhbXBsZUZpbGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgU3RyaW5nIGVudHJ5UHJlZml4ID0gIkNPTVBSRVNTLTIxNF91bml4X3N5bWxpbmtzLyI7CisgICAgICAgIGZpbmFsIFRyZWVNYXA8U3RyaW5nLCBTdHJpbmc+IGV4cGVjdGVkVmFscyA9IG5ldyBUcmVlTWFwPD4oKTsKKworICAgICAgICAvLyBJIHRocmV3IGluIHNvbWUgSmFwYW5lc2UgY2hhcmFjdGVycyB0byBrZWVwIHRoaW5ncyBpbnRlcmVzdGluZy4KKyAgICAgICAgZXhwZWN0ZWRWYWxzLnB1dChlbnRyeVByZWZpeCArICJsaW5rMSIsICIuLi9DT01QUkVTUy0yMTRfdW5peF9zeW1saW5rcy8uL2EvYi9jLy4uLy4uLy4uL1x1Rjk5OSIpOworICAgICAgICBleHBlY3RlZFZhbHMucHV0KGVudHJ5UHJlZml4ICsgImxpbmsyIiwgIi4uL0NPTVBSRVNTLTIxNF91bml4X3N5bWxpbmtzLy4vYS9iL2MvLi4vLi4vLi4vZyIpOworICAgICAgICBleHBlY3RlZFZhbHMucHV0KGVudHJ5UHJlZml4ICsgImxpbmszIiwgIi4uL0NPTVBSRVNTLTIxNF91bml4X3N5bWxpbmtzLy4vLi9hL2IvYy8uLi8uLi8uLi9cdTc2RjRcdTZBMzkiKTsKKyAgICAgICAgZXhwZWN0ZWRWYWxzLnB1dChlbnRyeVByZWZpeCArICJsaW5rNCIsICJcdTgyQjFcdTVCNTAvXHU3NDVCXHU1QjUwIik7CisgICAgICAgIGV4cGVjdGVkVmFscy5wdXQoZW50cnlQcmVmaXggKyAiXHVGOTk5IiwgIi4vXHU4MkIxXHU1QjUwL1x1NzQ1Qlx1NUI1MC9cdTU4OTdcdThDMzcvXHVGOTk5Iik7CisgICAgICAgIGV4cGVjdGVkVmFscy5wdXQoZW50cnlQcmVmaXggKyAiZyIsICIuL2EvYi9jL2QvZS9mL2ciKTsKKyAgICAgICAgZXhwZWN0ZWRWYWxzLnB1dChlbnRyeVByZWZpeCArICJcdTc2RjRcdTZBMzkiLCAiLi9nIik7CisKKyAgICAgICAgLy8gTm90aWNlIGhvdyBhIGRpcmVjdG9yeSBsaW5rIG1pZ2h0IGNvbnRhaW4gYSB0cmFpbGluZyBzbGFzaCwgb3IgaXQgbWlnaHQgbm90LgorICAgICAgICAvLyBBbHNvIG5vdGU6ICBzeW1saW5rcyBhcmUgYWx3YXlzIHN0b3JlZCBhcyBmaWxlcywgZXZlbiBpZiB0aGV5IGxpbmsgdG8gZGlyZWN0b3JpZXMuCisgICAgICAgIGV4cGVjdGVkVmFscy5wdXQoZW50cnlQcmVmaXggKyAibGluazUiLCAiLi4vQ09NUFJFU1MtMjE0X3VuaXhfc3ltbGlua3MvLi8uL2EvYiIpOworICAgICAgICBleHBlY3RlZFZhbHMucHV0KGVudHJ5UHJlZml4ICsgImxpbms2IiwgIi4uL0NPTVBSRVNTLTIxNF91bml4X3N5bWxpbmtzLy4vLi9hL2IvIik7CisKKyAgICAgICAgLy8gSSBsb29rZWQgaW50byBjcmVhdGluZyBhIHRlc3Qgd2l0aCBoYXJkIGxpbmtzLCBidXQgemlwIGRvZXMgbm90IGFwcGVhciB0bworICAgICAgICAvLyBzdXBwb3J0IGhhcmQgbGlua3MsIHNvIG5ldmVybWluZC4KKworICAgICAgICBmaW5hbCBGaWxlIGFyY2hpdmUgPSBnZXRGaWxlKCJDT01QUkVTUy0yMTRfdW5peF9zeW1saW5rcy56aXAiKTsKKworICAgICAgICB6ZiA9IG5ldyBaaXBGaWxlKGFyY2hpdmUpOworICAgICAgICBmaW5hbCBFbnVtZXJhdGlvbjxaaXBBcmNoaXZlRW50cnk+IGVuID0gemYuZ2V0RW50cmllcygpOworICAgICAgICB3aGlsZSAoZW4uaGFzTW9yZUVsZW1lbnRzKCkpIHsKKyAgICAgICAgICAgIGZpbmFsIFppcEFyY2hpdmVFbnRyeSB6YWUgPSBlbi5uZXh0RWxlbWVudCgpOworICAgICAgICAgICAgZmluYWwgU3RyaW5nIGxpbmsgPSB6Zi5nZXRVbml4U3ltbGluayh6YWUpOworICAgICAgICAgICAgaWYgKHphZS5pc1VuaXhTeW1saW5rKCkpIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgbmFtZSA9IHphZS5nZXROYW1lKCk7CisgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIGV4cGVjdGVkID0gZXhwZWN0ZWRWYWxzLmdldChuYW1lKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWQsIGxpbmspOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAvLyBTaG91bGQgYmUgbnVsbCBpZiBpdCdzIG5vdCBhIHN5bWxpbmshCisgICAgICAgICAgICAgICAgYXNzZXJ0TnVsbChsaW5rKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgImh0dHBzOi8vaXNzdWVzLmFwYWNoZS5vcmcvamlyYS9icm93c2UvQ09NUFJFU1MtMjI3IgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdER1cGxpY2F0ZUVudHJ5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGUgYXJjaGl2ZSA9IGdldEZpbGUoIkNPTVBSRVNTLTIyNy56aXAiKTsKKyAgICAgICAgemYgPSBuZXcgWmlwRmlsZShhcmNoaXZlKTsKKworICAgICAgICBmaW5hbCBaaXBBcmNoaXZlRW50cnkgemUgPSB6Zi5nZXRFbnRyeSgidGVzdDEudHh0Iik7CisgICAgICAgIGFzc2VydE5vdE51bGwoemUpOworICAgICAgICBhc3NlcnROb3ROdWxsKHpmLmdldElucHV0U3RyZWFtKHplKSk7CisKKyAgICAgICAgaW50IG51bWJlck9mRW50cmllcyA9IDA7CisgICAgICAgIGZvciAoZmluYWwgWmlwQXJjaGl2ZUVudHJ5IGVudHJ5IDogemYuZ2V0RW50cmllcygidGVzdDEudHh0IikpIHsKKyAgICAgICAgICAgIG51bWJlck9mRW50cmllcysrOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCh6Zi5nZXRJbnB1dFN0cmVhbShlbnRyeSkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygyLCBudW1iZXJPZkVudHJpZXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgImh0dHBzOi8vaXNzdWVzLmFwYWNoZS5vcmcvamlyYS9icm93c2UvQ09NUFJFU1MtMjI4IgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEV4Y2Vzc0RhdGFJblppcDY0RXh0cmFGaWVsZCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlIGFyY2hpdmUgPSBnZXRGaWxlKCJDT01QUkVTUy0yMjguemlwIik7CisgICAgICAgIHpmID0gbmV3IFppcEZpbGUoYXJjaGl2ZSk7CisgICAgICAgIC8vIGFjdHVhbGx5LCBpZiB3ZSBnZXQgaGVyZSwgdGhlIHRlc3QgYWxyZWFkeSBoYXMgcGFzc2VkCisKKyAgICAgICAgZmluYWwgWmlwQXJjaGl2ZUVudHJ5IHplID0gemYuZ2V0RW50cnkoInNyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvWmlwRmlsZS5qYXZhIik7CisgICAgICAgIGFzc2VydEVxdWFscygyNjEwMSwgemUuZ2V0U2l6ZSgpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RVbnNocmlua2luZygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB6ZiA9IG5ldyBaaXBGaWxlKGdldEZpbGUoIlNIUlVOSy5aSVAiKSk7CisgICAgICAgIFppcEFyY2hpdmVFbnRyeSB0ZXN0ID0gemYuZ2V0RW50cnkoIlRFU1QxLlhNTCIpOworICAgICAgICBGaWxlSW5wdXRTdHJlYW0gb3JpZ2luYWwgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGdldEZpbGUoInRlc3QxLnhtbCIpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKElPVXRpbHMudG9CeXRlQXJyYXkob3JpZ2luYWwpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU9VdGlscy50b0J5dGVBcnJheSh6Zi5nZXRJbnB1dFN0cmVhbSh0ZXN0KSkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgb3JpZ2luYWwuY2xvc2UoKTsKKyAgICAgICAgfQorICAgICAgICB0ZXN0ID0gemYuZ2V0RW50cnkoIlRFU1QyLlhNTCIpOworICAgICAgICBvcmlnaW5hbCA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oZ2V0RmlsZSgidGVzdDIueG1sIikpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMoSU9VdGlscy50b0J5dGVBcnJheShvcmlnaW5hbCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJT1V0aWxzLnRvQnl0ZUFycmF5KHpmLmdldElucHV0U3RyZWFtKHRlc3QpKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBvcmlnaW5hbC5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBjYXNlIGZvcgorICAgICAqIDxhIGhyZWY9Imh0dHBzOi8vaXNzdWVzLmFwYWNoZS5vcmcvamlyYS9icm93c2UvQ09NUFJFU1MtMjY0IgorICAgICAqID5DT01QUkVTUy0yNjQ8L2E+LgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFJlYWRpbmdPZkZpcnN0U3RvcmVkRW50cnkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgRmlsZSBhcmNoaXZlID0gZ2V0RmlsZSgiQ09NUFJFU1MtMjY0LnppcCIpOworICAgICAgICB6ZiA9IG5ldyBaaXBGaWxlKGFyY2hpdmUpOworICAgICAgICBmaW5hbCBaaXBBcmNoaXZlRW50cnkgemUgPSB6Zi5nZXRFbnRyeSgidGVzdC50eHQiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDUsIHplLmdldFNpemUoKSk7CisgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKG5ldyBieXRlW10geydkJywgJ2EnLCAndCcsICdhJywgJ1xuJ30sCisgICAgICAgICAgICAgICAgICAgICAgICAgIElPVXRpbHMudG9CeXRlQXJyYXkoemYuZ2V0SW5wdXRTdHJlYW0oemUpKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VW56aXBCWmlwMkNvbXByZXNzZWRFbnRyeSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlIGFyY2hpdmUgPSBnZXRGaWxlKCJiemlwMi16aXAuemlwIik7CisgICAgICAgIHpmID0gbmV3IFppcEZpbGUoYXJjaGl2ZSk7CisgICAgICAgIGZpbmFsIFppcEFyY2hpdmVFbnRyeSB6ZSA9IHpmLmdldEVudHJ5KCJsb3RzLW9mLWFzIik7CisgICAgICAgIGFzc2VydEVxdWFscyg0MiwgemUuZ2V0U2l6ZSgpKTsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGV4cGVjdGVkID0gbmV3IGJ5dGVbNDJdOworICAgICAgICBBcnJheXMuZmlsbChleHBlY3RlZCAsIChieXRlKSdhJyk7CisgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKGV4cGVjdGVkLCBJT1V0aWxzLnRvQnl0ZUFycmF5KHpmLmdldElucHV0U3RyZWFtKHplKSkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdENvbmN1cnJlbnRSZWFkU2Vla2FibGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gbWl4ZWQuemlwIGNvbnRhaW5zIGJvdGggaW5mbGF0ZWQgYW5kIHN0b3JlZCBmaWxlcworICAgICAgICBieXRlW10gZGF0YSA9IG51bGw7CisgICAgICAgIHRyeSAoRmlsZUlucHV0U3RyZWFtIGZpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oZ2V0RmlsZSgibWl4ZWQuemlwIikpKSB7CisgICAgICAgICAgICBkYXRhID0gSU9VdGlscy50b0J5dGVBcnJheShmaXMpOworICAgICAgICB9CisgICAgICAgIHpmID0gbmV3IFppcEZpbGUobmV3IFNlZWthYmxlSW5NZW1vcnlCeXRlQ2hhbm5lbChkYXRhKSwgWmlwRW5jb2RpbmdIZWxwZXIuVVRGOCk7CisKKyAgICAgICAgZmluYWwgTWFwPFN0cmluZywgYnl0ZVtdPiBjb250ZW50ID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBieXRlW10+KCk7CisgICAgICAgIGZvciAoWmlwQXJjaGl2ZUVudHJ5IGVudHJ5OiBDb2xsZWN0aW9ucy5saXN0KHpmLmdldEVudHJpZXMoKSkpIHsKKyAgICAgICAgICAgIGNvbnRlbnQucHV0KGVudHJ5LmdldE5hbWUoKSwgSU9VdGlscy50b0J5dGVBcnJheSh6Zi5nZXRJbnB1dFN0cmVhbShlbnRyeSkpKTsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIEF0b21pY0ludGVnZXIgcGFzc2VkQ291bnQgPSBuZXcgQXRvbWljSW50ZWdlcigpOworICAgICAgICBSdW5uYWJsZSBydW4gPSBuZXcgUnVubmFibGUoKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgICAgICBmb3IgKFppcEFyY2hpdmVFbnRyeSBlbnRyeTogQ29sbGVjdGlvbnMubGlzdCh6Zi5nZXRFbnRyaWVzKCkpKSB7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEFsbFJlYWRNZXRob2RzKGNvbnRlbnQuZ2V0KGVudHJ5LmdldE5hbWUoKSksIHpmLCBlbnRyeSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHBhc3NlZENvdW50LmluY3JlbWVudEFuZEdldCgpOworICAgICAgICAgICAgfQorICAgICAgICB9OworICAgICAgICBUaHJlYWQgdDAgPSBuZXcgVGhyZWFkKHJ1bik7CisgICAgICAgIFRocmVhZCB0MSA9IG5ldyBUaHJlYWQocnVuKTsKKyAgICAgICAgdDAuc3RhcnQoKTsKKyAgICAgICAgdDEuc3RhcnQoKTsKKyAgICAgICAgdDAuam9pbigpOworICAgICAgICB0MS5qb2luKCk7CisgICAgICAgIGFzc2VydEVxdWFscygyLCBwYXNzZWRDb3VudC5nZXQoKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29uY3VycmVudFJlYWRGaWxlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIG1peGVkLnppcCBjb250YWlucyBib3RoIGluZmxhdGVkIGFuZCBzdG9yZWQgZmlsZXMKKyAgICAgICAgZmluYWwgRmlsZSBhcmNoaXZlID0gZ2V0RmlsZSgibWl4ZWQuemlwIik7CisgICAgICAgIHpmID0gbmV3IFppcEZpbGUoYXJjaGl2ZSk7CisKKyAgICAgICAgZmluYWwgTWFwPFN0cmluZywgYnl0ZVtdPiBjb250ZW50ID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBieXRlW10+KCk7CisgICAgICAgIGZvciAoWmlwQXJjaGl2ZUVudHJ5IGVudHJ5OiBDb2xsZWN0aW9ucy5saXN0KHpmLmdldEVudHJpZXMoKSkpIHsKKyAgICAgICAgICAgIGNvbnRlbnQucHV0KGVudHJ5LmdldE5hbWUoKSwgSU9VdGlscy50b0J5dGVBcnJheSh6Zi5nZXRJbnB1dFN0cmVhbShlbnRyeSkpKTsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIEF0b21pY0ludGVnZXIgcGFzc2VkQ291bnQgPSBuZXcgQXRvbWljSW50ZWdlcigpOworICAgICAgICBSdW5uYWJsZSBydW4gPSBuZXcgUnVubmFibGUoKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgICAgICBmb3IgKFppcEFyY2hpdmVFbnRyeSBlbnRyeTogQ29sbGVjdGlvbnMubGlzdCh6Zi5nZXRFbnRyaWVzKCkpKSB7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEFsbFJlYWRNZXRob2RzKGNvbnRlbnQuZ2V0KGVudHJ5LmdldE5hbWUoKSksIHpmLCBlbnRyeSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHBhc3NlZENvdW50LmluY3JlbWVudEFuZEdldCgpOworICAgICAgICAgICAgfQorICAgICAgICB9OworICAgICAgICBUaHJlYWQgdDAgPSBuZXcgVGhyZWFkKHJ1bik7CisgICAgICAgIFRocmVhZCB0MSA9IG5ldyBUaHJlYWQocnVuKTsKKyAgICAgICAgdDAuc3RhcnQoKTsKKyAgICAgICAgdDEuc3RhcnQoKTsKKyAgICAgICAgdDAuam9pbigpOworICAgICAgICB0MS5qb2luKCk7CisgICAgICAgIGFzc2VydEVxdWFscygyLCBwYXNzZWRDb3VudC5nZXQoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBjb3JyZWN0IHBvcHVsYXRpb24gb2YgaGVhZGVyIGFuZCBkYXRhIG9mZnNldHMuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0T2Zmc2V0cygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBtaXhlZC56aXAgY29udGFpbnMgYm90aCBpbmZsYXRlZCBhbmQgc3RvcmVkIGZpbGVzCisgICAgICAgIGZpbmFsIEZpbGUgYXJjaGl2ZSA9IGdldEZpbGUoIm1peGVkLnppcCIpOworICAgICAgICB0cnkgKFppcEZpbGUgemYgPSBuZXcgWmlwRmlsZShhcmNoaXZlKSkgeworICAgICAgICAgICAgWmlwQXJjaGl2ZUVudHJ5IGluZmxhdGVkRW50cnkgPSB6Zi5nZXRFbnRyeSgiaW5mbGF0ZWQudHh0Iik7CisgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDB4MDAwMCwgaW5mbGF0ZWRFbnRyeS5nZXRMb2NhbEhlYWRlck9mZnNldCgpKTsKKyAgICAgICAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMHgwMDQ2LCBpbmZsYXRlZEVudHJ5LmdldERhdGFPZmZzZXQoKSk7CisgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShpbmZsYXRlZEVudHJ5LmlzU3RyZWFtQ29udGlndW91cygpKTsKKyAgICAgICAgICAgIFppcEFyY2hpdmVFbnRyeSBzdG9yZWRFbnRyeSA9IHpmLmdldEVudHJ5KCJzdG9yZWQudHh0Iik7CisgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDB4NTg5Miwgc3RvcmVkRW50cnkuZ2V0TG9jYWxIZWFkZXJPZmZzZXQoKSk7CisgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDB4NThkNiwgc3RvcmVkRW50cnkuZ2V0RGF0YU9mZnNldCgpKTsKKyAgICAgICAgICAgIEFzc2VydC5hc3NlcnRUcnVlKGluZmxhdGVkRW50cnkuaXNTdHJlYW1Db250aWd1b3VzKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBjb3JyZWN0IHBvcHVsYXRpb24gb2YgaGVhZGVyIGFuZCBkYXRhIG9mZnNldHMgd2hlbiB0aGV5IGFyZSB3cml0dGVuIGFmdGVyIHN0cmVhbS4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3REZWxheWVkT2Zmc2V0c0FuZFNpemVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSB6aXBDb250ZW50ID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICB0cnkgKFppcEFyY2hpdmVPdXRwdXRTdHJlYW0gemlwT3V0cHV0ID0gbmV3IFppcEFyY2hpdmVPdXRwdXRTdHJlYW0oemlwQ29udGVudCkpIHsKKyAgICAgICAgICAgIFppcEFyY2hpdmVFbnRyeSBpbmZsYXRlZEVudHJ5ID0gbmV3IFppcEFyY2hpdmVFbnRyeSgiaW5mbGF0ZWQudHh0Iik7CisgICAgICAgICAgICBpbmZsYXRlZEVudHJ5LnNldE1ldGhvZChaaXBFbnRyeS5ERUZMQVRFRCk7CisgICAgICAgICAgICB6aXBPdXRwdXQucHV0QXJjaGl2ZUVudHJ5KGluZmxhdGVkRW50cnkpOworICAgICAgICAgICAgemlwT3V0cHV0LndyaXRlKCJIZWxsbyBEZWZsYXRlZFxuIi5nZXRCeXRlcygpKTsKKyAgICAgICAgICAgIHppcE91dHB1dC5jbG9zZUFyY2hpdmVFbnRyeSgpOworCisgICAgICAgICAgICBieXRlW10gc3RvcmVkQ29udGVudCA9ICJIZWxsbyBTdG9yZWRcbiIuZ2V0Qnl0ZXMoKTsKKyAgICAgICAgICAgIFppcEFyY2hpdmVFbnRyeSBzdG9yZWRFbnRyeSA9IG5ldyBaaXBBcmNoaXZlRW50cnkoInN0b3JlZC50eHQiKTsKKyAgICAgICAgICAgIHN0b3JlZEVudHJ5LnNldE1ldGhvZChaaXBFbnRyeS5TVE9SRUQpOworICAgICAgICAgICAgc3RvcmVkRW50cnkuc2V0U2l6ZShzdG9yZWRDb250ZW50Lmxlbmd0aCk7CisgICAgICAgICAgICBzdG9yZWRFbnRyeS5zZXRDcmMoY2FsY3VsYXRlQ3JjMzIoc3RvcmVkQ29udGVudCkpOworICAgICAgICAgICAgemlwT3V0cHV0LnB1dEFyY2hpdmVFbnRyeShzdG9yZWRFbnRyeSk7CisgICAgICAgICAgICB6aXBPdXRwdXQud3JpdGUoIkhlbGxvIFN0b3JlZFxuIi5nZXRCeXRlcygpKTsKKyAgICAgICAgICAgIHppcE91dHB1dC5jbG9zZUFyY2hpdmVFbnRyeSgpOworCisgICAgICAgIH0KKworICAgICAgICB0cnkgKFppcEZpbGUgemYgPSBuZXcgWmlwRmlsZShuZXcgU2Vla2FibGVJbk1lbW9yeUJ5dGVDaGFubmVsKHppcENvbnRlbnQudG9CeXRlQXJyYXkoKSkpKSB7CisgICAgICAgICAgICBaaXBBcmNoaXZlRW50cnkgaW5mbGF0ZWRFbnRyeSA9IHpmLmdldEVudHJ5KCJpbmZsYXRlZC50eHQiKTsKKyAgICAgICAgICAgIEFzc2VydC5hc3NlcnROb3RFcXVhbHMoLTFMLCBpbmZsYXRlZEVudHJ5LmdldExvY2FsSGVhZGVyT2Zmc2V0KCkpOworICAgICAgICAgICAgQXNzZXJ0LmFzc2VydE5vdEVxdWFscygtMUwsIGluZmxhdGVkRW50cnkuZ2V0RGF0YU9mZnNldCgpKTsKKyAgICAgICAgICAgIEFzc2VydC5hc3NlcnRUcnVlKGluZmxhdGVkRW50cnkuaXNTdHJlYW1Db250aWd1b3VzKCkpOworICAgICAgICAgICAgQXNzZXJ0LmFzc2VydE5vdEVxdWFscygtMUwsIGluZmxhdGVkRW50cnkuZ2V0Q29tcHJlc3NlZFNpemUoKSk7CisgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0Tm90RXF1YWxzKC0xTCwgaW5mbGF0ZWRFbnRyeS5nZXRTaXplKCkpOworICAgICAgICAgICAgWmlwQXJjaGl2ZUVudHJ5IHN0b3JlZEVudHJ5ID0gemYuZ2V0RW50cnkoInN0b3JlZC50eHQiKTsKKyAgICAgICAgICAgIEFzc2VydC5hc3NlcnROb3RFcXVhbHMoLTFMLCBzdG9yZWRFbnRyeS5nZXRMb2NhbEhlYWRlck9mZnNldCgpKTsKKyAgICAgICAgICAgIEFzc2VydC5hc3NlcnROb3RFcXVhbHMoLTFMLCBzdG9yZWRFbnRyeS5nZXREYXRhT2Zmc2V0KCkpOworICAgICAgICAgICAgQXNzZXJ0LmFzc2VydFRydWUoaW5mbGF0ZWRFbnRyeS5pc1N0cmVhbUNvbnRpZ3VvdXMoKSk7CisgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0Tm90RXF1YWxzKC0xTCwgc3RvcmVkRW50cnkuZ2V0Q29tcHJlc3NlZFNpemUoKSk7CisgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0Tm90RXF1YWxzKC0xTCwgc3RvcmVkRW50cnkuZ2V0U2l6ZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZW50cmllcyBhbGlnbm1lbnQuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW50cnlBbGlnbm1lbnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU2Vla2FibGVJbk1lbW9yeUJ5dGVDaGFubmVsIHppcENvbnRlbnQgPSBuZXcgU2Vla2FibGVJbk1lbW9yeUJ5dGVDaGFubmVsKCk7CisgICAgICAgIHRyeSAoWmlwQXJjaGl2ZU91dHB1dFN0cmVhbSB6aXBPdXRwdXQgPSBuZXcgWmlwQXJjaGl2ZU91dHB1dFN0cmVhbSh6aXBDb250ZW50KSkgeworICAgICAgICAgICAgWmlwQXJjaGl2ZUVudHJ5IGluZmxhdGVkRW50cnkgPSBuZXcgWmlwQXJjaGl2ZUVudHJ5KCJpbmZsYXRlZC50eHQiKTsKKyAgICAgICAgICAgIGluZmxhdGVkRW50cnkuc2V0TWV0aG9kKFppcEVudHJ5LkRFRkxBVEVEKTsKKyAgICAgICAgICAgIGluZmxhdGVkRW50cnkuc2V0QWxpZ25tZW50KDEwMjQpOworICAgICAgICAgICAgemlwT3V0cHV0LnB1dEFyY2hpdmVFbnRyeShpbmZsYXRlZEVudHJ5KTsKKyAgICAgICAgICAgIHppcE91dHB1dC53cml0ZSgiSGVsbG8gRGVmbGF0ZWRcbiIuZ2V0Qnl0ZXMoQ2hhcnNldC5mb3JOYW1lKCJVVEYtOCIpKSk7CisgICAgICAgICAgICB6aXBPdXRwdXQuY2xvc2VBcmNoaXZlRW50cnkoKTsKKworICAgICAgICAgICAgWmlwQXJjaGl2ZUVudHJ5IHN0b3JlZEVudHJ5ID0gbmV3IFppcEFyY2hpdmVFbnRyeSgic3RvcmVkLnR4dCIpOworICAgICAgICAgICAgc3RvcmVkRW50cnkuc2V0TWV0aG9kKFppcEVudHJ5LlNUT1JFRCk7CisgICAgICAgICAgICBzdG9yZWRFbnRyeS5zZXRBbGlnbm1lbnQoMTAyNCk7CisgICAgICAgICAgICB6aXBPdXRwdXQucHV0QXJjaGl2ZUVudHJ5KHN0b3JlZEVudHJ5KTsKKyAgICAgICAgICAgIHppcE91dHB1dC53cml0ZSgiSGVsbG8gU3RvcmVkXG4iLmdldEJ5dGVzKENoYXJzZXQuZm9yTmFtZSgiVVRGLTgiKSkpOworICAgICAgICAgICAgemlwT3V0cHV0LmNsb3NlQXJjaGl2ZUVudHJ5KCk7CisKKyAgICAgICAgICAgIFppcEFyY2hpdmVFbnRyeSBzdG9yZWRFbnRyeTIgPSBuZXcgWmlwQXJjaGl2ZUVudHJ5KCJzdG9yZWQyLnR4dCIpOworICAgICAgICAgICAgc3RvcmVkRW50cnkyLnNldE1ldGhvZChaaXBFbnRyeS5TVE9SRUQpOworICAgICAgICAgICAgc3RvcmVkRW50cnkyLnNldEFsaWdubWVudCgxMDI0KTsKKyAgICAgICAgICAgIHN0b3JlZEVudHJ5Mi5hZGRFeHRyYUZpZWxkKG5ldyBSZXNvdXJjZUFsaWdubWVudEV4dHJhRmllbGQoMSkpOworICAgICAgICAgICAgemlwT3V0cHV0LnB1dEFyY2hpdmVFbnRyeShzdG9yZWRFbnRyeTIpOworICAgICAgICAgICAgemlwT3V0cHV0LndyaXRlKCJIZWxsbyBvdmVybG9hZC1hbGlnbm1lbnQgU3RvcmVkXG4iLmdldEJ5dGVzKENoYXJzZXQuZm9yTmFtZSgiVVRGLTgiKSkpOworICAgICAgICAgICAgemlwT3V0cHV0LmNsb3NlQXJjaGl2ZUVudHJ5KCk7CisKKyAgICAgICAgICAgIFppcEFyY2hpdmVFbnRyeSBzdG9yZWRFbnRyeTMgPSBuZXcgWmlwQXJjaGl2ZUVudHJ5KCJzdG9yZWQzLnR4dCIpOworICAgICAgICAgICAgc3RvcmVkRW50cnkzLnNldE1ldGhvZChaaXBFbnRyeS5TVE9SRUQpOworICAgICAgICAgICAgc3RvcmVkRW50cnkzLmFkZEV4dHJhRmllbGQobmV3IFJlc291cmNlQWxpZ25tZW50RXh0cmFGaWVsZCgxMDI0KSk7CisgICAgICAgICAgICB6aXBPdXRwdXQucHV0QXJjaGl2ZUVudHJ5KHN0b3JlZEVudHJ5Myk7CisgICAgICAgICAgICB6aXBPdXRwdXQud3JpdGUoIkhlbGxvIGNvcHktYWxpZ25tZW50IFN0b3JlZFxuIi5nZXRCeXRlcyhDaGFyc2V0LmZvck5hbWUoIlVURi04IikpKTsKKyAgICAgICAgICAgIHppcE91dHB1dC5jbG9zZUFyY2hpdmVFbnRyeSgpOworCisgICAgICAgIH0KKworICAgICAgICB0cnkgKFppcEZpbGUgemYgPSBuZXcgWmlwRmlsZShuZXcgU2Vla2FibGVJbk1lbW9yeUJ5dGVDaGFubmVsKAorICAgICAgICAgICAgICAgICAgICAgICAgQXJyYXlzLmNvcHlPZlJhbmdlKHppcENvbnRlbnQuYXJyYXkoKSwgMCwgKGludCl6aXBDb250ZW50LnNpemUoKSkKKyAgICAgICAgKSkpIHsKKyAgICAgICAgICAgIFppcEFyY2hpdmVFbnRyeSBpbmZsYXRlZEVudHJ5ID0gemYuZ2V0RW50cnkoImluZmxhdGVkLnR4dCIpOworICAgICAgICAgICAgUmVzb3VyY2VBbGlnbm1lbnRFeHRyYUZpZWxkIGluZmxhdGVkQWxpZ25tZW50RXggPQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIChSZXNvdXJjZUFsaWdubWVudEV4dHJhRmllbGQpaW5mbGF0ZWRFbnRyeS5nZXRFeHRyYUZpZWxkKFJlc291cmNlQWxpZ25tZW50RXh0cmFGaWVsZC5JRCk7CisgICAgICAgICAgICBhc3NlcnROb3RFcXVhbHMoLTFMLCBpbmZsYXRlZEVudHJ5LmdldENvbXByZXNzZWRTaXplKCkpOworICAgICAgICAgICAgYXNzZXJ0Tm90RXF1YWxzKC0xTCwgaW5mbGF0ZWRFbnRyeS5nZXRTaXplKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDBMLCBpbmZsYXRlZEVudHJ5LmdldERhdGFPZmZzZXQoKSUxMDI0KTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoaW5mbGF0ZWRBbGlnbm1lbnRFeCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMTAyNCwgaW5mbGF0ZWRBbGlnbm1lbnRFeC5nZXRBbGlnbm1lbnQoKSk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShpbmZsYXRlZEFsaWdubWVudEV4LmFsbG93TWV0aG9kQ2hhbmdlKCkpOworICAgICAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBzdHJlYW0gPSB6Zi5nZXRJbnB1dFN0cmVhbShpbmZsYXRlZEVudHJ5KSkgeworICAgICAgICAgICAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIkhlbGxvIERlZmxhdGVkXG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgU3RyaW5nKElPVXRpbHMudG9CeXRlQXJyYXkoc3RyZWFtKSwgQ2hhcnNldC5mb3JOYW1lKCJVVEYtOCIpKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBaaXBBcmNoaXZlRW50cnkgc3RvcmVkRW50cnkgPSB6Zi5nZXRFbnRyeSgic3RvcmVkLnR4dCIpOworICAgICAgICAgICAgUmVzb3VyY2VBbGlnbm1lbnRFeHRyYUZpZWxkIHN0b3JlZEFsaWdubWVudEV4ID0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoUmVzb3VyY2VBbGlnbm1lbnRFeHRyYUZpZWxkKXN0b3JlZEVudHJ5LmdldEV4dHJhRmllbGQoUmVzb3VyY2VBbGlnbm1lbnRFeHRyYUZpZWxkLklEKTsKKyAgICAgICAgICAgIGFzc2VydE5vdEVxdWFscygtMUwsIHN0b3JlZEVudHJ5LmdldENvbXByZXNzZWRTaXplKCkpOworICAgICAgICAgICAgYXNzZXJ0Tm90RXF1YWxzKC0xTCwgc3RvcmVkRW50cnkuZ2V0U2l6ZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygwTCwgc3RvcmVkRW50cnkuZ2V0RGF0YU9mZnNldCgpJTEwMjQpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChzdG9yZWRBbGlnbm1lbnRFeCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMTAyNCwgc3RvcmVkQWxpZ25tZW50RXguZ2V0QWxpZ25tZW50KCkpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2Uoc3RvcmVkQWxpZ25tZW50RXguYWxsb3dNZXRob2RDaGFuZ2UoKSk7CisgICAgICAgICAgICB0cnkgKElucHV0U3RyZWFtIHN0cmVhbSA9IHpmLmdldElucHV0U3RyZWFtKHN0b3JlZEVudHJ5KSkgeworICAgICAgICAgICAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIkhlbGxvIFN0b3JlZFxuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmluZyhJT1V0aWxzLnRvQnl0ZUFycmF5KHN0cmVhbSksIENoYXJzZXQuZm9yTmFtZSgiVVRGLTgiKSkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBaaXBBcmNoaXZlRW50cnkgc3RvcmVkRW50cnkyID0gemYuZ2V0RW50cnkoInN0b3JlZDIudHh0Iik7CisgICAgICAgICAgICBSZXNvdXJjZUFsaWdubWVudEV4dHJhRmllbGQgc3RvcmVkMkFsaWdubWVudEV4ID0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoUmVzb3VyY2VBbGlnbm1lbnRFeHRyYUZpZWxkKXN0b3JlZEVudHJ5Mi5nZXRFeHRyYUZpZWxkKFJlc291cmNlQWxpZ25tZW50RXh0cmFGaWVsZC5JRCk7CisgICAgICAgICAgICBhc3NlcnROb3RFcXVhbHMoLTFMLCBzdG9yZWRFbnRyeTIuZ2V0Q29tcHJlc3NlZFNpemUoKSk7CisgICAgICAgICAgICBhc3NlcnROb3RFcXVhbHMoLTFMLCBzdG9yZWRFbnRyeTIuZ2V0U2l6ZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygwTCwgc3RvcmVkRW50cnkyLmdldERhdGFPZmZzZXQoKSUxMDI0KTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoc3RvcmVkMkFsaWdubWVudEV4KTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygxMDI0LCBzdG9yZWQyQWxpZ25tZW50RXguZ2V0QWxpZ25tZW50KCkpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2Uoc3RvcmVkMkFsaWdubWVudEV4LmFsbG93TWV0aG9kQ2hhbmdlKCkpOworICAgICAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBzdHJlYW0gPSB6Zi5nZXRJbnB1dFN0cmVhbShzdG9yZWRFbnRyeTIpKSB7CisgICAgICAgICAgICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygiSGVsbG8gb3ZlcmxvYWQtYWxpZ25tZW50IFN0b3JlZFxuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmluZyhJT1V0aWxzLnRvQnl0ZUFycmF5KHN0cmVhbSksIENoYXJzZXQuZm9yTmFtZSgiVVRGLTgiKSkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBaaXBBcmNoaXZlRW50cnkgc3RvcmVkRW50cnkzID0gemYuZ2V0RW50cnkoInN0b3JlZDMudHh0Iik7CisgICAgICAgICAgICBSZXNvdXJjZUFsaWdubWVudEV4dHJhRmllbGQgc3RvcmVkM0FsaWdubWVudEV4ID0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoUmVzb3VyY2VBbGlnbm1lbnRFeHRyYUZpZWxkKXN0b3JlZEVudHJ5My5nZXRFeHRyYUZpZWxkKFJlc291cmNlQWxpZ25tZW50RXh0cmFGaWVsZC5JRCk7CisgICAgICAgICAgICBhc3NlcnROb3RFcXVhbHMoLTFMLCBzdG9yZWRFbnRyeTMuZ2V0Q29tcHJlc3NlZFNpemUoKSk7CisgICAgICAgICAgICBhc3NlcnROb3RFcXVhbHMoLTFMLCBzdG9yZWRFbnRyeTMuZ2V0U2l6ZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygwTCwgc3RvcmVkRW50cnkzLmdldERhdGFPZmZzZXQoKSUxMDI0KTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoc3RvcmVkM0FsaWdubWVudEV4KTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygxMDI0LCBzdG9yZWQzQWxpZ25tZW50RXguZ2V0QWxpZ25tZW50KCkpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2Uoc3RvcmVkM0FsaWdubWVudEV4LmFsbG93TWV0aG9kQ2hhbmdlKCkpOworICAgICAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBzdHJlYW0gPSB6Zi5nZXRJbnB1dFN0cmVhbShzdG9yZWRFbnRyeTMpKSB7CisgICAgICAgICAgICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygiSGVsbG8gY29weS1hbGlnbm1lbnQgU3RvcmVkXG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgU3RyaW5nKElPVXRpbHMudG9CeXRlQXJyYXkoc3RyZWFtKSwgQ2hhcnNldC5mb3JOYW1lKCJVVEYtOCIpKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHRvbyBiaWcgYWxpZ25tZW50LCByZXN1bHRpbmcgaW50byBleGNlZWRpbmcgZXh0cmEgZmllbGQgbGltaXQuCisgICAgICovCisgICAgQFRlc3QoZXhwZWN0ZWQgPSBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24uY2xhc3MpCisgICAgcHVibGljIHZvaWQgdGVzdEVudHJ5QWxpZ25tZW50RXhjZWVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFNlZWthYmxlSW5NZW1vcnlCeXRlQ2hhbm5lbCB6aXBDb250ZW50ID0gbmV3IFNlZWthYmxlSW5NZW1vcnlCeXRlQ2hhbm5lbCgpOworICAgICAgICB0cnkgKFppcEFyY2hpdmVPdXRwdXRTdHJlYW0gemlwT3V0cHV0ID0gbmV3IFppcEFyY2hpdmVPdXRwdXRTdHJlYW0oemlwQ29udGVudCkpIHsKKyAgICAgICAgICAgIFppcEFyY2hpdmVFbnRyeSBpbmZsYXRlZEVudHJ5ID0gbmV3IFppcEFyY2hpdmVFbnRyeSgiaW5mbGF0ZWQudHh0Iik7CisgICAgICAgICAgICBpbmZsYXRlZEVudHJ5LnNldE1ldGhvZChaaXBFbnRyeS5TVE9SRUQpOworICAgICAgICAgICAgaW5mbGF0ZWRFbnRyeS5zZXRBbGlnbm1lbnQoMHgyMDAwMCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IG5vbiBwb3dlciBvZiAyIGFsaWdubWVudC4KKyAgICAgKi8KKyAgICBAVGVzdChleHBlY3RlZCA9IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi5jbGFzcykKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW52YWxpZEFsaWdubWVudCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBaaXBBcmNoaXZlRW50cnkgZW50cnkgPSBuZXcgWmlwQXJjaGl2ZUVudHJ5KCJkdW1teSIpOworICAgICAgICBlbnRyeS5zZXRBbGlnbm1lbnQoMyk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBuYW1lU291cmNlRGVmYXVsdHNUb05hbWUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgbmFtZVNvdXJjZSgiYmxhLnppcCIsICJ0ZXN0MS54bWwiLCBaaXBBcmNoaXZlRW50cnkuTmFtZVNvdXJjZS5OQU1FKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIG5hbWVTb3VyY2VJc1NldFRvVW5pY29kZUV4dHJhRmllbGQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgbmFtZVNvdXJjZSgidXRmOC13aW56aXAtdGVzdC56aXAiLCAiXHUyMEFDX2Zvcl9Eb2xsYXIudHh0IiwKKyAgICAgICAgICAgICAgICAgICBaaXBBcmNoaXZlRW50cnkuTmFtZVNvdXJjZS5VTklDT0RFX0VYVFJBX0ZJRUxEKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIG5hbWVTb3VyY2VJc1NldFRvRUZTKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIG5hbWVTb3VyY2UoInV0ZjgtN3ppcC10ZXN0LnppcCIsICJcdTIwQUNfZm9yX0RvbGxhci50eHQiLAorICAgICAgICAgICAgICAgICAgIFppcEFyY2hpdmVFbnRyeS5OYW1lU291cmNlLk5BTUVfV0lUSF9FRlNfRkxBRyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSAiaHR0cHM6Ly9pc3N1ZXMuYXBhY2hlLm9yZy9qaXJhL2Jyb3dzZS9DT01QUkVTUy0zODAiCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCByZWFkRGVmbGF0ZTY0Q29tcHJlc3NlZFN0cmVhbSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlIGlucHV0ID0gZ2V0RmlsZSgiQ09NUFJFU1MtMzgwL0NPTVBSRVNTLTM4MC1pbnB1dCIpOworICAgICAgICBmaW5hbCBGaWxlIGFyY2hpdmUgPSBnZXRGaWxlKCJDT01QUkVTUy0zODAvQ09NUFJFU1MtMzgwLnppcCIpOworICAgICAgICB0cnkgKEZpbGVJbnB1dFN0cmVhbSBpbiA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpOworICAgICAgICAgICAgIFppcEZpbGUgemYgPSBuZXcgWmlwRmlsZShhcmNoaXZlKSkgeworICAgICAgICAgICAgYnl0ZVtdIG9yaWcgPSBJT1V0aWxzLnRvQnl0ZUFycmF5KGluKTsKKyAgICAgICAgICAgIFppcEFyY2hpdmVFbnRyeSBlID0gemYuZ2V0RW50cnkoImlucHV0MiIpOworICAgICAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBzID0gemYuZ2V0SW5wdXRTdHJlYW0oZSkpIHsKKyAgICAgICAgICAgICAgICBieXRlW10gZnJvbVppcCA9IElPVXRpbHMudG9CeXRlQXJyYXkocyk7CisgICAgICAgICAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMob3JpZywgZnJvbVppcCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHNpbmdsZUJ5dGVSZWFkQ29uc2lzdGVudGx5UmV0dXJuc01pbnVzT25lQXRFb2ZVc2luZ0RlZmxhdGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc2luZ2xlQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZihnZXRGaWxlKCJibGEuemlwIikpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgc2luZ2xlQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZlVzaW5nU3RvcmUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc2luZ2xlQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZihnZXRGaWxlKCJDT01QUkVTUy0yNjQuemlwIikpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgc2luZ2xlQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZlVzaW5nVW5zaHJpbmsoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc2luZ2xlQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZihnZXRGaWxlKCJTSFJVTksuWklQIikpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgc2luZ2xlQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZlVzaW5nRXhwbG9kZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzaW5nbGVCeXRlUmVhZENvbnNpc3RlbnRseVJldHVybnNNaW51c09uZUF0RW9mKGdldEZpbGUoImltcGxvZGluZy04S2RpY3QtM3RyZWVzLnppcCIpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHNpbmdsZUJ5dGVSZWFkQ29uc2lzdGVudGx5UmV0dXJuc01pbnVzT25lQXRFb2ZVc2luZ0RlZmxhdGU2NCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzaW5nbGVCeXRlUmVhZENvbnNpc3RlbnRseVJldHVybnNNaW51c09uZUF0RW9mKGdldEZpbGUoIkNPTVBSRVNTLTM4MC9DT01QUkVTUy0zODAuemlwIikpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgc2luZ2xlQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZlVzaW5nQnppcDIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc2luZ2xlQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZihnZXRGaWxlKCJiemlwMi16aXAuemlwIikpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBzaW5nbGVCeXRlUmVhZENvbnNpc3RlbnRseVJldHVybnNNaW51c09uZUF0RW9mKEZpbGUgZmlsZSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSAoWmlwRmlsZSBhcmNoaXZlID0gbmV3IFppcEZpbGUoZmlsZSkpIHsKKyAgICAgICAgICAgIFppcEFyY2hpdmVFbnRyeSBlID0gYXJjaGl2ZS5nZXRFbnRyaWVzKCkubmV4dEVsZW1lbnQoKTsKKyAgICAgICAgICAgIHRyeSAoSW5wdXRTdHJlYW0gaXMgPSBhcmNoaXZlLmdldElucHV0U3RyZWFtKGUpKSB7CisgICAgICAgICAgICAgICAgSU9VdGlscy50b0J5dGVBcnJheShpcyk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBpcy5yZWFkKCkpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygtMSwgaXMucmVhZCgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgbXVsdGlCeXRlUmVhZENvbnNpc3RlbnRseVJldHVybnNNaW51c09uZUF0RW9mVXNpbmdEZWZsYXRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIG11bHRpQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZihnZXRGaWxlKCJibGEuemlwIikpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgbXVsdGlCeXRlUmVhZENvbnNpc3RlbnRseVJldHVybnNNaW51c09uZUF0RW9mVXNpbmdTdG9yZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBtdWx0aUJ5dGVSZWFkQ29uc2lzdGVudGx5UmV0dXJuc01pbnVzT25lQXRFb2YoZ2V0RmlsZSgiQ09NUFJFU1MtMjY0LnppcCIpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIG11bHRpQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZlVzaW5nVW5zaHJpbmsoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgbXVsdGlCeXRlUmVhZENvbnNpc3RlbnRseVJldHVybnNNaW51c09uZUF0RW9mKGdldEZpbGUoIlNIUlVOSy5aSVAiKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBtdWx0aUJ5dGVSZWFkQ29uc2lzdGVudGx5UmV0dXJuc01pbnVzT25lQXRFb2ZVc2luZ0V4cGxvZGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgbXVsdGlCeXRlUmVhZENvbnNpc3RlbnRseVJldHVybnNNaW51c09uZUF0RW9mKGdldEZpbGUoImltcGxvZGluZy04S2RpY3QtM3RyZWVzLnppcCIpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIG11bHRpQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZlVzaW5nRGVmbGF0ZTY0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIG11bHRpQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZihnZXRGaWxlKCJDT01QUkVTUy0zODAvQ09NUFJFU1MtMzgwLnppcCIpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIG11bHRpQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZlVzaW5nQnppcDIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgbXVsdGlCeXRlUmVhZENvbnNpc3RlbnRseVJldHVybnNNaW51c09uZUF0RW9mKGdldEZpbGUoImJ6aXAyLXppcC56aXAiKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIG11bHRpQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZihGaWxlIGZpbGUpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBieXRlW10gYnVmID0gbmV3IGJ5dGVbMl07CisgICAgICAgIHRyeSAoWmlwRmlsZSBhcmNoaXZlID0gbmV3IFppcEZpbGUoZmlsZSkpIHsKKyAgICAgICAgICAgIFppcEFyY2hpdmVFbnRyeSBlID0gYXJjaGl2ZS5nZXRFbnRyaWVzKCkubmV4dEVsZW1lbnQoKTsKKyAgICAgICAgICAgIHRyeSAoSW5wdXRTdHJlYW0gaXMgPSBhcmNoaXZlLmdldElucHV0U3RyZWFtKGUpKSB7CisgICAgICAgICAgICAgICAgSU9VdGlscy50b0J5dGVBcnJheShpcyk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBpcy5yZWFkKGJ1ZikpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygtMSwgaXMucmVhZChidWYpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhc3NlcnRBbGxSZWFkTWV0aG9kcyhieXRlW10gZXhwZWN0ZWQsIFppcEZpbGUgemlwRmlsZSwgWmlwQXJjaGl2ZUVudHJ5IGVudHJ5KSB7CisgICAgICAgIC8vIHNpbXBsZSBJT1V0aWwgcmVhZAorICAgICAgICB0cnkgKElucHV0U3RyZWFtIHN0cmVhbSA9IHpmLmdldElucHV0U3RyZWFtKGVudHJ5KSkgeworICAgICAgICAgICAgYnl0ZVtdIGZ1bGwgPSBJT1V0aWxzLnRvQnl0ZUFycmF5KHN0cmVhbSk7CisgICAgICAgICAgICBhc3NlcnRBcnJheUVxdWFscyhleHBlY3RlZCwgZnVsbCk7CisgICAgICAgIH0KKyAgICAgICAgY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihleCk7CisgICAgICAgIH0KKworICAgICAgICAvLyBiaWcgYnVmZmVyIGF0IHRoZSBiZWdpbm5pbmcgYW5kIHRoZW4gY2h1bmtzIGJ5IElPVXRpbHMgcmVhZAorICAgICAgICB0cnkgKElucHV0U3RyZWFtIHN0cmVhbSA9IHpmLmdldElucHV0U3RyZWFtKGVudHJ5KSkgeworICAgICAgICAgICAgYnl0ZVtdIGZ1bGw7CisgICAgICAgICAgICBieXRlW10gYnl0ZXMgPSBuZXcgYnl0ZVsweDQwMDAwXTsKKyAgICAgICAgICAgIGludCByZWFkID0gc3RyZWFtLnJlYWQoYnl0ZXMpOworICAgICAgICAgICAgaWYgKHJlYWQgPCAwKSB7CisgICAgICAgICAgICAgICAgZnVsbCA9IG5ldyBieXRlWzBdOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZWxzZSB7CisgICAgICAgICAgICAgICAgZnVsbCA9IHJlYWRTdHJlYW1SZXN0KGJ5dGVzLCByZWFkLCBzdHJlYW0pOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMoZXhwZWN0ZWQsIGZ1bGwpOworICAgICAgICB9CisgICAgICAgIGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZXgpOworICAgICAgICB9CisKKyAgICAgICAgLy8gc21hbGwgY2h1bmsgLyBzaW5nbGUgYnl0ZSBhbmQgYmlnIGJ1ZmZlciB0aGVuCisgICAgICAgIHRyeSAoSW5wdXRTdHJlYW0gc3RyZWFtID0gemYuZ2V0SW5wdXRTdHJlYW0oZW50cnkpKSB7CisgICAgICAgICAgICBieXRlW10gZnVsbDsKKyAgICAgICAgICAgIGludCBzaW5nbGUgPSBzdHJlYW0ucmVhZCgpOworICAgICAgICAgICAgaWYgKHNpbmdsZSA8IDApIHsKKyAgICAgICAgICAgICAgICBmdWxsID0gbmV3IGJ5dGVbMF07CisgICAgICAgICAgICB9CisgICAgICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgICAgICBieXRlW10gYmlnID0gbmV3IGJ5dGVbMHg0MDAwMF07CisgICAgICAgICAgICAgICAgYmlnWzBdID0gKGJ5dGUpc2luZ2xlOworICAgICAgICAgICAgICAgIGludCByZWFkID0gc3RyZWFtLnJlYWQoYmlnLCAxLCBiaWcubGVuZ3RoLTEpOworICAgICAgICAgICAgICAgIGlmIChyZWFkIDwgMCkgeworICAgICAgICAgICAgICAgICAgICBmdWxsID0gbmV3IGJ5dGVbXXsgKGJ5dGUpc2luZ2xlIH07CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGVsc2UgeworICAgICAgICAgICAgICAgICAgICBmdWxsID0gcmVhZFN0cmVhbVJlc3QoYmlnLCByZWFkKzEsIHN0cmVhbSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMoZXhwZWN0ZWQsIGZ1bGwpOworICAgICAgICB9CisgICAgICAgIGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZXgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVXRpbGl0eSB0byBhcHBlbmQgdGhlIHJlc3Qgb2YgdGhlIHN0cmVhbSB0byBhbHJlYWR5IHJlYWQgZGF0YS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJ5dGVbXSByZWFkU3RyZWFtUmVzdChieXRlW10gYmVnaW5uaW5nLCBpbnQgbGVuZ3RoLCBJbnB1dFN0cmVhbSBzdHJlYW0pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSByZXN0ID0gSU9VdGlscy50b0J5dGVBcnJheShzdHJlYW0pOworICAgICAgICBieXRlW10gZnVsbCA9IG5ldyBieXRlW2xlbmd0aCtyZXN0Lmxlbmd0aF07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYmVnaW5uaW5nLCAwLCBmdWxsLCAwLCBsZW5ndGgpOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHJlc3QsIDAsIGZ1bGwsIGxlbmd0aCwgcmVzdC5sZW5ndGgpOworICAgICAgICByZXR1cm4gZnVsbDsKKyAgICB9CisKKyAgICBwcml2YXRlIGxvbmcgY2FsY3VsYXRlQ3JjMzIoYnl0ZVtdIGNvbnRlbnQpIHsKKyAgICAgICAgQ1JDMzIgY3JjID0gbmV3IENSQzMyKCk7CisgICAgICAgIGNyYy51cGRhdGUoY29udGVudCk7CisgICAgICAgIHJldHVybiBjcmMuZ2V0VmFsdWUoKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIG9yZGVydGVzdC56aXAgaGFzIGJlZW4gaGFuZGNyYWZ0ZWQuCisgICAgICoKKyAgICAgKiBJdCBjb250YWlucyBlbm91Z2ggZmlsZXMgc28gYW55IHJhbmRvbSBjb2luY2lkZW5jZSBvZgorICAgICAqIGVudHJpZXMua2V5U2V0KCkgYW5kIGNlbnRyYWwgZGlyZWN0b3J5IG9yZGVyIHdvdWxkIGJlIHVubGlrZWx5CisgICAgICogLSBpbiBmYWN0IHRlc3RDRE9yZGVyIGZhaWxzIGluIHN2biByZXZpc2lvbiA5MjAyODQuCisgICAgICoKKyAgICAgKiBUaGUgY2VudHJhbCBkaXJlY3RvcnkgaGFzIFppcEZpbGUgYW5kIFppcFV0aWwgc3dhcHBlZCBzbworICAgICAqIGNlbnRyYWwgZGlyZWN0b3J5IG9yZGVyIGlzIGRpZmZlcmVudCBmcm9tIGVudHJ5IGRhdGEgb3JkZXIuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHJlYWRPcmRlclRlc3QoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgRmlsZSBhcmNoaXZlID0gZ2V0RmlsZSgib3JkZXJ0ZXN0LnppcCIpOworICAgICAgICB6ZiA9IG5ldyBaaXBGaWxlKGFyY2hpdmUpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgYXNzZXJ0RW50cnlOYW1lKGZpbmFsIEFycmF5TGlzdDxaaXBBcmNoaXZlRW50cnk+IGVudHJpZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBleHBlY3RlZE5hbWUpIHsKKyAgICAgICAgZmluYWwgWmlwQXJjaGl2ZUVudHJ5IHplID0gZW50cmllcy5nZXQoaW5kZXgpOworICAgICAgICBhc3NlcnRFcXVhbHMoInNyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvIgorICAgICAgICAgICAgICAgICAgICAgKyBleHBlY3RlZE5hbWUgKyAiLmphdmEiLAorICAgICAgICAgICAgICAgICAgICAgemUuZ2V0TmFtZSgpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIG5hbWVTb3VyY2UoU3RyaW5nIGFyY2hpdmUsIFN0cmluZyBlbnRyeSwgWmlwQXJjaGl2ZUVudHJ5Lk5hbWVTb3VyY2UgZXhwZWN0ZWQpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgKFppcEZpbGUgemYgPSBuZXcgWmlwRmlsZShnZXRGaWxlKGFyY2hpdmUpKSkgeworICAgICAgICAgICAgWmlwQXJjaGl2ZUVudHJ5IHplID0gemYuZ2V0RW50cnkoZW50cnkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGVudHJ5LCB6ZS5nZXROYW1lKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkLCB6ZS5nZXROYW1lU291cmNlKCkpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9aaXBMb25nVGVzdC5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9aaXBMb25nVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc1NzA5ZmQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1ppcExvbmdUZXN0LmphdmEKQEAgLTAsMCArMSwxMTIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcDsKKworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworCitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuKjsKKworLyoqCisgKiBKVW5pdCB0ZXN0Y2FzZXMgZm9yIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwLlppcExvbmcuCisgKgorICovCitwdWJsaWMgY2xhc3MgWmlwTG9uZ1Rlc3QgeworCisgICAgLyoqCisgICAgICogVGVzdCBjb252ZXJzaW9uIHRvIGJ5dGVzLgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFRvQnl0ZXMoKSB7CisgICAgICAgIGZpbmFsIFppcExvbmcgemwgPSBuZXcgWmlwTG9uZygweDEyMzQ1Njc4KTsKKyAgICAgICAgZmluYWwgYnl0ZVtdIHJlc3VsdCA9IHpsLmdldEJ5dGVzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygibGVuZ3RoIGdldEJ5dGVzIiwgNCwgcmVzdWx0Lmxlbmd0aCk7CisgICAgICAgIGFzc2VydEVxdWFscygiZmlyc3QgYnl0ZSBnZXRCeXRlcyIsIDB4NzgsIHJlc3VsdFswXSk7CisgICAgICAgIGFzc2VydEVxdWFscygic2Vjb25kIGJ5dGUgZ2V0Qnl0ZXMiLCAweDU2LCByZXN1bHRbMV0pOworICAgICAgICBhc3NlcnRFcXVhbHMoInRoaXJkIGJ5dGUgZ2V0Qnl0ZXMiLCAweDM0LCByZXN1bHRbMl0pOworICAgICAgICBhc3NlcnRFcXVhbHMoImZvdXJ0aCBieXRlIGdldEJ5dGVzIiwgMHgxMiwgcmVzdWx0WzNdKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGNvbnZlcnNpb24gdG8gYnl0ZXMuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHV0KCkgeworICAgICAgICBmaW5hbCBieXRlW10gYXJyID0gbmV3IGJ5dGVbNV07CisgICAgICAgIFppcExvbmcucHV0TG9uZygweDEyMzQ1Njc4LCBhcnIsIDEpOworICAgICAgICBhc3NlcnRFcXVhbHMoImZpcnN0IGJ5dGUgZ2V0Qnl0ZXMiLCAweDc4LCBhcnJbMV0pOworICAgICAgICBhc3NlcnRFcXVhbHMoInNlY29uZCBieXRlIGdldEJ5dGVzIiwgMHg1NiwgYXJyWzJdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0aGlyZCBieXRlIGdldEJ5dGVzIiwgMHgzNCwgYXJyWzNdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmb3VydGggYnl0ZSBnZXRCeXRlcyIsIDB4MTIsIGFycls0XSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBjb252ZXJzaW9uIGZyb20gYnl0ZXMuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RnJvbUJ5dGVzKCkgeworICAgICAgICBmaW5hbCBieXRlW10gdmFsID0gbmV3IGJ5dGVbXSB7MHg3OCwgMHg1NiwgMHgzNCwgMHgxMn07CisgICAgICAgIGZpbmFsIFppcExvbmcgemwgPSBuZXcgWmlwTG9uZyh2YWwpOworICAgICAgICBhc3NlcnRFcXVhbHMoInZhbHVlIGZyb20gYnl0ZXMiLCAweDEyMzQ1Njc4LCB6bC5nZXRWYWx1ZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHRoZSBjb250cmFjdCBvZiB0aGUgZXF1YWxzIG1ldGhvZC4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RFcXVhbHMoKSB7CisgICAgICAgIGZpbmFsIFppcExvbmcgemwgPSBuZXcgWmlwTG9uZygweDEyMzQ1Njc4KTsKKyAgICAgICAgZmluYWwgWmlwTG9uZyB6bDIgPSBuZXcgWmlwTG9uZygweDEyMzQ1Njc4KTsKKyAgICAgICAgZmluYWwgWmlwTG9uZyB6bDMgPSBuZXcgWmlwTG9uZygweDg3NjU0MzIxKTsKKworICAgICAgICBhc3NlcnRUcnVlKCJyZWZsZXhpdmUiLCB6bC5lcXVhbHMoemwpKTsKKworICAgICAgICBhc3NlcnRUcnVlKCJ3b3JrcyIsIHpsLmVxdWFscyh6bDIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgid29ya3MsIHBhcnQgdHdvIiwgIXpsLmVxdWFscyh6bDMpKTsKKworICAgICAgICBhc3NlcnRUcnVlKCJzeW1tZXRyaWMiLCB6bDIuZXF1YWxzKHpsKSk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgibnVsbCBoYW5kbGluZyIsICF6bC5lcXVhbHMobnVsbCkpOworICAgICAgICBhc3NlcnRUcnVlKCJub24gWmlwTG9uZyBoYW5kbGluZyIsICF6bC5lcXVhbHMobmV3IEludGVnZXIoMHgxMjM0KSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3Qgc2lnbiBoYW5kbGluZy4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RTaWduKCkgeworICAgICAgICAgWmlwTG9uZyB6bCA9IG5ldyBaaXBMb25nKG5ldyBieXRlW10geyhieXRlKTB4RkYsIChieXRlKTB4RkYsIChieXRlKTB4RkYsIChieXRlKTB4RkZ9KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDB4MDAwMDAwMDBGRkZGRkZGRmwsIHpsLmdldFZhbHVlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTEsemwuZ2V0SW50VmFsdWUoKSk7CisKKyAgICAgICAgemwgPSBuZXcgWmlwTG9uZygweEZGRkZfRkZGRkwpOworICAgICAgICBhc3NlcnRFcXVhbHMoMHgwMDAwMDAwMEZGRkZGRkZGbCwgemwuZ2V0VmFsdWUoKSk7CisgICAgICAgIHpsID0gbmV3IFppcExvbmcoMHhGRkZGX0ZGRkYpOworICAgICAgICBhc3NlcnRFcXVhbHMoMHhGRkZGX0ZGRkZfRkZGRl9GRkZGTCwgemwuZ2V0VmFsdWUoKSk7CisKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RDbG9uZSgpIHsKKyAgICAgICAgZmluYWwgWmlwTG9uZyBzMSA9IG5ldyBaaXBMb25nKDQyKTsKKyAgICAgICAgZmluYWwgWmlwTG9uZyBzMiA9IChaaXBMb25nKSBzMS5jbG9uZSgpOworICAgICAgICBhc3NlcnROb3RTYW1lKHMxLCBzMik7CisgICAgICAgIGFzc2VydEVxdWFscyhzMSwgczIpOworICAgICAgICBhc3NlcnRFcXVhbHMoczEuZ2V0VmFsdWUoKSwgczIuZ2V0VmFsdWUoKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9aaXBTaG9ydFRlc3QuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvWmlwU2hvcnRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzM1NGU5NwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2FyY2hpdmVycy96aXAvWmlwU2hvcnRUZXN0LmphdmEKQEAgLTAsMCArMSwxMDMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcDsKKworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0Lio7CisKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworLyoqCisgKiBKVW5pdCB0ZXN0Y2FzZXMgZm9yIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwLlppcFNob3J0LgorICoKKyAqLworcHVibGljIGNsYXNzIFppcFNob3J0VGVzdCB7CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGNvbnZlcnNpb24gdG8gYnl0ZXMuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VG9CeXRlcygpIHsKKyAgICAgICAgZmluYWwgWmlwU2hvcnQgenMgPSBuZXcgWmlwU2hvcnQoMHgxMjM0KTsKKyAgICAgICAgZmluYWwgYnl0ZVtdIHJlc3VsdCA9IHpzLmdldEJ5dGVzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygibGVuZ3RoIGdldEJ5dGVzIiwgMiwgcmVzdWx0Lmxlbmd0aCk7CisgICAgICAgIGFzc2VydEVxdWFscygiZmlyc3QgYnl0ZSBnZXRCeXRlcyIsIDB4MzQsIHJlc3VsdFswXSk7CisgICAgICAgIGFzc2VydEVxdWFscygic2Vjb25kIGJ5dGUgZ2V0Qnl0ZXMiLCAweDEyLCByZXN1bHRbMV0pOworICAgIH0KKworCisgICAgLyoqCisgICAgICogVGVzdCBjb252ZXJzaW9uIHRvIGJ5dGVzLgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFB1dCgpIHsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGFyciA9IG5ldyBieXRlWzNdOworICAgICAgICBaaXBTaG9ydC5wdXRTaG9ydCgweDEyMzQsIGFyciwgMSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZmlyc3QgYnl0ZSBnZXRCeXRlcyIsIDB4MzQsIGFyclsxXSk7CisgICAgICAgIGFzc2VydEVxdWFscygic2Vjb25kIGJ5dGUgZ2V0Qnl0ZXMiLCAweDEyLCBhcnJbMl0pOworICAgIH0KKworCisgICAgLyoqCisgICAgICogVGVzdCBjb252ZXJzaW9uIGZyb20gYnl0ZXMuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RnJvbUJ5dGVzKCkgeworICAgICAgICBmaW5hbCBieXRlW10gdmFsID0gbmV3IGJ5dGVbXSB7MHgzNCwgMHgxMn07CisgICAgICAgIGZpbmFsIFppcFNob3J0IHpzID0gbmV3IFppcFNob3J0KHZhbCk7CisgICAgICAgIGFzc2VydEVxdWFscygidmFsdWUgZnJvbSBieXRlcyIsIDB4MTIzNCwgenMuZ2V0VmFsdWUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB0aGUgY29udHJhY3Qgb2YgdGhlIGVxdWFscyBtZXRob2QuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RXF1YWxzKCkgeworICAgICAgICBmaW5hbCBaaXBTaG9ydCB6cyA9IG5ldyBaaXBTaG9ydCgweDEyMzQpOworICAgICAgICBmaW5hbCBaaXBTaG9ydCB6czIgPSBuZXcgWmlwU2hvcnQoMHgxMjM0KTsKKyAgICAgICAgZmluYWwgWmlwU2hvcnQgenMzID0gbmV3IFppcFNob3J0KDB4NTY3OCk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgicmVmbGV4aXZlIiwgenMuZXF1YWxzKHpzKSk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgid29ya3MiLCB6cy5lcXVhbHMoenMyKSk7CisgICAgICAgIGFzc2VydFRydWUoIndvcmtzLCBwYXJ0IHR3byIsICF6cy5lcXVhbHMoenMzKSk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgic3ltbWV0cmljIiwgenMyLmVxdWFscyh6cykpOworCisgICAgICAgIGFzc2VydFRydWUoIm51bGwgaGFuZGxpbmciLCAhenMuZXF1YWxzKG51bGwpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgibm9uIFppcFNob3J0IGhhbmRsaW5nIiwgIXpzLmVxdWFscyhuZXcgSW50ZWdlcigweDEyMzQpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBzaWduIGhhbmRsaW5nLgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFNpZ24oKSB7CisgICAgICAgIGZpbmFsIFppcFNob3J0IHpzID0gbmV3IFppcFNob3J0KG5ldyBieXRlW10geyhieXRlKTB4RkYsIChieXRlKTB4RkZ9KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDB4MDAwMEZGRkYsIHpzLmdldFZhbHVlKCkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdENsb25lKCkgeworICAgICAgICBmaW5hbCBaaXBTaG9ydCBzMSA9IG5ldyBaaXBTaG9ydCg0Mik7CisgICAgICAgIGZpbmFsIFppcFNob3J0IHMyID0gKFppcFNob3J0KSBzMS5jbG9uZSgpOworICAgICAgICBhc3NlcnROb3RTYW1lKHMxLCBzMik7CisgICAgICAgIGFzc2VydEVxdWFscyhzMSwgczIpOworICAgICAgICBhc3NlcnRFcXVhbHMoczEuZ2V0VmFsdWUoKSwgczIuZ2V0VmFsdWUoKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9aaXBVdGlsVGVzdC5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvYXJjaGl2ZXJzL3ppcC9aaXBVdGlsVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFjZTgxOWYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9hcmNoaXZlcnMvemlwL1ppcFV0aWxUZXN0LmphdmEKQEAgLTAsMCArMSwyMzAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcDsKKworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0Lio7CisKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5DYWxlbmRhcjsKK2ltcG9ydCBqYXZhLnV0aWwuRGF0ZTsKK2ltcG9ydCBqYXZhLnV0aWwuVGltZVpvbmU7CisKK2ltcG9ydCBvcmcuanVuaXQuQmVmb3JlOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworCitwdWJsaWMgY2xhc3MgWmlwVXRpbFRlc3QgeworCisgICAgcHJpdmF0ZSBEYXRlIHRpbWU7CisgICAgcHJpdmF0ZSBaaXBMb25nIHpsOworCisgICAgQEJlZm9yZQorICAgIHB1YmxpYyB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRpbWUgPSBuZXcgRGF0ZSgpOworICAgICAgICBmaW5hbCBDYWxlbmRhciBjYWwgPSBDYWxlbmRhci5nZXRJbnN0YW5jZSgpOworICAgICAgICBjYWwuc2V0VGltZSh0aW1lKTsKKyAgICAgICAgZmluYWwgaW50IHllYXIgPSBjYWwuZ2V0KENhbGVuZGFyLllFQVIpOworICAgICAgICBmaW5hbCBpbnQgbW9udGggPSBjYWwuZ2V0KENhbGVuZGFyLk1PTlRIKSArIDE7CisgICAgICAgIGZpbmFsIGxvbmcgdmFsdWUgPSAgKCh5ZWFyIC0gMTk4MCkgPDwgMjUpCisgICAgICAgICAgICB8ICAgICAgICAgKG1vbnRoIDw8IDIxKQorICAgICAgICAgICAgfCAgICAgICAgIChjYWwuZ2V0KENhbGVuZGFyLkRBWV9PRl9NT05USCkgPDwgMTYpCisgICAgICAgICAgICB8ICAgICAgICAgKGNhbC5nZXQoQ2FsZW5kYXIuSE9VUl9PRl9EQVkpIDw8IDExKQorICAgICAgICAgICAgfCAgICAgICAgIChjYWwuZ2V0KENhbGVuZGFyLk1JTlVURSkgPDwgNSkKKyAgICAgICAgICAgIHwgICAgICAgICAoY2FsLmdldChDYWxlbmRhci5TRUNPTkQpID4+IDEpOworCisgICAgICAgIGZpbmFsIGJ5dGVbXSByZXN1bHQgPSBuZXcgYnl0ZVs0XTsKKyAgICAgICAgcmVzdWx0WzBdID0gKGJ5dGUpICgodmFsdWUgJiAweEZGKSk7CisgICAgICAgIHJlc3VsdFsxXSA9IChieXRlKSAoKHZhbHVlICYgMHhGRjAwKSA+PiA4KTsKKyAgICAgICAgcmVzdWx0WzJdID0gKGJ5dGUpICgodmFsdWUgJiAweEZGMDAwMCkgPj4gMTYpOworICAgICAgICByZXN1bHRbM10gPSAoYnl0ZSkgKCh2YWx1ZSAmIDB4RkYwMDAwMDBMKSA+PiAyNCk7CisgICAgICAgIHpsID0gbmV3IFppcExvbmcocmVzdWx0KTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RaaXBMb25nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFppcExvbmcgdGVzdCA9IFppcFV0aWwudG9Eb3NUaW1lKHRpbWUpOworICAgICAgICBhc3NlcnRFcXVhbHModGVzdC5nZXRWYWx1ZSgpLCB6bC5nZXRWYWx1ZSgpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RBZGp1c3RUb0xvbmcoKSB7CisgICAgICAgIGFzc2VydEVxdWFscyhJbnRlZ2VyLk1BWF9WQUxVRSwKKyAgICAgICAgICAgICAgICAgICAgIFppcFV0aWwuYWRqdXN0VG9Mb25nKEludGVnZXIuTUFYX1ZBTFVFKSk7CisgICAgICAgIGFzc2VydEVxdWFscygoKGxvbmcpIEludGVnZXIuTUFYX1ZBTFVFKSArIDEsCisgICAgICAgICAgICAgICAgICAgICBaaXBVdGlsLmFkanVzdFRvTG9uZyhJbnRlZ2VyLk1BWF9WQUxVRSArIDEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIgKiAoKGxvbmcpIEludGVnZXIuTUFYX1ZBTFVFKSwKKyAgICAgICAgICAgICAgICAgICAgIFppcFV0aWwuYWRqdXN0VG9Mb25nKDIgKiBJbnRlZ2VyLk1BWF9WQUxVRSkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdE1pblRpbWUoKXsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGIxID0gWmlwVXRpbC50b0Rvc1RpbWUoMCk7CisgICAgICAgIGZpbmFsIGJ5dGUgYjEwID0gYjFbMF07IC8vIFNhdmUgdGhlIGZpcnN0IGJ5dGUKKyAgICAgICAgYjFbMF0rKzsgLy8gY2hhbmdlIGl0CisgICAgICAgIGZpbmFsIGJ5dGVbXSBiMiA9IFppcFV0aWwudG9Eb3NUaW1lKDApOyAvLyBnZXQgdGhlIHNhbWUgdGltZQorICAgICAgICBhc3NlcnRFcXVhbHMoYjEwLGIyWzBdKTsgLy8gZmlyc3QgYnl0ZSBzaG91bGQgc3RpbGwgYmUgdGhlIHNhbWUKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RPdXRzaWRlQ2FsZW5kYXIoKXsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGIxID0gWmlwVXRpbC50b0Rvc1RpbWUoMTYwNDQxMjAwMDAwTCk7IC8vIDEuMS4uMTk3NQorICAgICAgICBhc3NlcnRFcXVhbHMoMCwgYjFbMF0pOworICAgICAgICBhc3NlcnRFcXVhbHMoMzMsIGIxWzFdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGIxWzJdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGIxWzNdKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RJbnNpZGVDYWxlbmRhcigpeworICAgICAgICBmaW5hbCBUaW1lWm9uZSB0eiA9IFRpbWVab25lLmdldERlZmF1bHQoKTsKKyAgICAgICAgZmluYWwgbG9uZyBkYXRlID0gNDc2MDk2NDAwMDAwTDsgLy8gMS4xLjE5ODUsIDEwOjAwIGFtIEdNVAorICAgICAgICBmaW5hbCBieXRlW10gYjEgPSBaaXBVdGlsLnRvRG9zVGltZShkYXRlIC0gdHouZ2V0T2Zmc2V0KGRhdGUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGIxWzBdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDcyLCBiMVsxXSk7CisgICAgICAgIGFzc2VydEVxdWFscyg2NSwgYjFbMl0pOworICAgICAgICBhc3NlcnRFcXVhbHMoMTAsIGIxWzNdKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RSZXZlcnNlKCkgeworICAgICAgICBmaW5hbCBieXRlW11bXSBiVGVzdCA9IG5ldyBieXRlWzZdW107CisgICAgICAgIGJUZXN0WzBdID0gbmV3IGJ5dGVbXXt9OworICAgICAgICBiVGVzdFsxXSA9IG5ldyBieXRlW117MX07CisgICAgICAgIGJUZXN0WzJdID0gbmV3IGJ5dGVbXXsxLCAyfTsKKyAgICAgICAgYlRlc3RbM10gPSBuZXcgYnl0ZVtdezEsIDIsIDN9OworICAgICAgICBiVGVzdFs0XSA9IG5ldyBieXRlW117MSwgMiwgMywgNH07CisgICAgICAgIGJUZXN0WzVdID0gbmV3IGJ5dGVbXXsxLCAyLCAzLCA0LCA1fTsKKworICAgICAgICBmaW5hbCBieXRlW11bXSByVGVzdCA9IG5ldyBieXRlWzZdW107CisgICAgICAgIHJUZXN0WzBdID0gbmV3IGJ5dGVbXXt9OworICAgICAgICByVGVzdFsxXSA9IG5ldyBieXRlW117MX07CisgICAgICAgIHJUZXN0WzJdID0gbmV3IGJ5dGVbXXsyLCAxfTsKKyAgICAgICAgclRlc3RbM10gPSBuZXcgYnl0ZVtdezMsIDIsIDF9OworICAgICAgICByVGVzdFs0XSA9IG5ldyBieXRlW117NCwgMywgMiwgMX07CisgICAgICAgIHJUZXN0WzVdID0gbmV3IGJ5dGVbXXs1LCA0LCAzLCAyLCAxfTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoInRlc3QgYW5kIHJlc3VsdCBhcnJheXMgYXJlIHNhbWUgbGVuZ3RoIiwgYlRlc3QubGVuZ3RoLCByVGVzdC5sZW5ndGgpOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYlRlc3QubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSByZXN1bHQgPSBaaXBVdGlsLnJldmVyc2UoYlRlc3RbaV0pOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgicmV2ZXJzZSBtdXRhdGVzIGluLXBsYWNlIiwgYlRlc3RbaV0gPT0gcmVzdWx0KTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoInJldmVyc2UgYWN0dWFsbHkgcmV2ZXJzZXMiLCBBcnJheXMuZXF1YWxzKHJUZXN0W2ldLCByZXN1bHQpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEJpZ1RvTG9uZygpIHsKKyAgICAgICAgZmluYWwgQmlnSW50ZWdlciBiaWcxID0gQmlnSW50ZWdlci52YWx1ZU9mKDEpOworICAgICAgICBmaW5hbCBCaWdJbnRlZ2VyIGJpZzIgPSBCaWdJbnRlZ2VyLnZhbHVlT2YoTG9uZy5NQVhfVkFMVUUpOworICAgICAgICBmaW5hbCBCaWdJbnRlZ2VyIGJpZzMgPSBCaWdJbnRlZ2VyLnZhbHVlT2YoTG9uZy5NSU5fVkFMVUUpOworCisgICAgICAgIGFzc2VydEVxdWFscygxTCwgWmlwVXRpbC5iaWdUb0xvbmcoYmlnMSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoTG9uZy5NQVhfVkFMVUUsIFppcFV0aWwuYmlnVG9Mb25nKGJpZzIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKExvbmcuTUlOX1ZBTFVFLCBaaXBVdGlsLmJpZ1RvTG9uZyhiaWczKSk7CisKKyAgICAgICAgZmluYWwgQmlnSW50ZWdlciBiaWc0ID0gYmlnMi5hZGQoYmlnMSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBaaXBVdGlsLmJpZ1RvTG9uZyhiaWc0KTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCBoYXZlIHRocm93biBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlhZSkgeworICAgICAgICAgICAgLy8gQWxsIGlzIGdvb2QuCisgICAgICAgIH0KKworICAgICAgICBmaW5hbCBCaWdJbnRlZ2VyIGJpZzUgPSBiaWczLnN1YnRyYWN0KGJpZzEpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgWmlwVXRpbC5iaWdUb0xvbmcoYmlnNSk7CisgICAgICAgICAgICBmYWlsKCJaaXBVdGlsLmJpZ1RvTG9uZyhCaWdJbnRlZ2VyKSBzaG91bGQgaGF2ZSB0aHJvd24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUpIHsKKyAgICAgICAgICAgIC8vIEFsbCBpcyBnb29kLgorICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TG9uZ1RvQmlnKCkgeworICAgICAgICBmaW5hbCBsb25nIGwwID0gMDsKKyAgICAgICAgZmluYWwgbG9uZyBsMSA9IDE7CisgICAgICAgIGZpbmFsIGxvbmcgbDIgPSAtMTsKKyAgICAgICAgZmluYWwgbG9uZyBsMyA9IEludGVnZXIuTUlOX1ZBTFVFOworICAgICAgICBmaW5hbCBsb25nIGw0ID0gTG9uZy5NQVhfVkFMVUU7CisgICAgICAgIGZpbmFsIGxvbmcgbDUgPSBMb25nLk1JTl9WQUxVRTsKKworICAgICAgICBmaW5hbCBCaWdJbnRlZ2VyIGJpZzAgPSBaaXBVdGlsLmxvbmdUb0JpZyhsMCk7CisgICAgICAgIGZpbmFsIEJpZ0ludGVnZXIgYmlnMSA9IFppcFV0aWwubG9uZ1RvQmlnKGwxKTsKKyAgICAgICAgZmluYWwgQmlnSW50ZWdlciBiaWcyID0gWmlwVXRpbC5sb25nVG9CaWcobDIpOworICAgICAgICBmaW5hbCBCaWdJbnRlZ2VyIGJpZzMgPSBaaXBVdGlsLmxvbmdUb0JpZyhsMyk7CisgICAgICAgIGZpbmFsIEJpZ0ludGVnZXIgYmlnNCA9IFppcFV0aWwubG9uZ1RvQmlnKGw0KTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgYmlnMC5sb25nVmFsdWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBiaWcxLmxvbmdWYWx1ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDB4RkZGRkZGRkZMLCBiaWcyLmxvbmdWYWx1ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDB4ODAwMDAwMDBMLCBiaWczLmxvbmdWYWx1ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKExvbmcuTUFYX1ZBTFVFLCBiaWc0LmxvbmdWYWx1ZSgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgWmlwVXRpbC5sb25nVG9CaWcobDUpOworICAgICAgICAgICAgZmFpbCgiWmlwVXRpbC5sb25nVG9CaWcobG9uZykgc2hvdWxkIGhhdmUgdGhyb3duIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChmaW5hbCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7CisKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFNpZ25lZEJ5dGVUb1Vuc2lnbmVkSW50KCkgeworICAgICAgICAvLyBZYXksIHdlIGNhbiBjb21wbGV0ZWx5IHRlc3QgYWxsIHBvc3NpYmxlIGlucHV0IHZhbHVlcyBpbiB0aGlzIGNhc2UhCisgICAgICAgIGludCBleHBlY3RlZFZhbCA9IDEyODsKKyAgICAgICAgZm9yIChpbnQgaSA9IEJ5dGUuTUlOX1ZBTFVFOyBpIDw9IEJ5dGUuTUFYX1ZBTFVFOyBpKyspIHsKKyAgICAgICAgICAgIGZpbmFsIGJ5dGUgYiA9IChieXRlKSBpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkVmFsLCBaaXBVdGlsLnNpZ25lZEJ5dGVUb1Vuc2lnbmVkSW50KGIpKTsKKyAgICAgICAgICAgIGV4cGVjdGVkVmFsKys7CisgICAgICAgICAgICBpZiAoZXhwZWN0ZWRWYWwgPT0gMjU2KSB7CisgICAgICAgICAgICAgICAgZXhwZWN0ZWRWYWwgPSAwOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VW5zaWduZWRJbnRUb1NpZ25lZEJ5dGUoKSB7CisgICAgICAgIGludCB1bnNpZ25lZFZhbCA9IDEyODsKKyAgICAgICAgZm9yIChpbnQgaSA9IEJ5dGUuTUlOX1ZBTFVFOyBpIDw9IEJ5dGUuTUFYX1ZBTFVFOyBpKyspIHsKKyAgICAgICAgICAgIGZpbmFsIGJ5dGUgZXhwZWN0ZWRWYWwgPSAoYnl0ZSkgaTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZFZhbCwgWmlwVXRpbC51bnNpZ25lZEludFRvU2lnbmVkQnl0ZSh1bnNpZ25lZFZhbCkpOworICAgICAgICAgICAgdW5zaWduZWRWYWwrKzsKKyAgICAgICAgICAgIGlmICh1bnNpZ25lZFZhbCA9PSAyNTYpIHsKKyAgICAgICAgICAgICAgICB1bnNpZ25lZFZhbCA9IDA7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgWmlwVXRpbC51bnNpZ25lZEludFRvU2lnbmVkQnl0ZSgtMSk7CisgICAgICAgICAgICBmYWlsKCJaaXBVdGlsLnVuc2lnbmVkSW50VG9TaWduZWRCeXRlKC0xKSBzaG91bGQgaGF2ZSB0aHJvd24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUpIHsKKyAgICAgICAgICAgIC8vIEFsbCBpcyBnb29kLgorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFppcFV0aWwudW5zaWduZWRJbnRUb1NpZ25lZEJ5dGUoMjU2KTsKKyAgICAgICAgICAgIGZhaWwoIlppcFV0aWwudW5zaWduZWRJbnRUb1NpZ25lZEJ5dGUoMjU2KSBzaG91bGQgaGF2ZSB0aHJvd24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUpIHsKKyAgICAgICAgICAgIC8vIEFsbCBpcyBnb29kLgorICAgICAgICB9CisKKyAgICB9CisKKworfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY2hhbmdlcy9DaGFuZ2VTZXRUZXN0Q2FzZS5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY2hhbmdlcy9DaGFuZ2VTZXRUZXN0Q2FzZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk1NjVhZTkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jaGFuZ2VzL0NoYW5nZVNldFRlc3RDYXNlLmphdmEKQEAgLTAsMCArMSwxMjk2IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNoYW5nZXM7CisKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC4qOworCitpbXBvcnQgamF2YS5pby5CdWZmZXJlZElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRSZWFkZXI7CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVSZWFkZXI7CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5BYnN0cmFjdFRlc3RDYXNlOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZUVudHJ5OworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZUlucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLmFyLkFyQXJjaGl2ZUVudHJ5OworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuY3Bpby5DcGlvQXJjaGl2ZUVudHJ5OworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuamFyLkphckFyY2hpdmVFbnRyeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnRhci5UYXJBcmNoaXZlRW50cnk7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXAuWmlwQXJjaGl2ZUVudHJ5OworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwLlppcEZpbGU7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CisKKy8qKgorICogQ2hlY2tzIHNldmVyYWwgQ2hhbmdlU2V0IGJ1c2luZXNzIGxvZ2ljcy4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIENoYW5nZVNldFRlc3RDYXNlIGV4dGVuZHMgQWJzdHJhY3RUZXN0Q2FzZSB7CisKKyAgICAvLyBEZWxldGUgYSBkaXJlY3RvcnkgdHJlZQorICAgIHByaXZhdGUgdm9pZCBhcmNoaXZlTGlzdERlbGV0ZURpcihmaW5hbCBTdHJpbmcgcHJlZml4KXsKKyAgICAgICAgZmluYWwgSXRlcmF0b3I8U3RyaW5nPiBpdCA9IGFyY2hpdmVMaXN0Lml0ZXJhdG9yKCk7CisgICAgICAgIHdoaWxlKGl0Lmhhc05leHQoKSl7CisgICAgICAgICAgICBmaW5hbCBTdHJpbmcgZW50cnkgPSBpdC5uZXh0KCk7CisgICAgICAgICAgICBpZiAoZW50cnkuc3RhcnRzV2l0aChwcmVmaXgrIi8iKSl7IC8vIFRPRE8gd29uJ3Qgd29yayB3aXRoIGZvbGRlcnMKKyAgICAgICAgICAgICAgICBpdC5yZW1vdmUoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIERlbGV0ZSBhIHNpbmdsZSBmaWxlCisgICAgcHJpdmF0ZSB2b2lkIGFyY2hpdmVMaXN0RGVsZXRlKGZpbmFsIFN0cmluZyBwcmVmaXgpeworICAgICAgICBmaW5hbCBJdGVyYXRvcjxTdHJpbmc+IGl0ID0gYXJjaGl2ZUxpc3QuaXRlcmF0b3IoKTsKKyAgICAgICAgd2hpbGUoaXQuaGFzTmV4dCgpKXsKKyAgICAgICAgICAgIGZpbmFsIFN0cmluZyBlbnRyeSA9IGl0Lm5leHQoKTsKKyAgICAgICAgICAgIGlmIChlbnRyeS5lcXVhbHMocHJlZml4KSl7CisgICAgICAgICAgICAgICAgaXQucmVtb3ZlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIGFuIEFyY2hpdmVFbnRyeSB3aXRoIHRoZSBzYW1lIG5hbWUgdHdvIHRpbWVzLgorICAgICAqIE9ubHkgdGhlIGxhdGVzdCBhZGRpdGlvbiBzaG91bGQgYmUgZm91bmQgaW4gdGhlIENoYW5nZVNldCwKKyAgICAgKiB0aGUgZmlyc3QgYWRkIHNob3VsZCBiZSByZXBsYWNlZC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QWRkQ2hhbmdlVHdpY2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgSW5wdXRTdHJlYW0gaW4gPSBudWxsOworICAgICAgICBJbnB1dFN0cmVhbSBpbjIgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW4gPSBuZXcgRmlsZUlucHV0U3RyZWFtKGdldEZpbGUoInRlc3QudHh0IikpOworICAgICAgICAgICAgaW4yID0gbmV3IEZpbGVJbnB1dFN0cmVhbShnZXRGaWxlKCJ0ZXN0Mi54bWwiKSk7CisKKyAgICAgICAgICAgIGZpbmFsIEFyY2hpdmVFbnRyeSBlID0gbmV3IFppcEFyY2hpdmVFbnRyeSgidGVzdC50eHQiKTsKKyAgICAgICAgICAgIGZpbmFsIEFyY2hpdmVFbnRyeSBlMiA9IG5ldyBaaXBBcmNoaXZlRW50cnkoInRlc3QudHh0Iik7CisKKyAgICAgICAgICAgIGZpbmFsIENoYW5nZVNldCBjaGFuZ2VzID0gbmV3IENoYW5nZVNldCgpOworICAgICAgICAgICAgY2hhbmdlcy5hZGQoZSwgaW4pOworICAgICAgICAgICAgY2hhbmdlcy5hZGQoZTIsIGluMik7CisKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCBjaGFuZ2VzLmdldENoYW5nZXMoKS5zaXplKCkpOworICAgICAgICAgICAgZmluYWwgQ2hhbmdlIGMgPSBjaGFuZ2VzLmdldENoYW5nZXMoKS5pdGVyYXRvcigpLm5leHQoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhpbjIsIGMuZ2V0SW5wdXQoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAoaW4gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGluLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoaW4yICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBpbjIuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgYW4gQXJjaGl2ZUVudHJ5IHdpdGggdGhlIHNhbWUgbmFtZSB0d28gdGltZXMuCisgICAgICogT25seSB0aGUgZmlyc3QgYWRkaXRpb24gc2hvdWxkIGJlIGZvdW5kIGluIHRoZSBDaGFuZ2VTZXQsCisgICAgICogdGhlIHNlY29uZCBhZGQgc2hvdWxkIG5ldmVyIGJlIGFkZGVkIHNpbmNlIHJlcGxhY2UgPSBmYWxzZQorICAgICAqCisgICAgICogQHRocm93cyBFeGNlcHRpb24KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RBZGRDaGFuZ2VUd2ljZVdpdGhvdXRSZXBsYWNlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIElucHV0U3RyZWFtIGluID0gbnVsbDsKKyAgICAgICAgSW5wdXRTdHJlYW0gaW4yID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGluID0gbmV3IEZpbGVJbnB1dFN0cmVhbShnZXRGaWxlKCJ0ZXN0LnR4dCIpKTsKKyAgICAgICAgICAgIGluMiA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oZ2V0RmlsZSgidGVzdDIueG1sIikpOworCisgICAgICAgICAgICBmaW5hbCBBcmNoaXZlRW50cnkgZSA9IG5ldyBaaXBBcmNoaXZlRW50cnkoInRlc3QudHh0Iik7CisgICAgICAgICAgICBmaW5hbCBBcmNoaXZlRW50cnkgZTIgPSBuZXcgWmlwQXJjaGl2ZUVudHJ5KCJ0ZXN0LnR4dCIpOworCisgICAgICAgICAgICBmaW5hbCBDaGFuZ2VTZXQgY2hhbmdlcyA9IG5ldyBDaGFuZ2VTZXQoKTsKKyAgICAgICAgICAgIGNoYW5nZXMuYWRkKGUsIGluLCB0cnVlKTsKKyAgICAgICAgICAgIGNoYW5nZXMuYWRkKGUyLCBpbjIsIGZhbHNlKTsKKworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGNoYW5nZXMuZ2V0Q2hhbmdlcygpLnNpemUoKSk7CisgICAgICAgICAgICBmaW5hbCBDaGFuZ2UgYyA9IGNoYW5nZXMuZ2V0Q2hhbmdlcygpLml0ZXJhdG9yKCkubmV4dCgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGluLCBjLmdldElucHV0KCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKGluICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGluMiAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgaW4yLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUcmllcyB0byBkZWxldGUgdGhlIGZvbGRlciAiYmxhIiBmcm9tIGFuIGFyY2hpdmUgZmlsZS4gVGhpcyBzaG91bGQgcmVzdWx0IGluCisgICAgICogdGhlIGRlbGV0aW9uIG9mIGJsYS8qLCB3aGljaCBhY3R1YWxseSBtZWFucyBibGEvdGVzdDQueG1sIHNob3VsZCBiZQorICAgICAqIHJlbW92ZWQgZnJvbSB0aGUgYXJjaGl2ZS4gVGhlIGZpbGUgc29tZXRoaW5nL2JsYSAod2l0aG91dCBlbmRpbmcsIG5hbWVkCisgICAgICogbGlrZSB0aGUgZm9sZGVyKSBzaG91bGQgbm90IGJlIGRlbGV0ZWQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdERlbGV0ZURpcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBTdHJpbmcgYXJjaGl2ZW5hbWUgPSAiY3BpbyI7CisgICAgICAgIGZpbmFsIEZpbGUgaW5wdXQgPSB0aGlzLmNyZWF0ZUFyY2hpdmUoYXJjaGl2ZW5hbWUpOworCisgICAgICAgIEFyY2hpdmVPdXRwdXRTdHJlYW0gb3V0ID0gbnVsbDsKKyAgICAgICAgQXJjaGl2ZUlucHV0U3RyZWFtIGFpcyA9IG51bGw7CisgICAgICAgIGZpbmFsIEZpbGUgcmVzdWx0ID0gRmlsZS5jcmVhdGVUZW1wRmlsZSgidGVzdCIsICIuIithcmNoaXZlbmFtZSk7CisgICAgICAgIHJlc3VsdC5kZWxldGVPbkV4aXQoKTsKKyAgICAgICAgdHJ5IHsKKworICAgICAgICAgICAgZmluYWwgSW5wdXRTdHJlYW0gaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGlucHV0KTsKKyAgICAgICAgICAgIGFpcyA9IGZhY3RvcnkuY3JlYXRlQXJjaGl2ZUlucHV0U3RyZWFtKGFyY2hpdmVuYW1lLCBpcyk7CisKKyAgICAgICAgICAgIG91dCA9IGZhY3RvcnkuY3JlYXRlQXJjaGl2ZU91dHB1dFN0cmVhbShhcmNoaXZlbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgbmV3IEZpbGVPdXRwdXRTdHJlYW0ocmVzdWx0KSk7CisKKyAgICAgICAgICAgIGZpbmFsIENoYW5nZVNldCBjaGFuZ2VzID0gbmV3IENoYW5nZVNldCgpOworICAgICAgICAgICAgY2hhbmdlcy5kZWxldGVEaXIoImJsYSIpOworICAgICAgICAgICAgYXJjaGl2ZUxpc3REZWxldGVEaXIoImJsYSIpOworICAgICAgICAgICAgZmluYWwgQ2hhbmdlU2V0UGVyZm9ybWVyIHBlcmZvcm1lciA9IG5ldyBDaGFuZ2VTZXRQZXJmb3JtZXIoY2hhbmdlcyk7CisgICAgICAgICAgICBwZXJmb3JtZXIucGVyZm9ybShhaXMsIG91dCk7CisgICAgICAgICAgICBpcy5jbG9zZSgpOworCisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAob3V0ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChhaXMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGFpcy5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdGhpcy5jaGVja0FyY2hpdmVDb250ZW50KHJlc3VsdCwgYXJjaGl2ZUxpc3QpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRyaWVzIHRvIGRlbGV0ZSB0aGUgZm9sZGVyICJsYSIgZnJvbSBhbiBhcmNoaXZlIGZpbGUuIFRoaXMgc2hvdWxkIHJlc3VsdCBpbgorICAgICAqIHRoZSBkZWxldGlvbiBvZiBsYS8qLCB3aGljaCBzaG91bGQgbm90IG1hdGNoIGFueSBmaWxlcy9mb2xkZXJzLgorICAgICAqCisgICAgICogQHRocm93cyBFeGNlcHRpb24KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3REZWxldGVEaXIyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFN0cmluZyBhcmNoaXZlbmFtZSA9ICJjcGlvIjsKKyAgICAgICAgZmluYWwgRmlsZSBpbnB1dCA9IHRoaXMuY3JlYXRlQXJjaGl2ZShhcmNoaXZlbmFtZSk7CisKKyAgICAgICAgQXJjaGl2ZU91dHB1dFN0cmVhbSBvdXQgPSBudWxsOworICAgICAgICBBcmNoaXZlSW5wdXRTdHJlYW0gYWlzID0gbnVsbDsKKyAgICAgICAgZmluYWwgRmlsZSByZXN1bHQgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKCJ0ZXN0IiwgIi4iK2FyY2hpdmVuYW1lKTsKKyAgICAgICAgcmVzdWx0LmRlbGV0ZU9uRXhpdCgpOworICAgICAgICB0cnkgeworCisgICAgICAgICAgICBmaW5hbCBJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpOworICAgICAgICAgICAgYWlzID0gZmFjdG9yeS5jcmVhdGVBcmNoaXZlSW5wdXRTdHJlYW0oYXJjaGl2ZW5hbWUsIGlzKTsKKworICAgICAgICAgICAgb3V0ID0gZmFjdG9yeS5jcmVhdGVBcmNoaXZlT3V0cHV0U3RyZWFtKGFyY2hpdmVuYW1lLAorICAgICAgICAgICAgICAgICAgICBuZXcgRmlsZU91dHB1dFN0cmVhbShyZXN1bHQpKTsKKworICAgICAgICAgICAgZmluYWwgQ2hhbmdlU2V0IGNoYW5nZXMgPSBuZXcgQ2hhbmdlU2V0KCk7CisgICAgICAgICAgICBjaGFuZ2VzLmRlbGV0ZURpcigibGEiKTsKKyAgICAgICAgICAgIGFyY2hpdmVMaXN0RGVsZXRlRGlyKCJsYSIpOworICAgICAgICAgICAgZmluYWwgQ2hhbmdlU2V0UGVyZm9ybWVyIHBlcmZvcm1lciA9IG5ldyBDaGFuZ2VTZXRQZXJmb3JtZXIoY2hhbmdlcyk7CisgICAgICAgICAgICBwZXJmb3JtZXIucGVyZm9ybShhaXMsIG91dCk7CisgICAgICAgICAgICBpcy5jbG9zZSgpOworCisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAob3V0ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChhaXMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGFpcy5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdGhpcy5jaGVja0FyY2hpdmVDb250ZW50KHJlc3VsdCwgYXJjaGl2ZUxpc3QpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRyaWVzIHRvIGRlbGV0ZSB0aGUgZm9sZGVyICJ0ZXN0LnR4dCIgZnJvbSBhbiBhcmNoaXZlIGZpbGUuCisgICAgICogVGhpcyBzaG91bGQgbm90IG1hdGNoIGFueSBmaWxlcy9mb2xkZXJzLgorICAgICAqCisgICAgICogQHRocm93cyBFeGNlcHRpb24KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3REZWxldGVEaXIzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFN0cmluZyBhcmNoaXZlbmFtZSA9ICJjcGlvIjsKKyAgICAgICAgZmluYWwgRmlsZSBpbnB1dCA9IHRoaXMuY3JlYXRlQXJjaGl2ZShhcmNoaXZlbmFtZSk7CisKKyAgICAgICAgQXJjaGl2ZU91dHB1dFN0cmVhbSBvdXQgPSBudWxsOworICAgICAgICBBcmNoaXZlSW5wdXRTdHJlYW0gYWlzID0gbnVsbDsKKyAgICAgICAgZmluYWwgRmlsZSByZXN1bHQgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKCJ0ZXN0IiwgIi4iK2FyY2hpdmVuYW1lKTsKKyAgICAgICAgcmVzdWx0LmRlbGV0ZU9uRXhpdCgpOworICAgICAgICB0cnkgeworCisgICAgICAgICAgICBmaW5hbCBJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpOworICAgICAgICAgICAgYWlzID0gZmFjdG9yeS5jcmVhdGVBcmNoaXZlSW5wdXRTdHJlYW0oYXJjaGl2ZW5hbWUsIGlzKTsKKworICAgICAgICAgICAgb3V0ID0gZmFjdG9yeS5jcmVhdGVBcmNoaXZlT3V0cHV0U3RyZWFtKGFyY2hpdmVuYW1lLAorICAgICAgICAgICAgICAgICAgICBuZXcgRmlsZU91dHB1dFN0cmVhbShyZXN1bHQpKTsKKworICAgICAgICAgICAgZmluYWwgQ2hhbmdlU2V0IGNoYW5nZXMgPSBuZXcgQ2hhbmdlU2V0KCk7CisgICAgICAgICAgICBjaGFuZ2VzLmRlbGV0ZURpcigidGVzdC50eHQiKTsKKyAgICAgICAgICAgIGFyY2hpdmVMaXN0RGVsZXRlRGlyKCJ0ZXN0LnR4dCIpOworICAgICAgICAgICAgZmluYWwgQ2hhbmdlU2V0UGVyZm9ybWVyIHBlcmZvcm1lciA9IG5ldyBDaGFuZ2VTZXRQZXJmb3JtZXIoY2hhbmdlcyk7CisgICAgICAgICAgICBwZXJmb3JtZXIucGVyZm9ybShhaXMsIG91dCk7CisgICAgICAgICAgICBpcy5jbG9zZSgpOworCisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAob3V0ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChhaXMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGFpcy5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdGhpcy5jaGVja0FyY2hpdmVDb250ZW50KHJlc3VsdCwgYXJjaGl2ZUxpc3QpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRyaWVzIHRvIGRlbGV0ZSB0aGUgZmlsZSAiYmxhL3Rlc3Q1LnhtbCIgZnJvbSBhbiBhcmNoaXZlLiBUaGlzIHNob3VsZAorICAgICAqIHJlc3VsdCBpbiB0aGUgZGVsZXRpb24gb2YgImJsYS90ZXN0NS54bWwiLgorICAgICAqCisgICAgICogQHRocm93cyBFeGNlcHRpb24KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3REZWxldGVGaWxlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFN0cmluZyBhcmNoaXZlbmFtZSA9ICJjcGlvIjsKKyAgICAgICAgZmluYWwgRmlsZSBpbnB1dCA9IHRoaXMuY3JlYXRlQXJjaGl2ZShhcmNoaXZlbmFtZSk7CisKKyAgICAgICAgQXJjaGl2ZU91dHB1dFN0cmVhbSBvdXQgPSBudWxsOworICAgICAgICBBcmNoaXZlSW5wdXRTdHJlYW0gYWlzID0gbnVsbDsKKyAgICAgICAgZmluYWwgRmlsZSByZXN1bHQgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKCJ0ZXN0IiwgIi4iK2FyY2hpdmVuYW1lKTsKKyAgICAgICAgcmVzdWx0LmRlbGV0ZU9uRXhpdCgpOworICAgICAgICB0cnkgeworCisgICAgICAgICAgICBmaW5hbCBJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpOworICAgICAgICAgICAgYWlzID0gZmFjdG9yeS5jcmVhdGVBcmNoaXZlSW5wdXRTdHJlYW0oYXJjaGl2ZW5hbWUsIGlzKTsKKworICAgICAgICAgICAgb3V0ID0gZmFjdG9yeS5jcmVhdGVBcmNoaXZlT3V0cHV0U3RyZWFtKGFyY2hpdmVuYW1lLAorICAgICAgICAgICAgICAgICAgICBuZXcgRmlsZU91dHB1dFN0cmVhbShyZXN1bHQpKTsKKworICAgICAgICAgICAgZmluYWwgQ2hhbmdlU2V0IGNoYW5nZXMgPSBuZXcgQ2hhbmdlU2V0KCk7CisgICAgICAgICAgICBjaGFuZ2VzLmRlbGV0ZSgiYmxhL3Rlc3Q1LnhtbCIpOworICAgICAgICAgICAgYXJjaGl2ZUxpc3REZWxldGUoImJsYS90ZXN0NS54bWwiKTsKKworICAgICAgICAgICAgZmluYWwgQ2hhbmdlU2V0UGVyZm9ybWVyIHBlcmZvcm1lciA9IG5ldyBDaGFuZ2VTZXRQZXJmb3JtZXIoY2hhbmdlcyk7CisgICAgICAgICAgICBwZXJmb3JtZXIucGVyZm9ybShhaXMsIG91dCk7CisgICAgICAgICAgICBpcy5jbG9zZSgpOworCisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAob3V0ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChhaXMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGFpcy5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdGhpcy5jaGVja0FyY2hpdmVDb250ZW50KHJlc3VsdCwgYXJjaGl2ZUxpc3QpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRyaWVzIHRvIGRlbGV0ZSB0aGUgZmlsZSAiYmxhIiBmcm9tIGFuIGFyY2hpdmUuIFRoaXMgc2hvdWxkCisgICAgICogcmVzdWx0IGluIHRoZSBkZWxldGlvbiBvZiBub3RoaW5nLgorICAgICAqCisgICAgICogQHRocm93cyBFeGNlcHRpb24KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3REZWxldGVGaWxlMigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBTdHJpbmcgYXJjaGl2ZW5hbWUgPSAiY3BpbyI7CisgICAgICAgIGZpbmFsIEZpbGUgaW5wdXQgPSB0aGlzLmNyZWF0ZUFyY2hpdmUoYXJjaGl2ZW5hbWUpOworCisgICAgICAgIEFyY2hpdmVPdXRwdXRTdHJlYW0gb3V0ID0gbnVsbDsKKyAgICAgICAgQXJjaGl2ZUlucHV0U3RyZWFtIGFpcyA9IG51bGw7CisgICAgICAgIGZpbmFsIEZpbGUgcmVzdWx0ID0gRmlsZS5jcmVhdGVUZW1wRmlsZSgidGVzdCIsICIuIithcmNoaXZlbmFtZSk7CisgICAgICAgIHJlc3VsdC5kZWxldGVPbkV4aXQoKTsKKyAgICAgICAgdHJ5IHsKKworICAgICAgICAgICAgZmluYWwgSW5wdXRTdHJlYW0gaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGlucHV0KTsKKyAgICAgICAgICAgIGFpcyA9IGZhY3RvcnkuY3JlYXRlQXJjaGl2ZUlucHV0U3RyZWFtKGFyY2hpdmVuYW1lLCBpcyk7CisKKyAgICAgICAgICAgIG91dCA9IGZhY3RvcnkuY3JlYXRlQXJjaGl2ZU91dHB1dFN0cmVhbShhcmNoaXZlbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgbmV3IEZpbGVPdXRwdXRTdHJlYW0ocmVzdWx0KSk7CisKKyAgICAgICAgICAgIGZpbmFsIENoYW5nZVNldCBjaGFuZ2VzID0gbmV3IENoYW5nZVNldCgpOworICAgICAgICAgICAgY2hhbmdlcy5kZWxldGUoImJsYSIpOworICAgICAgICAgICAgLy9hcmNoaXZlTGlzdERlbGV0ZSgiYmxhIik7CisKKyAgICAgICAgICAgIGZpbmFsIENoYW5nZVNldFBlcmZvcm1lciBwZXJmb3JtZXIgPSBuZXcgQ2hhbmdlU2V0UGVyZm9ybWVyKGNoYW5nZXMpOworICAgICAgICAgICAgcGVyZm9ybWVyLnBlcmZvcm0oYWlzLCBvdXQpOworICAgICAgICAgICAgaXMuY2xvc2UoKTsKKworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKG91dCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgb3V0LmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoYWlzICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBhaXMuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHRoaXMuY2hlY2tBcmNoaXZlQ29udGVudChyZXN1bHQsIGFyY2hpdmVMaXN0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUcmllcyB0byBkZWxldGUgYW5kIHRoZW4gYWRkIGEgZmlsZSB3aXRoIHRoZSBzYW1lIG5hbWUuCisgICAgICogU2hvdWxkIGRlbGV0ZSB0ZXN0L3Rlc3QzLnhtbCBhbmQgYWRkcyB0ZXN0LnR4dCB3aXRoIHRoZSBuYW1lCisgICAgICogdGVzdC90ZXN0My54bWwKKyAgICAgKgorICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGVsZXRlUGx1c0FkZFNhbWUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgU3RyaW5nIGFyY2hpdmVuYW1lID0gInppcCI7CisgICAgICAgIGZpbmFsIEZpbGUgaW5wdXQgPSB0aGlzLmNyZWF0ZUFyY2hpdmUoYXJjaGl2ZW5hbWUpOworCisgICAgICAgIEFyY2hpdmVPdXRwdXRTdHJlYW0gb3V0ID0gbnVsbDsKKyAgICAgICAgQXJjaGl2ZUlucHV0U3RyZWFtIGFpcyA9IG51bGw7CisgICAgICAgIGZpbmFsIEZpbGUgcmVzdWx0ID0gRmlsZS5jcmVhdGVUZW1wRmlsZSgidGVzdCIsICIuIithcmNoaXZlbmFtZSk7CisgICAgICAgIHJlc3VsdC5kZWxldGVPbkV4aXQoKTsKKworICAgICAgICBGaWxlIHRlc3R0eHQgPSBudWxsOworICAgICAgICB0cnkgeworCisgICAgICAgICAgICBmaW5hbCBJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpOworICAgICAgICAgICAgYWlzID0gZmFjdG9yeS5jcmVhdGVBcmNoaXZlSW5wdXRTdHJlYW0oYXJjaGl2ZW5hbWUsIGlzKTsKKyAgICAgICAgICAgIG91dCA9IGZhY3RvcnkuY3JlYXRlQXJjaGl2ZU91dHB1dFN0cmVhbShhcmNoaXZlbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgbmV3IEZpbGVPdXRwdXRTdHJlYW0ocmVzdWx0KSk7CisKKyAgICAgICAgICAgIGZpbmFsIENoYW5nZVNldCBjaGFuZ2VzID0gbmV3IENoYW5nZVNldCgpOworICAgICAgICAgICAgY2hhbmdlcy5kZWxldGUoInRlc3QvdGVzdDMueG1sIik7CisgICAgICAgICAgICBhcmNoaXZlTGlzdERlbGV0ZSgidGVzdC90ZXN0My54bWwiKTsKKworICAgICAgICAgICAgLy8gQWRkIGEgZmlsZQorICAgICAgICAgICAgdGVzdHR4dCA9IGdldEZpbGUoInRlc3QudHh0Iik7CisgICAgICAgICAgICBmaW5hbCBBcmNoaXZlRW50cnkgZW50cnkgPSBvdXQuY3JlYXRlQXJjaGl2ZUVudHJ5KHRlc3R0eHQsICJ0ZXN0L3Rlc3QzLnhtbCIpOworICAgICAgICAgICAgY2hhbmdlcy5hZGQoZW50cnksIG5ldyBGaWxlSW5wdXRTdHJlYW0odGVzdHR4dCkpOworICAgICAgICAgICAgYXJjaGl2ZUxpc3QuYWRkKCJ0ZXN0L3Rlc3QzLnhtbCIpOworCisgICAgICAgICAgICBmaW5hbCBDaGFuZ2VTZXRQZXJmb3JtZXIgcGVyZm9ybWVyID0gbmV3IENoYW5nZVNldFBlcmZvcm1lcihjaGFuZ2VzKTsKKyAgICAgICAgICAgIHBlcmZvcm1lci5wZXJmb3JtKGFpcywgb3V0KTsKKyAgICAgICAgICAgIGlzLmNsb3NlKCk7CisKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmIChvdXQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGFpcyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgYWlzLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyBDaGVja3MKKyAgICAgICAgQXJjaGl2ZUlucHV0U3RyZWFtIGluID0gbnVsbDsKKyAgICAgICAgRmlsZSBjaGVjayA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmaW5hbCBJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0ocmVzdWx0KTsKKyAgICAgICAgICAgIGZpbmFsIEJ1ZmZlcmVkSW5wdXRTdHJlYW0gYnVmID0gbmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0oaXMpOworICAgICAgICAgICAgaW4gPSBmYWN0b3J5LmNyZWF0ZUFyY2hpdmVJbnB1dFN0cmVhbShidWYpOworICAgICAgICAgICAgY2hlY2sgPSB0aGlzLmNoZWNrQXJjaGl2ZUNvbnRlbnQoaW4sIGFyY2hpdmVMaXN0LCBmYWxzZSk7CisgICAgICAgICAgICBmaW5hbCBGaWxlIHRlc3QzeG1sID0gbmV3IEZpbGUoY2hlY2ssInJlc3VsdC90ZXN0L3Rlc3QzLnhtbCIpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHRlc3R0eHQubGVuZ3RoKCksIHRlc3QzeG1sLmxlbmd0aCgpKTsKKworICAgICAgICAgICAgZmluYWwgQnVmZmVyZWRSZWFkZXIgcmVhZGVyID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKG5ldyBGaWxlUmVhZGVyKHRlc3QzeG1sKSk7CisgICAgICAgICAgICBTdHJpbmcgc3RyOworICAgICAgICAgICAgd2hpbGUgKChzdHIgPSByZWFkZXIucmVhZExpbmUoKSkgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIC8vIEFsbCBsaW5lcyBsb29rIGxpa2UgdGhpcworICAgICAgICAgICAgICAgICIxMTExMTExMTExMTExMTExMTExMTExMTExMTEwMDAxMDEwMTEiLmVxdWFscyhzdHIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmVhZGVyLmNsb3NlKCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAoaW4gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGluLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBybWRpcihjaGVjayk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgZm9yIHRoZSBjb3JyZWN0IENoYW5nZVNldFJlc3VsdHMKKyAgICAgKgorICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2hhbmdlU2V0UmVzdWx0cygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBTdHJpbmcgYXJjaGl2ZW5hbWUgPSAiY3BpbyI7CisgICAgICAgIGZpbmFsIEZpbGUgaW5wdXQgPSB0aGlzLmNyZWF0ZUFyY2hpdmUoYXJjaGl2ZW5hbWUpOworCisgICAgICAgIEFyY2hpdmVPdXRwdXRTdHJlYW0gb3V0ID0gbnVsbDsKKyAgICAgICAgQXJjaGl2ZUlucHV0U3RyZWFtIGFpcyA9IG51bGw7CisgICAgICAgIGZpbmFsIEZpbGUgcmVzdWx0ID0gRmlsZS5jcmVhdGVUZW1wRmlsZSgidGVzdCIsICIuIithcmNoaXZlbmFtZSk7CisgICAgICAgIHJlc3VsdC5kZWxldGVPbkV4aXQoKTsKKyAgICAgICAgdHJ5IHsKKworICAgICAgICAgICAgZmluYWwgSW5wdXRTdHJlYW0gaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGlucHV0KTsKKyAgICAgICAgICAgIGFpcyA9IGZhY3RvcnkuY3JlYXRlQXJjaGl2ZUlucHV0U3RyZWFtKGFyY2hpdmVuYW1lLCBpcyk7CisgICAgICAgICAgICBvdXQgPSBmYWN0b3J5LmNyZWF0ZUFyY2hpdmVPdXRwdXRTdHJlYW0oYXJjaGl2ZW5hbWUsCisgICAgICAgICAgICAgICAgICAgIG5ldyBGaWxlT3V0cHV0U3RyZWFtKHJlc3VsdCkpOworCisgICAgICAgICAgICBmaW5hbCBDaGFuZ2VTZXQgY2hhbmdlcyA9IG5ldyBDaGFuZ2VTZXQoKTsKKyAgICAgICAgICAgIGNoYW5nZXMuZGVsZXRlRGlyKCJibGEiKTsKKyAgICAgICAgICAgIGFyY2hpdmVMaXN0RGVsZXRlRGlyKCJibGEiKTsKKworICAgICAgICAgICAgLy8gQWRkIGEgZmlsZQorICAgICAgICAgICAgZmluYWwgRmlsZSBmaWxlMSA9IGdldEZpbGUoInRlc3QudHh0Iik7CisgICAgICAgICAgICBmaW5hbCBBcmNoaXZlRW50cnkgZW50cnkgPSBvdXQuY3JlYXRlQXJjaGl2ZUVudHJ5KGZpbGUxLCAiYmxhL3Rlc3QudHh0Iik7CisgICAgICAgICAgICBjaGFuZ2VzLmFkZChlbnRyeSwgbmV3IEZpbGVJbnB1dFN0cmVhbShmaWxlMSkpOworICAgICAgICAgICAgYXJjaGl2ZUxpc3QuYWRkKCJibGEvdGVzdC50eHQiKTsKKworICAgICAgICAgICAgZmluYWwgQ2hhbmdlU2V0UGVyZm9ybWVyIHBlcmZvcm1lciA9IG5ldyBDaGFuZ2VTZXRQZXJmb3JtZXIoY2hhbmdlcyk7CisgICAgICAgICAgICBmaW5hbCBDaGFuZ2VTZXRSZXN1bHRzIHJlc3VsdHMgPSBwZXJmb3JtZXIucGVyZm9ybShhaXMsIG91dCk7CisgICAgICAgICAgICBpcy5jbG9zZSgpOworCisgICAgICAgICAgICAvLyBDaGVja3MKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygxLHJlc3VsdHMuZ2V0QWRkZWRGcm9tQ2hhbmdlU2V0KCkuc2l6ZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiYmxhL3Rlc3QudHh0IixyZXN1bHRzLmdldEFkZGVkRnJvbUNoYW5nZVNldCgpLml0ZXJhdG9yKCkubmV4dCgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygzLHJlc3VsdHMuZ2V0RGVsZXRlZCgpLnNpemUoKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdHMuZ2V0RGVsZXRlZCgpLmNvbnRhaW5zKCJibGEvdGVzdDQueG1sIikpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHRzLmdldERlbGV0ZWQoKS5jb250YWlucygiYmxhL3Rlc3Q1LnhtbCIpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUocmVzdWx0cy5nZXREZWxldGVkKCkuY29udGFpbnMoImJsYS9ibHViYmVyL3Rlc3Q2LnhtbCIpKTsKKworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHRzLmdldEFkZGVkRnJvbVN0cmVhbSgpLmNvbnRhaW5zKCJ0ZXN0ZGF0YS90ZXN0MS54bWwiKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdHMuZ2V0QWRkZWRGcm9tU3RyZWFtKCkuY29udGFpbnMoInRlc3RkYXRhL3Rlc3QyLnhtbCIpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUocmVzdWx0cy5nZXRBZGRlZEZyb21TdHJlYW0oKS5jb250YWlucygidGVzdC90ZXN0My54bWwiKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdHMuZ2V0QWRkZWRGcm9tU3RyZWFtKCkuY29udGFpbnMoInRlc3QudHh0IikpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHRzLmdldEFkZGVkRnJvbVN0cmVhbSgpLmNvbnRhaW5zKCJzb21ldGhpbmcvYmxhIikpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHRzLmdldEFkZGVkRnJvbVN0cmVhbSgpLmNvbnRhaW5zKCJ0ZXN0IHdpdGggc3BhY2VzLnR4dCIpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyg2LHJlc3VsdHMuZ2V0QWRkZWRGcm9tU3RyZWFtKCkuc2l6ZSgpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmIChvdXQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGFpcyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgYWlzLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB0aGlzLmNoZWNrQXJjaGl2ZUNvbnRlbnQocmVzdWx0LCBhcmNoaXZlTGlzdCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVHJpZXMgdG8gZGVsZXRlIGEgZGlyZWN0b3J5IHdpdGggYSBmaWxlIGFuZCBhZGRzIGEgbmV3IGRpcmVjdG9yeSB3aXRoIGEKKyAgICAgKiBuZXcgZmlsZSBhbmQgd2l0aCB0aGUgc2FtZSBuYW1lLiBTaG91bGQgZGVsZXRlIGRpcjEvKiBhbmQgYWRkCisgICAgICogZGlyMS90ZXN0LnR4dCBhdCB0aGUgZW5kCisgICAgICoKKyAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdERlbGV0ZVBsdXNBZGQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgU3RyaW5nIGFyY2hpdmVuYW1lID0gImNwaW8iOworICAgICAgICBmaW5hbCBGaWxlIGlucHV0ID0gdGhpcy5jcmVhdGVBcmNoaXZlKGFyY2hpdmVuYW1lKTsKKworICAgICAgICBBcmNoaXZlT3V0cHV0U3RyZWFtIG91dCA9IG51bGw7CisgICAgICAgIEFyY2hpdmVJbnB1dFN0cmVhbSBhaXMgPSBudWxsOworICAgICAgICBmaW5hbCBGaWxlIHJlc3VsdCA9IEZpbGUuY3JlYXRlVGVtcEZpbGUoInRlc3QiLCAiLiIrYXJjaGl2ZW5hbWUpOworICAgICAgICByZXN1bHQuZGVsZXRlT25FeGl0KCk7CisgICAgICAgIHRyeSB7CisKKyAgICAgICAgICAgIGZpbmFsIElucHV0U3RyZWFtIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShpbnB1dCk7CisgICAgICAgICAgICBhaXMgPSBmYWN0b3J5LmNyZWF0ZUFyY2hpdmVJbnB1dFN0cmVhbShhcmNoaXZlbmFtZSwgaXMpOworICAgICAgICAgICAgb3V0ID0gZmFjdG9yeS5jcmVhdGVBcmNoaXZlT3V0cHV0U3RyZWFtKGFyY2hpdmVuYW1lLAorICAgICAgICAgICAgICAgICAgICBuZXcgRmlsZU91dHB1dFN0cmVhbShyZXN1bHQpKTsKKworICAgICAgICAgICAgZmluYWwgQ2hhbmdlU2V0IGNoYW5nZXMgPSBuZXcgQ2hhbmdlU2V0KCk7CisgICAgICAgICAgICBjaGFuZ2VzLmRlbGV0ZURpcigiYmxhIik7CisgICAgICAgICAgICBhcmNoaXZlTGlzdERlbGV0ZURpcigiYmxhIik7CisKKyAgICAgICAgICAgIC8vIEFkZCBhIGZpbGUKKyAgICAgICAgICAgIGZpbmFsIEZpbGUgZmlsZTEgPSBnZXRGaWxlKCJ0ZXN0LnR4dCIpOworICAgICAgICAgICAgZmluYWwgQXJjaGl2ZUVudHJ5IGVudHJ5ID0gb3V0LmNyZWF0ZUFyY2hpdmVFbnRyeShmaWxlMSwgImJsYS90ZXN0LnR4dCIpOworICAgICAgICAgICAgY2hhbmdlcy5hZGQoZW50cnksIG5ldyBGaWxlSW5wdXRTdHJlYW0oZmlsZTEpKTsKKyAgICAgICAgICAgIGFyY2hpdmVMaXN0LmFkZCgiYmxhL3Rlc3QudHh0Iik7CisKKyAgICAgICAgICAgIGZpbmFsIENoYW5nZVNldFBlcmZvcm1lciBwZXJmb3JtZXIgPSBuZXcgQ2hhbmdlU2V0UGVyZm9ybWVyKGNoYW5nZXMpOworICAgICAgICAgICAgcGVyZm9ybWVyLnBlcmZvcm0oYWlzLCBvdXQpOworICAgICAgICAgICAgaXMuY2xvc2UoKTsKKworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKG91dCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgb3V0LmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoYWlzICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBhaXMuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHRoaXMuY2hlY2tBcmNoaXZlQ29udGVudChyZXN1bHQsIGFyY2hpdmVMaXN0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIGEgZmlsZSB0byBhIHppcCBhcmNoaXZlLiBEZWxldGVzIGFuIG90aGVyIGZpbGUuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdERlbGV0ZUZyb21BbmRBZGRUb1ppcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBTdHJpbmcgYXJjaGl2ZW5hbWUgPSAiemlwIjsKKyAgICAgICAgZmluYWwgRmlsZSBpbnB1dCA9IHRoaXMuY3JlYXRlQXJjaGl2ZShhcmNoaXZlbmFtZSk7CisKKyAgICAgICAgQXJjaGl2ZU91dHB1dFN0cmVhbSBvdXQgPSBudWxsOworICAgICAgICBBcmNoaXZlSW5wdXRTdHJlYW0gYWlzID0gbnVsbDsKKyAgICAgICAgZmluYWwgRmlsZSByZXN1bHQgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKCJ0ZXN0IiwgIi4iK2FyY2hpdmVuYW1lKTsKKyAgICAgICAgcmVzdWx0LmRlbGV0ZU9uRXhpdCgpOworICAgICAgICB0cnkgeworCisgICAgICAgICAgICBmaW5hbCBJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpOworICAgICAgICAgICAgYWlzID0gZmFjdG9yeS5jcmVhdGVBcmNoaXZlSW5wdXRTdHJlYW0oYXJjaGl2ZW5hbWUsIGlzKTsKKyAgICAgICAgICAgIG91dCA9IGZhY3RvcnkuY3JlYXRlQXJjaGl2ZU91dHB1dFN0cmVhbShhcmNoaXZlbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgbmV3IEZpbGVPdXRwdXRTdHJlYW0ocmVzdWx0KSk7CisKKyAgICAgICAgICAgIGZpbmFsIENoYW5nZVNldCBjaGFuZ2VzID0gbmV3IENoYW5nZVNldCgpOworCisgICAgICAgICAgICBmaW5hbCBGaWxlIGZpbGUxID0gZ2V0RmlsZSgidGVzdC50eHQiKTsKKyAgICAgICAgICAgIGZpbmFsIEFyY2hpdmVFbnRyeSBlbnRyeSA9IG5ldyBaaXBBcmNoaXZlRW50cnkoImJsdWIvdGVzdC50eHQiKTsKKyAgICAgICAgICAgIGNoYW5nZXMuYWRkKGVudHJ5LCBuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGUxKSk7CisgICAgICAgICAgICBhcmNoaXZlTGlzdC5hZGQoImJsdWIvdGVzdC50eHQiKTsKKworICAgICAgICAgICAgY2hhbmdlcy5kZWxldGUoInRlc3RkYXRhL3Rlc3QxLnhtbCIpOworICAgICAgICAgICAgYXJjaGl2ZUxpc3REZWxldGUoInRlc3RkYXRhL3Rlc3QxLnhtbCIpOworCisgICAgICAgICAgICBmaW5hbCBDaGFuZ2VTZXRQZXJmb3JtZXIgcGVyZm9ybWVyID0gbmV3IENoYW5nZVNldFBlcmZvcm1lcihjaGFuZ2VzKTsKKyAgICAgICAgICAgIHBlcmZvcm1lci5wZXJmb3JtKGFpcywgb3V0KTsKKyAgICAgICAgICAgIGlzLmNsb3NlKCk7CisKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmIChvdXQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGFpcyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgYWlzLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB0aGlzLmNoZWNrQXJjaGl2ZUNvbnRlbnQocmVzdWx0LCBhcmNoaXZlTGlzdCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkcyBhIGZpbGUgdG8gYSB6aXAgYXJjaGl2ZS4gRGVsZXRlcyBhbiBvdGhlciBmaWxlLgorICAgICAqCisgICAgICogQHRocm93cyBFeGNlcHRpb24KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3REZWxldGVGcm9tQW5kQWRkVG9aaXBVc2luZ1ppcEZpbGVQZXJmb3JtKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFN0cmluZyBhcmNoaXZlbmFtZSA9ICJ6aXAiOworICAgICAgICBmaW5hbCBGaWxlIGlucHV0ID0gdGhpcy5jcmVhdGVBcmNoaXZlKGFyY2hpdmVuYW1lKTsKKworICAgICAgICBBcmNoaXZlT3V0cHV0U3RyZWFtIG91dCA9IG51bGw7CisgICAgICAgIFppcEZpbGUgYWlzID0gbnVsbDsKKyAgICAgICAgZmluYWwgRmlsZSByZXN1bHQgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKCJ0ZXN0IiwgIi4iK2FyY2hpdmVuYW1lKTsKKyAgICAgICAgcmVzdWx0LmRlbGV0ZU9uRXhpdCgpOworICAgICAgICB0cnkgeworCisgICAgICAgICAgICBhaXMgPSBuZXcgWmlwRmlsZShpbnB1dCk7CisgICAgICAgICAgICBvdXQgPSBmYWN0b3J5LmNyZWF0ZUFyY2hpdmVPdXRwdXRTdHJlYW0oYXJjaGl2ZW5hbWUsCisgICAgICAgICAgICAgICAgICAgIG5ldyBGaWxlT3V0cHV0U3RyZWFtKHJlc3VsdCkpOworCisgICAgICAgICAgICBmaW5hbCBDaGFuZ2VTZXQgY2hhbmdlcyA9IG5ldyBDaGFuZ2VTZXQoKTsKKworICAgICAgICAgICAgZmluYWwgRmlsZSBmaWxlMSA9IGdldEZpbGUoInRlc3QudHh0Iik7CisgICAgICAgICAgICBmaW5hbCBBcmNoaXZlRW50cnkgZW50cnkgPSBuZXcgWmlwQXJjaGl2ZUVudHJ5KCJibHViL3Rlc3QudHh0Iik7CisgICAgICAgICAgICBjaGFuZ2VzLmFkZChlbnRyeSwgbmV3IEZpbGVJbnB1dFN0cmVhbShmaWxlMSkpOworICAgICAgICAgICAgYXJjaGl2ZUxpc3QuYWRkKCJibHViL3Rlc3QudHh0Iik7CisKKyAgICAgICAgICAgIGNoYW5nZXMuZGVsZXRlKCJ0ZXN0ZGF0YS90ZXN0MS54bWwiKTsKKyAgICAgICAgICAgIGFyY2hpdmVMaXN0RGVsZXRlKCJ0ZXN0ZGF0YS90ZXN0MS54bWwiKTsKKworICAgICAgICAgICAgZmluYWwgQ2hhbmdlU2V0UGVyZm9ybWVyIHBlcmZvcm1lciA9IG5ldyBDaGFuZ2VTZXRQZXJmb3JtZXIoY2hhbmdlcyk7CisgICAgICAgICAgICBwZXJmb3JtZXIucGVyZm9ybShhaXMsIG91dCk7CisKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmIChvdXQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGFpcyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgYWlzLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB0aGlzLmNoZWNrQXJjaGl2ZUNvbnRlbnQocmVzdWx0LCBhcmNoaXZlTGlzdCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogYWRkIGJsdWIvdGVzdC50eHQgKyBkZWxldGUgYmx1YiBTaG91bGQgYWRkIGJsdWIvdGVzdC50eHQgYW5kIGRlbGV0ZSBpdAorICAgICAqIGFmdGVyd2FyZHMuIEluIHRoaXMgZXhhbXBsZSwgdGhlIGFyY2hpdmUgc2hvdWxkIHN0YXkgdW50b3VjaGVkLgorICAgICAqCisgICAgICogQHRocm93cyBFeGNlcHRpb24KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RBZGREZWxldGVBZGQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgU3RyaW5nIGFyY2hpdmVuYW1lID0gImNwaW8iOworICAgICAgICBmaW5hbCBGaWxlIGlucHV0ID0gdGhpcy5jcmVhdGVBcmNoaXZlKGFyY2hpdmVuYW1lKTsKKworICAgICAgICBBcmNoaXZlT3V0cHV0U3RyZWFtIG91dCA9IG51bGw7CisgICAgICAgIEFyY2hpdmVJbnB1dFN0cmVhbSBhaXMgPSBudWxsOworICAgICAgICBmaW5hbCBGaWxlIHJlc3VsdCA9IEZpbGUuY3JlYXRlVGVtcEZpbGUoInRlc3QiLCAiLiIrYXJjaGl2ZW5hbWUpOworICAgICAgICByZXN1bHQuZGVsZXRlT25FeGl0KCk7CisgICAgICAgIHRyeSB7CisKKyAgICAgICAgICAgIGZpbmFsIElucHV0U3RyZWFtIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShpbnB1dCk7CisgICAgICAgICAgICBhaXMgPSBmYWN0b3J5LmNyZWF0ZUFyY2hpdmVJbnB1dFN0cmVhbShhcmNoaXZlbmFtZSwgaXMpOworICAgICAgICAgICAgb3V0ID0gZmFjdG9yeS5jcmVhdGVBcmNoaXZlT3V0cHV0U3RyZWFtKGFyY2hpdmVuYW1lLAorICAgICAgICAgICAgICAgICAgICBuZXcgRmlsZU91dHB1dFN0cmVhbShyZXN1bHQpKTsKKworICAgICAgICAgICAgZmluYWwgQ2hhbmdlU2V0IGNoYW5nZXMgPSBuZXcgQ2hhbmdlU2V0KCk7CisKKyAgICAgICAgICAgIGZpbmFsIEZpbGUgZmlsZTEgPSBnZXRGaWxlKCJ0ZXN0LnR4dCIpOworICAgICAgICAgICAgZmluYWwgQXJjaGl2ZUVudHJ5IGVudHJ5ID0gbmV3IENwaW9BcmNoaXZlRW50cnkoImJsdWIvdGVzdC50eHQiKTsKKyAgICAgICAgICAgIGNoYW5nZXMuYWRkKGVudHJ5LCBuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGUxKSk7CisgICAgICAgICAgICBhcmNoaXZlTGlzdC5hZGQoImJsdWIvdGVzdC50eHQiKTsKKworICAgICAgICAgICAgY2hhbmdlcy5kZWxldGVEaXIoImJsdWIiKTsKKyAgICAgICAgICAgIGFyY2hpdmVMaXN0RGVsZXRlRGlyKCJibHViIik7CisKKyAgICAgICAgICAgIGZpbmFsIENoYW5nZVNldFBlcmZvcm1lciBwZXJmb3JtZXIgPSBuZXcgQ2hhbmdlU2V0UGVyZm9ybWVyKGNoYW5nZXMpOworICAgICAgICAgICAgcGVyZm9ybWVyLnBlcmZvcm0oYWlzLCBvdXQpOworCisgICAgICAgICAgICBpcy5jbG9zZSgpOworCisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAob3V0ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChhaXMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGFpcy5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdGhpcy5jaGVja0FyY2hpdmVDb250ZW50KHJlc3VsdCwgYXJjaGl2ZUxpc3QpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGRlbGV0ZSBibGEgKyBhZGQgYmxhL3Rlc3QudHh0ICsgZGVsZXRlIGJsYSBEZWxldGVzIGRpcjEvKiBmaXJzdCwgdGhlbgorICAgICAqIHN1cHByZXNzZXMgdGhlIGFkZCBvZiBibGEudHh0IGJlY2F1c2UgdGhlcmUgaXMgYSBkZWxldGUgb3BlcmF0aW9uIGxhdGVyLgorICAgICAqCisgICAgICogQHRocm93cyBFeGNlcHRpb24KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3REZWxldGVBZGREZWxldGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgU3RyaW5nIGFyY2hpdmVuYW1lID0gImNwaW8iOworICAgICAgICBmaW5hbCBGaWxlIGlucHV0ID0gdGhpcy5jcmVhdGVBcmNoaXZlKGFyY2hpdmVuYW1lKTsKKworICAgICAgICBBcmNoaXZlT3V0cHV0U3RyZWFtIG91dCA9IG51bGw7CisgICAgICAgIEFyY2hpdmVJbnB1dFN0cmVhbSBhaXMgPSBudWxsOworICAgICAgICBmaW5hbCBGaWxlIHJlc3VsdCA9IEZpbGUuY3JlYXRlVGVtcEZpbGUoInRlc3QiLCAiLiIrYXJjaGl2ZW5hbWUpOworICAgICAgICByZXN1bHQuZGVsZXRlT25FeGl0KCk7CisgICAgICAgIHRyeSB7CisKKyAgICAgICAgICAgIGZpbmFsIElucHV0U3RyZWFtIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShpbnB1dCk7CisgICAgICAgICAgICBhaXMgPSBmYWN0b3J5LmNyZWF0ZUFyY2hpdmVJbnB1dFN0cmVhbShhcmNoaXZlbmFtZSwgaXMpOworICAgICAgICAgICAgb3V0ID0gZmFjdG9yeS5jcmVhdGVBcmNoaXZlT3V0cHV0U3RyZWFtKGFyY2hpdmVuYW1lLAorICAgICAgICAgICAgICAgICAgICBuZXcgRmlsZU91dHB1dFN0cmVhbShyZXN1bHQpKTsKKworICAgICAgICAgICAgZmluYWwgQ2hhbmdlU2V0IGNoYW5nZXMgPSBuZXcgQ2hhbmdlU2V0KCk7CisKKyAgICAgICAgICAgIGNoYW5nZXMuZGVsZXRlRGlyKCJibGEiKTsKKworICAgICAgICAgICAgZmluYWwgRmlsZSBmaWxlMSA9IGdldEZpbGUoInRlc3QudHh0Iik7CisgICAgICAgICAgICBmaW5hbCBBcmNoaXZlRW50cnkgZW50cnkgPSBuZXcgQ3Bpb0FyY2hpdmVFbnRyeSgiYmxhL3Rlc3QudHh0Iik7CisgICAgICAgICAgICBjaGFuZ2VzLmFkZChlbnRyeSwgbmV3IEZpbGVJbnB1dFN0cmVhbShmaWxlMSkpOworICAgICAgICAgICAgYXJjaGl2ZUxpc3QuYWRkKCJibGEvdGVzdC50eHQiKTsKKworICAgICAgICAgICAgY2hhbmdlcy5kZWxldGVEaXIoImJsYSIpOworICAgICAgICAgICAgYXJjaGl2ZUxpc3REZWxldGVEaXIoImJsYSIpOworCisgICAgICAgICAgICBmaW5hbCBDaGFuZ2VTZXRQZXJmb3JtZXIgcGVyZm9ybWVyID0gbmV3IENoYW5nZVNldFBlcmZvcm1lcihjaGFuZ2VzKTsKKyAgICAgICAgICAgIHBlcmZvcm1lci5wZXJmb3JtKGFpcywgb3V0KTsKKworICAgICAgICAgICAgaXMuY2xvc2UoKTsKKworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKG91dCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgb3V0LmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoYWlzICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBhaXMuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHRoaXMuY2hlY2tBcmNoaXZlQ29udGVudChyZXN1bHQsIGFyY2hpdmVMaXN0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTaW1wbGUgRGVsZXRlIGZyb20gYSB6aXAgZmlsZS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGVsZXRlRnJvbVppcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBBcmNoaXZlT3V0cHV0U3RyZWFtIG91dCA9IG51bGw7CisgICAgICAgIEFyY2hpdmVJbnB1dFN0cmVhbSBhaXMgPSBudWxsOworICAgICAgICBGaWxlIHRlbXAgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmluYWwgQ2hhbmdlU2V0IGNoYW5nZXMgPSBuZXcgQ2hhbmdlU2V0KCk7CisgICAgICAgICAgICBjaGFuZ2VzLmRlbGV0ZSgidGVzdDIueG1sIik7CisKKyAgICAgICAgICAgIGZpbmFsIEZpbGUgaW5wdXQgPSBnZXRGaWxlKCJibGEuemlwIik7CisgICAgICAgICAgICBmaW5hbCBJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpOworICAgICAgICAgICAgYWlzID0gZmFjdG9yeS5jcmVhdGVBcmNoaXZlSW5wdXRTdHJlYW0oInppcCIsIGlzKTsKKworICAgICAgICAgICAgdGVtcCA9IEZpbGUuY3JlYXRlVGVtcEZpbGUoInRlc3QiLCAiLnppcCIpOworICAgICAgICAgICAgdGVtcC5kZWxldGVPbkV4aXQoKTsKKyAgICAgICAgICAgIG91dCA9IGZhY3RvcnkuY3JlYXRlQXJjaGl2ZU91dHB1dFN0cmVhbSgiemlwIiwKKyAgICAgICAgICAgICAgICAgICAgbmV3IEZpbGVPdXRwdXRTdHJlYW0odGVtcCkpOworCisgICAgICAgICAgICBmaW5hbCBDaGFuZ2VTZXRQZXJmb3JtZXIgcGVyZm9ybWVyID0gbmV3IENoYW5nZVNldFBlcmZvcm1lcihjaGFuZ2VzKTsKKyAgICAgICAgICAgIHBlcmZvcm1lci5wZXJmb3JtKGFpcywgb3V0KTsKKworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKG91dCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgb3V0LmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoYWlzICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBhaXMuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIExpc3Q8U3RyaW5nPiBleHBlY3RlZCA9IG5ldyBBcnJheUxpc3Q8PigpOworICAgICAgICBleHBlY3RlZC5hZGQoInRlc3QxLnhtbCIpOworCisgICAgICAgIHRoaXMuY2hlY2tBcmNoaXZlQ29udGVudCh0ZW1wLCBleHBlY3RlZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2ltcGxlIGRlbGV0ZSBmcm9tIGEgdGFyIGZpbGUKKyAgICAgKgorICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGVsZXRlRnJvbVRhcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBBcmNoaXZlT3V0cHV0U3RyZWFtIG91dCA9IG51bGw7CisgICAgICAgIEFyY2hpdmVJbnB1dFN0cmVhbSBhaXMgPSBudWxsOworICAgICAgICBGaWxlIHRlbXAgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmluYWwgQ2hhbmdlU2V0IGNoYW5nZXMgPSBuZXcgQ2hhbmdlU2V0KCk7CisgICAgICAgICAgICBjaGFuZ2VzLmRlbGV0ZSgidGVzdDIueG1sIik7CisKKyAgICAgICAgICAgIGZpbmFsIEZpbGUgaW5wdXQgPSBnZXRGaWxlKCJibGEudGFyIik7CisgICAgICAgICAgICBmaW5hbCBJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpOworICAgICAgICAgICAgYWlzID0gZmFjdG9yeS5jcmVhdGVBcmNoaXZlSW5wdXRTdHJlYW0oInRhciIsIGlzKTsKKworICAgICAgICAgICAgdGVtcCA9IG5ldyBGaWxlKGRpciwgImJsYS50YXIiKTsKKyAgICAgICAgICAgIG91dCA9IGZhY3RvcnkuY3JlYXRlQXJjaGl2ZU91dHB1dFN0cmVhbSgidGFyIiwKKyAgICAgICAgICAgICAgICAgICAgbmV3IEZpbGVPdXRwdXRTdHJlYW0odGVtcCkpOworCisgICAgICAgICAgICBmaW5hbCBDaGFuZ2VTZXRQZXJmb3JtZXIgcGVyZm9ybWVyID0gbmV3IENoYW5nZVNldFBlcmZvcm1lcihjaGFuZ2VzKTsKKyAgICAgICAgICAgIHBlcmZvcm1lci5wZXJmb3JtKGFpcywgb3V0KTsKKworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKG91dCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgb3V0LmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoYWlzICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBhaXMuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBmaW5hbCBMaXN0PFN0cmluZz4gZXhwZWN0ZWQgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKyAgICAgICAgZXhwZWN0ZWQuYWRkKCJ0ZXN0MS54bWwiKTsKKyAgICAgICAgdGhpcy5jaGVja0FyY2hpdmVDb250ZW50KHRlbXAsIGV4cGVjdGVkKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTaW1wbGUgZGVsZXRlIGZyb20gYSBqYXIgZmlsZQorICAgICAqCisgICAgICogQHRocm93cyBFeGNlcHRpb24KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3REZWxldGVGcm9tSmFyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEFyY2hpdmVPdXRwdXRTdHJlYW0gb3V0ID0gbnVsbDsKKyAgICAgICAgQXJjaGl2ZUlucHV0U3RyZWFtIGFpcyA9IG51bGw7CisgICAgICAgIEZpbGUgdGVtcCA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmaW5hbCBDaGFuZ2VTZXQgY2hhbmdlcyA9IG5ldyBDaGFuZ2VTZXQoKTsKKyAgICAgICAgICAgIGNoYW5nZXMuZGVsZXRlKCJ0ZXN0Mi54bWwiKTsKKyAgICAgICAgICAgIGNoYW5nZXMuZGVsZXRlRGlyKCJNRVRBLUlORiIpOworICAgICAgICAgICAgY2hhbmdlcy5kZWxldGUoIi5jbGFzc3BhdGgiKTsKKyAgICAgICAgICAgIGNoYW5nZXMuZGVsZXRlKCIucHJvamVjdCIpOworCisgICAgICAgICAgICBmaW5hbCBGaWxlIGlucHV0ID0gZ2V0RmlsZSgiYmxhLmphciIpOworICAgICAgICAgICAgZmluYWwgSW5wdXRTdHJlYW0gaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGlucHV0KTsKKyAgICAgICAgICAgIGFpcyA9IGZhY3RvcnkuY3JlYXRlQXJjaGl2ZUlucHV0U3RyZWFtKCJqYXIiLCBpcyk7CisKKyAgICAgICAgICAgIHRlbXAgPSBuZXcgRmlsZShkaXIsICJibGEuamFyIik7CisgICAgICAgICAgICBvdXQgPSBmYWN0b3J5LmNyZWF0ZUFyY2hpdmVPdXRwdXRTdHJlYW0oImphciIsCisgICAgICAgICAgICAgICAgICAgIG5ldyBGaWxlT3V0cHV0U3RyZWFtKHRlbXApKTsKKworICAgICAgICAgICAgZmluYWwgQ2hhbmdlU2V0UGVyZm9ybWVyIHBlcmZvcm1lciA9IG5ldyBDaGFuZ2VTZXRQZXJmb3JtZXIoY2hhbmdlcyk7CisgICAgICAgICAgICBwZXJmb3JtZXIucGVyZm9ybShhaXMsIG91dCk7CisKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmIChvdXQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGFpcyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgYWlzLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgZmluYWwgTGlzdDxTdHJpbmc+IGV4cGVjdGVkID0gbmV3IEFycmF5TGlzdDw+KCk7CisgICAgICAgIGV4cGVjdGVkLmFkZCgidGVzdDEueG1sIik7CisgICAgICAgIHRoaXMuY2hlY2tBcmNoaXZlQ29udGVudCh0ZW1wLCBleHBlY3RlZCk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGVsZXRlRnJvbUFuZEFkZFRvVGFyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEFyY2hpdmVPdXRwdXRTdHJlYW0gb3V0ID0gbnVsbDsKKyAgICAgICAgQXJjaGl2ZUlucHV0U3RyZWFtIGFpcyA9IG51bGw7CisgICAgICAgIEZpbGUgdGVtcCA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmaW5hbCBDaGFuZ2VTZXQgY2hhbmdlcyA9IG5ldyBDaGFuZ2VTZXQoKTsKKyAgICAgICAgICAgIGNoYW5nZXMuZGVsZXRlKCJ0ZXN0Mi54bWwiKTsKKworICAgICAgICAgICAgZmluYWwgRmlsZSBmaWxlMSA9IGdldEZpbGUoInRlc3QudHh0Iik7CisKKyAgICAgICAgICAgIGZpbmFsIFRhckFyY2hpdmVFbnRyeSBlbnRyeSA9IG5ldyBUYXJBcmNoaXZlRW50cnkoCisgICAgICAgICAgICAgICAgICAgICJ0ZXN0ZGF0YS90ZXN0LnR4dCIpOworICAgICAgICAgICAgZW50cnkuc2V0TW9kVGltZSgwKTsKKyAgICAgICAgICAgIGVudHJ5LnNldFNpemUoZmlsZTEubGVuZ3RoKCkpOworICAgICAgICAgICAgZW50cnkuc2V0VXNlcklkKDApOworICAgICAgICAgICAgZW50cnkuc2V0R3JvdXBJZCgwKTsKKyAgICAgICAgICAgIGVudHJ5LnNldFVzZXJOYW1lKCJhdmFsb24iKTsKKyAgICAgICAgICAgIGVudHJ5LnNldEdyb3VwTmFtZSgiZXhjYWxpYnVyIik7CisgICAgICAgICAgICBlbnRyeS5zZXRNb2RlKDAxMDAwMDApOworCisgICAgICAgICAgICBjaGFuZ2VzLmFkZChlbnRyeSwgbmV3IEZpbGVJbnB1dFN0cmVhbShmaWxlMSkpOworCisgICAgICAgICAgICBmaW5hbCBGaWxlIGlucHV0ID0gZ2V0RmlsZSgiYmxhLnRhciIpOworICAgICAgICAgICAgZmluYWwgSW5wdXRTdHJlYW0gaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGlucHV0KTsKKyAgICAgICAgICAgIGFpcyA9IGZhY3RvcnkuY3JlYXRlQXJjaGl2ZUlucHV0U3RyZWFtKCJ0YXIiLCBpcyk7CisKKyAgICAgICAgICAgIHRlbXAgPSBuZXcgRmlsZShkaXIsICJibGEudGFyIik7CisgICAgICAgICAgICBvdXQgPSBmYWN0b3J5LmNyZWF0ZUFyY2hpdmVPdXRwdXRTdHJlYW0oInRhciIsCisgICAgICAgICAgICAgICAgICAgIG5ldyBGaWxlT3V0cHV0U3RyZWFtKHRlbXApKTsKKworICAgICAgICAgICAgZmluYWwgQ2hhbmdlU2V0UGVyZm9ybWVyIHBlcmZvcm1lciA9IG5ldyBDaGFuZ2VTZXRQZXJmb3JtZXIoY2hhbmdlcyk7CisgICAgICAgICAgICBwZXJmb3JtZXIucGVyZm9ybShhaXMsIG91dCk7CisKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmIChvdXQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGFpcyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgYWlzLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgZmluYWwgTGlzdDxTdHJpbmc+IGV4cGVjdGVkID0gbmV3IEFycmF5TGlzdDw+KCk7CisgICAgICAgIGV4cGVjdGVkLmFkZCgidGVzdDEueG1sIik7CisgICAgICAgIGV4cGVjdGVkLmFkZCgidGVzdGRhdGEvdGVzdC50eHQiKTsKKyAgICAgICAgZmluYWwgQXJjaGl2ZUlucHV0U3RyZWFtIGluID0gZmFjdG9yeS5jcmVhdGVBcmNoaXZlSW5wdXRTdHJlYW0oInRhciIsIG5ldyBGaWxlSW5wdXRTdHJlYW0odGVtcCkpOworICAgICAgICB0aGlzLmNoZWNrQXJjaGl2ZUNvbnRlbnQoaW4sIGV4cGVjdGVkKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZWxldGUgZnJvbSBhIGphciBmaWxlIGFuZCBhZGQgYW5vdGhlciBmaWxlCisgICAgICoKKyAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdERlbGV0ZUZyb21BbmRBZGRUb0phcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBBcmNoaXZlT3V0cHV0U3RyZWFtIG91dCA9IG51bGw7CisgICAgICAgIEFyY2hpdmVJbnB1dFN0cmVhbSBhaXMgPSBudWxsOworICAgICAgICBGaWxlIHRlbXAgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmluYWwgQ2hhbmdlU2V0IGNoYW5nZXMgPSBuZXcgQ2hhbmdlU2V0KCk7CisgICAgICAgICAgICBjaGFuZ2VzLmRlbGV0ZSgidGVzdDIueG1sIik7CisgICAgICAgICAgICBjaGFuZ2VzLmRlbGV0ZURpcigiTUVUQS1JTkYiKTsKKyAgICAgICAgICAgIGNoYW5nZXMuZGVsZXRlKCIuY2xhc3NwYXRoIik7CisgICAgICAgICAgICBjaGFuZ2VzLmRlbGV0ZSgiLnByb2plY3QiKTsKKworICAgICAgICAgICAgZmluYWwgRmlsZSBmaWxlMSA9IGdldEZpbGUoInRlc3QudHh0Iik7CisgICAgICAgICAgICBmaW5hbCBKYXJBcmNoaXZlRW50cnkgZW50cnkgPSBuZXcgSmFyQXJjaGl2ZUVudHJ5KCJ0ZXN0ZGF0YS90ZXN0LnR4dCIpOworICAgICAgICAgICAgY2hhbmdlcy5hZGQoZW50cnksIG5ldyBGaWxlSW5wdXRTdHJlYW0oZmlsZTEpKTsKKworICAgICAgICAgICAgZmluYWwgRmlsZSBpbnB1dCA9IGdldEZpbGUoImJsYS5qYXIiKTsKKyAgICAgICAgICAgIGZpbmFsIElucHV0U3RyZWFtIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShpbnB1dCk7CisgICAgICAgICAgICBhaXMgPSBmYWN0b3J5LmNyZWF0ZUFyY2hpdmVJbnB1dFN0cmVhbSgiamFyIiwgaXMpOworCisgICAgICAgICAgICB0ZW1wID0gbmV3IEZpbGUoZGlyLCAiYmxhLmphciIpOworICAgICAgICAgICAgb3V0ID0gZmFjdG9yeS5jcmVhdGVBcmNoaXZlT3V0cHV0U3RyZWFtKCJqYXIiLAorICAgICAgICAgICAgICAgICAgICBuZXcgRmlsZU91dHB1dFN0cmVhbSh0ZW1wKSk7CisKKyAgICAgICAgICAgIGZpbmFsIENoYW5nZVNldFBlcmZvcm1lciBwZXJmb3JtZXIgPSBuZXcgQ2hhbmdlU2V0UGVyZm9ybWVyKGNoYW5nZXMpOworICAgICAgICAgICAgcGVyZm9ybWVyLnBlcmZvcm0oYWlzLCBvdXQpOworCisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAob3V0ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChhaXMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGFpcy5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGZpbmFsIExpc3Q8U3RyaW5nPiBleHBlY3RlZCA9IG5ldyBBcnJheUxpc3Q8PigpOworICAgICAgICBleHBlY3RlZC5hZGQoInRlc3QxLnhtbCIpOworICAgICAgICBleHBlY3RlZC5hZGQoInRlc3RkYXRhL3Rlc3QudHh0Iik7CisgICAgICAgIHRoaXMuY2hlY2tBcmNoaXZlQ29udGVudCh0ZW1wLCBleHBlY3RlZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2ltcGxlIGRlbGV0ZSBmcm9tIGFuIGFyIGZpbGUKKyAgICAgKgorICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGVsZXRlRnJvbUFyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEFyY2hpdmVPdXRwdXRTdHJlYW0gb3V0ID0gbnVsbDsKKyAgICAgICAgQXJjaGl2ZUlucHV0U3RyZWFtIGFpcyA9IG51bGw7CisgICAgICAgIEZpbGUgdGVtcCA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmaW5hbCBDaGFuZ2VTZXQgY2hhbmdlcyA9IG5ldyBDaGFuZ2VTZXQoKTsKKyAgICAgICAgICAgIGNoYW5nZXMuZGVsZXRlKCJ0ZXN0Mi54bWwiKTsKKworICAgICAgICAgICAgZmluYWwgRmlsZSBpbnB1dCA9IGdldEZpbGUoImJsYS5hciIpOworICAgICAgICAgICAgZmluYWwgSW5wdXRTdHJlYW0gaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGlucHV0KTsKKyAgICAgICAgICAgIGFpcyA9IGZhY3RvcnkuY3JlYXRlQXJjaGl2ZUlucHV0U3RyZWFtKCJhciIsIGlzKTsKKworICAgICAgICAgICAgdGVtcCA9IG5ldyBGaWxlKGRpciwgImJsYS5hciIpOworICAgICAgICAgICAgb3V0ID0gZmFjdG9yeS5jcmVhdGVBcmNoaXZlT3V0cHV0U3RyZWFtKCJhciIsCisgICAgICAgICAgICAgICAgICAgIG5ldyBGaWxlT3V0cHV0U3RyZWFtKHRlbXApKTsKKworICAgICAgICAgICAgZmluYWwgQ2hhbmdlU2V0UGVyZm9ybWVyIHBlcmZvcm1lciA9IG5ldyBDaGFuZ2VTZXRQZXJmb3JtZXIoY2hhbmdlcyk7CisgICAgICAgICAgICBwZXJmb3JtZXIucGVyZm9ybShhaXMsIG91dCk7CisKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmIChvdXQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGFpcyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgYWlzLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBmaW5hbCBMaXN0PFN0cmluZz4gZXhwZWN0ZWQgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKyAgICAgICAgZXhwZWN0ZWQuYWRkKCJ0ZXN0MS54bWwiKTsKKyAgICAgICAgdGhpcy5jaGVja0FyY2hpdmVDb250ZW50KHRlbXAsIGV4cGVjdGVkKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZWxldGVzIGEgZmlsZSBmcm9tIGFuIEFSLWFyY2hpdmUgYW5kIGFkZHMgYW5vdGhlcgorICAgICAqCisgICAgICogQHRocm93cyBFeGNlcHRpb24KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3REZWxldGVGcm9tQW5kQWRkVG9BcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBBcmNoaXZlT3V0cHV0U3RyZWFtIG91dCA9IG51bGw7CisgICAgICAgIEFyY2hpdmVJbnB1dFN0cmVhbSBhaXMgPSBudWxsOworICAgICAgICBGaWxlIHRlbXAgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmluYWwgQ2hhbmdlU2V0IGNoYW5nZXMgPSBuZXcgQ2hhbmdlU2V0KCk7CisgICAgICAgICAgICBjaGFuZ2VzLmRlbGV0ZSgidGVzdDIueG1sIik7CisKKyAgICAgICAgICAgIGZpbmFsIEZpbGUgZmlsZTEgPSBnZXRGaWxlKCJ0ZXN0LnR4dCIpOworCisgICAgICAgICAgICBmaW5hbCBBckFyY2hpdmVFbnRyeSBlbnRyeSA9IG5ldyBBckFyY2hpdmVFbnRyeSgidGVzdC50eHQiLCBmaWxlMQorICAgICAgICAgICAgICAgICAgICAubGVuZ3RoKCkpOworCisgICAgICAgICAgICBjaGFuZ2VzLmFkZChlbnRyeSwgbmV3IEZpbGVJbnB1dFN0cmVhbShmaWxlMSkpOworCisgICAgICAgICAgICBmaW5hbCBGaWxlIGlucHV0ID0gZ2V0RmlsZSgiYmxhLmFyIik7CisgICAgICAgICAgICBmaW5hbCBJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpOworICAgICAgICAgICAgYWlzID0gZmFjdG9yeS5jcmVhdGVBcmNoaXZlSW5wdXRTdHJlYW0oImFyIiwgaXMpOworCisgICAgICAgICAgICB0ZW1wID0gbmV3IEZpbGUoZGlyLCAiYmxhLmFyIik7CisgICAgICAgICAgICBvdXQgPSBmYWN0b3J5LmNyZWF0ZUFyY2hpdmVPdXRwdXRTdHJlYW0oImFyIiwKKyAgICAgICAgICAgICAgICAgICAgbmV3IEZpbGVPdXRwdXRTdHJlYW0odGVtcCkpOworCisgICAgICAgICAgICBmaW5hbCBDaGFuZ2VTZXRQZXJmb3JtZXIgcGVyZm9ybWVyID0gbmV3IENoYW5nZVNldFBlcmZvcm1lcihjaGFuZ2VzKTsKKyAgICAgICAgICAgIHBlcmZvcm1lci5wZXJmb3JtKGFpcywgb3V0KTsKKworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKG91dCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgb3V0LmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoYWlzICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBhaXMuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBmaW5hbCBMaXN0PFN0cmluZz4gZXhwZWN0ZWQgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKyAgICAgICAgZXhwZWN0ZWQuYWRkKCJ0ZXN0MS54bWwiKTsKKyAgICAgICAgZXhwZWN0ZWQuYWRkKCJ0ZXN0LnR4dCIpOworICAgICAgICB0aGlzLmNoZWNrQXJjaGl2ZUNvbnRlbnQodGVtcCwgZXhwZWN0ZWQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRPRE86IE1vdmUgb3BlcmF0aW9ucyBhcmUgbm90IHN1cHBvcnRlZCBjdXJyZW50bHkKKyAgICAgKgorICAgICAqIG12IGRpcjEvdGVzdC50ZXh0IGRpcjIvdGVzdC50eHQgKyBkZWxldGUgZGlyMSBNb3ZlcyB0aGUgZmlsZSB0byBkaXIyIGFuZAorICAgICAqIGRlbGV0ZXMgZXZlcnl0aGluZyBpbiBkaXIxCisgICAgICoKKyAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFJlbmFtZUFuZERlbGV0ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIH0KKworICAgIC8qKgorICAgICAqIFRPRE86IE1vdmUgb3BlcmF0aW9ucyBhcmUgbm90IHN1cHBvcnRlZCBjdXJyZW50bHkKKyAgICAgKgorICAgICAqIGFkZCBkaXIxL2JsYS50eHQgKyBtdiBkaXIxL3Rlc3QudGV4dCBkaXIyL3Rlc3QudHh0ICsgZGVsZXRlIGRpcjEKKyAgICAgKgorICAgICAqIEFkZCBkaXIxL2JsYS50eHQgc2hvdWxkIGJlIHN1cnByZXNzZWQuIEFsbCBvdGhlciBkaXIxIGZpbGVzIHdpbGwgYmUKKyAgICAgKiBkZWxldGVkLCBleGNlcHQgZGlyMS90ZXN0LnRleHQgd2lsbCBiZSBtb3ZlZAorICAgICAqCisgICAgICogQHRocm93cyBFeGNlcHRpb24KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RBZGRNb3ZlRGVsZXRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2sgY2FuIGFkZCBhIGZpbGUgdG8gYW4gZW1wdHkgYXJjaGl2ZS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QWRkVG9FbXB0eUFyY2hpdmUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgU3RyaW5nIGFyY2hpdmVuYW1lID0gInppcCI7CisgICAgICAgIGZpbmFsIEZpbGUgaW5wdXQgPSB0aGlzLmNyZWF0ZUVtcHR5QXJjaGl2ZShhcmNoaXZlbmFtZSk7CisKKyAgICAgICAgQXJjaGl2ZU91dHB1dFN0cmVhbSBvdXQgPSBudWxsOworICAgICAgICBBcmNoaXZlSW5wdXRTdHJlYW0gYWlzID0gbnVsbDsKKyAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSBudWxsOworICAgICAgICBmaW5hbCBGaWxlIHJlc3VsdCA9IEZpbGUuY3JlYXRlVGVtcEZpbGUoInRlc3QiLCAiLiIrYXJjaGl2ZW5hbWUpOworICAgICAgICByZXN1bHQuZGVsZXRlT25FeGl0KCk7CisgICAgICAgIGZpbmFsIENoYW5nZVNldCBjaGFuZ2VzID0gbmV3IENoYW5nZVNldCgpOworICAgICAgICB0cnkgeworCisgICAgICAgICAgICBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpOworICAgICAgICAgICAgYWlzID0gZmFjdG9yeS5jcmVhdGVBcmNoaXZlSW5wdXRTdHJlYW0oYXJjaGl2ZW5hbWUsIGlzKTsKKworICAgICAgICAgICAgb3V0ID0gZmFjdG9yeS5jcmVhdGVBcmNoaXZlT3V0cHV0U3RyZWFtKGFyY2hpdmVuYW1lLAorICAgICAgICAgICAgICAgICAgICBuZXcgRmlsZU91dHB1dFN0cmVhbShyZXN1bHQpKTsKKworICAgICAgICAgICAgZmluYWwgRmlsZSBmaWxlMSA9IGdldEZpbGUoInRlc3QudHh0Iik7CisgICAgICAgICAgICBmaW5hbCBBcmNoaXZlRW50cnkgZW50cnkgPSBuZXcgWmlwQXJjaGl2ZUVudHJ5KCJibGEvdGVzdC50eHQiKTsKKyAgICAgICAgICAgIGNoYW5nZXMuYWRkKGVudHJ5LCBuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGUxKSk7CisgICAgICAgICAgICBhcmNoaXZlTGlzdC5hZGQoImJsYS90ZXN0LnR4dCIpOworICAgICAgICAgICAgZmluYWwgQ2hhbmdlU2V0UGVyZm9ybWVyIHBlcmZvcm1lciA9IG5ldyBDaGFuZ2VTZXRQZXJmb3JtZXIoY2hhbmdlcyk7CisgICAgICAgICAgICBwZXJmb3JtZXIucGVyZm9ybShhaXMsIG91dCk7CisgICAgICAgICAgICBpcy5jbG9zZSgpOworCisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAob3V0ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChhaXMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGFpcy5jbG9zZSgpOyAvLyB3aWxsIGNsb3NlIGlzCisgICAgICAgICAgICB9IGVsc2UgaWYgKGlzICE9IG51bGwpeworICAgICAgICAgICAgICAgIGlzLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB0aGlzLmNoZWNrQXJjaGl2ZUNvbnRlbnQocmVzdWx0LCBhcmNoaXZlTGlzdCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2sgY2FuIGRlbGV0ZSBhbmQgYWRkIGEgZmlsZSB0byBhbiBhcmNoaXZlIHdpdGggYSBzaW5nbGUgZmlsZQorICAgICAqCisgICAgICogQHRocm93cyBFeGNlcHRpb24KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3REZWxldGVBZGRUb09uZUZpbGVBcmNoaXZlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFN0cmluZyBhcmNoaXZlbmFtZSA9ICJ6aXAiOworICAgICAgICBmaW5hbCBGaWxlIGlucHV0ID0gdGhpcy5jcmVhdGVTaW5nbGVFbnRyeUFyY2hpdmUoYXJjaGl2ZW5hbWUpOworCisgICAgICAgIEFyY2hpdmVPdXRwdXRTdHJlYW0gb3V0ID0gbnVsbDsKKyAgICAgICAgQXJjaGl2ZUlucHV0U3RyZWFtIGFpcyA9IG51bGw7CisgICAgICAgIElucHV0U3RyZWFtIGlzID0gbnVsbDsKKyAgICAgICAgZmluYWwgRmlsZSByZXN1bHQgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKCJ0ZXN0IiwgIi4iK2FyY2hpdmVuYW1lKTsKKyAgICAgICAgcmVzdWx0LmRlbGV0ZU9uRXhpdCgpOworICAgICAgICBmaW5hbCBDaGFuZ2VTZXQgY2hhbmdlcyA9IG5ldyBDaGFuZ2VTZXQoKTsKKyAgICAgICAgdHJ5IHsKKworICAgICAgICAgICAgaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGlucHV0KTsKKyAgICAgICAgICAgIGFpcyA9IGZhY3RvcnkuY3JlYXRlQXJjaGl2ZUlucHV0U3RyZWFtKGFyY2hpdmVuYW1lLCBpcyk7CisKKyAgICAgICAgICAgIG91dCA9IGZhY3RvcnkuY3JlYXRlQXJjaGl2ZU91dHB1dFN0cmVhbShhcmNoaXZlbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgbmV3IEZpbGVPdXRwdXRTdHJlYW0ocmVzdWx0KSk7CisgICAgICAgICAgICBjaGFuZ2VzLmRlbGV0ZSgidGVzdDEueG1sIik7CisgICAgICAgICAgICBhcmNoaXZlTGlzdERlbGV0ZSgidGVzdDEueG1sIik7CisKKyAgICAgICAgICAgIGZpbmFsIEZpbGUgZmlsZSA9IGdldEZpbGUoInRlc3QudHh0Iik7CisgICAgICAgICAgICBmaW5hbCBBcmNoaXZlRW50cnkgZW50cnkgPSBvdXQuY3JlYXRlQXJjaGl2ZUVudHJ5KGZpbGUsImJsYS90ZXN0LnR4dCIpOworICAgICAgICAgICAgY2hhbmdlcy5hZGQoZW50cnksIG5ldyBGaWxlSW5wdXRTdHJlYW0oZmlsZSkpOworICAgICAgICAgICAgYXJjaGl2ZUxpc3QuYWRkKCJibGEvdGVzdC50eHQiKTsKKworICAgICAgICAgICAgZmluYWwgQ2hhbmdlU2V0UGVyZm9ybWVyIHBlcmZvcm1lciA9IG5ldyBDaGFuZ2VTZXRQZXJmb3JtZXIoY2hhbmdlcyk7CisgICAgICAgICAgICBwZXJmb3JtZXIucGVyZm9ybShhaXMsIG91dCk7CisgICAgICAgICAgICBpcy5jbG9zZSgpOworCisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAob3V0ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChhaXMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGFpcy5jbG9zZSgpOyAvLyB3aWxsIGNsb3NlIGlzCisgICAgICAgICAgICB9IGVsc2UgaWYgKGlzICE9IG51bGwpeworICAgICAgICAgICAgICAgIGlzLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB0aGlzLmNoZWNrQXJjaGl2ZUNvbnRlbnQocmVzdWx0LCBhcmNoaXZlTGlzdCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2sgY2FuIGFkZCBhbmQgZGVsZXRlIGEgZmlsZSB0byBhbiBhcmNoaXZlIHdpdGggYSBzaW5nbGUgZmlsZQorICAgICAqCisgICAgICogQHRocm93cyBFeGNlcHRpb24KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RBZGREZWxldGVUb09uZUZpbGVBcmNoaXZlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFN0cmluZyBhcmNoaXZlbmFtZSA9ICJjcGlvIjsKKyAgICAgICAgZmluYWwgRmlsZSBpbnB1dCA9IHRoaXMuY3JlYXRlU2luZ2xlRW50cnlBcmNoaXZlKGFyY2hpdmVuYW1lKTsKKworICAgICAgICBBcmNoaXZlT3V0cHV0U3RyZWFtIG91dCA9IG51bGw7CisgICAgICAgIEFyY2hpdmVJbnB1dFN0cmVhbSBhaXMgPSBudWxsOworICAgICAgICBJbnB1dFN0cmVhbSBpcyA9IG51bGw7CisgICAgICAgIGZpbmFsIEZpbGUgcmVzdWx0ID0gRmlsZS5jcmVhdGVUZW1wRmlsZSgidGVzdCIsICIuIithcmNoaXZlbmFtZSk7CisgICAgICAgIHJlc3VsdC5kZWxldGVPbkV4aXQoKTsKKyAgICAgICAgZmluYWwgQ2hhbmdlU2V0IGNoYW5nZXMgPSBuZXcgQ2hhbmdlU2V0KCk7CisgICAgICAgIHRyeSB7CisKKyAgICAgICAgICAgIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShpbnB1dCk7CisgICAgICAgICAgICBhaXMgPSBmYWN0b3J5LmNyZWF0ZUFyY2hpdmVJbnB1dFN0cmVhbShhcmNoaXZlbmFtZSwgaXMpOworCisgICAgICAgICAgICBvdXQgPSBmYWN0b3J5LmNyZWF0ZUFyY2hpdmVPdXRwdXRTdHJlYW0oYXJjaGl2ZW5hbWUsCisgICAgICAgICAgICAgICAgICAgIG5ldyBGaWxlT3V0cHV0U3RyZWFtKHJlc3VsdCkpOworICAgICAgICAgICAgZmluYWwgRmlsZSBmaWxlID0gZ2V0RmlsZSgidGVzdC50eHQiKTsKKyAgICAgICAgICAgIGZpbmFsIEFyY2hpdmVFbnRyeSBlbnRyeSA9IG91dC5jcmVhdGVBcmNoaXZlRW50cnkoZmlsZSwiYmxhL3Rlc3QudHh0Iik7CisgICAgICAgICAgICBjaGFuZ2VzLmFkZChlbnRyeSwgbmV3IEZpbGVJbnB1dFN0cmVhbShmaWxlKSk7CisgICAgICAgICAgICBhcmNoaXZlTGlzdC5hZGQoImJsYS90ZXN0LnR4dCIpOworCisgICAgICAgICAgICBjaGFuZ2VzLmRlbGV0ZSgidGVzdDEueG1sIik7CisgICAgICAgICAgICBhcmNoaXZlTGlzdERlbGV0ZSgidGVzdDEueG1sIik7CisKKyAgICAgICAgICAgIGZpbmFsIENoYW5nZVNldFBlcmZvcm1lciBwZXJmb3JtZXIgPSBuZXcgQ2hhbmdlU2V0UGVyZm9ybWVyKGNoYW5nZXMpOworICAgICAgICAgICAgcGVyZm9ybWVyLnBlcmZvcm0oYWlzLCBvdXQpOworICAgICAgICAgICAgaXMuY2xvc2UoKTsKKworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKG91dCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgb3V0LmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoYWlzICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBhaXMuY2xvc2UoKTsgLy8gd2lsbCBjbG9zZSBpcworICAgICAgICAgICAgfSBlbHNlIGlmIChpcyAhPSBudWxsKXsKKyAgICAgICAgICAgICAgICBpcy5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdGhpcy5jaGVja0FyY2hpdmVDb250ZW50KHJlc3VsdCwgYXJjaGl2ZUxpc3QpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgYSBmaWxlIHdpdGggdGhlIHNhbWUgZmlsZW5hbWUgYXMgYW4gZXhpc3RpbmcgZmlsZSBmcm9tIHRoZSBzdHJlYW0uCisgICAgICogU2hvdWxkIGxlYWQgdG8gYSByZXBsYWNlbWVudC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QWRkQWxscmVhZHlFeGlzdGluZ1dpdGhSZXBsYWNlVHJ1ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBTdHJpbmcgYXJjaGl2ZW5hbWUgPSAiemlwIjsKKyAgICAgICAgZmluYWwgRmlsZSBpbnB1dCA9IHRoaXMuY3JlYXRlQXJjaGl2ZShhcmNoaXZlbmFtZSk7CisKKyAgICAgICAgQXJjaGl2ZU91dHB1dFN0cmVhbSBvdXQgPSBudWxsOworICAgICAgICBBcmNoaXZlSW5wdXRTdHJlYW0gYWlzID0gbnVsbDsKKyAgICAgICAgZmluYWwgRmlsZSByZXN1bHQgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKCJ0ZXN0IiwgIi4iK2FyY2hpdmVuYW1lKTsKKyAgICAgICAgcmVzdWx0LmRlbGV0ZU9uRXhpdCgpOworICAgICAgICB0cnkgeworCisgICAgICAgICAgICBmaW5hbCBJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpOworICAgICAgICAgICAgYWlzID0gZmFjdG9yeS5jcmVhdGVBcmNoaXZlSW5wdXRTdHJlYW0oYXJjaGl2ZW5hbWUsIGlzKTsKKyAgICAgICAgICAgIG91dCA9IGZhY3RvcnkuY3JlYXRlQXJjaGl2ZU91dHB1dFN0cmVhbShhcmNoaXZlbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgbmV3IEZpbGVPdXRwdXRTdHJlYW0ocmVzdWx0KSk7CisKKyAgICAgICAgICAgIGZpbmFsIENoYW5nZVNldCBjaGFuZ2VzID0gbmV3IENoYW5nZVNldCgpOworCisgICAgICAgICAgICBmaW5hbCBGaWxlIGZpbGUxID0gZ2V0RmlsZSgidGVzdC50eHQiKTsKKyAgICAgICAgICAgIGZpbmFsIEFyY2hpdmVFbnRyeSBlbnRyeSA9IG5ldyBaaXBBcmNoaXZlRW50cnkoInRlc3RkYXRhL3Rlc3QxLnhtbCIpOworICAgICAgICAgICAgY2hhbmdlcy5hZGQoZW50cnksIG5ldyBGaWxlSW5wdXRTdHJlYW0oZmlsZTEpLCB0cnVlKTsKKworICAgICAgICAgICAgZmluYWwgQ2hhbmdlU2V0UGVyZm9ybWVyIHBlcmZvcm1lciA9IG5ldyBDaGFuZ2VTZXRQZXJmb3JtZXIoY2hhbmdlcyk7CisgICAgICAgICAgICBmaW5hbCBDaGFuZ2VTZXRSZXN1bHRzIHJlc3VsdHMgPSBwZXJmb3JtZXIucGVyZm9ybShhaXMsIG91dCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdHMuZ2V0QWRkZWRGcm9tQ2hhbmdlU2V0KCkuY29udGFpbnMoInRlc3RkYXRhL3Rlc3QxLnhtbCIpKTsKKyAgICAgICAgICAgIGlzLmNsb3NlKCk7CisKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmIChvdXQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGFpcyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgYWlzLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB0aGlzLmNoZWNrQXJjaGl2ZUNvbnRlbnQocmVzdWx0LCBhcmNoaXZlTGlzdCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkcyBhIGZpbGUgd2l0aCB0aGUgc2FtZSBmaWxlbmFtZSBhcyBhbiBleGlzdGluZyBmaWxlIGZyb20gdGhlIHN0cmVhbS4KKyAgICAgKiBTaG91bGQgbGVhZCB0byBhIHJlcGxhY2VtZW50LgorICAgICAqCisgICAgICogQHRocm93cyBFeGNlcHRpb24KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RBZGRBbGxyZWFkeUV4aXN0aW5nV2l0aFJlcGxhY2VGYWxzZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBTdHJpbmcgYXJjaGl2ZW5hbWUgPSAiemlwIjsKKyAgICAgICAgZmluYWwgRmlsZSBpbnB1dCA9IHRoaXMuY3JlYXRlQXJjaGl2ZShhcmNoaXZlbmFtZSk7CisKKyAgICAgICAgQXJjaGl2ZU91dHB1dFN0cmVhbSBvdXQgPSBudWxsOworICAgICAgICBBcmNoaXZlSW5wdXRTdHJlYW0gYWlzID0gbnVsbDsKKyAgICAgICAgZmluYWwgRmlsZSByZXN1bHQgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKCJ0ZXN0IiwgIi4iK2FyY2hpdmVuYW1lKTsKKyAgICAgICAgcmVzdWx0LmRlbGV0ZU9uRXhpdCgpOworICAgICAgICB0cnkgeworCisgICAgICAgICAgICBmaW5hbCBJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpOworICAgICAgICAgICAgYWlzID0gZmFjdG9yeS5jcmVhdGVBcmNoaXZlSW5wdXRTdHJlYW0oYXJjaGl2ZW5hbWUsIGlzKTsKKyAgICAgICAgICAgIG91dCA9IGZhY3RvcnkuY3JlYXRlQXJjaGl2ZU91dHB1dFN0cmVhbShhcmNoaXZlbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgbmV3IEZpbGVPdXRwdXRTdHJlYW0ocmVzdWx0KSk7CisKKyAgICAgICAgICAgIGZpbmFsIENoYW5nZVNldCBjaGFuZ2VzID0gbmV3IENoYW5nZVNldCgpOworCisgICAgICAgICAgICBmaW5hbCBGaWxlIGZpbGUxID0gZ2V0RmlsZSgidGVzdC50eHQiKTsKKyAgICAgICAgICAgIGZpbmFsIEFyY2hpdmVFbnRyeSBlbnRyeSA9IG5ldyBaaXBBcmNoaXZlRW50cnkoInRlc3RkYXRhL3Rlc3QxLnhtbCIpOworICAgICAgICAgICAgY2hhbmdlcy5hZGQoZW50cnksIG5ldyBGaWxlSW5wdXRTdHJlYW0oZmlsZTEpLCBmYWxzZSk7CisKKyAgICAgICAgICAgIGZpbmFsIENoYW5nZVNldFBlcmZvcm1lciBwZXJmb3JtZXIgPSBuZXcgQ2hhbmdlU2V0UGVyZm9ybWVyKGNoYW5nZXMpOworICAgICAgICAgICAgZmluYWwgQ2hhbmdlU2V0UmVzdWx0cyByZXN1bHRzID0gcGVyZm9ybWVyLnBlcmZvcm0oYWlzLCBvdXQpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHRzLmdldEFkZGVkRnJvbVN0cmVhbSgpLmNvbnRhaW5zKCJ0ZXN0ZGF0YS90ZXN0MS54bWwiKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdHMuZ2V0QWRkZWRGcm9tQ2hhbmdlU2V0KCkuaXNFbXB0eSgpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUocmVzdWx0cy5nZXREZWxldGVkKCkuaXNFbXB0eSgpKTsKKyAgICAgICAgICAgIGlzLmNsb3NlKCk7CisKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmIChvdXQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGFpcyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgYWlzLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB0aGlzLmNoZWNrQXJjaGl2ZUNvbnRlbnQocmVzdWx0LCBhcmNoaXZlTGlzdCk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jaGFuZ2VzL0NoYW5nZVRlc3QuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NoYW5nZXMvQ2hhbmdlVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkwNzA0MWMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jaGFuZ2VzL0NoYW5nZVRlc3QuamF2YQpAQCAtMCwwICsxLDY0IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNoYW5nZXM7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLm1lbW9yeS5NZW1vcnlBcmNoaXZlRW50cnk7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CisKK2ltcG9ydCBqYXZhLmlvLlBpcGVkSW5wdXRTdHJlYW07CisKKworLyoqCisgKiBVbml0IHRlc3RzIGZvciBjbGFzcyB7QGxpbmsgQ2hhbmdlfS4KKyAqCisgKiBAZGF0ZSAxNi4wNi4yMDE3CisgKiBAc2VlIENoYW5nZQorICoqLworcHVibGljIGNsYXNzIENoYW5nZVRlc3QgeworCisKKyAgICBAVGVzdChleHBlY3RlZCA9IE51bGxQb2ludGVyRXhjZXB0aW9uLmNsYXNzKQorICAgIHB1YmxpYyB2b2lkIHRlc3RGYWlsc1RvQ3JlYXRlQ2hhbmdlVGFraW5nRm91ckFyZ3VtZW50c1Rocm93c051bGxQb2ludGVyRXhjZXB0aW9uT25lKCkgeworCisgICAgICAgIE1lbW9yeUFyY2hpdmVFbnRyeSBtZW1vcnlBcmNoaXZlRW50cnkgPSBuZXcgTWVtb3J5QXJjaGl2ZUVudHJ5KCJ4Iik7CisKKyAgICAgICAgQ2hhbmdlIGNoYW5nZSAgPSBuZXcgQ2hhbmdlKG1lbW9yeUFyY2hpdmVFbnRyeSwgbnVsbCwgZmFsc2UpOworCisgICAgfQorCisKKyAgICBAVGVzdChleHBlY3RlZCA9IE51bGxQb2ludGVyRXhjZXB0aW9uLmNsYXNzKQorICAgIHB1YmxpYyB2b2lkIHRlc3RGYWlsc1RvQ3JlYXRlQ2hhbmdlVGFraW5nRm91ckFyZ3VtZW50c1Rocm93c051bGxQb2ludGVyRXhjZXB0aW9uVHdvKCkgeworCisgICAgICAgIFBpcGVkSW5wdXRTdHJlYW0gcGlwZWRJbnB1dFN0cmVhbSA9IG5ldyBQaXBlZElucHV0U3RyZWFtKDEpOworCisgICAgICAgIENoYW5nZSBjaGFuZ2UgID0gbmV3IENoYW5nZShudWxsLCBwaXBlZElucHV0U3RyZWFtLCBmYWxzZSk7CisKKyAgICB9CisKKworICAgIEBUZXN0KGV4cGVjdGVkID0gTnVsbFBvaW50ZXJFeGNlcHRpb24uY2xhc3MpCisgICAgcHVibGljIHZvaWQgdGVzdEZhaWxzVG9DcmVhdGVDaGFuZ2VUYWtpbmdUaHJlZUFyZ3VtZW50c1Rocm93c051bGxQb2ludGVyRXhjZXB0aW9uKCkgeworCisgICAgICAgIENoYW5nZSBjaGFuZ2UgID0gbmV3IENoYW5nZShudWxsLCAoLTQwNykpOworCisgICAgfQorCisKK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9CWmlwMlRlc3RDYXNlLmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9CWmlwMlRlc3RDYXNlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODhhY2E4ZAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL0JaaXAyVGVzdENhc2UuamF2YQpAQCAtMCwwICsxLDExNiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29yczsKKworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0Lio7CisKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuQWJzdHJhY3RUZXN0Q2FzZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuYnppcDIuQlppcDJDb21wcmVzc29ySW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLklPVXRpbHM7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBCWmlwMlRlc3RDYXNlIGV4dGVuZHMgQWJzdHJhY3RUZXN0Q2FzZSB7CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RCemlwQ3JlYXRpb24oKSAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEZpbGUgb3V0cHV0ID0gbnVsbDsKKyAgICAgICAgZmluYWwgRmlsZSBpbnB1dCA9IGdldEZpbGUoInRlc3QudHh0Iik7CisgICAgICAgIHsKKyAgICAgICAgICAgIG91dHB1dCA9IG5ldyBGaWxlKGRpciwgInRlc3QudHh0LmJ6MiIpOworICAgICAgICAgICAgZmluYWwgT3V0cHV0U3RyZWFtIG91dCA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKG91dHB1dCk7CisgICAgICAgICAgICBmaW5hbCBDb21wcmVzc29yT3V0cHV0U3RyZWFtIGNvcyA9IG5ldyBDb21wcmVzc29yU3RyZWFtRmFjdG9yeSgpLmNyZWF0ZUNvbXByZXNzb3JPdXRwdXRTdHJlYW0oImJ6aXAyIiwgb3V0KTsKKyAgICAgICAgICAgIGZpbmFsIEZpbGVJbnB1dFN0cmVhbSBpbiA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpOworICAgICAgICAgICAgSU9VdGlscy5jb3B5KGluLCBjb3MpOworICAgICAgICAgICAgY29zLmNsb3NlKCk7CisgICAgICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICB9CisKKyAgICAgICAgZmluYWwgRmlsZSBkZWNvbXByZXNzZWQgPSBuZXcgRmlsZShkaXIsICJkZWNvbXByZXNzZWQudHh0Iik7CisgICAgICAgIHsKKyAgICAgICAgICAgIGZpbmFsIEZpbGUgdG9EZWNvbXByZXNzID0gb3V0cHV0OworICAgICAgICAgICAgZmluYWwgSW5wdXRTdHJlYW0gaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKHRvRGVjb21wcmVzcyk7CisgICAgICAgICAgICBmaW5hbCBDb21wcmVzc29ySW5wdXRTdHJlYW0gaW4gPQorICAgICAgICAgICAgICAgIG5ldyBDb21wcmVzc29yU3RyZWFtRmFjdG9yeSgpLmNyZWF0ZUNvbXByZXNzb3JJbnB1dFN0cmVhbSgiYnppcDIiLCBpcyk7CisgICAgICAgICAgICBmaW5hbCBGaWxlT3V0cHV0U3RyZWFtIG9zID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0oZGVjb21wcmVzc2VkKTsKKyAgICAgICAgICAgIElPVXRpbHMuY29weShpbiwgb3MpOworICAgICAgICAgICAgaXMuY2xvc2UoKTsKKyAgICAgICAgICAgIG9zLmNsb3NlKCk7CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRFcXVhbHMoaW5wdXQubGVuZ3RoKCksZGVjb21wcmVzc2VkLmxlbmd0aCgpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RCemlwMlVuYXJjaGl2ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlIGlucHV0ID0gZ2V0RmlsZSgiYmxhLnR4dC5iejIiKTsKKyAgICAgICAgZmluYWwgRmlsZSBvdXRwdXQgPSBuZXcgRmlsZShkaXIsICJibGEudHh0Iik7CisgICAgICAgIGZpbmFsIElucHV0U3RyZWFtIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShpbnB1dCk7CisgICAgICAgIGZpbmFsIENvbXByZXNzb3JJbnB1dFN0cmVhbSBpbiA9IG5ldyBDb21wcmVzc29yU3RyZWFtRmFjdG9yeSgpLmNyZWF0ZUNvbXByZXNzb3JJbnB1dFN0cmVhbSgiYnppcDIiLCBpcyk7CisgICAgICAgIGZpbmFsIEZpbGVPdXRwdXRTdHJlYW0gb3MgPSBuZXcgRmlsZU91dHB1dFN0cmVhbShvdXRwdXQpOworICAgICAgICBJT1V0aWxzLmNvcHkoaW4sIG9zKTsKKyAgICAgICAgaXMuY2xvc2UoKTsKKyAgICAgICAgb3MuY2xvc2UoKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RDb25jYXRlbmF0ZWRTdHJlYW1zUmVhZEZpcnN0T25seSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlIGlucHV0ID0gZ2V0RmlsZSgibXVsdGlwbGUuYnoyIik7CisgICAgICAgIHRyeSAoSW5wdXRTdHJlYW0gaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGlucHV0KSkgeworICAgICAgICAgICAgdHJ5IChDb21wcmVzc29ySW5wdXRTdHJlYW0gaW4gPSBuZXcgQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkoKQorICAgICAgICAgICAgICAgICAgICAuY3JlYXRlQ29tcHJlc3NvcklucHV0U3RyZWFtKCJiemlwMiIsIGlzKSkgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygnYScsIGluLnJlYWQoKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBpbi5yZWFkKCkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29uY2F0ZW5hdGVkU3RyZWFtc1JlYWRGdWxseSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlIGlucHV0ID0gZ2V0RmlsZSgibXVsdGlwbGUuYnoyIik7CisgICAgICAgIHRyeSAoSW5wdXRTdHJlYW0gaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGlucHV0KSkgeworICAgICAgICAgICAgdHJ5IChDb21wcmVzc29ySW5wdXRTdHJlYW0gaW4gPSBuZXcgQlppcDJDb21wcmVzc29ySW5wdXRTdHJlYW0oaXMsIHRydWUpKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCdhJywgaW4ucmVhZCgpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoJ2InLCBpbi5yZWFkKCkpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygwLCBpbi5hdmFpbGFibGUoKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBpbi5yZWFkKCkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q09NUFJFU1MxMzEoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgRmlsZSBpbnB1dCA9IGdldEZpbGUoIkNPTVBSRVNTLTEzMS5iejIiKTsKKyAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpKSB7CisgICAgICAgICAgICB0cnkgKENvbXByZXNzb3JJbnB1dFN0cmVhbSBpbiA9IG5ldyBCWmlwMkNvbXByZXNzb3JJbnB1dFN0cmVhbShpcywgdHJ1ZSkpIHsKKyAgICAgICAgICAgICAgICBpbnQgbCA9IDA7CisgICAgICAgICAgICAgICAgd2hpbGUgKGluLnJlYWQoKSAhPSAtMSkgeworICAgICAgICAgICAgICAgICAgICBsKys7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyg1MzksIGwpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9CWmlwMlV0aWxzVGVzdENhc2UuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL0JaaXAyVXRpbHNUZXN0Q2FzZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI3MTU0ZWYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9CWmlwMlV0aWxzVGVzdENhc2UuamF2YQpAQCAtMCwwICsxLDc5IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzOworCitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuKjsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5iemlwMi5CWmlwMlV0aWxzOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworCitwdWJsaWMgY2xhc3MgQlppcDJVdGlsc1Rlc3RDYXNlIHsKKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdElzQ29tcHJlc3NlZEZpbGVuYW1lKCkgeworICAgICAgICBhc3NlcnRGYWxzZShCWmlwMlV0aWxzLmlzQ29tcHJlc3NlZEZpbGVuYW1lKCIiKSk7CisgICAgICAgIGFzc2VydEZhbHNlKEJaaXAyVXRpbHMuaXNDb21wcmVzc2VkRmlsZW5hbWUoIi5neiIpKTsKKworICAgICAgICBhc3NlcnRUcnVlKEJaaXAyVXRpbHMuaXNDb21wcmVzc2VkRmlsZW5hbWUoIngudGJ6MiIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShCWmlwMlV0aWxzLmlzQ29tcHJlc3NlZEZpbGVuYW1lKCJ4LnRieiIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShCWmlwMlV0aWxzLmlzQ29tcHJlc3NlZEZpbGVuYW1lKCJ4LmJ6MiIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShCWmlwMlV0aWxzLmlzQ29tcHJlc3NlZEZpbGVuYW1lKCJ4LmJ6IikpOworCisgICAgICAgIGFzc2VydEZhbHNlKEJaaXAyVXRpbHMuaXNDb21wcmVzc2VkRmlsZW5hbWUoInhiejIiKSk7CisgICAgICAgIGFzc2VydEZhbHNlKEJaaXAyVXRpbHMuaXNDb21wcmVzc2VkRmlsZW5hbWUoInhieiIpKTsKKworICAgICAgICBhc3NlcnRUcnVlKEJaaXAyVXRpbHMuaXNDb21wcmVzc2VkRmlsZW5hbWUoInguVEJaMiIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShCWmlwMlV0aWxzLmlzQ29tcHJlc3NlZEZpbGVuYW1lKCJ4LlRiejIiKSk7CisgICAgICAgIGFzc2VydFRydWUoQlppcDJVdGlscy5pc0NvbXByZXNzZWRGaWxlbmFtZSgieC50YloyIikpOworCisgICAgICAgIGFzc2VydEZhbHNlKEJaaXAyVXRpbHMuaXNDb21wcmVzc2VkRmlsZW5hbWUoInguYnogIikpOworICAgICAgICBhc3NlcnRGYWxzZShCWmlwMlV0aWxzLmlzQ29tcHJlc3NlZEZpbGVuYW1lKCJ4LnRielxuIikpOworICAgICAgICBhc3NlcnRGYWxzZShCWmlwMlV0aWxzLmlzQ29tcHJlc3NlZEZpbGVuYW1lKCJ4LnRiejIueSIpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRVbmNvbXByZXNzZWRGaWxlbmFtZSgpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCBCWmlwMlV0aWxzLmdldFVuY29tcHJlc3NlZEZpbGVuYW1lKCIiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiLmJ6MiIsIEJaaXAyVXRpbHMuZ2V0VW5jb21wcmVzc2VkRmlsZW5hbWUoIi5iejIiKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ4LnRhciIsIEJaaXAyVXRpbHMuZ2V0VW5jb21wcmVzc2VkRmlsZW5hbWUoIngudGJ6MiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ4LnRhciIsIEJaaXAyVXRpbHMuZ2V0VW5jb21wcmVzc2VkRmlsZW5hbWUoIngudGJ6IikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIngiLCBCWmlwMlV0aWxzLmdldFVuY29tcHJlc3NlZEZpbGVuYW1lKCJ4LmJ6MiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ4IiwgQlppcDJVdGlscy5nZXRVbmNvbXByZXNzZWRGaWxlbmFtZSgieC5ieiIpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIngudGFyIiwgQlppcDJVdGlscy5nZXRVbmNvbXByZXNzZWRGaWxlbmFtZSgieC5UQloyIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlgudGFyIiwgQlppcDJVdGlscy5nZXRVbmNvbXByZXNzZWRGaWxlbmFtZSgiWC5UYnoyIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlgudGFyIiwgQlppcDJVdGlscy5nZXRVbmNvbXByZXNzZWRGaWxlbmFtZSgiWC50YloyIikpOworCisgICAgICAgIGFzc2VydEVxdWFscygieC5ieiAiLCBCWmlwMlV0aWxzLmdldFVuY29tcHJlc3NlZEZpbGVuYW1lKCJ4LmJ6ICIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ4LnRielxuIiwgQlppcDJVdGlscy5nZXRVbmNvbXByZXNzZWRGaWxlbmFtZSgieC50YnpcbiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ4LnRiejIueSIsIEJaaXAyVXRpbHMuZ2V0VW5jb21wcmVzc2VkRmlsZW5hbWUoIngudGJ6Mi55IikpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEdldENvbXByZXNzZWRGaWxlbmFtZSgpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIuYnoyIiwgQlppcDJVdGlscy5nZXRDb21wcmVzc2VkRmlsZW5hbWUoIiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIgLmJ6MiIsIEJaaXAyVXRpbHMuZ2V0Q29tcHJlc3NlZEZpbGVuYW1lKCIgIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoInguYnoyIiwgQlppcDJVdGlscy5nZXRDb21wcmVzc2VkRmlsZW5hbWUoIngiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiWC5iejIiLCBCWmlwMlV0aWxzLmdldENvbXByZXNzZWRGaWxlbmFtZSgiWCIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ4LnRhci5iejIiLCBCWmlwMlV0aWxzLmdldENvbXByZXNzZWRGaWxlbmFtZSgieC50YXIiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygieC50YXIuYnoyIiwgQlppcDJVdGlscy5nZXRDb21wcmVzc2VkRmlsZW5hbWUoInguVEFSIikpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvQ29tcHJlc3NvclNlcnZpY2VMb2FkZXJUZXN0LmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9Db21wcmVzc29yU2VydmljZUxvYWRlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kMTAyN2VmCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvQ29tcHJlc3NvclNlcnZpY2VMb2FkZXJUZXN0LmphdmEKQEAgLTAsMCArMSw0MCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5UZXN0Q29tcHJlc3NvclN0cmVhbVByb3ZpZGVyLkludm9jYXRpb25Db25maXJtYXRpb25FeGNlcHRpb247CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CisKK3B1YmxpYyBjbGFzcyBDb21wcmVzc29yU2VydmljZUxvYWRlclRlc3QgeworCisgICAgQFRlc3QoZXhwZWN0ZWQgPSBJbnZvY2F0aW9uQ29uZmlybWF0aW9uRXhjZXB0aW9uLmNsYXNzKQorICAgIHB1YmxpYyB2b2lkIHRlc3RJbnB1dFN0cmVhbSgpIHRocm93cyBDb21wcmVzc29yRXhjZXB0aW9uIHsKKyAgICAgICAgbmV3IENvbXByZXNzb3JTdHJlYW1GYWN0b3J5KCkuY3JlYXRlQ29tcHJlc3NvcklucHV0U3RyZWFtKCJUZXN0SW5wdXQxIiwgbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKG5ldyBieXRlW10ge30pKTsKKyAgICB9CisKKyAgICBAVGVzdChleHBlY3RlZCA9IEludm9jYXRpb25Db25maXJtYXRpb25FeGNlcHRpb24uY2xhc3MpCisgICAgcHVibGljIHZvaWQgdGVzdE91dHB1dFN0cmVhbSgpIHRocm93cyBDb21wcmVzc29yRXhjZXB0aW9uIHsKKyAgICAgICAgbmV3IENvbXByZXNzb3JTdHJlYW1GYWN0b3J5KCkuY3JlYXRlQ29tcHJlc3Nvck91dHB1dFN0cmVhbSgiVGVzdE91dHB1dDEiLCBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCkpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvQ29tcHJlc3NvclN0cmVhbUZhY3RvcnlSb3VuZHRyaXBUZXN0LmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9Db21wcmVzc29yU3RyZWFtRmFjdG9yeVJvdW5kdHJpcFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MmZmNmU4Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvQ29tcHJlc3NvclN0cmVhbUZhY3RvcnlSb3VuZHRyaXBUZXN0LmphdmEKQEAgLTAsMCArMSw3NSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29yczsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuSU9VdGlsczsKK2ltcG9ydCBvcmcuanVuaXQuQXNzZXJ0OworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXIuUnVuV2l0aDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVycy5QYXJhbWV0ZXJpemVkOworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXJzLlBhcmFtZXRlcml6ZWQuUGFyYW1ldGVyczsKKworQFJ1bldpdGgoUGFyYW1ldGVyaXplZC5jbGFzcykKK3B1YmxpYyBjbGFzcyBDb21wcmVzc29yU3RyZWFtRmFjdG9yeVJvdW5kdHJpcFRlc3QgeworCisgICAgQFBhcmFtZXRlcnMobmFtZSA9ICJ7MH0iKQorICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nW10gZGF0YSgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmdbXSB7IC8vCisgICAgICAgICAgICAgICAgQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkuQlpJUDIsIC8vCisgICAgICAgICAgICAgICAgQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkuREVGTEFURSwgLy8KKyAgICAgICAgICAgICAgICBDb21wcmVzc29yU3RyZWFtRmFjdG9yeS5HWklQLCAvLworICAgICAgICAgICAgICAgIC8vIENvbXByZXNzb3JTdHJlYW1GYWN0b3J5LkxaTUEsIC8vIE5vdCBpbXBsZW1lbnRlZCB5ZXQKKyAgICAgICAgICAgICAgICAvLyBDb21wcmVzc29yU3RyZWFtRmFjdG9yeS5QQUNLMjAwLCAvLyBCdWcKKyAgICAgICAgICAgICAgICAvLyBDb21wcmVzc29yU3RyZWFtRmFjdG9yeS5TTkFQUFlfRlJBTUVELCAvLyBOb3QgaW1wbGVtZW50ZWQgeWV0CisgICAgICAgICAgICAgICAgLy8gQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkuU05BUFBZX1JBVywgLy8gTm90IGltcGxlbWVudGVkIHlldAorICAgICAgICAgICAgICAgIENvbXByZXNzb3JTdHJlYW1GYWN0b3J5LlhaLCAvLworICAgICAgICAgICAgICAgIC8vIENvbXByZXNzb3JTdHJlYW1GYWN0b3J5LlosIC8vIE5vdCBpbXBsZW1lbnRlZCB5ZXQKKyAgICAgICAgfTsKKyAgICB9CisKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBjb21wcmVzc29yTmFtZTsKKworICAgIHB1YmxpYyBDb21wcmVzc29yU3RyZWFtRmFjdG9yeVJvdW5kdHJpcFRlc3QoZmluYWwgU3RyaW5nIGNvbXByZXNzb3JOYW1lKSB7CisgICAgICAgIHRoaXMuY29tcHJlc3Nvck5hbWUgPSBjb21wcmVzc29yTmFtZTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RDb21wcmVzc29yU3RyZWFtRmFjdG9yeVJvdW5kdHJpcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBDb21wcmVzc29yU3RyZWFtUHJvdmlkZXIgZmFjdG9yeSA9IG5ldyBDb21wcmVzc29yU3RyZWFtRmFjdG9yeSgpOworICAgICAgICBmaW5hbCBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gY29tcHJlc3NlZE9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICBmaW5hbCBDb21wcmVzc29yT3V0cHV0U3RyZWFtIGNvbXByZXNzb3JPdXRwdXRTdHJlYW0gPSBmYWN0b3J5LmNyZWF0ZUNvbXByZXNzb3JPdXRwdXRTdHJlYW0oY29tcHJlc3Nvck5hbWUsCisgICAgICAgICAgICAgICAgY29tcHJlc3NlZE9zKTsKKyAgICAgICAgZmluYWwgU3RyaW5nIGZpeHR1cmUgPSAiVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZyI7CisgICAgICAgIGNvbXByZXNzb3JPdXRwdXRTdHJlYW0ud3JpdGUoZml4dHVyZS5nZXRCeXRlcygiVVRGLTgiKSk7CisgICAgICAgIGNvbXByZXNzb3JPdXRwdXRTdHJlYW0uZmx1c2goKTsKKyAgICAgICAgY29tcHJlc3Nvck91dHB1dFN0cmVhbS5jbG9zZSgpOworICAgICAgICBmaW5hbCBCeXRlQXJyYXlJbnB1dFN0cmVhbSBpcyA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShjb21wcmVzc2VkT3MudG9CeXRlQXJyYXkoKSk7CisgICAgICAgIGZpbmFsIENvbXByZXNzb3JJbnB1dFN0cmVhbSBjb21wcmVzc29ySW5wdXRTdHJlYW0gPSBmYWN0b3J5LmNyZWF0ZUNvbXByZXNzb3JJbnB1dFN0cmVhbShjb21wcmVzc29yTmFtZSwgaXMsIGZhbHNlKTsKKyAgICAgICAgZmluYWwgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGRlY29tcHJlc3NlZE9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICBJT1V0aWxzLmNvcHkoY29tcHJlc3NvcklucHV0U3RyZWFtLCBkZWNvbXByZXNzZWRPcyk7CisgICAgICAgIGNvbXByZXNzb3JJbnB1dFN0cmVhbS5jbG9zZSgpOworICAgICAgICBkZWNvbXByZXNzZWRPcy5mbHVzaCgpOworICAgICAgICBkZWNvbXByZXNzZWRPcy5jbG9zZSgpOworICAgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKGZpeHR1cmUsIGRlY29tcHJlc3NlZE9zLnRvU3RyaW5nKCJVVEYtOCIpKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL0RlZmxhdGVUZXN0Q2FzZS5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvRGVmbGF0ZVRlc3RDYXNlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDY4Y2I1NwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL0RlZmxhdGVUZXN0Q2FzZS5qYXZhCkBAIC0wLDAgKzEsMTIxIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzOworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLkFic3RyYWN0VGVzdENhc2U7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLmRlZmxhdGUuRGVmbGF0ZUNvbXByZXNzb3JJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuZGVmbGF0ZS5EZWZsYXRlQ29tcHJlc3Nvck91dHB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuZGVmbGF0ZS5EZWZsYXRlUGFyYW1ldGVyczsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuSU9VdGlsczsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworcHVibGljIGZpbmFsIGNsYXNzIERlZmxhdGVUZXN0Q2FzZSBleHRlbmRzIEFic3RyYWN0VGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogVGVzdHMgdGhlIGNyZWF0aW9uIG9mIGEgREVGTEFURSBhcmNoaXZlIHdpdGggemxpYiBoZWFkZXIKKyAgICAgKgorICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGVmbGF0ZUNyZWF0aW9uKCkgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlIGlucHV0ID0gZ2V0RmlsZSgidGVzdDEueG1sIik7CisgICAgICAgIGZpbmFsIEZpbGUgb3V0cHV0ID0gbmV3IEZpbGUoZGlyLCAidGVzdDEueG1sLmRlZmxhdGV6Iik7CisgICAgICAgIHRyeSAoT3V0cHV0U3RyZWFtIG91dCA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKG91dHB1dCkpIHsKKyAgICAgICAgICAgIHRyeSAoQ29tcHJlc3Nvck91dHB1dFN0cmVhbSBjb3MgPSBuZXcgQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkoKQorICAgICAgICAgICAgICAgICAgICAuY3JlYXRlQ29tcHJlc3Nvck91dHB1dFN0cmVhbSgiZGVmbGF0ZSIsIG91dCkpIHsKKyAgICAgICAgICAgICAgICBJT1V0aWxzLmNvcHkobmV3IEZpbGVJbnB1dFN0cmVhbShpbnB1dCksIGNvcyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0cyB0aGUgY3JlYXRpb24gb2YgYSAicmF3IiBERUZMQVRFIGFyY2hpdmUgKHdpdGhvdXQgemxpYiBoZWFkZXIpCisgICAgICoKKyAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFJhd0RlZmxhdGVDcmVhdGlvbigpICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgRmlsZSBpbnB1dCA9IGdldEZpbGUoInRlc3QxLnhtbCIpOworICAgICAgICBmaW5hbCBGaWxlIG91dHB1dCA9IG5ldyBGaWxlKGRpciwgInRlc3QxLnhtbC5kZWZsYXRlIik7CisgICAgICAgIHRyeSAoT3V0cHV0U3RyZWFtIG91dCA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKG91dHB1dCkpIHsKKyAgICAgICAgICAgIGZpbmFsIERlZmxhdGVQYXJhbWV0ZXJzIHBhcmFtcyA9IG5ldyBEZWZsYXRlUGFyYW1ldGVycygpOworICAgICAgICAgICAgcGFyYW1zLnNldFdpdGhabGliSGVhZGVyKGZhbHNlKTsKKyAgICAgICAgICAgIHRyeSAoQ29tcHJlc3Nvck91dHB1dFN0cmVhbSBjb3MgPSBuZXcgRGVmbGF0ZUNvbXByZXNzb3JPdXRwdXRTdHJlYW0ob3V0LCBwYXJhbXMpKSB7CisgICAgICAgICAgICAgICAgSU9VdGlscy5jb3B5KG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpLCBjb3MpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdHMgdGhlIGV4dHJhY3Rpb24gb2YgYSBERUZMQVRFIGFyY2hpdmUgd2l0aCB6bGliIGhlYWRlcgorICAgICAqCisgICAgICogQHRocm93cyBFeGNlcHRpb24KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3REZWZsYXRlVW5hcmNoaXZlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGUgaW5wdXQgPSBnZXRGaWxlKCJibGEudGFyLmRlZmxhdGV6Iik7CisgICAgICAgIGZpbmFsIEZpbGUgb3V0cHV0ID0gbmV3IEZpbGUoZGlyLCAiYmxhLnRhciIpOworICAgICAgICB0cnkgKElucHV0U3RyZWFtIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShpbnB1dCkpIHsKKyAgICAgICAgICAgIGZpbmFsIENvbXByZXNzb3JJbnB1dFN0cmVhbSBpbiA9IG5ldyBDb21wcmVzc29yU3RyZWFtRmFjdG9yeSgpCisgICAgICAgICAgICAgICAgICAgIC5jcmVhdGVDb21wcmVzc29ySW5wdXRTdHJlYW0oImRlZmxhdGUiLCBpcyk7IC8vIHpsaWIgaGVhZGVyIGlzIGV4cGVjdGVkIGJ5IGRlZmF1bHQKKyAgICAgICAgICAgIEZpbGVPdXRwdXRTdHJlYW0gb3V0ID0gbnVsbDsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgb3V0ID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0ob3V0cHV0KTsKKyAgICAgICAgICAgICAgICBJT1V0aWxzLmNvcHkoaW4sIG91dCk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIGlmIChvdXQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3RzIHRoZSBleHRyYWN0aW9uIG9mIGEgInJhdyIgREVGTEFURSBhcmNoaXZlICh3aXRob3V0IHpsaWIgaGVhZGVyKQorICAgICAqCisgICAgICogQHRocm93cyBFeGNlcHRpb24KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RSYXdEZWZsYXRlVW5hcmNoaXZlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGUgaW5wdXQgPSBnZXRGaWxlKCJibGEudGFyLmRlZmxhdGUiKTsKKyAgICAgICAgZmluYWwgRmlsZSBvdXRwdXQgPSBuZXcgRmlsZShkaXIsICJibGEudGFyIik7CisgICAgICAgIHRyeSAoSW5wdXRTdHJlYW0gaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGlucHV0KSkgeworICAgICAgICAgICAgZmluYWwgRGVmbGF0ZVBhcmFtZXRlcnMgcGFyYW1zID0gbmV3IERlZmxhdGVQYXJhbWV0ZXJzKCk7CisgICAgICAgICAgICBwYXJhbXMuc2V0V2l0aFpsaWJIZWFkZXIoZmFsc2UpOworICAgICAgICAgICAgZmluYWwgQ29tcHJlc3NvcklucHV0U3RyZWFtIGluID0gbmV3IERlZmxhdGVDb21wcmVzc29ySW5wdXRTdHJlYW0oaXMsIHBhcmFtcyk7CisgICAgICAgICAgICBGaWxlT3V0cHV0U3RyZWFtIG91dCA9IG51bGw7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIG91dCA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKG91dHB1dCk7CisgICAgICAgICAgICAgICAgSU9VdGlscy5jb3B5KGluLCBvdXQpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBpZiAob3V0ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgb3V0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGluLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9EZXRlY3RDb21wcmVzc29yVGVzdENhc2UuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL0RldGVjdENvbXByZXNzb3JUZXN0Q2FzZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE1OWJjNjAKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9EZXRlY3RDb21wcmVzc29yVGVzdENhc2UuamF2YQpAQCAtMCwwICsxLDI4NSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29yczsKKworaW1wb3J0IHN0YXRpYyBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuQWJzdHJhY3RUZXN0Q2FzZS5nZXRGaWxlOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEVxdWFsczsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRGYWxzZTsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnROb3ROdWxsOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydFRydWU7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuZmFpbDsKKworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5NZW1vcnlMaW1pdEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuTW9ja0V2aWxJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuYnppcDIuQlppcDJDb21wcmVzc29ySW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLmRlZmxhdGUuRGVmbGF0ZUNvbXByZXNzb3JJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuZ3ppcC5HemlwQ29tcHJlc3NvcklucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5wYWNrMjAwLlBhY2syMDBDb21wcmVzc29ySW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLnh6LlhaQ29tcHJlc3NvcklucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy56c3RhbmRhcmQuWnN0ZENvbXByZXNzb3JJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworQFN1cHByZXNzV2FybmluZ3MoImRlcHJlY2F0aW9uIikgLy8gZGVsaWJlcmF0ZWx5IHRlc3RzIHNldERlY29tcHJlc3NDb25jYXRlbmF0ZWQKK3B1YmxpYyBmaW5hbCBjbGFzcyBEZXRlY3RDb21wcmVzc29yVGVzdENhc2UgeworCisgICAgZmluYWwgQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkgZmFjdG9yeSA9IG5ldyBDb21wcmVzc29yU3RyZWFtRmFjdG9yeSgpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIENvbXByZXNzb3JTdHJlYW1GYWN0b3J5IGZhY3RvcnlUcnVlID0gbmV3IENvbXByZXNzb3JTdHJlYW1GYWN0b3J5KHRydWUpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIENvbXByZXNzb3JTdHJlYW1GYWN0b3J5IGZhY3RvcnlGYWxzZSA9IG5ldyBDb21wcmVzc29yU3RyZWFtRmFjdG9yeShmYWxzZSk7CisKKyAgICAvLyBNdXN0IGJlIHN0YXRpYyB0byBhbGxvdyB1c2UgaW4gdGhlIFRlc3REYXRhIGVudHJpZXMKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBDb21wcmVzc29yU3RyZWFtRmFjdG9yeSBmYWN0b3J5U2V0VHJ1ZTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBDb21wcmVzc29yU3RyZWFtRmFjdG9yeSBmYWN0b3J5U2V0RmFsc2U7CisKKyAgICBzdGF0aWMgeworICAgICAgICBmYWN0b3J5U2V0VHJ1ZSA9IG5ldyBDb21wcmVzc29yU3RyZWFtRmFjdG9yeSgpOworICAgICAgICBmYWN0b3J5U2V0VHJ1ZS5zZXREZWNvbXByZXNzQ29uY2F0ZW5hdGVkKHRydWUpOworICAgICAgICBmYWN0b3J5U2V0RmFsc2UgPSBuZXcgQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkoKTsKKyAgICAgICAgZmFjdG9yeVNldEZhbHNlLnNldERlY29tcHJlc3NDb25jYXRlbmF0ZWQoZmFsc2UpOworICAgIH0KKworICAgIHN0YXRpYyBjbGFzcyBUZXN0RGF0YSB7CisgICAgICAgIGZpbmFsIFN0cmluZyBmaWxlTmFtZTsgLy8gVGhlIG11bHRpcGxlIGZpbGUgbmFtZQorICAgICAgICBmaW5hbCBjaGFyW10gZW50cnlOYW1lczsgLy8gZXhwZWN0ZWQgZW50cmllcyAuLi4KKyAgICAgICAgZmluYWwgQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkgZmFjdG9yeTsgLy8gLi4uIHdoZW4gdXNpbmcgdGhpcyBmYWN0b3J5CisgICAgICAgIGZpbmFsIGJvb2xlYW4gY29uY2F0OyAvLyBleHBlY3RlZCB2YWx1ZSBmb3IgZGVjb21wcmVzc0NvbmNhdGVuYXRlZAorICAgICAgICBUZXN0RGF0YShmaW5hbCBTdHJpbmcgbmFtZSwgZmluYWwgY2hhcltdIG5hbWVzLCBmaW5hbCBDb21wcmVzc29yU3RyZWFtRmFjdG9yeSBmYWN0b3J5LCBmaW5hbCBib29sZWFuIGNvbmNhdCkgeworICAgICAgICAgICAgdGhpcy5maWxlTmFtZSA9IG5hbWU7CisgICAgICAgICAgICB0aGlzLmVudHJ5TmFtZXMgPSBuYW1lczsKKyAgICAgICAgICAgIHRoaXMuZmFjdG9yeSA9IGZhY3Rvcnk7CisgICAgICAgICAgICB0aGlzLmNvbmNhdCA9IGNvbmNhdDsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgZmluYWwgVGVzdERhdGFbXSB0ZXN0cyA9IHsKKyAgICAgICAgbmV3IFRlc3REYXRhKCJtdWx0aXBsZS5iejIiLCBuZXcgY2hhcltdeydhJywnYid9LCBmYWN0b3J5VHJ1ZSwgdHJ1ZSksCisgICAgICAgIG5ldyBUZXN0RGF0YSgibXVsdGlwbGUuYnoyIiwgbmV3IGNoYXJbXXsnYScsJ2InfSwgZmFjdG9yeVNldFRydWUsIHRydWUpLAorICAgICAgICBuZXcgVGVzdERhdGEoIm11bHRpcGxlLmJ6MiIsIG5ldyBjaGFyW117J2EnfSwgZmFjdG9yeUZhbHNlLCBmYWxzZSksCisgICAgICAgIG5ldyBUZXN0RGF0YSgibXVsdGlwbGUuYnoyIiwgbmV3IGNoYXJbXXsnYSd9LCBmYWN0b3J5U2V0RmFsc2UsIGZhbHNlKSwKKyAgICAgICAgbmV3IFRlc3REYXRhKCJtdWx0aXBsZS5iejIiLCBuZXcgY2hhcltdeydhJ30sIGZhY3RvcnksIGZhbHNlKSwKKworICAgICAgICBuZXcgVGVzdERhdGEoIm11bHRpcGxlLmd6IiwgbmV3IGNoYXJbXXsnYScsJ2InfSwgZmFjdG9yeVRydWUsIHRydWUpLAorICAgICAgICBuZXcgVGVzdERhdGEoIm11bHRpcGxlLmd6IiwgbmV3IGNoYXJbXXsnYScsJ2InfSwgZmFjdG9yeVNldFRydWUsIHRydWUpLAorICAgICAgICBuZXcgVGVzdERhdGEoIm11bHRpcGxlLmd6IiwgbmV3IGNoYXJbXXsnYSd9LCBmYWN0b3J5RmFsc2UsIGZhbHNlKSwKKyAgICAgICAgbmV3IFRlc3REYXRhKCJtdWx0aXBsZS5neiIsIG5ldyBjaGFyW117J2EnfSwgZmFjdG9yeVNldEZhbHNlLCBmYWxzZSksCisgICAgICAgIG5ldyBUZXN0RGF0YSgibXVsdGlwbGUuZ3oiLCBuZXcgY2hhcltdeydhJ30sIGZhY3RvcnksIGZhbHNlKSwKKworICAgICAgICBuZXcgVGVzdERhdGEoIm11bHRpcGxlLnh6IiwgbmV3IGNoYXJbXXsnYScsJ2InfSwgZmFjdG9yeVRydWUsIHRydWUpLAorICAgICAgICBuZXcgVGVzdERhdGEoIm11bHRpcGxlLnh6IiwgbmV3IGNoYXJbXXsnYScsJ2InfSwgZmFjdG9yeVNldFRydWUsIHRydWUpLAorICAgICAgICBuZXcgVGVzdERhdGEoIm11bHRpcGxlLnh6IiwgbmV3IGNoYXJbXXsnYSd9LCBmYWN0b3J5RmFsc2UsIGZhbHNlKSwKKyAgICAgICAgbmV3IFRlc3REYXRhKCJtdWx0aXBsZS54eiIsIG5ldyBjaGFyW117J2EnfSwgZmFjdG9yeVNldEZhbHNlLCBmYWxzZSksCisgICAgICAgIG5ldyBUZXN0RGF0YSgibXVsdGlwbGUueHoiLCBuZXcgY2hhcltdeydhJ30sIGZhY3RvcnksIGZhbHNlKSwKKyAgICB9OworCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGV0ZWN0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIENvbXByZXNzb3JJbnB1dFN0cmVhbSBiemlwMiA9IGdldFN0cmVhbUZvcigiYmxhLnR4dC5iejIiKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChiemlwMik7CisgICAgICAgIGFzc2VydFRydWUoYnppcDIgaW5zdGFuY2VvZiBCWmlwMkNvbXByZXNzb3JJbnB1dFN0cmVhbSk7CisKKyAgICAgICAgZmluYWwgQ29tcHJlc3NvcklucHV0U3RyZWFtIGd6aXAgPSBnZXRTdHJlYW1Gb3IoImJsYS50Z3oiKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChnemlwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShnemlwIGluc3RhbmNlb2YgR3ppcENvbXByZXNzb3JJbnB1dFN0cmVhbSk7CisKKyAgICAgICAgZmluYWwgQ29tcHJlc3NvcklucHV0U3RyZWFtIHBhY2syMDAgPSBnZXRTdHJlYW1Gb3IoImJsYS5wYWNrIik7CisgICAgICAgIGFzc2VydE5vdE51bGwocGFjazIwMCk7CisgICAgICAgIGFzc2VydFRydWUocGFjazIwMCBpbnN0YW5jZW9mIFBhY2syMDBDb21wcmVzc29ySW5wdXRTdHJlYW0pOworCisgICAgICAgIGZpbmFsIENvbXByZXNzb3JJbnB1dFN0cmVhbSB4eiA9IGdldFN0cmVhbUZvcigiYmxhLnRhci54eiIpOworICAgICAgICBhc3NlcnROb3ROdWxsKHh6KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh4eiBpbnN0YW5jZW9mIFhaQ29tcHJlc3NvcklucHV0U3RyZWFtKTsKKworICAgICAgICBmaW5hbCBDb21wcmVzc29ySW5wdXRTdHJlYW0gemxpYiA9IGdldFN0cmVhbUZvcigiYmxhLnRhci5kZWZsYXRleiIpOworICAgICAgICBhc3NlcnROb3ROdWxsKHpsaWIpOworICAgICAgICBhc3NlcnRUcnVlKHpsaWIgaW5zdGFuY2VvZiBEZWZsYXRlQ29tcHJlc3NvcklucHV0U3RyZWFtKTsKKworICAgICAgICBmaW5hbCBDb21wcmVzc29ySW5wdXRTdHJlYW0genN0ZCA9IGdldFN0cmVhbUZvcigiYmxhLnRhci56c3QiKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCh6c3RkKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh6c3RkIGluc3RhbmNlb2YgWnN0ZENvbXByZXNzb3JJbnB1dFN0cmVhbSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZhY3RvcnkuY3JlYXRlQ29tcHJlc3NvcklucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShuZXcgYnl0ZVswXSkpOworICAgICAgICAgICAgZmFpbCgiTm8gZXhjZXB0aW9uIHRocm93biBmb3IgYW4gZW1wdHkgaW5wdXQgc3RyZWFtIik7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIENvbXByZXNzb3JFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdERldGVjdCgpIHRocm93cyBFeGNlcHRpb24geworCisgICAgICAgIGFzc2VydEVxdWFscyhDb21wcmVzc29yU3RyZWFtRmFjdG9yeS5CWklQMiwgZGV0ZWN0KCJibGEudHh0LmJ6MiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKENvbXByZXNzb3JTdHJlYW1GYWN0b3J5LkdaSVAsIGRldGVjdCgiYmxhLnRneiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKENvbXByZXNzb3JTdHJlYW1GYWN0b3J5LlBBQ0syMDAsIGRldGVjdCgiYmxhLnBhY2siKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhDb21wcmVzc29yU3RyZWFtRmFjdG9yeS5YWiwgZGV0ZWN0KCJibGEudGFyLnh6IikpOworICAgICAgICBhc3NlcnRFcXVhbHMoQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkuREVGTEFURSwgZGV0ZWN0KCJibGEudGFyLmRlZmxhdGV6IikpOworICAgICAgICBhc3NlcnRFcXVhbHMoQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkuTFo0X0ZSQU1FRCwgZGV0ZWN0KCJibGEudGFyLmx6NCIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKENvbXByZXNzb3JTdHJlYW1GYWN0b3J5LkxaTUEsIGRldGVjdCgiYmxhLnRhci5sem1hIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkuU05BUFBZX0ZSQU1FRCwgZGV0ZWN0KCJibGEudGFyLnN6IikpOworICAgICAgICBhc3NlcnRFcXVhbHMoQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkuWiwgZGV0ZWN0KCJibGEudGFyLloiKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhDb21wcmVzc29yU3RyZWFtRmFjdG9yeS5aU1RBTkRBUkQsIGRldGVjdCgiYmxhLnRhci56c3QiKSk7CisKKyAgICAgICAgLy9tYWtlIHN1cmUgd2UgZG9uJ3Qgb29tIG9uIGRldGVjdAorICAgICAgICBhc3NlcnRFcXVhbHMoQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkuWiwgZGV0ZWN0KCJDT01QUkVTUy0zODYiKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhDb21wcmVzc29yU3RyZWFtRmFjdG9yeS5MWk1BLCBkZXRlY3QoIkNPTVBSRVNTLTM4MiIpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkuZGV0ZWN0KG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShuZXcgYnl0ZVswXSkpKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZG4ndCBiZSBhYmxlIHRvIGRldGVjdCBlbXB0eSBzdHJlYW0iKTsKKyAgICAgICAgfSBjYXRjaCAoQ29tcHJlc3NvckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIk5vIENvbXByZXNzb3IgZm91bmQgZm9yIHRoZSBzdHJlYW0gc2lnbmF0dXJlLiIsIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDb21wcmVzc29yU3RyZWFtRmFjdG9yeS5kZXRlY3QobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJzaG91bGRuJ3QgYmUgYWJsZSB0byBkZXRlY3QgbnVsbCBzdHJlYW0iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiU3RyZWFtIG11c3Qgbm90IGJlIG51bGwuIiwgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENvbXByZXNzb3JTdHJlYW1GYWN0b3J5LmRldGVjdChuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShuZXcgTW9ja0V2aWxJbnB1dFN0cmVhbSgpKSk7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBJT0V4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChDb21wcmVzc29yRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSU9FeGNlcHRpb24gd2hpbGUgcmVhZGluZyBzaWduYXR1cmUuIiwgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKworICAgIH0KKworICAgIHByaXZhdGUgU3RyaW5nIGRldGVjdChTdHJpbmcgdGVzdEZpbGVOYW1lKSB0aHJvd3MgSU9FeGNlcHRpb24sIENvbXByZXNzb3JFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgbmFtZSA9IG51bGw7CisgICAgICAgIHRyeSAoSW5wdXRTdHJlYW0gaXMgPSBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbSgKKyAgICAgICAgICAgICAgICBuZXcgRmlsZUlucHV0U3RyZWFtKGdldEZpbGUodGVzdEZpbGVOYW1lKSkpKSB7CisgICAgICAgICAgICBuYW1lID0gQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkuZGV0ZWN0KGlzKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmFtZTsKKyAgICB9CisKKyAgICBAVGVzdChleHBlY3RlZCA9IE1lbW9yeUxpbWl0RXhjZXB0aW9uLmNsYXNzKQorICAgIHB1YmxpYyB2b2lkIHRlc3RMWk1BTWVtb3J5TGltaXQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZ2V0U3RyZWFtRm9yKCJDT01QUkVTUy0zODIiLCAxMDApOworICAgIH0KKworICAgIEBUZXN0KGV4cGVjdGVkID0gTWVtb3J5TGltaXRFeGNlcHRpb24uY2xhc3MpCisgICAgcHVibGljIHZvaWQgdGVzdFpNZW1vcnlMaW1pdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBnZXRTdHJlYW1Gb3IoIkNPTVBSRVNTLTM4NiIsIDEwMCk7CisgICAgfQorCisgICAgQFRlc3QoZXhwZWN0ZWQgPSBNZW1vcnlMaW1pdEV4Y2VwdGlvbi5jbGFzcykKKyAgICBwdWJsaWMgdm9pZCB0ZXN0WFpNZW1vcnlMaW1pdE9uUmVhZCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvL0V2ZW4gdGhvdWdoIHRoZSBmaWxlIGlzIHZlcnkgc21hbGwsIHRoZSBtZW1vcnkgbGltaXQKKyAgICAgICAgLy9oYXMgdG8gYmUgcXVpdGUgbGFyZ2UgKDgyOTYgS2lCKSBiZWNhdXNlIG9mIHRoZSBkaWN0aW9uYXJ5IHNpemUKKworICAgICAgICAvL1RoaXMgaXMgdHJpZ2dlcmVkIG9uIHJlYWQoKTsgbm90IGR1cmluZyBpbml0aWFsaXphdGlvbi4KKyAgICAgICAgLy9UaGlzIHRlc3QgaXMgaGVyZSBpbnN0ZWFkIG9mIHRoZSB4eiB1bml0IHRlc3QgdG8gbWFrZSBzdXJlCisgICAgICAgIC8vdGhhdCB0aGUgcGFyYW1ldGVyIGlzIHByb3Blcmx5IHBhc3NlZCB2aWEgdGhlIENvbXByZXNzb3JTdHJlYW1GYWN0b3J5CisgICAgICAgIHRyeSAoSW5wdXRTdHJlYW0gY29tcHJlc3NvcklzID0gZ2V0U3RyZWFtRm9yKCJibGEudGFyLnh6IiwgMTAwKSkgeworICAgICAgICAgICAgY29tcHJlc3NvcklzLnJlYWQoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0KGV4cGVjdGVkID0gTWVtb3J5TGltaXRFeGNlcHRpb24uY2xhc3MpCisgICAgcHVibGljIHZvaWQgdGVzdFhaTWVtb3J5TGltaXRPblNraXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBjb21wcmVzc29ySXMgPSBnZXRTdHJlYW1Gb3IoImJsYS50YXIueHoiLCAxMDApKSB7CisgICAgICAgICAgICBjb21wcmVzc29ySXMuc2tpcCgxMCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIElucHV0U3RyZWFtIGdldFN0cmVhbUZvcihmaW5hbCBTdHJpbmcgZmlsZU5hbWUsIGZpbmFsIGludCBtZW1vcnlMaW1pdEluS2IpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBDb21wcmVzc29yU3RyZWFtRmFjdG9yeSBmYWMgPSBuZXcgQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkodHJ1ZSwKKyAgICAgICAgICAgICAgICBtZW1vcnlMaW1pdEluS2IpOworICAgICAgICBJbnB1dFN0cmVhbSBpcyA9IG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKAorICAgICAgICAgICAgICAgIG5ldyBGaWxlSW5wdXRTdHJlYW0oZ2V0RmlsZShmaWxlTmFtZSkpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBmYWMuY3JlYXRlQ29tcHJlc3NvcklucHV0U3RyZWFtKGlzKTsKKyAgICAgICAgfSBjYXRjaCAoQ29tcHJlc3NvckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBpZiAoZS5nZXRDYXVzZSgpICE9IG51bGwgJiYgZS5nZXRDYXVzZSgpIGluc3RhbmNlb2YgRXhjZXB0aW9uKSB7CisgICAgICAgICAgICAgICAgLy91bndyYXAgY2F1c2UgdG8gcmV2ZWFsIE1lbW9yeUxpbWl0RXhjZXB0aW9uCisgICAgICAgICAgICAgICAgdGhyb3cgKEV4Y2VwdGlvbillLmdldENhdXNlKCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHRocm93IGU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgIH0KKworCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0T3ZlcnJpZGUoKSB7CisgICAgICAgIENvbXByZXNzb3JTdHJlYW1GYWN0b3J5IGZhYyA9IG5ldyBDb21wcmVzc29yU3RyZWFtRmFjdG9yeSgpOworICAgICAgICBhc3NlcnRGYWxzZShmYWMuZ2V0RGVjb21wcmVzc0NvbmNhdGVuYXRlZCgpKTsKKyAgICAgICAgZmFjLnNldERlY29tcHJlc3NDb25jYXRlbmF0ZWQodHJ1ZSk7CisgICAgICAgIGFzc2VydFRydWUoZmFjLmdldERlY29tcHJlc3NDb25jYXRlbmF0ZWQoKSk7CisKKyAgICAgICAgZmFjID0gbmV3IENvbXByZXNzb3JTdHJlYW1GYWN0b3J5KGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoZmFjLmdldERlY29tcHJlc3NDb25jYXRlbmF0ZWQoKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmYWMuc2V0RGVjb21wcmVzc0NvbmNhdGVuYXRlZCh0cnVlKTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChmaW5hbCBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaXNlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgZmFjID0gbmV3IENvbXByZXNzb3JTdHJlYW1GYWN0b3J5KHRydWUpOworICAgICAgICBhc3NlcnRUcnVlKGZhYy5nZXREZWNvbXByZXNzQ29uY2F0ZW5hdGVkKCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmFjLnNldERlY29tcHJlc3NDb25jYXRlbmF0ZWQodHJ1ZSk7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBJbGxlZ2FsU3RhdGVFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlzZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdE11dGlwbGVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZvcihpbnQgaT0wOyBpIDx0ZXN0cy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgZmluYWwgVGVzdERhdGEgdGVzdCA9IHRlc3RzW2ldOworICAgICAgICAgICAgZmluYWwgQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkgZmFjID0gdGVzdC5mYWN0b3J5OworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiVGVzdCBlbnRyeSAiK2ksIGZhYyk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgZW50cnkgIitpLCB0ZXN0LmNvbmNhdCwgZmFjLmdldERlY29tcHJlc3NDb25jYXRlbmF0ZWQoKSk7CisgICAgICAgICAgICBmaW5hbCBDb21wcmVzc29ySW5wdXRTdHJlYW0gaW4gPSBnZXRTdHJlYW1Gb3IodGVzdC5maWxlTmFtZSwgZmFjKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoIlRlc3QgZW50cnkgIitpLGluKTsKKyAgICAgICAgICAgIGZvciAoZmluYWwgY2hhciBlbnRyeSA6IHRlc3QuZW50cnlOYW1lcykgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCBlbnRyeSIgKyBpLCBlbnRyeSwgaW4ucmVhZCgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydEVxdWFscygwLCBpbi5hdmFpbGFibGUoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIGluLnJlYWQoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIENvbXByZXNzb3JJbnB1dFN0cmVhbSBnZXRTdHJlYW1Gb3IoZmluYWwgU3RyaW5nIHJlc291cmNlKQorICAgICAgICAgICAgdGhyb3dzIENvbXByZXNzb3JFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGZhY3RvcnkuY3JlYXRlQ29tcHJlc3NvcklucHV0U3RyZWFtKAorICAgICAgICAgICAgICAgICAgIG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKG5ldyBGaWxlSW5wdXRTdHJlYW0oCisgICAgICAgICAgICAgICAgICAgICAgIGdldEZpbGUocmVzb3VyY2UpKSkpOworICAgIH0KKworICAgIHByaXZhdGUgQ29tcHJlc3NvcklucHV0U3RyZWFtIGdldFN0cmVhbUZvcihmaW5hbCBTdHJpbmcgcmVzb3VyY2UsIGZpbmFsIENvbXByZXNzb3JTdHJlYW1GYWN0b3J5IGZhY3RvcnkpCisgICAgICAgICAgICB0aHJvd3MgQ29tcHJlc3NvckV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gZmFjdG9yeS5jcmVhdGVDb21wcmVzc29ySW5wdXRTdHJlYW0oCisgICAgICAgICAgICAgICAgICAgbmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0obmV3IEZpbGVJbnB1dFN0cmVhbSgKKyAgICAgICAgICAgICAgICAgICAgICAgZ2V0RmlsZShyZXNvdXJjZSkpKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvRnJhbWVkU25hcHB5VGVzdENhc2UuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL0ZyYW1lZFNuYXBweVRlc3RDYXNlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTMzYzdmZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL0ZyYW1lZFNuYXBweVRlc3RDYXNlLmphdmEKQEAgLTAsMCArMSwxNTUgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnM7CisKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC4qOworCitpbXBvcnQgamF2YS5pby5CdWZmZXJlZElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5SYW5kb207CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuQWJzdHJhY3RUZXN0Q2FzZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuc25hcHB5LkZyYW1lZFNuYXBweUNvbXByZXNzb3JJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuSU9VdGlsczsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworcHVibGljIGZpbmFsIGNsYXNzIEZyYW1lZFNuYXBweVRlc3RDYXNlCisgICAgZXh0ZW5kcyBBYnN0cmFjdFRlc3RDYXNlIHsKKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdERlZmF1bHRFeHRyYWN0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RVbmFyY2hpdmUobmV3IFN0cmVhbVdyYXBwZXI8Q29tcHJlc3NvcklucHV0U3RyZWFtPigpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIENvbXByZXNzb3JJbnB1dFN0cmVhbSB3cmFwKGZpbmFsIElucHV0U3RyZWFtIGlzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgRnJhbWVkU25hcHB5Q29tcHJlc3NvcklucHV0U3RyZWFtKGlzKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGVmYXVsdEV4dHJhY3Rpb25WaWFGYWN0b3J5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RVbmFyY2hpdmUobmV3IFN0cmVhbVdyYXBwZXI8Q29tcHJlc3NvcklucHV0U3RyZWFtPigpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIENvbXByZXNzb3JJbnB1dFN0cmVhbSB3cmFwKGZpbmFsIElucHV0U3RyZWFtIGlzKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IENvbXByZXNzb3JTdHJlYW1GYWN0b3J5KCkKKyAgICAgICAgICAgICAgICAgICAgLmNyZWF0ZUNvbXByZXNzb3JJbnB1dFN0cmVhbShDb21wcmVzc29yU3RyZWFtRmFjdG9yeS5TTkFQUFlfRlJBTUVELAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGVmYXVsdEV4dHJhY3Rpb25WaWFGYWN0b3J5QXV0b2RldGVjdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0VW5hcmNoaXZlKG5ldyBTdHJlYW1XcmFwcGVyPENvbXByZXNzb3JJbnB1dFN0cmVhbT4oKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBDb21wcmVzc29ySW5wdXRTdHJlYW0gd3JhcChmaW5hbCBJbnB1dFN0cmVhbSBpcykgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBDb21wcmVzc29yU3RyZWFtRmFjdG9yeSgpLmNyZWF0ZUNvbXByZXNzb3JJbnB1dFN0cmVhbShpcyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0pOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0VW5hcmNoaXZlKGZpbmFsIFN0cmVhbVdyYXBwZXI8Q29tcHJlc3NvcklucHV0U3RyZWFtPiB3cmFwcGVyKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgRmlsZSBpbnB1dCA9IGdldEZpbGUoImJsYS50YXIuc3oiKTsKKyAgICAgICAgZmluYWwgRmlsZSBvdXRwdXQgPSBuZXcgRmlsZShkaXIsICJibGEudGFyIik7CisgICAgICAgIHRyeSAoRmlsZUlucHV0U3RyZWFtIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShpbnB1dCkpIHsKKyAgICAgICAgICAgIC8vIHRoZSBpbnRlcm1lZGlhdGUgQnVmZmVyZWRJbnB1dFN0cmVhbSBpcyB0aGVyZSBmb3IgbWFyaworICAgICAgICAgICAgLy8gc3VwcG9ydCBpbiB0aGUgYXV0b2RldGVjdGlvbiB0ZXN0CisgICAgICAgICAgICBmaW5hbCBDb21wcmVzc29ySW5wdXRTdHJlYW0gaW4gPSB3cmFwcGVyLndyYXAobmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0oaXMpKTsKKyAgICAgICAgICAgIEZpbGVPdXRwdXRTdHJlYW0gb3V0ID0gbnVsbDsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgb3V0ID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0ob3V0cHV0KTsKKyAgICAgICAgICAgICAgICBJT1V0aWxzLmNvcHkoaW4sIG91dCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDk5NSwgaW4uZ2V0Qnl0ZXNSZWFkKCkpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBpZiAob3V0ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgb3V0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGluLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgZmluYWwgRmlsZSBvcmlnaW5hbCA9IGdldEZpbGUoImJsYS50YXIiKTsKKyAgICAgICAgdHJ5IChGaWxlSW5wdXRTdHJlYW0gd3JpdHRlbiA9IG5ldyBGaWxlSW5wdXRTdHJlYW0ob3V0cHV0KSkgeworICAgICAgICAgICAgdHJ5IChGaWxlSW5wdXRTdHJlYW0gb3JpZyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0ob3JpZ2luYWwpKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMoSU9VdGlscy50b0J5dGVBcnJheSh3cml0dGVuKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIElPVXRpbHMudG9CeXRlQXJyYXkob3JpZykpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Um91bmR0cmlwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RSb3VuZHRyaXAoZ2V0RmlsZSgidGVzdC50eHQiKSk7CisgICAgICAgIHRlc3RSb3VuZHRyaXAoZ2V0RmlsZSgiYmxhLnRhciIpKTsKKyAgICAgICAgdGVzdFJvdW5kdHJpcChnZXRGaWxlKCJDT01QUkVTUy0yNTYuN3oiKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Um91bmR0cmlwV2l0aE9uZUJpZ1dyaXRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFJhbmRvbSByID0gbmV3IFJhbmRvbSgpOworICAgICAgICBGaWxlIGlucHV0ID0gbmV3IEZpbGUoZGlyLCAiYmlnQ2h1bmtUZXN0Iik7CisgICAgICAgIHRyeSAoRmlsZU91dHB1dFN0cmVhbSBmcyA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKGlucHV0KSkgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDAgOyBpIDwgMSA8PCAxNzsgaSsrKSB7CisgICAgICAgICAgICAgICAgZnMud3JpdGUoci5uZXh0SW50KDI1NikpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGxvbmcgc3RhcnQgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICAgICAgZmluYWwgRmlsZSBvdXRwdXRTeiA9IG5ldyBGaWxlKGRpciwgaW5wdXQuZ2V0TmFtZSgpICsgIi5zeiIpOworICAgICAgICB0cnkgKEZpbGVJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpOworICAgICAgICAgICAgIEZpbGVPdXRwdXRTdHJlYW0gb3MgPSBuZXcgRmlsZU91dHB1dFN0cmVhbShvdXRwdXRTeik7CisgICAgICAgICAgICAgQ29tcHJlc3Nvck91dHB1dFN0cmVhbSBzb3MgPSBuZXcgQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkoKQorICAgICAgICAgICAgICAgICAuY3JlYXRlQ29tcHJlc3Nvck91dHB1dFN0cmVhbSgic25hcHB5LWZyYW1lZCIsIG9zKSkgeworICAgICAgICAgICAgYnl0ZVtdIGIgPSBJT1V0aWxzLnRvQnl0ZUFycmF5KGlzKTsKKyAgICAgICAgICAgIHNvcy53cml0ZShiWzBdKTsKKyAgICAgICAgICAgIHNvcy53cml0ZShiLCAxLCBiLmxlbmd0aCAtIDEpOyAvLyBtdXN0IGJlIHNwbGl0IGludG8gbXVsdGlwbGUgY29tcHJlc3NlZCBjaHVua3MKKyAgICAgICAgfQorICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oaW5wdXQuZ2V0TmFtZSgpICsgIiB3cml0dGVuLCB1bmNvbXByZXNzZWQgYnl0ZXM6ICIgKyBpbnB1dC5sZW5ndGgoKQorICAgICAgICAgICAgKyAiLCBjb21wcmVzc2VkIGJ5dGVzOiAiICsgb3V0cHV0U3oubGVuZ3RoKCkgKyAiIGFmdGVyICIgKyAoU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgLSBzdGFydCkgKyAibXMiKTsKKyAgICAgICAgdHJ5IChGaWxlSW5wdXRTdHJlYW0gaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGlucHV0KTsKKyAgICAgICAgICAgICBDb21wcmVzc29ySW5wdXRTdHJlYW0gc2lzID0gbmV3IENvbXByZXNzb3JTdHJlYW1GYWN0b3J5KCkKKyAgICAgICAgICAgICAgICAgLmNyZWF0ZUNvbXByZXNzb3JJbnB1dFN0cmVhbSgic25hcHB5LWZyYW1lZCIsIG5ldyBGaWxlSW5wdXRTdHJlYW0ob3V0cHV0U3opKSkgeworICAgICAgICAgICAgYnl0ZVtdIGV4cGVjdGVkID0gSU9VdGlscy50b0J5dGVBcnJheShpcyk7CisgICAgICAgICAgICBieXRlW10gYWN0dWFsID0gSU9VdGlscy50b0J5dGVBcnJheShzaXMpOworICAgICAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMoZXhwZWN0ZWQsIGFjdHVhbCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdGVzdFJvdW5kdHJpcChGaWxlIGlucHV0KSAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGxvbmcgc3RhcnQgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICAgICAgZmluYWwgRmlsZSBvdXRwdXRTeiA9IG5ldyBGaWxlKGRpciwgaW5wdXQuZ2V0TmFtZSgpICsgIi5zeiIpOworICAgICAgICB0cnkgKEZpbGVJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpOworICAgICAgICAgICAgIEZpbGVPdXRwdXRTdHJlYW0gb3MgPSBuZXcgRmlsZU91dHB1dFN0cmVhbShvdXRwdXRTeik7CisgICAgICAgICAgICAgQ29tcHJlc3Nvck91dHB1dFN0cmVhbSBzb3MgPSBuZXcgQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkoKQorICAgICAgICAgICAgICAgICAuY3JlYXRlQ29tcHJlc3Nvck91dHB1dFN0cmVhbSgic25hcHB5LWZyYW1lZCIsIG9zKSkgeworICAgICAgICAgICAgSU9VdGlscy5jb3B5KGlzLCBzb3MpOworICAgICAgICB9CisgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbihpbnB1dC5nZXROYW1lKCkgKyAiIHdyaXR0ZW4sIHVuY29tcHJlc3NlZCBieXRlczogIiArIGlucHV0Lmxlbmd0aCgpCisgICAgICAgICAgICArICIsIGNvbXByZXNzZWQgYnl0ZXM6ICIgKyBvdXRwdXRTei5sZW5ndGgoKSArICIgYWZ0ZXIgIiArIChTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSAtIHN0YXJ0KSArICJtcyIpOworICAgICAgICB0cnkgKEZpbGVJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpOworICAgICAgICAgICAgIENvbXByZXNzb3JJbnB1dFN0cmVhbSBzaXMgPSBuZXcgQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkoKQorICAgICAgICAgICAgICAgICAuY3JlYXRlQ29tcHJlc3NvcklucHV0U3RyZWFtKCJzbmFwcHktZnJhbWVkIiwgbmV3IEZpbGVJbnB1dFN0cmVhbShvdXRwdXRTeikpKSB7CisgICAgICAgICAgICBieXRlW10gZXhwZWN0ZWQgPSBJT1V0aWxzLnRvQnl0ZUFycmF5KGlzKTsKKyAgICAgICAgICAgIGJ5dGVbXSBhY3R1YWwgPSBJT1V0aWxzLnRvQnl0ZUFycmF5KHNpcyk7CisgICAgICAgICAgICBhc3NlcnRBcnJheUVxdWFscyhleHBlY3RlZCwgYWN0dWFsKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL0daaXBUZXN0Q2FzZS5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvR1ppcFRlc3RDYXNlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWZhYTg3NAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL0daaXBUZXN0Q2FzZS5qYXZhCkBAIC0wLDAgKzEsMzA5IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzOworCitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuKjsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLnppcC5EZWZsYXRlcjsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLkdaSVBJbnB1dFN0cmVhbTsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5BYnN0cmFjdFRlc3RDYXNlOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5nemlwLkd6aXBDb21wcmVzc29ySW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLmd6aXAuR3ppcENvbXByZXNzb3JPdXRwdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLmd6aXAuR3ppcFBhcmFtZXRlcnM7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLklPVXRpbHM7CitpbXBvcnQgb3JnLmp1bml0LkFzc2VydDsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworcHVibGljIGZpbmFsIGNsYXNzIEdaaXBUZXN0Q2FzZSBleHRlbmRzIEFic3RyYWN0VGVzdENhc2UgeworCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R3ppcENyZWF0aW9uKCkgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlIGlucHV0ID0gZ2V0RmlsZSgidGVzdDEueG1sIik7CisgICAgICAgIGZpbmFsIEZpbGUgb3V0cHV0ID0gbmV3IEZpbGUoZGlyLCAidGVzdDEueG1sLmd6Iik7CisgICAgICAgIHRyeSAoT3V0cHV0U3RyZWFtIG91dCA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKG91dHB1dCkpIHsKKyAgICAgICAgICAgIHRyeSAoQ29tcHJlc3Nvck91dHB1dFN0cmVhbSBjb3MgPSBuZXcgQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkoKQorICAgICAgICAgICAgICAgICAgICAuY3JlYXRlQ29tcHJlc3Nvck91dHB1dFN0cmVhbSgiZ3oiLCBvdXQpKSB7CisgICAgICAgICAgICAgICAgSU9VdGlscy5jb3B5KG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpLCBjb3MpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R3ppcFVuYXJjaGl2ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlIGlucHV0ID0gZ2V0RmlsZSgiYmxhLnRneiIpOworICAgICAgICBmaW5hbCBGaWxlIG91dHB1dCA9IG5ldyBGaWxlKGRpciwgImJsYS50YXIiKTsKKyAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpKSB7CisgICAgICAgICAgICBmaW5hbCBDb21wcmVzc29ySW5wdXRTdHJlYW0gaW4gPSBuZXcgQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkoKQorICAgICAgICAgICAgICAgICAgICAuY3JlYXRlQ29tcHJlc3NvcklucHV0U3RyZWFtKCJneiIsIGlzKTsKKyAgICAgICAgICAgIEZpbGVPdXRwdXRTdHJlYW0gb3V0ID0gbnVsbDsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgb3V0ID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0ob3V0cHV0KTsKKyAgICAgICAgICAgICAgICBJT1V0aWxzLmNvcHkoaW4sIG91dCk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIGlmIChvdXQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdENvbmNhdGVuYXRlZFN0cmVhbXNSZWFkRmlyc3RPbmx5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGUgaW5wdXQgPSBnZXRGaWxlKCJtdWx0aXBsZS5neiIpOworICAgICAgICB0cnkgKElucHV0U3RyZWFtIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShpbnB1dCkpIHsKKyAgICAgICAgICAgIHRyeSAoQ29tcHJlc3NvcklucHV0U3RyZWFtIGluID0gbmV3IENvbXByZXNzb3JTdHJlYW1GYWN0b3J5KCkKKyAgICAgICAgICAgICAgICAgICAgLmNyZWF0ZUNvbXByZXNzb3JJbnB1dFN0cmVhbSgiZ3oiLCBpcykpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoJ2EnLCBpbi5yZWFkKCkpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygtMSwgaW4ucmVhZCgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdENvbmNhdGVuYXRlZFN0cmVhbXNSZWFkRnVsbHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgRmlsZSBpbnB1dCA9IGdldEZpbGUoIm11bHRpcGxlLmd6Iik7CisgICAgICAgIHRyeSAoSW5wdXRTdHJlYW0gaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGlucHV0KSkgeworICAgICAgICAgICAgdHJ5IChDb21wcmVzc29ySW5wdXRTdHJlYW0gaW4gPSBuZXcgR3ppcENvbXByZXNzb3JJbnB1dFN0cmVhbShpcywgdHJ1ZSkpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoJ2EnLCBpbi5yZWFkKCkpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygnYicsIGluLnJlYWQoKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGluLmF2YWlsYWJsZSgpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIGluLnJlYWQoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlICJodHRwczovL2lzc3Vlcy5hcGFjaGUub3JnL2ppcmEvYnJvd3NlL0NPTVBSRVNTLTg0IgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdENvcnJ1cHRlZElucHV0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIElucHV0U3RyZWFtIGluID0gbnVsbDsKKyAgICAgICAgT3V0cHV0U3RyZWFtIG91dCA9IG51bGw7CisgICAgICAgIENvbXByZXNzb3JJbnB1dFN0cmVhbSBjaW4gPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW4gPSBuZXcgRmlsZUlucHV0U3RyZWFtKGdldEZpbGUoImJsYS50Z3oiKSk7CisgICAgICAgICAgICBvdXQgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgICAgICBJT1V0aWxzLmNvcHkoaW4sIG91dCk7CisgICAgICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICAgICAgb3V0LmNsb3NlKCk7CisKKyAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBkYXRhID0gKChCeXRlQXJyYXlPdXRwdXRTdHJlYW0pIG91dCkudG9CeXRlQXJyYXkoKTsKKyAgICAgICAgICAgIGluID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGRhdGEsIDAsIGRhdGEubGVuZ3RoIC0gMSk7CisgICAgICAgICAgICBjaW4gPSBuZXcgQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkoKQorICAgICAgICAgICAgICAgIC5jcmVhdGVDb21wcmVzc29ySW5wdXRTdHJlYW0oImd6IiwgaW4pOworICAgICAgICAgICAgb3V0ID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIElPVXRpbHMuY29weShjaW4sIG91dCk7CisgICAgICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgYW4gZXhjZXB0aW9uIik7CisgICAgICAgICAgICB9IGNhdGNoIChmaW5hbCBJT0V4Y2VwdGlvbiBpb2V4KSB7CisgICAgICAgICAgICAgICAgLy8gdGhlIHdob2xlIHBvaW50IG9mIHRoZSB0ZXN0CisgICAgICAgICAgICB9CisKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmIChvdXQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGNpbiAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgY2luLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoaW4gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGluLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RJbnRlcm9wZXJhYmlsaXR5V2l0aEd6aXBDb21wcmVzc29ySW5wdXRTdHJlYW0oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGNvbnRlbnQ7CisgICAgICAgIHRyeSAoRmlsZUlucHV0U3RyZWFtIGZpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oZ2V0RmlsZSgidGVzdDMueG1sIikpKSB7CisgICAgICAgICAgICBjb250ZW50ID0gSU9VdGlscy50b0J5dGVBcnJheShmaXMpOworICAgICAgICB9CisKKyAgICAgICAgZmluYWwgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvdXQgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisKKyAgICAgICAgZmluYWwgR3ppcFBhcmFtZXRlcnMgcGFyYW1ldGVycyA9IG5ldyBHemlwUGFyYW1ldGVycygpOworICAgICAgICBwYXJhbWV0ZXJzLnNldENvbXByZXNzaW9uTGV2ZWwoRGVmbGF0ZXIuQkVTVF9DT01QUkVTU0lPTik7CisgICAgICAgIHBhcmFtZXRlcnMuc2V0T3BlcmF0aW5nU3lzdGVtKDMpOworICAgICAgICBwYXJhbWV0ZXJzLnNldEZpbGVuYW1lKCJ0ZXN0My54bWwiKTsKKyAgICAgICAgcGFyYW1ldGVycy5zZXRDb21tZW50KCJUZXN0IGZpbGUiKTsKKyAgICAgICAgcGFyYW1ldGVycy5zZXRNb2RpZmljYXRpb25UaW1lKFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpKTsKKyAgICAgICAgZmluYWwgR3ppcENvbXByZXNzb3JPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IEd6aXBDb21wcmVzc29yT3V0cHV0U3RyZWFtKGJvdXQsIHBhcmFtZXRlcnMpOworICAgICAgICBvdXQud3JpdGUoY29udGVudCk7CisgICAgICAgIG91dC5mbHVzaCgpOworICAgICAgICBvdXQuY2xvc2UoKTsKKworICAgICAgICBmaW5hbCBHemlwQ29tcHJlc3NvcklucHV0U3RyZWFtIGluID0gbmV3IEd6aXBDb21wcmVzc29ySW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJvdXQudG9CeXRlQXJyYXkoKSkpOworICAgICAgICBmaW5hbCBieXRlW10gY29udGVudDIgPSBJT1V0aWxzLnRvQnl0ZUFycmF5KGluKTsKKworICAgICAgICBBc3NlcnQuYXNzZXJ0QXJyYXlFcXVhbHMoInVuY29tcHJlc3NlZCBjb250ZW50IiwgY29udGVudCwgY29udGVudDIpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEludGVyb3BlcmFiaWxpdHlXaXRoR1pJUElucHV0U3RyZWFtKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBjb250ZW50OworICAgICAgICB0cnkgKEZpbGVJbnB1dFN0cmVhbSBmaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGdldEZpbGUoInRlc3QzLnhtbCIpKSkgeworICAgICAgICAgICAgY29udGVudCA9IElPVXRpbHMudG9CeXRlQXJyYXkoZmlzKTsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBib3V0ID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworCisgICAgICAgIGZpbmFsIEd6aXBQYXJhbWV0ZXJzIHBhcmFtZXRlcnMgPSBuZXcgR3ppcFBhcmFtZXRlcnMoKTsKKyAgICAgICAgcGFyYW1ldGVycy5zZXRDb21wcmVzc2lvbkxldmVsKERlZmxhdGVyLkJFU1RfQ09NUFJFU1NJT04pOworICAgICAgICBwYXJhbWV0ZXJzLnNldE9wZXJhdGluZ1N5c3RlbSgzKTsKKyAgICAgICAgcGFyYW1ldGVycy5zZXRGaWxlbmFtZSgidGVzdDMueG1sIik7CisgICAgICAgIHBhcmFtZXRlcnMuc2V0Q29tbWVudCgiVGVzdCBmaWxlIik7CisgICAgICAgIHBhcmFtZXRlcnMuc2V0TW9kaWZpY2F0aW9uVGltZShTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSk7CisgICAgICAgIGZpbmFsIEd6aXBDb21wcmVzc29yT3V0cHV0U3RyZWFtIG91dCA9IG5ldyBHemlwQ29tcHJlc3Nvck91dHB1dFN0cmVhbShib3V0LCBwYXJhbWV0ZXJzKTsKKyAgICAgICAgb3V0LndyaXRlKGNvbnRlbnQpOworICAgICAgICBvdXQuZmx1c2goKTsKKyAgICAgICAgb3V0LmNsb3NlKCk7CisKKyAgICAgICAgZmluYWwgR1pJUElucHV0U3RyZWFtIGluID0gbmV3IEdaSVBJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYm91dC50b0J5dGVBcnJheSgpKSk7CisgICAgICAgIGZpbmFsIGJ5dGVbXSBjb250ZW50MiA9IElPVXRpbHMudG9CeXRlQXJyYXkoaW4pOworCisgICAgICAgIEFzc2VydC5hc3NlcnRBcnJheUVxdWFscygidW5jb21wcmVzc2VkIGNvbnRlbnQiLCBjb250ZW50LCBjb250ZW50Mik7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW52YWxpZENvbXByZXNzaW9uTGV2ZWwoKSB7CisgICAgICAgIGZpbmFsIEd6aXBQYXJhbWV0ZXJzIHBhcmFtZXRlcnMgPSBuZXcgR3ppcFBhcmFtZXRlcnMoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHBhcmFtZXRlcnMuc2V0Q29tcHJlc3Npb25MZXZlbCgxMCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChmaW5hbCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwYXJhbWV0ZXJzLnNldENvbXByZXNzaW9uTGV2ZWwoLTUpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdGVzdEV4dHJhRmxhZ3MoZmluYWwgaW50IGNvbXByZXNzaW9uTGV2ZWwsIGZpbmFsIGludCBmbGFnKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGNvbnRlbnQ7CisgICAgICAgIHRyeSAoRmlsZUlucHV0U3RyZWFtIGZpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oZ2V0RmlsZSgidGVzdDMueG1sIikpKSB7CisgICAgICAgICAgICBjb250ZW50ID0gSU9VdGlscy50b0J5dGVBcnJheShmaXMpOworICAgICAgICB9CisKKyAgICAgICAgZmluYWwgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvdXQgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisKKyAgICAgICAgZmluYWwgR3ppcFBhcmFtZXRlcnMgcGFyYW1ldGVycyA9IG5ldyBHemlwUGFyYW1ldGVycygpOworICAgICAgICBwYXJhbWV0ZXJzLnNldENvbXByZXNzaW9uTGV2ZWwoY29tcHJlc3Npb25MZXZlbCk7CisgICAgICAgIGZpbmFsIEd6aXBDb21wcmVzc29yT3V0cHV0U3RyZWFtIG91dCA9IG5ldyBHemlwQ29tcHJlc3Nvck91dHB1dFN0cmVhbShib3V0LCBwYXJhbWV0ZXJzKTsKKyAgICAgICAgSU9VdGlscy5jb3B5KG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShjb250ZW50KSwgb3V0KTsKKyAgICAgICAgb3V0LmZsdXNoKCk7CisgICAgICAgIG91dC5jbG9zZSgpOworCisgICAgICAgIGFzc2VydEVxdWFscygiZXh0cmEgZmxhZ3MgKFhGTCkiLCBmbGFnLCBib3V0LnRvQnl0ZUFycmF5KClbOF0pOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEV4dHJhRmxhZ3NGYXN0ZXN0Q29tcHJlc3Npb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdEV4dHJhRmxhZ3MoRGVmbGF0ZXIuQkVTVF9TUEVFRCwgNCk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RXh0cmFGbGFnc0Jlc3RDb21wcmVzc2lvbigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0RXh0cmFGbGFncyhEZWZsYXRlci5CRVNUX0NPTVBSRVNTSU9OLCAyKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RFeHRyYUZsYWdzRGVmYXVsdENvbXByZXNzaW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RFeHRyYUZsYWdzKERlZmxhdGVyLkRFRkFVTFRfQ09NUFJFU1NJT04sIDApOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdE92ZXJXcml0ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBHemlwQ29tcHJlc3Nvck91dHB1dFN0cmVhbSBvdXQgPSBuZXcgR3ppcENvbXByZXNzb3JPdXRwdXRTdHJlYW0obmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpKTsKKyAgICAgICAgb3V0LmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvdXQud3JpdGUoMCk7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChmaW5hbCBJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWV0YWRhdGFSb3VuZFRyaXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvdXQgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisKKyAgICAgICAgZmluYWwgR3ppcFBhcmFtZXRlcnMgcGFyYW1ldGVycyA9IG5ldyBHemlwUGFyYW1ldGVycygpOworICAgICAgICBwYXJhbWV0ZXJzLnNldENvbXByZXNzaW9uTGV2ZWwoRGVmbGF0ZXIuQkVTVF9DT01QUkVTU0lPTik7CisgICAgICAgIHBhcmFtZXRlcnMuc2V0TW9kaWZpY2F0aW9uVGltZSgxMjM0NTYwMDApOworICAgICAgICBwYXJhbWV0ZXJzLnNldE9wZXJhdGluZ1N5c3RlbSgxMyk7CisgICAgICAgIHBhcmFtZXRlcnMuc2V0RmlsZW5hbWUoInRlc3QzLnhtbCIpOworICAgICAgICBwYXJhbWV0ZXJzLnNldENvbW1lbnQoIlVtbGF1dGUgbcO2Z2xpY2g/Iik7CisgICAgICAgIHRyeSAoR3ppcENvbXByZXNzb3JPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IEd6aXBDb21wcmVzc29yT3V0cHV0U3RyZWFtKGJvdXQsIHBhcmFtZXRlcnMpOyBGaWxlSW5wdXRTdHJlYW0gZmlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShnZXRGaWxlKCJ0ZXN0MyIgKworICAgICAgICAgICAgICAgICIueG1sIikpKSB7CisgICAgICAgICAgICBJT1V0aWxzLmNvcHkoZmlzLCBvdXQpOworICAgICAgICB9CisKKyAgICAgICAgZmluYWwgR3ppcENvbXByZXNzb3JJbnB1dFN0cmVhbSBpbnB1dCA9CisgICAgICAgICAgICBuZXcgR3ppcENvbXByZXNzb3JJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYm91dC50b0J5dGVBcnJheSgpKSk7CisgICAgICAgIGlucHV0LmNsb3NlKCk7CisgICAgICAgIGZpbmFsIEd6aXBQYXJhbWV0ZXJzIHJlYWRQYXJhbXMgPSBpbnB1dC5nZXRNZXRhRGF0YSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoRGVmbGF0ZXIuQkVTVF9DT01QUkVTU0lPTiwgcmVhZFBhcmFtcy5nZXRDb21wcmVzc2lvbkxldmVsKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMTIzNDU2MDAwLCByZWFkUGFyYW1zLmdldE1vZGlmaWNhdGlvblRpbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxMywgcmVhZFBhcmFtcy5nZXRPcGVyYXRpbmdTeXN0ZW0oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygidGVzdDMueG1sIiwgcmVhZFBhcmFtcy5nZXRGaWxlbmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJVbWxhdXRlIG3DtmdsaWNoPyIsIHJlYWRQYXJhbXMuZ2V0Q29tbWVudCgpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHNpbmdsZUJ5dGVSZWFkQ29uc2lzdGVudGx5UmV0dXJuc01pbnVzT25lQXRFb2YoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlIGlucHV0ID0gZ2V0RmlsZSgiYmxhLnRneiIpOworICAgICAgICB0cnkgKElucHV0U3RyZWFtIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShpbnB1dCkpIHsKKyAgICAgICAgICAgIGZpbmFsIEd6aXBDb21wcmVzc29ySW5wdXRTdHJlYW0gaW4gPQorICAgICAgICAgICAgICAgICAgICBuZXcgR3ppcENvbXByZXNzb3JJbnB1dFN0cmVhbShpcyk7CisgICAgICAgICAgICBJT1V0aWxzLnRvQnl0ZUFycmF5KGluKTsKKyAgICAgICAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoLTEsIGluLnJlYWQoKSk7CisgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKC0xLCBpbi5yZWFkKCkpOworICAgICAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgbXVsdGlCeXRlUmVhZENvbnNpc3RlbnRseVJldHVybnNNaW51c09uZUF0RW9mKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgRmlsZSBpbnB1dCA9IGdldEZpbGUoImJsYS50Z3oiKTsKKyAgICAgICAgYnl0ZVtdIGJ1ZiA9IG5ldyBieXRlWzJdOworICAgICAgICB0cnkgKElucHV0U3RyZWFtIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShpbnB1dCkpIHsKKyAgICAgICAgICAgIGZpbmFsIEd6aXBDb21wcmVzc29ySW5wdXRTdHJlYW0gaW4gPQorICAgICAgICAgICAgICAgICAgICBuZXcgR3ppcENvbXByZXNzb3JJbnB1dFN0cmVhbShpcyk7CisgICAgICAgICAgICBJT1V0aWxzLnRvQnl0ZUFycmF5KGluKTsKKyAgICAgICAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoLTEsIGluLnJlYWQoYnVmKSk7CisgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKC0xLCBpbi5yZWFkKGJ1ZikpOworICAgICAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL0d6aXBVdGlsc1Rlc3RDYXNlLmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9HemlwVXRpbHNUZXN0Q2FzZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFhNjg4YjUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9HemlwVXRpbHNUZXN0Q2FzZS5qYXZhCkBAIC0wLDAgKzEsMTA0IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzOworCitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuKjsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5nemlwLkd6aXBVdGlsczsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworcHVibGljIGNsYXNzIEd6aXBVdGlsc1Rlc3RDYXNlIHsKKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdElzQ29tcHJlc3NlZEZpbGVuYW1lKCkgeworICAgICAgICBhc3NlcnRGYWxzZShHemlwVXRpbHMuaXNDb21wcmVzc2VkRmlsZW5hbWUoIiIpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoR3ppcFV0aWxzLmlzQ29tcHJlc3NlZEZpbGVuYW1lKCIuZ3oiKSk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShHemlwVXRpbHMuaXNDb21wcmVzc2VkRmlsZW5hbWUoIngudGd6IikpOworICAgICAgICBhc3NlcnRUcnVlKEd6aXBVdGlscy5pc0NvbXByZXNzZWRGaWxlbmFtZSgieC50YXoiKSk7CisgICAgICAgIGFzc2VydFRydWUoR3ppcFV0aWxzLmlzQ29tcHJlc3NlZEZpbGVuYW1lKCJ4LnN2Z3oiKSk7CisgICAgICAgIGFzc2VydFRydWUoR3ppcFV0aWxzLmlzQ29tcHJlc3NlZEZpbGVuYW1lKCJ4LmNwZ3oiKSk7CisgICAgICAgIGFzc2VydFRydWUoR3ppcFV0aWxzLmlzQ29tcHJlc3NlZEZpbGVuYW1lKCJ4LndteiIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShHemlwVXRpbHMuaXNDb21wcmVzc2VkRmlsZW5hbWUoInguZW16IikpOworICAgICAgICBhc3NlcnRUcnVlKEd6aXBVdGlscy5pc0NvbXByZXNzZWRGaWxlbmFtZSgieC5neiIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShHemlwVXRpbHMuaXNDb21wcmVzc2VkRmlsZW5hbWUoIngueiIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShHemlwVXRpbHMuaXNDb21wcmVzc2VkRmlsZW5hbWUoIngtZ3oiKSk7CisgICAgICAgIGFzc2VydFRydWUoR3ppcFV0aWxzLmlzQ29tcHJlc3NlZEZpbGVuYW1lKCJ4LXoiKSk7CisgICAgICAgIGFzc2VydFRydWUoR3ppcFV0aWxzLmlzQ29tcHJlc3NlZEZpbGVuYW1lKCJ4X3oiKSk7CisKKyAgICAgICAgYXNzZXJ0RmFsc2UoR3ppcFV0aWxzLmlzQ29tcHJlc3NlZEZpbGVuYW1lKCJ4eGd6IikpOworICAgICAgICBhc3NlcnRGYWxzZShHemlwVXRpbHMuaXNDb21wcmVzc2VkRmlsZW5hbWUoInh6eiIpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoR3ppcFV0aWxzLmlzQ29tcHJlc3NlZEZpbGVuYW1lKCJ4YXoiKSk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShHemlwVXRpbHMuaXNDb21wcmVzc2VkRmlsZW5hbWUoInguU1ZHWiIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShHemlwVXRpbHMuaXNDb21wcmVzc2VkRmlsZW5hbWUoInguU3ZneiIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShHemlwVXRpbHMuaXNDb21wcmVzc2VkRmlsZW5hbWUoInguc3ZHWiIpKTsKKworICAgICAgICBhc3NlcnRGYWxzZShHemlwVXRpbHMuaXNDb21wcmVzc2VkRmlsZW5hbWUoIngud216ICIpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoR3ppcFV0aWxzLmlzQ29tcHJlc3NlZEZpbGVuYW1lKCJ4LndtelxuIikpOworICAgICAgICBhc3NlcnRGYWxzZShHemlwVXRpbHMuaXNDb21wcmVzc2VkRmlsZW5hbWUoIngud216LnkiKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0VW5jb21wcmVzc2VkRmlsZW5hbWUoKSB7CisgICAgICAgIGFzc2VydEVxdWFscygiIiwgR3ppcFV0aWxzLmdldFVuY29tcHJlc3NlZEZpbGVuYW1lKCIiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiLmd6IiwgR3ppcFV0aWxzLmdldFVuY29tcHJlc3NlZEZpbGVuYW1lKCIuZ3oiKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ4LnRhciIsIEd6aXBVdGlscy5nZXRVbmNvbXByZXNzZWRGaWxlbmFtZSgieC50Z3oiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygieC50YXIiLCBHemlwVXRpbHMuZ2V0VW5jb21wcmVzc2VkRmlsZW5hbWUoIngudGF6IikpOworICAgICAgICBhc3NlcnRFcXVhbHMoInguc3ZnIiwgR3ppcFV0aWxzLmdldFVuY29tcHJlc3NlZEZpbGVuYW1lKCJ4LnN2Z3oiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygieC5jcGlvIiwgR3ppcFV0aWxzLmdldFVuY29tcHJlc3NlZEZpbGVuYW1lKCJ4LmNwZ3oiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygieC53bWYiLCBHemlwVXRpbHMuZ2V0VW5jb21wcmVzc2VkRmlsZW5hbWUoIngud216IikpOworICAgICAgICBhc3NlcnRFcXVhbHMoInguZW1mIiwgR3ppcFV0aWxzLmdldFVuY29tcHJlc3NlZEZpbGVuYW1lKCJ4LmVteiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ4IiwgR3ppcFV0aWxzLmdldFVuY29tcHJlc3NlZEZpbGVuYW1lKCJ4Lmd6IikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIngiLCBHemlwVXRpbHMuZ2V0VW5jb21wcmVzc2VkRmlsZW5hbWUoIngueiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ4IiwgR3ppcFV0aWxzLmdldFVuY29tcHJlc3NlZEZpbGVuYW1lKCJ4LWd6IikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIngiLCBHemlwVXRpbHMuZ2V0VW5jb21wcmVzc2VkRmlsZW5hbWUoIngteiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ4IiwgR3ppcFV0aWxzLmdldFVuY29tcHJlc3NlZEZpbGVuYW1lKCJ4X3oiKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ4LnN2ZyIsIEd6aXBVdGlscy5nZXRVbmNvbXByZXNzZWRGaWxlbmFtZSgieC5TVkdaIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlguc3ZnIiwgR3ppcFV0aWxzLmdldFVuY29tcHJlc3NlZEZpbGVuYW1lKCJYLlNWR1oiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiWC5zdmciLCBHemlwVXRpbHMuZ2V0VW5jb21wcmVzc2VkRmlsZW5hbWUoIlguc3ZHWiIpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIngud216ICIsIEd6aXBVdGlscy5nZXRVbmNvbXByZXNzZWRGaWxlbmFtZSgieC53bXogIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIngud216XG4iLCBHemlwVXRpbHMuZ2V0VW5jb21wcmVzc2VkRmlsZW5hbWUoIngud216XG4iKSk7CisgICAgICAgIGFzc2VydEVxdWFscygieC53bXoueSIsIEd6aXBVdGlscy5nZXRVbmNvbXByZXNzZWRGaWxlbmFtZSgieC53bXoueSIpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRDb21wcmVzc2VkRmlsZW5hbWUoKSB7CisgICAgICAgIGFzc2VydEVxdWFscygiLmd6IiwgR3ppcFV0aWxzLmdldENvbXByZXNzZWRGaWxlbmFtZSgiIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoInguZ3oiLCBHemlwVXRpbHMuZ2V0Q29tcHJlc3NlZEZpbGVuYW1lKCJ4IikpOworCisgICAgICAgIGFzc2VydEVxdWFscygieC50Z3oiLCBHemlwVXRpbHMuZ2V0Q29tcHJlc3NlZEZpbGVuYW1lKCJ4LnRhciIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ4LnN2Z3oiLCBHemlwVXRpbHMuZ2V0Q29tcHJlc3NlZEZpbGVuYW1lKCJ4LnN2ZyIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ4LmNwZ3oiLCBHemlwVXRpbHMuZ2V0Q29tcHJlc3NlZEZpbGVuYW1lKCJ4LmNwaW8iKSk7CisgICAgICAgIGFzc2VydEVxdWFscygieC53bXoiLCBHemlwVXRpbHMuZ2V0Q29tcHJlc3NlZEZpbGVuYW1lKCJ4LndtZiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ4LmVteiIsIEd6aXBVdGlscy5nZXRDb21wcmVzc2VkRmlsZW5hbWUoInguZW1mIikpOworCisgICAgICAgIGFzc2VydEVxdWFscygieC5zdmd6IiwgR3ppcFV0aWxzLmdldENvbXByZXNzZWRGaWxlbmFtZSgieC5TVkciKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiWC5zdmd6IiwgR3ppcFV0aWxzLmdldENvbXByZXNzZWRGaWxlbmFtZSgiWC5TVkciKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiWC5zdmd6IiwgR3ppcFV0aWxzLmdldENvbXByZXNzZWRGaWxlbmFtZSgiWC5zdkciKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ4LndtZiAuZ3oiLCBHemlwVXRpbHMuZ2V0Q29tcHJlc3NlZEZpbGVuYW1lKCJ4LndtZiAiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygieC53bWZcbi5neiIsIEd6aXBVdGlscy5nZXRDb21wcmVzc2VkRmlsZW5hbWUoIngud21mXG4iKSk7CisgICAgICAgIGFzc2VydEVxdWFscygieC53bWYueS5neiIsIEd6aXBVdGlscy5nZXRDb21wcmVzc2VkRmlsZW5hbWUoIngud21mLnkiKSk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9MWk1BVGVzdENhc2UuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL0xaTUFUZXN0Q2FzZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNkMmFiMDIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9MWk1BVGVzdENhc2UuamF2YQpAQCAtMCwwICsxLDExOSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29yczsKKworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5BYnN0cmFjdFRlc3RDYXNlOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5sem1hLkxaTUFDb21wcmVzc29ySW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLklPVXRpbHM7CitpbXBvcnQgb3JnLmp1bml0LkFzc2VydDsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworcHVibGljIGZpbmFsIGNsYXNzIExaTUFUZXN0Q2FzZSBleHRlbmRzIEFic3RyYWN0VGVzdENhc2UgeworCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBsem1hUm91bmR0cmlwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGUgaW5wdXQgPSBnZXRGaWxlKCJ0ZXN0MS54bWwiKTsKKyAgICAgICAgZmluYWwgRmlsZSBjb21wcmVzc2VkID0gbmV3IEZpbGUoZGlyLCAidGVzdDEueG1sLnh6Iik7CisgICAgICAgIHRyeSAoT3V0cHV0U3RyZWFtIG91dCA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKGNvbXByZXNzZWQpKSB7CisgICAgICAgICAgICB0cnkgKENvbXByZXNzb3JPdXRwdXRTdHJlYW0gY29zID0gbmV3IENvbXByZXNzb3JTdHJlYW1GYWN0b3J5KCkKKyAgICAgICAgICAgICAgICAgICAgLmNyZWF0ZUNvbXByZXNzb3JPdXRwdXRTdHJlYW0oImx6bWEiLCBvdXQpKSB7CisgICAgICAgICAgICAgICAgSU9VdGlscy5jb3B5KG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpLCBjb3MpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGJ5dGVbXSBvcmlnOworICAgICAgICB0cnkgKElucHV0U3RyZWFtIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShpbnB1dCkpIHsKKyAgICAgICAgICAgIG9yaWcgPSBJT1V0aWxzLnRvQnl0ZUFycmF5KGlzKTsKKyAgICAgICAgfQorICAgICAgICBieXRlW10gdW5jb21wcmVzc2VkOworICAgICAgICB0cnkgKElucHV0U3RyZWFtIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShjb21wcmVzc2VkKTsKKyAgICAgICAgICAgICBDb21wcmVzc29ySW5wdXRTdHJlYW0gaW4gPSBuZXcgTFpNQUNvbXByZXNzb3JJbnB1dFN0cmVhbShpcykpIHsKKyAgICAgICAgICAgIHVuY29tcHJlc3NlZCA9IElPVXRpbHMudG9CeXRlQXJyYXkoaW4pOworICAgICAgICB9CisgICAgICAgIEFzc2VydC5hc3NlcnRBcnJheUVxdWFscyhvcmlnLCB1bmNvbXByZXNzZWQpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdExaTUFVbmFyY2hpdmUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgRmlsZSBpbnB1dCA9IGdldEZpbGUoImJsYS50YXIubHptYSIpOworICAgICAgICBmaW5hbCBGaWxlIG91dHB1dCA9IG5ldyBGaWxlKGRpciwgImJsYS50YXIiKTsKKyAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpKSB7CisgICAgICAgICAgICBmaW5hbCBDb21wcmVzc29ySW5wdXRTdHJlYW0gaW4gPSBuZXcgTFpNQUNvbXByZXNzb3JJbnB1dFN0cmVhbShpcyk7CisgICAgICAgICAgICBjb3B5KGluLCBvdXRwdXQpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TFpNQVVuYXJjaGl2ZVdpdGhBdXRvZGV0ZWN0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGUgaW5wdXQgPSBnZXRGaWxlKCJibGEudGFyLmx6bWEiKTsKKyAgICAgICAgZmluYWwgRmlsZSBvdXRwdXQgPSBuZXcgRmlsZShkaXIsICJibGEudGFyIik7CisgICAgICAgIHRyeSAoSW5wdXRTdHJlYW0gaXMgPSBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShuZXcgRmlsZUlucHV0U3RyZWFtKGlucHV0KSkpIHsKKyAgICAgICAgICAgIGZpbmFsIENvbXByZXNzb3JJbnB1dFN0cmVhbSBpbiA9IG5ldyBDb21wcmVzc29yU3RyZWFtRmFjdG9yeSgpCisgICAgICAgICAgICAgICAgICAgIC5jcmVhdGVDb21wcmVzc29ySW5wdXRTdHJlYW0oaXMpOworICAgICAgICAgICAgY29weShpbiwgb3V0cHV0KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgc2luZ2xlQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGUgaW5wdXQgPSBnZXRGaWxlKCJibGEudGFyLmx6bWEiKTsKKyAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpKSB7CisgICAgICAgICAgICBmaW5hbCBMWk1BQ29tcHJlc3NvcklucHV0U3RyZWFtIGluID0KKyAgICAgICAgICAgICAgICAgICAgbmV3IExaTUFDb21wcmVzc29ySW5wdXRTdHJlYW0oaXMpOworICAgICAgICAgICAgSU9VdGlscy50b0J5dGVBcnJheShpbik7CisgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKC0xLCBpbi5yZWFkKCkpOworICAgICAgICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygtMSwgaW4ucmVhZCgpKTsKKyAgICAgICAgICAgIGluLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIG11bHRpQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGUgaW5wdXQgPSBnZXRGaWxlKCJibGEudGFyLmx6bWEiKTsKKyAgICAgICAgYnl0ZVtdIGJ1ZiA9IG5ldyBieXRlWzJdOworICAgICAgICB0cnkgKElucHV0U3RyZWFtIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShpbnB1dCkpIHsKKyAgICAgICAgICAgIGZpbmFsIExaTUFDb21wcmVzc29ySW5wdXRTdHJlYW0gaW4gPQorICAgICAgICAgICAgICAgICAgICBuZXcgTFpNQUNvbXByZXNzb3JJbnB1dFN0cmVhbShpcyk7CisgICAgICAgICAgICBJT1V0aWxzLnRvQnl0ZUFycmF5KGluKTsKKyAgICAgICAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoLTEsIGluLnJlYWQoYnVmKSk7CisgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKC0xLCBpbi5yZWFkKGJ1ZikpOworICAgICAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBjb3B5KGZpbmFsIElucHV0U3RyZWFtIGluLCBmaW5hbCBGaWxlIG91dHB1dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgRmlsZU91dHB1dFN0cmVhbSBvdXQgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgb3V0ID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0ob3V0cHV0KTsKKyAgICAgICAgICAgIElPVXRpbHMuY29weShpbiwgb3V0KTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmIChvdXQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL1BhY2syMDBUZXN0Q2FzZS5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvUGFjazIwMFRlc3RDYXNlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDM0NjE4NQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL1BhY2syMDBUZXN0Q2FzZS5qYXZhCkBAIC0wLDAgKzEsMjQzIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzOworCitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuKjsKKworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuQWJzdHJhY3RUZXN0Q2FzZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLkFyY2hpdmVFbnRyeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLkFyY2hpdmVJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLkFyY2hpdmVPdXRwdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5BcmNoaXZlU3RyZWFtRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuYXJjaGl2ZXJzLnppcC5aaXBBcmNoaXZlRW50cnk7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLnBhY2syMDAuUGFjazIwMENvbXByZXNzb3JJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMucGFjazIwMC5QYWNrMjAwQ29tcHJlc3Nvck91dHB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMucGFjazIwMC5QYWNrMjAwU3RyYXRlZ3k7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLklPVXRpbHM7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBQYWNrMjAwVGVzdENhc2UgZXh0ZW5kcyBBYnN0cmFjdFRlc3RDYXNlIHsKKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEphclVuYXJjaGl2ZUFsbEluTWVtb3J5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGphclVuYXJjaGl2ZUFsbChmYWxzZSwgUGFjazIwMFN0cmF0ZWd5LklOX01FTU9SWSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SmFyVW5hcmNoaXZlQWxsRmlsZUFyZ0luTWVtb3J5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGphclVuYXJjaGl2ZUFsbCh0cnVlLCBQYWNrMjAwU3RyYXRlZ3kuSU5fTUVNT1JZKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RKYXJVbmFyY2hpdmVBbGxUZW1wRmlsZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBqYXJVbmFyY2hpdmVBbGwoZmFsc2UsIFBhY2syMDBTdHJhdGVneS5URU1QX0ZJTEUpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEphclVuYXJjaGl2ZUFsbEZpbGVUZW1wRmlsZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBqYXJVbmFyY2hpdmVBbGwodHJ1ZSwgUGFjazIwMFN0cmF0ZWd5LlRFTVBfRklMRSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGphclVuYXJjaGl2ZUFsbChmaW5hbCBib29sZWFuIHVzZUZpbGUsIGZpbmFsIFBhY2syMDBTdHJhdGVneSBtb2RlKQorICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgRmlsZSBpbnB1dCA9IGdldEZpbGUoImJsYS5wYWNrIik7CisgICAgICAgIHRyeSAoSW5wdXRTdHJlYW0gaXMgPSB1c2VGaWxlCisgICAgICAgICAgICAgICAgPyBuZXcgUGFjazIwMENvbXByZXNzb3JJbnB1dFN0cmVhbShpbnB1dCwgbW9kZSkKKyAgICAgICAgICAgICAgICA6IG5ldyBQYWNrMjAwQ29tcHJlc3NvcklucHV0U3RyZWFtKG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpLAorICAgICAgICAgICAgICAgIG1vZGUpKSB7CisgICAgICAgICAgICBmaW5hbCBBcmNoaXZlSW5wdXRTdHJlYW0gaW4gPSBuZXcgQXJjaGl2ZVN0cmVhbUZhY3RvcnkoKQorICAgICAgICAgICAgICAgICAgICAuY3JlYXRlQXJjaGl2ZUlucHV0U3RyZWFtKCJqYXIiLCBpcyk7CisKKyAgICAgICAgICAgIEFyY2hpdmVFbnRyeSBlbnRyeSA9IGluLmdldE5leHRFbnRyeSgpOworICAgICAgICAgICAgd2hpbGUgKGVudHJ5ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBGaWxlIGFyY2hpdmVFbnRyeSA9IG5ldyBGaWxlKGRpciwgZW50cnkuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgICAgICBhcmNoaXZlRW50cnkuZ2V0UGFyZW50RmlsZSgpLm1rZGlycygpOworICAgICAgICAgICAgICAgIGlmIChlbnRyeS5pc0RpcmVjdG9yeSgpKSB7CisgICAgICAgICAgICAgICAgICAgIGFyY2hpdmVFbnRyeS5ta2RpcigpOworICAgICAgICAgICAgICAgICAgICBlbnRyeSA9IGluLmdldE5leHRFbnRyeSgpOworICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZmluYWwgT3V0cHV0U3RyZWFtIG91dCA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKGFyY2hpdmVFbnRyeSk7CisgICAgICAgICAgICAgICAgSU9VdGlscy5jb3B5KGluLCBvdXQpOworICAgICAgICAgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICAgICAgICAgIGVudHJ5ID0gaW4uZ2V0TmV4dEVudHJ5KCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGluLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RKYXJBcmNoaXZlQ3JlYXRpb25Jbk1lbW9yeSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBqYXJBcmNoaXZlQ3JlYXRpb24oUGFjazIwMFN0cmF0ZWd5LklOX01FTU9SWSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SmFyQXJjaGl2ZUNyZWF0aW9uVGVtcEZpbGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgamFyQXJjaGl2ZUNyZWF0aW9uKFBhY2syMDBTdHJhdGVneS5URU1QX0ZJTEUpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBqYXJBcmNoaXZlQ3JlYXRpb24oZmluYWwgUGFjazIwMFN0cmF0ZWd5IG1vZGUpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlIG91dHB1dCA9IG5ldyBGaWxlKGRpciwgImJsYS5wYWNrIik7CisKKyAgICAgICAgZmluYWwgRmlsZSBmaWxlMSA9IGdldEZpbGUoInRlc3QxLnhtbCIpOworICAgICAgICBmaW5hbCBGaWxlIGZpbGUyID0gZ2V0RmlsZSgidGVzdDIueG1sIik7CisKKyAgICAgICAgdHJ5IChPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IFBhY2syMDBDb21wcmVzc29yT3V0cHV0U3RyZWFtKG5ldyBGaWxlT3V0cHV0U3RyZWFtKG91dHB1dCksCisgICAgICAgICAgICAgICAgbW9kZSkpIHsKKyAgICAgICAgICAgIGZpbmFsIEFyY2hpdmVPdXRwdXRTdHJlYW0gb3MgPSBuZXcgQXJjaGl2ZVN0cmVhbUZhY3RvcnkoKQorICAgICAgICAgICAgICAgICAgICAuY3JlYXRlQXJjaGl2ZU91dHB1dFN0cmVhbSgiamFyIiwgb3V0KTsKKworICAgICAgICAgICAgb3MucHV0QXJjaGl2ZUVudHJ5KG5ldyBaaXBBcmNoaXZlRW50cnkoInRlc3RkYXRhL3Rlc3QxLnhtbCIpKTsKKyAgICAgICAgICAgIElPVXRpbHMuY29weShuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGUxKSwgb3MpOworICAgICAgICAgICAgb3MuY2xvc2VBcmNoaXZlRW50cnkoKTsKKworICAgICAgICAgICAgb3MucHV0QXJjaGl2ZUVudHJ5KG5ldyBaaXBBcmNoaXZlRW50cnkoInRlc3RkYXRhL3Rlc3QyLnhtbCIpKTsKKyAgICAgICAgICAgIElPVXRpbHMuY29weShuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGUyKSwgb3MpOworICAgICAgICAgICAgb3MuY2xvc2VBcmNoaXZlRW50cnkoKTsKKworICAgICAgICAgICAgb3MuY2xvc2UoKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSAoSW5wdXRTdHJlYW0gaXMgPSBuZXcgUGFjazIwMENvbXByZXNzb3JJbnB1dFN0cmVhbShvdXRwdXQpKSB7CisgICAgICAgICAgICBmaW5hbCBBcmNoaXZlSW5wdXRTdHJlYW0gaW4gPSBuZXcgQXJjaGl2ZVN0cmVhbUZhY3RvcnkoKQorICAgICAgICAgICAgICAgICAgICAuY3JlYXRlQXJjaGl2ZUlucHV0U3RyZWFtKCJqYXIiLCBpcyk7CisgICAgICAgICAgICBmaW5hbCBMaXN0PFN0cmluZz4gZmlsZXMgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKyAgICAgICAgICAgIGZpbGVzLmFkZCgidGVzdGRhdGEvdGVzdDEueG1sIik7CisgICAgICAgICAgICBmaWxlcy5hZGQoInRlc3RkYXRhL3Rlc3QyLnhtbCIpOworICAgICAgICAgICAgY2hlY2tBcmNoaXZlQ29udGVudChpbiwgZmlsZXMpOworICAgICAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEdvb2RTaWduYXR1cmUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oZ2V0RmlsZSgiYmxhLnBhY2siKSkpIHsKKyAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBzaWcgPSBuZXcgYnl0ZVs0XTsKKyAgICAgICAgICAgIGlzLnJlYWQoc2lnKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoUGFjazIwMENvbXByZXNzb3JJbnB1dFN0cmVhbS5tYXRjaGVzKHNpZywgNCkpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QmFkU2lnbmF0dXJlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSAoSW5wdXRTdHJlYW0gaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGdldEZpbGUoImJsYS5qYXIiKSkpIHsKKyAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBzaWcgPSBuZXcgYnl0ZVs0XTsKKyAgICAgICAgICAgIGlzLnJlYWQoc2lnKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKFBhY2syMDBDb21wcmVzc29ySW5wdXRTdHJlYW0ubWF0Y2hlcyhzaWcsIDQpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFNob3J0U2lnbmF0dXJlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSAoSW5wdXRTdHJlYW0gaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGdldEZpbGUoImJsYS5wYWNrIikpKSB7CisgICAgICAgICAgICBmaW5hbCBieXRlW10gc2lnID0gbmV3IGJ5dGVbMl07CisgICAgICAgICAgICBpcy5yZWFkKHNpZyk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShQYWNrMjAwQ29tcHJlc3NvcklucHV0U3RyZWFtLm1hdGNoZXMoc2lnLCAyKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RJbnB1dFN0cmVhbU1ldGhvZHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgTWFwPFN0cmluZywgU3RyaW5nPiBtID0gbmV3IEhhc2hNYXA8PigpOworICAgICAgICBtLnB1dCgiZm9vIiwgImJhciIpOworICAgICAgICB0cnkgKElucHV0U3RyZWFtIGlzID0gbmV3IFBhY2syMDBDb21wcmVzc29ySW5wdXRTdHJlYW0obmV3IEZpbGVJbnB1dFN0cmVhbShnZXRGaWxlKCJibGEuamFyIikpLAorICAgICAgICAgICAgICAgIG0pKSB7CisgICAgICAgICAgICAvLyBwYWNrZWQgZmlsZSBpcyBhIGphciwgd2hpY2ggaXMgYSB6aXAgc28gaXQgc3RhcnRzIHdpdGgKKyAgICAgICAgICAgIC8vIGEgbG9jYWwgZmlsZSBoZWFkZXIKKyAgICAgICAgICAgIGFzc2VydFRydWUoaXMubWFya1N1cHBvcnRlZCgpKTsKKyAgICAgICAgICAgIGlzLm1hcmsoNSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMHg1MCwgaXMucmVhZCgpKTsKKyAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSByZXN0ID0gbmV3IGJ5dGVbM107CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMywgaXMucmVhZChyZXN0KSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMHg0YiwgcmVzdFswXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMywgcmVzdFsxXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoNCwgcmVzdFsyXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMSwgaXMuc2tpcCgxKSk7CisgICAgICAgICAgICBpcy5yZXNldCgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDB4NTAsIGlzLnJlYWQoKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKGlzLmF2YWlsYWJsZSgpID4gMCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RPdXRwdXRTdHJlYW1NZXRob2RzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGUgb3V0cHV0ID0gbmV3IEZpbGUoZGlyLCAiYmxhLnBhY2siKTsKKyAgICAgICAgZmluYWwgTWFwPFN0cmluZywgU3RyaW5nPiBtID0gbmV3IEhhc2hNYXA8PigpOworICAgICAgICBtLnB1dCgiZm9vIiwgImJhciIpOworICAgICAgICB0cnkgKE91dHB1dFN0cmVhbSBvdXQgPSBuZXcgRmlsZU91dHB1dFN0cmVhbShvdXRwdXQpKSB7CisgICAgICAgICAgICBmaW5hbCBPdXRwdXRTdHJlYW0gb3MgPSBuZXcgUGFjazIwMENvbXByZXNzb3JPdXRwdXRTdHJlYW0ob3V0LCBtKTsKKyAgICAgICAgICAgIG9zLndyaXRlKDEpOworICAgICAgICAgICAgb3Mud3JpdGUobmV3IGJ5dGVbXSB7IDIsIDMgfSk7CisgICAgICAgICAgICBvcy5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBzaW5nbGVCeXRlUmVhZEZyb21NZW1vcnlDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzaW5nbGVCeXRlUmVhZENvbnNpc3RlbnRseVJldHVybnNNaW51c09uZUF0RW9mKFBhY2syMDBTdHJhdGVneS5JTl9NRU1PUlkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgc2luZ2xlQnl0ZVJlYWRGcm9tVGVtcEZpbGVDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzaW5nbGVCeXRlUmVhZENvbnNpc3RlbnRseVJldHVybnNNaW51c09uZUF0RW9mKFBhY2syMDBTdHJhdGVneS5URU1QX0ZJTEUpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBzaW5nbGVCeXRlUmVhZENvbnNpc3RlbnRseVJldHVybnNNaW51c09uZUF0RW9mKFBhY2syMDBTdHJhdGVneSBzKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgRmlsZSBpbnB1dCA9IGdldEZpbGUoImJsYS5wYWNrIik7CisgICAgICAgIHRyeSAoZmluYWwgUGFjazIwMENvbXByZXNzb3JJbnB1dFN0cmVhbSBpbiA9IG5ldyBQYWNrMjAwQ29tcHJlc3NvcklucHV0U3RyZWFtKGlucHV0LCBzKSkgeworICAgICAgICAgICAgSU9VdGlscy50b0J5dGVBcnJheShpbik7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIGluLnJlYWQoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIGluLnJlYWQoKSk7CisgICAgICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBtdWx0aUJ5dGVSZWFkRnJvbU1lbW9yeUNvbnNpc3RlbnRseVJldHVybnNNaW51c09uZUF0RW9mKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIG11bHRpQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZihQYWNrMjAwU3RyYXRlZ3kuSU5fTUVNT1JZKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIG11bHRpQnl0ZVJlYWRGcm9tVGVtcEZpbGVDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBtdWx0aUJ5dGVSZWFkQ29uc2lzdGVudGx5UmV0dXJuc01pbnVzT25lQXRFb2YoUGFjazIwMFN0cmF0ZWd5LlRFTVBfRklMRSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIG11bHRpQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZihQYWNrMjAwU3RyYXRlZ3kgcykgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGUgaW5wdXQgPSBnZXRGaWxlKCJibGEucGFjayIpOworICAgICAgICBieXRlW10gYnVmID0gbmV3IGJ5dGVbMl07CisgICAgICAgIHRyeSAoZmluYWwgUGFjazIwMENvbXByZXNzb3JJbnB1dFN0cmVhbSBpbiA9IG5ldyBQYWNrMjAwQ29tcHJlc3NvcklucHV0U3RyZWFtKGlucHV0LCBzKSkgeworICAgICAgICAgICAgSU9VdGlscy50b0J5dGVBcnJheShpbik7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIGluLnJlYWQoYnVmKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIGluLnJlYWQoYnVmKSk7CisgICAgICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9UZXN0Q29tcHJlc3NvclN0cmVhbVByb3ZpZGVyLmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9UZXN0Q29tcHJlc3NvclN0cmVhbVByb3ZpZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjJkNzJlOQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL1Rlc3RDb21wcmVzc29yU3RyZWFtUHJvdmlkZXIuamF2YQpAQCAtMCwwICsxLDYxIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnM7CisKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuU2V0czsKKworcHVibGljIGNsYXNzIFRlc3RDb21wcmVzc29yU3RyZWFtUHJvdmlkZXIgaW1wbGVtZW50cyBDb21wcmVzc29yU3RyZWFtUHJvdmlkZXIgeworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBJbnZvY2F0aW9uQ29uZmlybWF0aW9uRXhjZXB0aW9uIGV4dGVuZHMgQ29tcHJlc3NvckV4Y2VwdGlvbiB7CisKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7CisKKyAgICAgICAgcHVibGljIEludm9jYXRpb25Db25maXJtYXRpb25FeGNlcHRpb24oZmluYWwgU3RyaW5nIG1lc3NhZ2UpIHsKKyAgICAgICAgICAgIHN1cGVyKG1lc3NhZ2UpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIENvbXByZXNzb3JJbnB1dFN0cmVhbSBjcmVhdGVDb21wcmVzc29ySW5wdXRTdHJlYW0oZmluYWwgU3RyaW5nIG5hbWUsIGZpbmFsIElucHV0U3RyZWFtIGluLAorICAgICAgICAgICAgZmluYWwgYm9vbGVhbiBkZWNvbXByZXNzQ29uY2F0ZW5hdGVkKSB0aHJvd3MgQ29tcHJlc3NvckV4Y2VwdGlvbiB7CisgICAgICAgIHRocm93IG5ldyBJbnZvY2F0aW9uQ29uZmlybWF0aW9uRXhjZXB0aW9uKG5hbWUpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBDb21wcmVzc29yT3V0cHV0U3RyZWFtIGNyZWF0ZUNvbXByZXNzb3JPdXRwdXRTdHJlYW0oZmluYWwgU3RyaW5nIG5hbWUsIGZpbmFsIE91dHB1dFN0cmVhbSBvdXQpCisgICAgICAgICAgICB0aHJvd3MgQ29tcHJlc3NvckV4Y2VwdGlvbiB7CisgICAgICAgIHRocm93IG5ldyBJbnZvY2F0aW9uQ29uZmlybWF0aW9uRXhjZXB0aW9uKG5hbWUpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTZXQ8U3RyaW5nPiBnZXRJbnB1dFN0cmVhbUNvbXByZXNzb3JOYW1lcygpIHsKKyAgICAgICAgcmV0dXJuIFNldHMubmV3SGFzaFNldCgiVGVzdElucHV0MSIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTZXQ8U3RyaW5nPiBnZXRPdXRwdXRTdHJlYW1Db21wcmVzc29yTmFtZXMoKSB7CisgICAgICAgIHJldHVybiBTZXRzLm5ld0hhc2hTZXQoIlRlc3RPdXRwdXQxIik7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9YWlRlc3RDYXNlLmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9YWlRlc3RDYXNlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2Q2MDVhOQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL1haVGVzdENhc2UuamF2YQpAQCAtMCwwICsxLDk1IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzOworCitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuKjsKKworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmxhbmcubWFuYWdlbWVudC5NYW5hZ2VtZW50RmFjdG9yeTsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5BYnN0cmFjdFRlc3RDYXNlOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy54ei5YWkNvbXByZXNzb3JJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuSU9VdGlsczsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworcHVibGljIGZpbmFsIGNsYXNzIFhaVGVzdENhc2UgZXh0ZW5kcyBBYnN0cmFjdFRlc3RDYXNlIHsKKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFhaQ3JlYXRpb24oKSAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIGxvbmcgbWF4ID0gTWFuYWdlbWVudEZhY3RvcnkuZ2V0TWVtb3J5TVhCZWFuKCkuZ2V0SGVhcE1lbW9yeVVzYWdlKCkuZ2V0TWF4KCk7CisgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiWFpUZXN0Q2FzZTogSGVhcE1heD0iK21heCsiIGJ5dGVzICIrKGRvdWJsZSltYXgvKDEwMjQqMTAyNCkrIiBNQiIpOworICAgICAgICBmaW5hbCBGaWxlIGlucHV0ID0gZ2V0RmlsZSgidGVzdDEueG1sIik7CisgICAgICAgIGZpbmFsIEZpbGUgb3V0cHV0ID0gbmV3IEZpbGUoZGlyLCAidGVzdDEueG1sLnh6Iik7CisgICAgICAgIHRyeSAoT3V0cHV0U3RyZWFtIG91dCA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKG91dHB1dCkpIHsKKyAgICAgICAgICAgIHRyeSAoQ29tcHJlc3Nvck91dHB1dFN0cmVhbSBjb3MgPSBuZXcgQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkoKQorICAgICAgICAgICAgICAgICAgICAuY3JlYXRlQ29tcHJlc3Nvck91dHB1dFN0cmVhbSgieHoiLCBvdXQpKSB7CisgICAgICAgICAgICAgICAgSU9VdGlscy5jb3B5KG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpLCBjb3MpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0WFpVbmFyY2hpdmUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgRmlsZSBpbnB1dCA9IGdldEZpbGUoImJsYS50YXIueHoiKTsKKyAgICAgICAgZmluYWwgRmlsZSBvdXRwdXQgPSBuZXcgRmlsZShkaXIsICJibGEudGFyIik7CisgICAgICAgIHRyeSAoSW5wdXRTdHJlYW0gaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGlucHV0KSkgeworICAgICAgICAgICAgZmluYWwgQ29tcHJlc3NvcklucHV0U3RyZWFtIGluID0gbmV3IENvbXByZXNzb3JTdHJlYW1GYWN0b3J5KCkKKyAgICAgICAgICAgICAgICAgICAgLmNyZWF0ZUNvbXByZXNzb3JJbnB1dFN0cmVhbSgieHoiLCBpcyk7CisgICAgICAgICAgICBGaWxlT3V0cHV0U3RyZWFtIG91dCA9IG51bGw7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIG91dCA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKG91dHB1dCk7CisgICAgICAgICAgICAgICAgSU9VdGlscy5jb3B5KGluLCBvdXQpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBpZiAob3V0ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgb3V0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGluLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RDb25jYXRlbmF0ZWRTdHJlYW1zUmVhZEZpcnN0T25seSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlIGlucHV0ID0gZ2V0RmlsZSgibXVsdGlwbGUueHoiKTsKKyAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpKSB7CisgICAgICAgICAgICB0cnkgKENvbXByZXNzb3JJbnB1dFN0cmVhbSBpbiA9IG5ldyBDb21wcmVzc29yU3RyZWFtRmFjdG9yeSgpCisgICAgICAgICAgICAgICAgICAgIC5jcmVhdGVDb21wcmVzc29ySW5wdXRTdHJlYW0oInh6IiwgaXMpKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCdhJywgaW4ucmVhZCgpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIGluLnJlYWQoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RDb25jYXRlbmF0ZWRTdHJlYW1zUmVhZEZ1bGx5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGUgaW5wdXQgPSBnZXRGaWxlKCJtdWx0aXBsZS54eiIpOworICAgICAgICB0cnkgKElucHV0U3RyZWFtIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShpbnB1dCkpIHsKKyAgICAgICAgICAgIHRyeSAoQ29tcHJlc3NvcklucHV0U3RyZWFtIGluID0gbmV3IFhaQ29tcHJlc3NvcklucHV0U3RyZWFtKGlzLCB0cnVlKSkgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygnYScsIGluLnJlYWQoKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCdiJywgaW4ucmVhZCgpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMCwgaW4uYXZhaWxhYmxlKCkpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygtMSwgaW4ucmVhZCgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL1pUZXN0Q2FzZS5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvWlRlc3RDYXNlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjgwYTRhMAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL1pUZXN0Q2FzZS5qYXZhCkBAIC0wLDAgKzEsOTkgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnM7CisKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC4qOworCitpbXBvcnQgamF2YS5pby5CdWZmZXJlZElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLkFic3RyYWN0VGVzdENhc2U7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLnouWkNvbXByZXNzb3JJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuSU9VdGlsczsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworcHVibGljIGZpbmFsIGNsYXNzIFpUZXN0Q2FzZSBleHRlbmRzIEFic3RyYWN0VGVzdENhc2UgeworCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0WlVuYXJjaGl2ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0VW5hcmNoaXZlKG5ldyBTdHJlYW1XcmFwcGVyPENvbXByZXNzb3JJbnB1dFN0cmVhbT4oKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBDb21wcmVzc29ySW5wdXRTdHJlYW0gd3JhcChmaW5hbCBJbnB1dFN0cmVhbSBpcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFpDb21wcmVzc29ySW5wdXRTdHJlYW0oaXMpOworICAgICAgICAgICAgfQorICAgICAgICB9KTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RaVW5hcmNoaXZlVmlhRmFjdG9yeSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0VW5hcmNoaXZlKG5ldyBTdHJlYW1XcmFwcGVyPENvbXByZXNzb3JJbnB1dFN0cmVhbT4oKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBDb21wcmVzc29ySW5wdXRTdHJlYW0gd3JhcChmaW5hbCBJbnB1dFN0cmVhbSBpcykgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBDb21wcmVzc29yU3RyZWFtRmFjdG9yeSgpCisgICAgICAgICAgICAgICAgICAgIC5jcmVhdGVDb21wcmVzc29ySW5wdXRTdHJlYW0oQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkuWiwgaXMpOworICAgICAgICAgICAgfQorICAgICAgICB9KTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RaVW5hcmNoaXZlVmlhQXV0b0RldGVjdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0VW5hcmNoaXZlKG5ldyBTdHJlYW1XcmFwcGVyPENvbXByZXNzb3JJbnB1dFN0cmVhbT4oKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBDb21wcmVzc29ySW5wdXRTdHJlYW0gd3JhcChmaW5hbCBJbnB1dFN0cmVhbSBpcykgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBDb21wcmVzc29yU3RyZWFtRmFjdG9yeSgpCisgICAgICAgICAgICAgICAgICAgIC5jcmVhdGVDb21wcmVzc29ySW5wdXRTdHJlYW0obmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0oaXMpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWF0Y2hlcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRGYWxzZShaQ29tcHJlc3NvcklucHV0U3RyZWFtLm1hdGNoZXMobmV3IGJ5dGVbXSB7IDEsIDIsIDMsIDQgfSwgNCkpOworICAgICAgICBhc3NlcnRGYWxzZShaQ29tcHJlc3NvcklucHV0U3RyZWFtLm1hdGNoZXMobmV3IGJ5dGVbXSB7IDB4MWYsIDIsIDMsIDQgfSwgNCkpOworICAgICAgICBhc3NlcnRGYWxzZShaQ29tcHJlc3NvcklucHV0U3RyZWFtLm1hdGNoZXMobmV3IGJ5dGVbXSB7IDEsIChieXRlKTB4OWQsIDMsIDQgfSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDQpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoWkNvbXByZXNzb3JJbnB1dFN0cmVhbS5tYXRjaGVzKG5ldyBieXRlW10geyAweDFmLCAoYnl0ZSkgMHg5ZCwgMywgNCB9LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMykpOworICAgICAgICBhc3NlcnRUcnVlKFpDb21wcmVzc29ySW5wdXRTdHJlYW0ubWF0Y2hlcyhuZXcgYnl0ZVtdIHsgMHgxZiwgKGJ5dGUpIDB4OWQsIDMsIDQgfSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgNCkpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0VW5hcmNoaXZlKGZpbmFsIFN0cmVhbVdyYXBwZXI8Q29tcHJlc3NvcklucHV0U3RyZWFtPiB3cmFwcGVyKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgRmlsZSBpbnB1dCA9IGdldEZpbGUoImJsYS50YXIuWiIpOworICAgICAgICBmaW5hbCBGaWxlIG91dHB1dCA9IG5ldyBGaWxlKGRpciwgImJsYS50YXIiKTsKKyAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpKSB7CisgICAgICAgICAgICBmaW5hbCBJbnB1dFN0cmVhbSBpbiA9IHdyYXBwZXIud3JhcChpcyk7CisgICAgICAgICAgICBGaWxlT3V0cHV0U3RyZWFtIG91dCA9IG51bGw7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIG91dCA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKG91dHB1dCk7CisgICAgICAgICAgICAgICAgSU9VdGlscy5jb3B5KGluLCBvdXQpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBpZiAob3V0ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgb3V0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGluLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2Jyb3RsaS9Ccm90bGlDb21wcmVzc29ySW5wdXRTdHJlYW1UZXN0LmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9icm90bGkvQnJvdGxpQ29tcHJlc3NvcklucHV0U3RyZWFtVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjcyMWFiMzMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9icm90bGkvQnJvdGxpQ29tcHJlc3NvcklucHV0U3RyZWFtVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTcyIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLmJyb3RsaTsKKworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEVxdWFsczsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUcnVlOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuQWJzdHJhY3RUZXN0Q2FzZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuQ29tcHJlc3NvcklucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5Db21wcmVzc29yU3RyZWFtRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuSU9VdGlsczsKK2ltcG9ydCBvcmcuanVuaXQuQXNzZXJ0OworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworCitwdWJsaWMgY2xhc3MgQnJvdGxpQ29tcHJlc3NvcklucHV0U3RyZWFtVGVzdCBleHRlbmRzIEFic3RyYWN0VGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogVGVzdCBicmlkZ2Ugd29ya3MgZmluZQorICAgICAqIEB0aHJvd3Mge0BsaW5rIElPRXhjZXB0aW9ufQorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEJyb3RsaURlY29kZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGUgaW5wdXQgPSBnZXRGaWxlKCJicm90bGkudGVzdGRhdGEuY29tcHJlc3NlZCIpOworICAgICAgICBmaW5hbCBGaWxlIGV4cGVjdGVkID0gZ2V0RmlsZSgiYnJvdGxpLnRlc3RkYXRhLnVuY29tcHJlc3NlZCIpOworICAgICAgICB0cnkgKElucHV0U3RyZWFtIGlucHV0U3RyZWFtID0gbmV3IEZpbGVJbnB1dFN0cmVhbShpbnB1dCk7CisgICAgICAgICAgICAgICAgSW5wdXRTdHJlYW0gZXhwZWN0ZWRTdHJlYW0gPSBuZXcgRmlsZUlucHV0U3RyZWFtKGV4cGVjdGVkKTsKKyAgICAgICAgICAgICAgICBCcm90bGlDb21wcmVzc29ySW5wdXRTdHJlYW0gYnJvdGxpSW5wdXRTdHJlYW0gPSBuZXcgQnJvdGxpQ29tcHJlc3NvcklucHV0U3RyZWFtKGlucHV0U3RyZWFtKSkgeworICAgICAgICAgICAgZmluYWwgYnl0ZVtdIGIgPSBuZXcgYnl0ZVsyMF07CisgICAgICAgICAgICBJT1V0aWxzLnJlYWRGdWxseShleHBlY3RlZFN0cmVhbSwgYik7CisgICAgICAgICAgICBmaW5hbCBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICAgICAgaW50IHJlYWRCeXRlID0gLTE7CisgICAgICAgICAgICB3aGlsZSgocmVhZEJ5dGUgPSBicm90bGlJbnB1dFN0cmVhbS5yZWFkKCkpICE9IC0xKSB7CisgICAgICAgICAgICAgICAgYm9zLndyaXRlKHJlYWRCeXRlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIEFzc2VydC5hc3NlcnRBcnJheUVxdWFscyhiLCBib3MudG9CeXRlQXJyYXkoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RDYWNoaW5nSXNFbmFibGVkQnlEZWZhdWx0QW5kQnJvdGxpSXNQcmVzZW50KCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoQnJvdGxpVXRpbHMuQ2FjaGVkQXZhaWxhYmlsaXR5LkNBQ0hFRF9BVkFJTEFCTEUsIEJyb3RsaVV0aWxzLmdldENhY2hlZEJyb3RsaUF2YWlsYWJpbGl0eSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShCcm90bGlVdGlscy5pc0Jyb3RsaUNvbXByZXNzaW9uQXZhaWxhYmxlKCkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdENhblR1cm5PZmZDYWNoaW5nKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgQnJvdGxpVXRpbHMuc2V0Q2FjaGVCcm90bGlBdmFpbGFibGl0eShmYWxzZSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoQnJvdGxpVXRpbHMuQ2FjaGVkQXZhaWxhYmlsaXR5LkRPTlRfQ0FDSEUsIEJyb3RsaVV0aWxzLmdldENhY2hlZEJyb3RsaUF2YWlsYWJpbGl0eSgpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoQnJvdGxpVXRpbHMuaXNCcm90bGlDb21wcmVzc2lvbkF2YWlsYWJsZSgpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIEJyb3RsaVV0aWxzLnNldENhY2hlQnJvdGxpQXZhaWxhYmxpdHkodHJ1ZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RUdXJuaW5nT25DYWNoaW5nUmVFdmFsdWF0ZXNBdmFpbGFiaWxpdHkoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBCcm90bGlVdGlscy5zZXRDYWNoZUJyb3RsaUF2YWlsYWJsaXR5KGZhbHNlKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhCcm90bGlVdGlscy5DYWNoZWRBdmFpbGFiaWxpdHkuRE9OVF9DQUNIRSwgQnJvdGxpVXRpbHMuZ2V0Q2FjaGVkQnJvdGxpQXZhaWxhYmlsaXR5KCkpOworICAgICAgICAgICAgQnJvdGxpVXRpbHMuc2V0Q2FjaGVCcm90bGlBdmFpbGFibGl0eSh0cnVlKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhCcm90bGlVdGlscy5DYWNoZWRBdmFpbGFiaWxpdHkuQ0FDSEVEX0FWQUlMQUJMRSwgQnJvdGxpVXRpbHMuZ2V0Q2FjaGVkQnJvdGxpQXZhaWxhYmlsaXR5KCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgQnJvdGxpVXRpbHMuc2V0Q2FjaGVCcm90bGlBdmFpbGFibGl0eSh0cnVlKTsKKyAgICAgICAgfQorICAgIH0KKworCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBhdmFpbGFibGVTaG91bGRSZXR1cm5aZXJvKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgRmlsZSBpbnB1dCA9IGdldEZpbGUoImJyb3RsaS50ZXN0ZGF0YS5jb21wcmVzc2VkIik7CisgICAgICAgIHRyeSAoSW5wdXRTdHJlYW0gaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGlucHV0KSkgeworICAgICAgICAgICAgZmluYWwgQnJvdGxpQ29tcHJlc3NvcklucHV0U3RyZWFtIGluID0KKyAgICAgICAgICAgICAgICAgICAgbmV3IEJyb3RsaUNvbXByZXNzb3JJbnB1dFN0cmVhbShpcyk7CisgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShpbi5hdmFpbGFibGUoKSA9PSAwKTsKKyAgICAgICAgICAgIGluLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHNob3VsZEJlQWJsZVRvU2tpcEFCeXRlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgRmlsZSBpbnB1dCA9IGdldEZpbGUoImJyb3RsaS50ZXN0ZGF0YS5jb21wcmVzc2VkIik7CisgICAgICAgIHRyeSAoSW5wdXRTdHJlYW0gaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGlucHV0KSkgeworICAgICAgICAgICAgZmluYWwgQnJvdGxpQ29tcHJlc3NvcklucHV0U3RyZWFtIGluID0KKyAgICAgICAgICAgICAgICAgICAgbmV3IEJyb3RsaUNvbXByZXNzb3JJbnB1dFN0cmVhbShpcyk7CisgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDEsIGluLnNraXAoMSkpOworICAgICAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgc2luZ2xlQnl0ZVJlYWRXb3Jrc0FzRXhwZWN0ZWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlIGlucHV0ID0gZ2V0RmlsZSgiYnJvdGxpLnRlc3RkYXRhLmNvbXByZXNzZWQiKTsKKyAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpKSB7CisgICAgICAgICAgICBmaW5hbCBCcm90bGlDb21wcmVzc29ySW5wdXRTdHJlYW0gaW4gPQorICAgICAgICAgICAgICAgICAgICBuZXcgQnJvdGxpQ29tcHJlc3NvcklucHV0U3RyZWFtKGlzKTsKKyAgICAgICAgICAgIC8vICBzdGFydHMgd2l0aCBmaWxlbmFtZSAiWFhYIgorICAgICAgICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygnWCcsIGluLnJlYWQoKSk7CisgICAgICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBzaW5nbGVCeXRlUmVhZENvbnNpc3RlbnRseVJldHVybnNNaW51c09uZUF0RW9mKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgRmlsZSBpbnB1dCA9IGdldEZpbGUoImJyb3RsaS50ZXN0ZGF0YS5jb21wcmVzc2VkIik7CisgICAgICAgIHRyeSAoSW5wdXRTdHJlYW0gaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGlucHV0KSkgeworICAgICAgICAgICAgZmluYWwgQnJvdGxpQ29tcHJlc3NvcklucHV0U3RyZWFtIGluID0KKyAgICAgICAgICAgICAgICAgICAgbmV3IEJyb3RsaUNvbXByZXNzb3JJbnB1dFN0cmVhbShpcyk7CisgICAgICAgICAgICBJT1V0aWxzLnRvQnl0ZUFycmF5KGluKTsKKyAgICAgICAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoLTEsIGluLnJlYWQoKSk7CisgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKC0xLCBpbi5yZWFkKCkpOworICAgICAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgbXVsdGlCeXRlUmVhZENvbnNpc3RlbnRseVJldHVybnNNaW51c09uZUF0RW9mKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgRmlsZSBpbnB1dCA9IGdldEZpbGUoImJyb3RsaS50ZXN0ZGF0YS5jb21wcmVzc2VkIik7CisgICAgICAgIGJ5dGVbXSBidWYgPSBuZXcgYnl0ZVsyXTsKKyAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpKSB7CisgICAgICAgICAgICBmaW5hbCBCcm90bGlDb21wcmVzc29ySW5wdXRTdHJlYW0gaW4gPQorICAgICAgICAgICAgICAgICAgICBuZXcgQnJvdGxpQ29tcHJlc3NvcklucHV0U3RyZWFtKGlzKTsKKyAgICAgICAgICAgIElPVXRpbHMudG9CeXRlQXJyYXkoaW4pOworICAgICAgICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygtMSwgaW4ucmVhZChidWYpKTsKKyAgICAgICAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoLTEsIGluLnJlYWQoYnVmKSk7CisgICAgICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QnJvdGxpVW5hcmNoaXZlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGUgaW5wdXQgPSBnZXRGaWxlKCJibGEudGFyLmJyIik7CisgICAgICAgIGZpbmFsIEZpbGUgb3V0cHV0ID0gbmV3IEZpbGUoZGlyLCAiYmxhLnRhciIpOworICAgICAgICB0cnkgKElucHV0U3RyZWFtIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShpbnB1dCkpIHsKKyAgICAgICAgICAgIGZpbmFsIENvbXByZXNzb3JJbnB1dFN0cmVhbSBpbiA9IG5ldyBDb21wcmVzc29yU3RyZWFtRmFjdG9yeSgpCisgICAgICAgICAgICAgICAgICAgIC5jcmVhdGVDb21wcmVzc29ySW5wdXRTdHJlYW0oImJyIiwgaXMpOworICAgICAgICAgICAgRmlsZU91dHB1dFN0cmVhbSBvdXQgPSBudWxsOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBvdXQgPSBuZXcgRmlsZU91dHB1dFN0cmVhbShvdXRwdXQpOworICAgICAgICAgICAgICAgIElPVXRpbHMuY29weShpbiwgb3V0KTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgaWYgKG91dCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9iemlwMi9CWmlwMkNvbXByZXNzb3JJbnB1dFN0cmVhbVRlc3QuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2J6aXAyL0JaaXAyQ29tcHJlc3NvcklucHV0U3RyZWFtVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjcxMzBkOTIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9iemlwMi9CWmlwMkNvbXByZXNzb3JJbnB1dFN0cmVhbVRlc3QuamF2YQpAQCAtMCwwICsxLDEwMCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5iemlwMjsKKworaW1wb3J0IHN0YXRpYyBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuQWJzdHJhY3RUZXN0Q2FzZS5nZXRGaWxlOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5JT1V0aWxzOworaW1wb3J0IG9yZy5qdW5pdC5Bc3NlcnQ7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CisKK3B1YmxpYyBjbGFzcyBCWmlwMkNvbXByZXNzb3JJbnB1dFN0cmVhbVRlc3QgeworCisgICAgQFRlc3QoZXhwZWN0ZWQgPSBJT0V4Y2VwdGlvbi5jbGFzcykKKyAgICBwdWJsaWMgdm9pZCBzaG91bGRUaHJvd0FuSU9FeGNlcHRpb25XaGVuQXBwbGllZFRvQVppcEZpbGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IChGaWxlSW5wdXRTdHJlYW0gaW4gPSBuZXcgRmlsZUlucHV0U3RyZWFtKGdldEZpbGUoImJsYS56aXAiKSkpIHsKKyAgICAgICAgICAgIEJaaXAyQ29tcHJlc3NvcklucHV0U3RyZWFtIGJpcyA9IG5ldyBCWmlwMkNvbXByZXNzb3JJbnB1dFN0cmVhbShpbik7CisgICAgICAgICAgICBiaXMuY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgImh0dHBzOi8vaXNzdWVzLmFwYWNoZS5vcmcvamlyYS9icm93c2UvQ09NUFJFU1MtMzA5IgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgcmVhZE9mTGVuZ3RoMFNob3VsZFJldHVybjAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gQ3JlYXRlIGEgYmlnIHJhbmRvbSBwaWVjZSBvZiBkYXRhCisgICAgICAgIGZpbmFsIGJ5dGVbXSByYXdEYXRhID0gbmV3IGJ5dGVbMTA0ODU3Nl07CisgICAgICAgIGZvciAoaW50IGk9MDsgaSA8IHJhd0RhdGEubGVuZ3RoOyArK2kpIHsKKyAgICAgICAgICAgIHJhd0RhdGFbaV0gPSAoYnl0ZSkgTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpKjI1Nik7CisgICAgICAgIH0KKworICAgICAgICAvLyBDb21wcmVzcyBpdAorICAgICAgICBmaW5hbCBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYmFvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgZmluYWwgQlppcDJDb21wcmVzc29yT3V0cHV0U3RyZWFtIGJ6aXBPdXQgPSBuZXcgQlppcDJDb21wcmVzc29yT3V0cHV0U3RyZWFtKGJhb3MpOworICAgICAgICBiemlwT3V0LndyaXRlKHJhd0RhdGEpOworICAgICAgICBiemlwT3V0LmZsdXNoKCk7CisgICAgICAgIGJ6aXBPdXQuY2xvc2UoKTsKKyAgICAgICAgYmFvcy5mbHVzaCgpOworICAgICAgICBiYW9zLmNsb3NlKCk7CisKKyAgICAgICAgLy8gVHJ5IHRvIHJlYWQgaXQgYmFjayBpbgorICAgICAgICBmaW5hbCBCeXRlQXJyYXlJbnB1dFN0cmVhbSBiYWlzID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJhb3MudG9CeXRlQXJyYXkoKSk7CisgICAgICAgIGZpbmFsIEJaaXAyQ29tcHJlc3NvcklucHV0U3RyZWFtIGJ6aXBJbiA9IG5ldyBCWmlwMkNvbXByZXNzb3JJbnB1dFN0cmVhbShiYWlzKTsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGJ1ZmZlciA9IG5ldyBieXRlWzEwMjRdOworICAgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDEwMjQsIGJ6aXBJbi5yZWFkKGJ1ZmZlciwgMCwgMTAyNCkpOworICAgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDAsIGJ6aXBJbi5yZWFkKGJ1ZmZlciwgMTAyNCwgMCkpOworICAgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDEwMjQsIGJ6aXBJbi5yZWFkKGJ1ZmZlciwgMCwgMTAyNCkpOworICAgICAgICBiemlwSW4uY2xvc2UoKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHNpbmdsZUJ5dGVSZWFkQ29uc2lzdGVudGx5UmV0dXJuc01pbnVzT25lQXRFb2YoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlIGlucHV0ID0gZ2V0RmlsZSgiYmxhLnR4dC5iejIiKTsKKyAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpKSB7CisgICAgICAgICAgICBmaW5hbCBCWmlwMkNvbXByZXNzb3JJbnB1dFN0cmVhbSBpbiA9CisgICAgICAgICAgICAgICAgICAgIG5ldyBCWmlwMkNvbXByZXNzb3JJbnB1dFN0cmVhbShpcyk7CisgICAgICAgICAgICBJT1V0aWxzLnRvQnl0ZUFycmF5KGluKTsKKyAgICAgICAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoLTEsIGluLnJlYWQoKSk7CisgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKC0xLCBpbi5yZWFkKCkpOworICAgICAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgbXVsdGlCeXRlUmVhZENvbnNpc3RlbnRseVJldHVybnNNaW51c09uZUF0RW9mKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgRmlsZSBpbnB1dCA9IGdldEZpbGUoImJsYS50eHQuYnoyIik7CisgICAgICAgIGJ5dGVbXSBidWYgPSBuZXcgYnl0ZVsyXTsKKyAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpKSB7CisgICAgICAgICAgICBmaW5hbCBCWmlwMkNvbXByZXNzb3JJbnB1dFN0cmVhbSBpbiA9CisgICAgICAgICAgICAgICAgICAgIG5ldyBCWmlwMkNvbXByZXNzb3JJbnB1dFN0cmVhbShpcyk7CisgICAgICAgICAgICBJT1V0aWxzLnRvQnl0ZUFycmF5KGluKTsKKyAgICAgICAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoLTEsIGluLnJlYWQoYnVmKSk7CisgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKC0xLCBpbi5yZWFkKGJ1ZikpOworICAgICAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvYnppcDIvQmxvY2tTb3J0VGVzdC5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvYnppcDIvQmxvY2tTb3J0VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM3YjI3ZWYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9iemlwMi9CbG9ja1NvcnRUZXN0LmphdmEKQEAgLTAsMCArMSwxNzEgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuYnppcDI7CisKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEFycmF5RXF1YWxzOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEVxdWFsczsKKworcHVibGljIGNsYXNzIEJsb2NrU29ydFRlc3QgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIEZJWFRVUkUgPSB7IDAsIDEsIChieXRlKSAyNTIsIChieXRlKSAyNTMsIChieXRlKSAyNTUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAyNTQsIDMsIDIsIChieXRlKSAxMjggfTsKKworICAgIC8qCisgICAgICBCdXJyb3dzLVdoZWVsZXIgdHJhbnNmb3JtIG9mIGZpeHR1cmUgdGhlIG1hbnVhbCB3YXk6CisKKyAgICAgICogYnVpbGQgdGhlIG1hdHJpeAorCisgICAgICAwLCAxLCAyNTIsIDI1MywgMjU1LCAyNTQsIDMsIDIsIDEyOAorICAgICAgMSwgMjUyLCAyNTMsIDI1NSwgMjU0LCAzLCAyLCAxMjgsIDAKKyAgICAgIDI1MiwgMjUzLCAyNTUsIDI1NCwgMywgMiwgMTI4LCAwLCAxCisgICAgICAyNTMsIDI1NSwgMjU0LCAzLCAyLCAxMjgsIDAsIDEsIDI1MgorICAgICAgMjU1LCAyNTQsIDMsIDIsIDEyOCwgMCwgMSwgMjUyLCAyNTMKKyAgICAgIDI1NCwgMywgMiwgMTI4LCAwLCAxLCAyNTIsIDI1MywgMjU1CisgICAgICAzLCAyLCAxMjgsIDAsIDEsIDI1MiwgMjUzLCAyNTUsIDI1NAorICAgICAgMiwgMTI4LCAwLCAxLCAyNTIsIDI1MywgMjU1LCAyNTQsIDMKKyAgICAgIDEyOCwgMCwgMSwgMjUyLCAyNTMsIDI1NSwgMjU0LCAzLCAyCisKKyAgICAgICogc29ydCBpdAorCisgICAgICAwLCAxLCAyNTIsIDI1MywgMjU1LCAyNTQsIDMsIDIsIDEyOAorICAgICAgMSwgMjUyLCAyNTMsIDI1NSwgMjU0LCAzLCAyLCAxMjgsIDAKKyAgICAgIDIsIDEyOCwgMCwgMSwgMjUyLCAyNTMsIDI1NSwgMjU0LCAzCisgICAgICAzLCAyLCAxMjgsIDAsIDEsIDI1MiwgMjUzLCAyNTUsIDI1NAorICAgICAgMTI4LCAwLCAxLCAyNTIsIDI1MywgMjU1LCAyNTQsIDMsIDIKKyAgICAgIDI1MiwgMjUzLCAyNTUsIDI1NCwgMywgMiwgMTI4LCAwLCAxCisgICAgICAyNTMsIDI1NSwgMjU0LCAzLCAyLCAxMjgsIDAsIDEsIDI1MgorICAgICAgMjU0LCAzLCAyLCAxMjgsIDAsIDEsIDI1MiwgMjUzLCAyNTUKKyAgICAgIDI1NSwgMjU0LCAzLCAyLCAxMjgsIDAsIDEsIDI1MiwgMjUzCisKKyAgICAgICogZ3JhYiBsYXN0IGNvbHVtbgorCisgICAgICAxMjgsIDAsIDMsIDI1NCwgMiwgMSwgMjUyLCAyNTUsIDI1MworCisgICAgICAgIGFuZCB0aGUgb3JpZ2luYWwgbGluZSBoYXMgYmVlbiAwCisgICAgKi8KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBGSVhUVVJFX0JXVCA9IHsgKGJ5dGUpIDEyOCwgMCwgMywgKGJ5dGUpIDI1NCwgMiwgMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAyNTIsIChieXRlKSAyNTUsIChieXRlKSAyNTMgfTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludFtdIEZJWFRVUkVfU09SVEVEID0geworICAgICAgICAwLCAxLCA3LCA2LCA4LCAyLCAzLCA1LCA0CisgICAgfTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBGSVhUVVJFMiA9IHsKKyAgICAgICAgJ0MnLCAnbycsICdtJywgJ20nLCAnbycsICduJywgJ3MnLCAnICcsICdDJywgJ28nLCAnbScsICdwJywgJ3InLCAnZScsICdzJywgJ3MnLAorICAgIH07CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gRklYVFVSRTJfQldUID0geworICAgICAgICAncycsICdzJywgJyAnLCAncicsICdvJywgJ20nLCAnbycsICdvJywgJ0MnLCAnQycsICdtJywgJ20nLCAncCcsICduJywgJ3MnLCAnZScsCisgICAgfTsKKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFNvcnRGaXh0dXJlKCkgeworICAgICAgICBmaW5hbCBEUyBkcyA9IHNldFVwRml4dHVyZSgpOworICAgICAgICBkcy5zLmJsb2NrU29ydChkcy5kYXRhLCBGSVhUVVJFLmxlbmd0aCAtIDEpOworICAgICAgICBhc3NlcnRGaXh0dXJlU29ydGVkKGRzLmRhdGEpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgZHMuZGF0YS5vcmlnUHRyKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RTb3J0Rml4dHVyZU1haW5Tb3J0KCkgeworICAgICAgICBmaW5hbCBEUyBkcyA9IHNldFVwRml4dHVyZSgpOworICAgICAgICBkcy5zLm1haW5Tb3J0KGRzLmRhdGEsIEZJWFRVUkUubGVuZ3RoIC0gMSk7CisgICAgICAgIGFzc2VydEZpeHR1cmVTb3J0ZWQoZHMuZGF0YSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U29ydEZpeHR1cmVGYWxsYmFja1NvcnQoKSB7CisgICAgICAgIGZpbmFsIERTIGRzID0gc2V0VXBGaXh0dXJlKCk7CisgICAgICAgIGRzLnMuZmFsbGJhY2tTb3J0KGRzLmRhdGEsIEZJWFRVUkUubGVuZ3RoIC0gMSk7CisgICAgICAgIGFzc2VydEZpeHR1cmVTb3J0ZWQoZHMuZGF0YSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U29ydEZpeHR1cmUyKCkgeworICAgICAgICBmaW5hbCBEUyBkcyA9IHNldFVwRml4dHVyZTIoKTsKKyAgICAgICAgZHMucy5ibG9ja1NvcnQoZHMuZGF0YSwgRklYVFVSRTIubGVuZ3RoIC0gMSk7CisgICAgICAgIGFzc2VydEZpeHR1cmUyU29ydGVkKGRzLmRhdGEpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgZHMuZGF0YS5vcmlnUHRyKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RTb3J0Rml4dHVyZTJNYWluU29ydCgpIHsKKyAgICAgICAgZmluYWwgRFMgZHMgPSBzZXRVcEZpeHR1cmUyKCk7CisgICAgICAgIGRzLnMubWFpblNvcnQoZHMuZGF0YSwgRklYVFVSRTIubGVuZ3RoIC0gMSk7CisgICAgICAgIGFzc2VydEZpeHR1cmUyU29ydGVkKGRzLmRhdGEpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFNvcnRGaXh0dXJlMkZhbGxiYWNrU29ydCgpIHsKKyAgICAgICAgZmluYWwgRFMgZHMgPSBzZXRVcEZpeHR1cmUyKCk7CisgICAgICAgIGRzLnMuZmFsbGJhY2tTb3J0KGRzLmRhdGEsIEZJWFRVUkUyLmxlbmd0aCAtIDEpOworICAgICAgICBhc3NlcnRGaXh0dXJlMlNvcnRlZChkcy5kYXRhKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RGYWxsYmFja1NvcnQoKSB7CisgICAgICAgIGZpbmFsIEJaaXAyQ29tcHJlc3Nvck91dHB1dFN0cmVhbS5EYXRhIGRhdGEgPSBuZXcgQlppcDJDb21wcmVzc29yT3V0cHV0U3RyZWFtLkRhdGEoMSk7CisgICAgICAgIGZpbmFsIEJsb2NrU29ydCBzID0gbmV3IEJsb2NrU29ydChkYXRhKTsKKyAgICAgICAgZmluYWwgaW50W10gZm1hcCA9IG5ldyBpbnRbRklYVFVSRS5sZW5ndGhdOworICAgICAgICBzLmZhbGxiYWNrU29ydChmbWFwLCBGSVhUVVJFLCBGSVhUVVJFLmxlbmd0aCk7CisgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKEZJWFRVUkVfU09SVEVELCBmbWFwKTsKKyAgICB9CisKKyAgICBwcml2YXRlIERTIHNldFVwRml4dHVyZSgpIHsKKyAgICAgICAgcmV0dXJuIHNldFVwRml4dHVyZShGSVhUVVJFKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYXNzZXJ0Rml4dHVyZVNvcnRlZChmaW5hbCBCWmlwMkNvbXByZXNzb3JPdXRwdXRTdHJlYW0uRGF0YSBkYXRhKSB7CisgICAgICAgIGFzc2VydEZpeHR1cmVTb3J0ZWQoZGF0YSwgRklYVFVSRSwgRklYVFVSRV9CV1QpOworICAgIH0KKworICAgIHByaXZhdGUgRFMgc2V0VXBGaXh0dXJlMigpIHsKKyAgICAgICAgcmV0dXJuIHNldFVwRml4dHVyZShGSVhUVVJFMik7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGFzc2VydEZpeHR1cmUyU29ydGVkKGZpbmFsIEJaaXAyQ29tcHJlc3Nvck91dHB1dFN0cmVhbS5EYXRhIGRhdGEpIHsKKyAgICAgICAgYXNzZXJ0Rml4dHVyZVNvcnRlZChkYXRhLCBGSVhUVVJFMiwgRklYVFVSRTJfQldUKTsKKyAgICB9CisKKyAgICBwcml2YXRlIERTIHNldFVwRml4dHVyZShmaW5hbCBieXRlW10gZml4dHVyZSkgeworICAgICAgICBmaW5hbCBCWmlwMkNvbXByZXNzb3JPdXRwdXRTdHJlYW0uRGF0YSBkYXRhID0gbmV3IEJaaXAyQ29tcHJlc3Nvck91dHB1dFN0cmVhbS5EYXRhKDEpOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGZpeHR1cmUsIDAsIGRhdGEuYmxvY2ssIDEsIGZpeHR1cmUubGVuZ3RoKTsKKyAgICAgICAgcmV0dXJuIG5ldyBEUyhkYXRhLCBuZXcgQmxvY2tTb3J0KGRhdGEpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYXNzZXJ0Rml4dHVyZVNvcnRlZChmaW5hbCBCWmlwMkNvbXByZXNzb3JPdXRwdXRTdHJlYW0uRGF0YSBkYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBmaXh0dXJlLCBmaW5hbCBieXRlW10gZml4dHVyZUJ3dCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoZml4dHVyZVtmaXh0dXJlLmxlbmd0aCAtIDFdLCBkYXRhLmJsb2NrWzBdKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaXh0dXJlLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoZml4dHVyZUJ3dFtpXSwgZGF0YS5ibG9ja1tkYXRhLmZtYXBbaV1dKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIERTIHsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBCWmlwMkNvbXByZXNzb3JPdXRwdXRTdHJlYW0uRGF0YSBkYXRhOworICAgICAgICBwcml2YXRlIGZpbmFsIEJsb2NrU29ydCBzOworICAgICAgICBEUyhmaW5hbCBCWmlwMkNvbXByZXNzb3JPdXRwdXRTdHJlYW0uRGF0YSBkYXRhLCBmaW5hbCBCbG9ja1NvcnQgcykgeworICAgICAgICAgICAgdGhpcy5kYXRhID0gZGF0YTsKKyAgICAgICAgICAgIHRoaXMucyA9IHM7CisgICAgICAgIH0KKyAgICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvYnppcDIvUHl0aG9uVHJ1bmNhdGVkQnppcDJUZXN0LmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9iemlwMi9QeXRob25UcnVuY2F0ZWRCemlwMlRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yYmRkMDE0Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvYnppcDIvUHl0aG9uVHJ1bmNhdGVkQnppcDJUZXN0LmphdmEKQEAgLTAsMCArMSwxMjAgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuYnppcDI7CisKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRBcnJheUVxdWFsczsKKworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLkNoYW5uZWxzOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLlJlYWRhYmxlQnl0ZUNoYW5uZWw7CitpbXBvcnQgb3JnLmp1bml0LkFmdGVyOworaW1wb3J0IG9yZy5qdW5pdC5Bc3NlcnQ7CitpbXBvcnQgb3JnLmp1bml0LkJlZm9yZTsKK2ltcG9ydCBvcmcuanVuaXQuQmVmb3JlQ2xhc3M7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CisKKy8qKgorICogVGVzdGNhc2UgcG9ydGluZyBhIHRlc3QgZnJvbSBQeXRob24ncyB0ZXN0c3VpdGUuCisgKiBAc2VlICJodHRwczovL2lzc3Vlcy5hcGFjaGUub3JnL2ppcmEvYnJvd3NlL0NPTVBSRVNTLTI1MyIKKyAqLworcHVibGljIGNsYXNzIFB5dGhvblRydW5jYXRlZEJ6aXAyVGVzdCB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgVEVYVCA9ICJyb290Ong6MDowOnJvb3Q6L3Jvb3Q6L2Jpbi9iYXNoXG5iaW46eDoxOjE6YmluOi9iaW46XG5kYWVtb246eDoyOjI6ZGFlbW9uOi9zYmluOlxuYWRtOng6Mzo0OmFkbTovdmFyL2FkbTpcbmxwOng6NDo3OmxwOi92YXIvc3Bvb2wvbHBkOlxuc3luYzp4OjU6MDpzeW5jOi9zYmluOi9iaW4vc3luY1xuc2h1dGRvd246eDo2OjA6c2h1dGRvd246L3NiaW46L3NiaW4vc2h1dGRvd25cbmhhbHQ6eDo3OjA6aGFsdDovc2Jpbjovc2Jpbi9oYWx0XG5tYWlsOng6ODoxMjptYWlsOi92YXIvc3Bvb2wvbWFpbDpcbm5ld3M6eDo5OjEzOm5ld3M6L3Zhci9zcG9vbC9uZXdzOlxudXVjcDp4OjEwOjE0OnV1Y3A6L3Zhci9zcG9vbC91dWNwOlxub3BlcmF0b3I6eDoxMTowOm9wZXJhdG9yOi9yb290OlxuZ2FtZXM6eDoxMjoxMDA6Z2FtZXM6L3Vzci9nYW1lczpcbmdvcGhlcjp4OjEzOjMwOmdvcGhlcjovdXNyL2xpYi9nb3BoZXItZGF0YTpcbmZ0cDp4OjE0OjUwOkZUUCBVc2VyOi92YXIvZnRwOi9iaW4vYmFzaFxubm9ib2R5Ong6NjU1MzQ6NjU1MzQ6Tm9ib2R5Oi9ob21lOlxucG9zdGZpeDp4OjEwMDoxMDE6cG9zdGZpeDovdmFyL3Nwb29sL3Bvc3RmaXg6XG5uaWVtZXllcjp4OjUwMDo1MDA6Oi9ob21lL25pZW1leWVyOi9iaW4vYmFzaFxucG9zdGdyZXM6eDoxMDE6MTAyOlBvc3RncmVTUUwgU2VydmVyOi92YXIvbGliL3Bnc3FsOi9iaW4vYmFzaFxubXlzcWw6eDoxMDI6MTAzOk15U1FMIHNlcnZlcjovdmFyL2xpYi9teXNxbDovYmluL2Jhc2hcbnd3dzp4OjEwMzoxMDQ6Oi92YXIvd3d3Oi9iaW4vZmFsc2VcbiI7CisKKyAgICBwcml2YXRlIHN0YXRpYyBieXRlW10gREFUQTsKKyAgICBwcml2YXRlIHN0YXRpYyBieXRlW10gVFJVTkNBVEVEX0RBVEE7CisgICAgcHJpdmF0ZSBSZWFkYWJsZUJ5dGVDaGFubmVsIGJ6MkNoYW5uZWw7CisKKyAgICBAQmVmb3JlQ2xhc3MKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgaW5pdGlhbGl6ZVRlc3REYXRhKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIG91dCA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgZmluYWwgQlppcDJDb21wcmVzc29yT3V0cHV0U3RyZWFtIGJ6Mm91dCA9IG5ldyBCWmlwMkNvbXByZXNzb3JPdXRwdXRTdHJlYW0ob3V0KTsKKyAgICAgICAgYnoyb3V0LndyaXRlKFRFWFQuZ2V0Qnl0ZXMoKSwgMCwgVEVYVC5nZXRCeXRlcygpLmxlbmd0aCk7CisgICAgICAgIGJ6Mm91dC5jbG9zZSgpOworICAgICAgICBEQVRBID0gb3V0LnRvQnl0ZUFycmF5KCk7CisKKyAgICAgICAgLy8gRHJvcCB0aGUgZW9zX21hZ2ljIGZpZWxkICg2IGJ5dGVzKSBhbmQgQ1JDICg0IGJ5dGVzKS4KKyAgICAgICAgVFJVTkNBVEVEX0RBVEEgPSBjb3B5T2ZSYW5nZShEQVRBLCAwLCBEQVRBLmxlbmd0aCAtIDEwKTsKKyAgICB9CisKKyAgICBAQmVmb3JlCisgICAgcHVibGljIHZvaWQgaW5pdGlhbGl6ZUNoYW5uZWwoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBJbnB1dFN0cmVhbSBzb3VyY2UgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oVFJVTkNBVEVEX0RBVEEpOworICAgICAgICB0aGlzLmJ6MkNoYW5uZWwgPSBtYWtlQloyQyhzb3VyY2UpOworICAgIH0KKworICAgIEBBZnRlcgorICAgIHB1YmxpYyB2b2lkIGNsb3NlQ2hhbm5lbCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJ6MkNoYW5uZWwuY2xvc2UoKTsKKyAgICAgICAgYnoyQ2hhbm5lbCA9IG51bGw7CisgICAgfQorCisgICAgQFRlc3QoZXhwZWN0ZWQgPSBJT0V4Y2VwdGlvbi5jbGFzcykKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VHJ1bmNhdGVkRGF0YSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vd2l0aCBCWjJGaWxlKHNlbGYuZmlsZW5hbWUpIGFzIGY6CisgICAgICAgIC8vICAgIHNlbGYuYXNzZXJ0UmFpc2VzKEVPRkVycm9yLCBmLnJlYWQpCisgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiQXR0ZW1wdCB0byByZWFkIHRoZSB3aG9sZSB0aGluZyBpbiwgc2hvdWxkIHRocm93IC4uLiIpOworICAgICAgICBmaW5hbCBCeXRlQnVmZmVyIGJ1ZmZlciA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUoODE5Mik7CisgICAgICAgIGJ6MkNoYW5uZWwucmVhZChidWZmZXIpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFBhcnRpYWxSZWFkVHJ1bmNhdGVkRGF0YSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vd2l0aCBCWjJGaWxlKHNlbGYuZmlsZW5hbWUpIGFzIGY6CisgICAgICAgIC8vICAgIHNlbGYuYXNzZXJ0RXF1YWwoZi5yZWFkKGxlbihzZWxmLlRFWFQpKSwgc2VsZi5URVhUKQorICAgICAgICAvLyAgICBzZWxmLmFzc2VydFJhaXNlcyhFT0ZFcnJvciwgZi5yZWFkLCAxKQorCisgICAgICAgIGZpbmFsIGludCBsZW5ndGggPSBURVhULmxlbmd0aCgpOworICAgICAgICBCeXRlQnVmZmVyIGJ1ZmZlciA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUobGVuZ3RoKTsKKyAgICAgICAgYnoyQ2hhbm5lbC5yZWFkKGJ1ZmZlcik7CisKKyAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMoY29weU9mUmFuZ2UoVEVYVC5nZXRCeXRlcygpLCAwLCBsZW5ndGgpLAorICAgICAgICAgICAgICAgIGJ1ZmZlci5hcnJheSgpKTsKKworICAgICAgICAvLyBzdWJzZXF1ZW50IHJlYWQgc2hvdWxkIHRocm93CisgICAgICAgIGJ1ZmZlciA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUoMSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBiejJDaGFubmVsLnJlYWQoYnVmZmVyKTsKKyAgICAgICAgICAgIEFzc2VydC5mYWlsKCJUaGUgcmVhZCBzaG91bGQgaGF2ZSB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIHBhc3MKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIFJlYWRhYmxlQnl0ZUNoYW5uZWwgbWFrZUJaMkMoZmluYWwgSW5wdXRTdHJlYW0gc291cmNlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBCdWZmZXJlZElucHV0U3RyZWFtIGJpbiA9IG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKHNvdXJjZSk7CisgICAgICAgIGZpbmFsIEJaaXAyQ29tcHJlc3NvcklucHV0U3RyZWFtIGJaaW4gPSBuZXcgQlppcDJDb21wcmVzc29ySW5wdXRTdHJlYW0oYmluLCB0cnVlKTsKKworICAgICAgICByZXR1cm4gQ2hhbm5lbHMubmV3Q2hhbm5lbChiWmluKTsKKyAgICB9CisKKyAgICAvLyBIZWxwZXIgbWV0aG9kIHNpbmNlIEFycmF5cyNjb3B5T2ZSYW5nZSBpcyBKYXZhIDEuNisKKyAgICAvLyBEb2VzIG5vdCBjaGVjayBwYXJhbWV0ZXJzLCBzbyBtYXkgZmFpbCBpZiB0aGV5IGFyZSBpbmNvbXBhdGlibGUKKyAgICBwcml2YXRlIHN0YXRpYyBieXRlW10gY29weU9mUmFuZ2UoZmluYWwgYnl0ZVtdIG9yaWdpbmFsLCBmaW5hbCBpbnQgZnJvbSwgZmluYWwgaW50IHRvKSB7CisgICAgICAgIGZpbmFsIGludCBsZW5ndGggPSB0byAtIGZyb207CisgICAgICAgIGZpbmFsIGJ5dGUgYnVmZltdID0gbmV3IGJ5dGVbbGVuZ3RoXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShvcmlnaW5hbCwgZnJvbSwgYnVmZiwgMCwgbGVuZ3RoKTsKKyAgICAgICAgcmV0dXJuIGJ1ZmY7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvZGVmbGF0ZS9EZWZsYXRlQ29tcHJlc3NvcklucHV0U3RyZWFtVGVzdC5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvZGVmbGF0ZS9EZWZsYXRlQ29tcHJlc3NvcklucHV0U3RyZWFtVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk3YTAxMGYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9kZWZsYXRlL0RlZmxhdGVDb21wcmVzc29ySW5wdXRTdHJlYW1UZXN0LmphdmEKQEAgLTAsMCArMSw5NCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5kZWZsYXRlOworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5BYnN0cmFjdFRlc3RDYXNlOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5JT1V0aWxzOworaW1wb3J0IG9yZy5qdW5pdC5Bc3NlcnQ7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CisKK3B1YmxpYyBjbGFzcyBEZWZsYXRlQ29tcHJlc3NvcklucHV0U3RyZWFtVGVzdCB7CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIGF2YWlsYWJsZVNob3VsZFJldHVybk5vblplcm8oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlIGlucHV0ID0gQWJzdHJhY3RUZXN0Q2FzZS5nZXRGaWxlKCJibGEudGFyLmRlZmxhdGV6Iik7CisgICAgICAgIHRyeSAoSW5wdXRTdHJlYW0gaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGlucHV0KSkgeworICAgICAgICAgICAgZmluYWwgRGVmbGF0ZUNvbXByZXNzb3JJbnB1dFN0cmVhbSBpbiA9CisgICAgICAgICAgICAgICAgICAgIG5ldyBEZWZsYXRlQ29tcHJlc3NvcklucHV0U3RyZWFtKGlzKTsKKyAgICAgICAgICAgIEFzc2VydC5hc3NlcnRUcnVlKGluLmF2YWlsYWJsZSgpID4gMCk7CisgICAgICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBzaG91bGRCZUFibGVUb1NraXBBQnl0ZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGUgaW5wdXQgPSBBYnN0cmFjdFRlc3RDYXNlLmdldEZpbGUoImJsYS50YXIuZGVmbGF0ZXoiKTsKKyAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpKSB7CisgICAgICAgICAgICBmaW5hbCBEZWZsYXRlQ29tcHJlc3NvcklucHV0U3RyZWFtIGluID0KKyAgICAgICAgICAgICAgICAgICAgbmV3IERlZmxhdGVDb21wcmVzc29ySW5wdXRTdHJlYW0oaXMpOworICAgICAgICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygxLCBpbi5za2lwKDEpKTsKKyAgICAgICAgICAgIGluLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHNpbmdsZUJ5dGVSZWFkV29ya3NBc0V4cGVjdGVkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgRmlsZSBpbnB1dCA9IEFic3RyYWN0VGVzdENhc2UuZ2V0RmlsZSgiYmxhLnRhci5kZWZsYXRleiIpOworICAgICAgICB0cnkgKElucHV0U3RyZWFtIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShpbnB1dCkpIHsKKyAgICAgICAgICAgIGZpbmFsIERlZmxhdGVDb21wcmVzc29ySW5wdXRTdHJlYW0gaW4gPQorICAgICAgICAgICAgICAgICAgICBuZXcgRGVmbGF0ZUNvbXByZXNzb3JJbnB1dFN0cmVhbShpcyk7CisgICAgICAgICAgICAvLyB0YXIgaGVhZGVyIHN0YXJ0cyB3aXRoIGZpbGVuYW1lICJ0ZXN0MS54bWwiCisgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKCd0JywgaW4ucmVhZCgpKTsKKyAgICAgICAgICAgIGluLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHNpbmdsZUJ5dGVSZWFkQ29uc2lzdGVudGx5UmV0dXJuc01pbnVzT25lQXRFb2YoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlIGlucHV0ID0gQWJzdHJhY3RUZXN0Q2FzZS5nZXRGaWxlKCJibGEudGFyLmRlZmxhdGV6Iik7CisgICAgICAgIHRyeSAoSW5wdXRTdHJlYW0gaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGlucHV0KSkgeworICAgICAgICAgICAgZmluYWwgRGVmbGF0ZUNvbXByZXNzb3JJbnB1dFN0cmVhbSBpbiA9CisgICAgICAgICAgICAgICAgICAgIG5ldyBEZWZsYXRlQ29tcHJlc3NvcklucHV0U3RyZWFtKGlzKTsKKyAgICAgICAgICAgIElPVXRpbHMudG9CeXRlQXJyYXkoaW4pOworICAgICAgICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygtMSwgaW4ucmVhZCgpKTsKKyAgICAgICAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoLTEsIGluLnJlYWQoKSk7CisgICAgICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBtdWx0aUJ5dGVSZWFkQ29uc2lzdGVudGx5UmV0dXJuc01pbnVzT25lQXRFb2YoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlIGlucHV0ID0gQWJzdHJhY3RUZXN0Q2FzZS5nZXRGaWxlKCJibGEudGFyLmRlZmxhdGV6Iik7CisgICAgICAgIGJ5dGVbXSBidWYgPSBuZXcgYnl0ZVsyXTsKKyAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpKSB7CisgICAgICAgICAgICBmaW5hbCBEZWZsYXRlQ29tcHJlc3NvcklucHV0U3RyZWFtIGluID0KKyAgICAgICAgICAgICAgICAgICAgbmV3IERlZmxhdGVDb21wcmVzc29ySW5wdXRTdHJlYW0oaXMpOworICAgICAgICAgICAgSU9VdGlscy50b0J5dGVBcnJheShpbik7CisgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKC0xLCBpbi5yZWFkKGJ1ZikpOworICAgICAgICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygtMSwgaW4ucmVhZChidWYpKTsKKyAgICAgICAgICAgIGluLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2RlZmxhdGUvRGVmbGF0ZUNvbXByZXNzb3JPdXRwdXRTdHJlYW1UZXN0LmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9kZWZsYXRlL0RlZmxhdGVDb21wcmVzc29yT3V0cHV0U3RyZWFtVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVjMTk0MDYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9kZWZsYXRlL0RlZmxhdGVDb21wcmVzc29yT3V0cHV0U3RyZWFtVGVzdC5qYXZhCkBAIC0wLDAgKzEsNDAgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuZGVmbGF0ZTsKKworaW1wb3J0IG9yZy5qdW5pdC5Bc3NlcnQ7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCitwdWJsaWMgY2xhc3MgRGVmbGF0ZUNvbXByZXNzb3JPdXRwdXRTdHJlYW1UZXN0IHsKKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgY2FuUmVhZEFTaW5nbGVCeXRlRmx1c2hBbmRGaW5pc2goKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0cnkgKGZpbmFsIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBib3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgICAgICAgICAgZmluYWwgRGVmbGF0ZUNvbXByZXNzb3JPdXRwdXRTdHJlYW0gY29zID0gbmV3IERlZmxhdGVDb21wcmVzc29yT3V0cHV0U3RyZWFtKGJvcykpIHsKKyAgICAgICAgICAgIGNvcy53cml0ZSg5OSk7CisgICAgICAgICAgICBjb3MuZmx1c2goKTsKKyAgICAgICAgICAgIGNvcy5maW5pc2goKTsKKyAgICAgICAgICAgIEFzc2VydC5hc3NlcnRUcnVlKGJvcy50b0J5dGVBcnJheSgpLmxlbmd0aCA+IDApOworICAgICAgICB9CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9kZWZsYXRlL0RlZmxhdGVQYXJhbWV0ZXJzVGVzdC5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvZGVmbGF0ZS9EZWZsYXRlUGFyYW1ldGVyc1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wYTQzNzk4Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvZGVmbGF0ZS9EZWZsYXRlUGFyYW1ldGVyc1Rlc3QuamF2YQpAQCAtMCwwICsxLDQ0IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLmRlZmxhdGU7CisKK2ltcG9ydCBvcmcuanVuaXQuQXNzZXJ0OworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworCitwdWJsaWMgY2xhc3MgRGVmbGF0ZVBhcmFtZXRlcnNUZXN0IHsKKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgc2hvdWxkQmVBYmxlVG9TZXRDb21wcmVzc2lvbkxldmVsKCkgeworICAgICAgICBmaW5hbCBEZWZsYXRlUGFyYW1ldGVycyBwID0gbmV3IERlZmxhdGVQYXJhbWV0ZXJzKCk7CisgICAgICAgIHAuc2V0Q29tcHJlc3Npb25MZXZlbCg1KTsKKyAgICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyg1LCBwLmdldENvbXByZXNzaW9uTGV2ZWwoKSk7CisgICAgfQorCisgICAgQFRlc3QoZXhwZWN0ZWQgPSBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24uY2xhc3MpCisgICAgcHVibGljIHZvaWQgc2hvdWxkTm90QmVBYmxlVG9TZXRDb21wcmVzc2lvbkxldmVsVG9BTmVnYXRpdmVWYWx1ZSgpIHsKKyAgICAgICAgZmluYWwgRGVmbGF0ZVBhcmFtZXRlcnMgcCA9IG5ldyBEZWZsYXRlUGFyYW1ldGVycygpOworICAgICAgICBwLnNldENvbXByZXNzaW9uTGV2ZWwoLTIpOworICAgIH0KKworICAgIEBUZXN0KGV4cGVjdGVkID0gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLmNsYXNzKQorICAgIHB1YmxpYyB2b2lkIHNob3VsZE5vdEJlQWJsZVRvU2V0Q29tcHJlc3Npb25MZXZlbFRvQURvdWJsZURpZ2l0VmFsdWUoKSB7CisgICAgICAgIGZpbmFsIERlZmxhdGVQYXJhbWV0ZXJzIHAgPSBuZXcgRGVmbGF0ZVBhcmFtZXRlcnMoKTsKKyAgICAgICAgcC5zZXRDb21wcmVzc2lvbkxldmVsKDEyKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9kZWZsYXRlNjQvRGVmbGF0ZTY0QnVnc1Rlc3QuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2RlZmxhdGU2NC9EZWZsYXRlNjRCdWdzVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQyMWYwNTIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9kZWZsYXRlNjQvRGVmbGF0ZTY0QnVnc1Rlc3QuamF2YQpAQCAtMCwwICsxLDQ5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5kZWZsYXRlNjQ7CisKK2ltcG9ydCBzdGF0aWMgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLkFic3RyYWN0VGVzdENhc2UuZ2V0RmlsZTsKKworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXAuWmlwQXJjaGl2ZUVudHJ5OworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuemlwLlppcEZpbGU7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CisKK3B1YmxpYyBjbGFzcyBEZWZsYXRlNjRCdWdzVGVzdCB7CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHJlYWRCZXlvbmRNZW1vcnlFeGNlcHRpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IChaaXBGaWxlIHpmaWxlID0gbmV3IFppcEZpbGUoZ2V0RmlsZSgiQ09NUFJFU1MtMzgwL0NPTVBSRVNTLTM4MC1yZWFkYmV5b25kbWVtb3J5LnppcCIpKSkgeworICAgICAgICAgICAgRW51bWVyYXRpb248WmlwQXJjaGl2ZUVudHJ5PiBlbnRyaWVzID0gemZpbGUuZ2V0RW50cmllcygpOworICAgICAgICAgICAgd2hpbGUgKGVudHJpZXMuaGFzTW9yZUVsZW1lbnRzKCkpIHsKKyAgICAgICAgICAgICAgICBaaXBBcmNoaXZlRW50cnkgZSA9IGVudHJpZXMubmV4dEVsZW1lbnQoKTsKKyAgICAgICAgICAgICAgICBieXRlIFtdIGJ1ZiA9IG5ldyBieXRlIFsxMDI0ICogOF07CisgICAgICAgICAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBpcyA9IHpmaWxlLmdldElucHV0U3RyZWFtKGUpKSB7CisgICAgICAgICAgICAgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpbnQgcmVhZCA9IGlzLnJlYWQoYnVmKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZWFkID09IC0xKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9kZWZsYXRlNjQvRGVmbGF0ZTY0Q29tcHJlc3NvcklucHV0U3RyZWFtVGVzdC5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvZGVmbGF0ZTY0L0RlZmxhdGU2NENvbXByZXNzb3JJbnB1dFN0cmVhbVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MzFhMTRmCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvZGVmbGF0ZTY0L0RlZmxhdGU2NENvbXByZXNzb3JJbnB1dFN0cmVhbVRlc3QuamF2YQpAQCAtMCwwICsxLDE3OSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICoKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuZGVmbGF0ZTY0OworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLkNvbXByZXNzb3JTdHJlYW1GYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5JT1V0aWxzOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXIuUnVuV2l0aDsKK2ltcG9ydCBvcmcubW9ja2l0by5Nb2NrOworaW1wb3J0IG9yZy5tb2NraXRvLk1vY2tpdG87CitpbXBvcnQgb3JnLm1vY2tpdG8ucnVubmVycy5Nb2NraXRvSlVuaXRSdW5uZXI7CisKK2ltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkUmVhZGVyOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtUmVhZGVyOworCitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0RXF1YWxzOworaW1wb3J0IHN0YXRpYyBvcmcubW9ja2l0by5Nb2NraXRvLnRpbWVzOworCitAUnVuV2l0aChNb2NraXRvSlVuaXRSdW5uZXIuY2xhc3MpCitwdWJsaWMgY2xhc3MgRGVmbGF0ZTY0Q29tcHJlc3NvcklucHV0U3RyZWFtVGVzdCB7CisgICAgcHJpdmF0ZSBmaW5hbCBIdWZmbWFuRGVjb2RlciBudWxsRGVjb2RlciA9IG51bGw7CisKKyAgICBATW9jaworICAgIHByaXZhdGUgSHVmZm1hbkRlY29kZXIgZGVjb2RlcjsKKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgcmVhZFdoZW5DbG9zZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgRGVmbGF0ZTY0Q29tcHJlc3NvcklucHV0U3RyZWFtIGlucHV0ID0gbmV3IERlZmxhdGU2NENvbXByZXNzb3JJbnB1dFN0cmVhbShudWxsRGVjb2Rlcik7CisgICAgICAgIGFzc2VydEVxdWFscygtMSwgaW5wdXQucmVhZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBpbnB1dC5yZWFkKG5ldyBieXRlWzFdKSk7CisgICAgICAgIGFzc2VydEVxdWFscygtMSwgaW5wdXQucmVhZChuZXcgYnl0ZVsxXSwgMCwgMSkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgcHJvcGVyU2l6ZVdoZW5DbG9zZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgRGVmbGF0ZTY0Q29tcHJlc3NvcklucHV0U3RyZWFtIGlucHV0ID0gbmV3IERlZmxhdGU2NENvbXByZXNzb3JJbnB1dFN0cmVhbShudWxsRGVjb2Rlcik7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBpbnB1dC5hdmFpbGFibGUoKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBkZWxlZ2F0ZXNBdmFpbGFibGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTW9ja2l0by53aGVuKGRlY29kZXIuYXZhaWxhYmxlKCkpLnRoZW5SZXR1cm4oMTAyNCk7CisKKyAgICAgICAgRGVmbGF0ZTY0Q29tcHJlc3NvcklucHV0U3RyZWFtIGlucHV0ID0gbmV3IERlZmxhdGU2NENvbXByZXNzb3JJbnB1dFN0cmVhbShkZWNvZGVyKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEwMjQsIGlucHV0LmF2YWlsYWJsZSgpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIGNsb3NlQ2FsbHNEZWNvZGVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisKKyAgICAgICAgRGVmbGF0ZTY0Q29tcHJlc3NvcklucHV0U3RyZWFtIGlucHV0ID0gbmV3IERlZmxhdGU2NENvbXByZXNzb3JJbnB1dFN0cmVhbShkZWNvZGVyKTsKKyAgICAgICAgaW5wdXQuY2xvc2UoKTsKKworICAgICAgICBNb2NraXRvLnZlcmlmeShkZWNvZGVyLCB0aW1lcygxKSkuY2xvc2UoKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIGNsb3NlSXNEZWxlZ2F0ZWRKdXN0T25jZSgpIHRocm93cyBFeGNlcHRpb24geworCisgICAgICAgIERlZmxhdGU2NENvbXByZXNzb3JJbnB1dFN0cmVhbSBpbnB1dCA9IG5ldyBEZWZsYXRlNjRDb21wcmVzc29ySW5wdXRTdHJlYW0oZGVjb2Rlcik7CisKKyAgICAgICAgaW5wdXQuY2xvc2UoKTsKKyAgICAgICAgaW5wdXQuY2xvc2UoKTsKKworICAgICAgICBNb2NraXRvLnZlcmlmeShkZWNvZGVyLCB0aW1lcygxKSkuY2xvc2UoKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHVuY29tcHJlc3NlZEJsb2NrKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBkYXRhID0geworICAgICAgICAgICAgMSwgMTEsIDAsIC0xMiwgLTEsCisgICAgICAgICAgICAnSCcsICdlJywgJ2wnLCAnbCcsICdvJywgJyAnLCAnVycsICdvJywgJ3InLCAnbCcsICdkJworICAgICAgICB9OworCisgICAgICAgIHRyeSAoRGVmbGF0ZTY0Q29tcHJlc3NvcklucHV0U3RyZWFtIGlucHV0ID0gbmV3IERlZmxhdGU2NENvbXByZXNzb3JJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oZGF0YSkpOworICAgICAgICAgICAgIEJ1ZmZlcmVkUmVhZGVyIGJyID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKG5ldyBJbnB1dFN0cmVhbVJlYWRlcihpbnB1dCkpKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkhlbGxvIFdvcmxkIiwgYnIucmVhZExpbmUoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgYnIucmVhZExpbmUoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHVuY29tcHJlc3NlZEJsb2NrVmlhRmFjdG9yeSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBieXRlW10gZGF0YSA9IHsKKyAgICAgICAgICAgIDEsIDExLCAwLCAtMTIsIC0xLAorICAgICAgICAgICAgJ0gnLCAnZScsICdsJywgJ2wnLCAnbycsICcgJywgJ1cnLCAnbycsICdyJywgJ2wnLCAnZCcKKyAgICAgICAgfTsKKworICAgICAgICB0cnkgKElucHV0U3RyZWFtIGlucHV0ID0gbmV3IENvbXByZXNzb3JTdHJlYW1GYWN0b3J5KCkKKyAgICAgICAgICAgICAuY3JlYXRlQ29tcHJlc3NvcklucHV0U3RyZWFtKENvbXByZXNzb3JTdHJlYW1GYWN0b3J5LkRFRkxBVEU2NCwgbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGRhdGEpKTsKKyAgICAgICAgICAgICBCdWZmZXJlZFJlYWRlciBiciA9IG5ldyBCdWZmZXJlZFJlYWRlcihuZXcgSW5wdXRTdHJlYW1SZWFkZXIoaW5wdXQpKSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJIZWxsbyBXb3JsZCIsIGJyLnJlYWRMaW5lKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIGJyLnJlYWRMaW5lKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB1bmNvbXByZXNzZWRCbG9ja0F2YWlsYWJsZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBieXRlW10gZGF0YSA9IHsKKyAgICAgICAgICAgIDEsIDExLCAwLCAtMTIsIC0xLAorICAgICAgICAgICAgJ0gnLCAnZScsICdsJywgJ2wnLCAnbycsICcgJywgJ1cnLCAnbycsICdyJywgJ2wnLCAnZCcKKyAgICAgICAgfTsKKworICAgICAgICB0cnkgKERlZmxhdGU2NENvbXByZXNzb3JJbnB1dFN0cmVhbSBpbnB1dCA9IG5ldyBEZWZsYXRlNjRDb21wcmVzc29ySW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGRhdGEpKSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCdIJywgaW5wdXQucmVhZCgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygxMCwgaW5wdXQuYXZhaWxhYmxlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBzdHJlYW1JZ25vcmVzRXh0cmFCeXRlc0FmdGVyRGVmbGF0ZWRJbnB1dCgpIHRocm93cyBFeGNlcHRpb24KKyAgICB7CisgICAgICAgIGJ5dGVbXSBkYXRhID0geworICAgICAgICAgICAgMSwgMTEsIDAsIC0xMiwgLTEsCisgICAgICAgICAgICAnSCcsICdlJywgJ2wnLCAnbCcsICdvJywgJyAnLCAnVycsICdvJywgJ3InLCAnbCcsICdkJywgJ1gnCisgICAgICAgIH07CisKKyAgICAgICAgdHJ5IChEZWZsYXRlNjRDb21wcmVzc29ySW5wdXRTdHJlYW0gaW5wdXQgPSBuZXcgRGVmbGF0ZTY0Q29tcHJlc3NvcklucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShkYXRhKSk7CisgICAgICAgICAgICAgQnVmZmVyZWRSZWFkZXIgYnIgPSBuZXcgQnVmZmVyZWRSZWFkZXIobmV3IElucHV0U3RyZWFtUmVhZGVyKGlucHV0KSkpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSGVsbG8gV29ybGQiLCBici5yZWFkTGluZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBici5yZWFkTGluZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0KGV4cGVjdGVkID0gamF2YS5pby5FT0ZFeGNlcHRpb24uY2xhc3MpCisgICAgcHVibGljIHZvaWQgdGhyb3dzRU9GRXhjZXB0aW9uT25UcnVuY2F0ZWRTdHJlYW1zKCkgdGhyb3dzIEV4Y2VwdGlvbgorICAgIHsKKyAgICAgICAgYnl0ZVtdIGRhdGEgPSB7CisgICAgICAgICAgICAxLCAxMSwgMCwgLTEyLCAtMSwKKyAgICAgICAgICAgICdIJywgJ2UnLCAnbCcsICdsJywgJ28nLCAnICcsICdXJywgJ28nLCAncicsICdsJywKKyAgICAgICAgfTsKKworICAgICAgICB0cnkgKERlZmxhdGU2NENvbXByZXNzb3JJbnB1dFN0cmVhbSBpbnB1dCA9IG5ldyBEZWZsYXRlNjRDb21wcmVzc29ySW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGRhdGEpKTsKKyAgICAgICAgICAgICBCdWZmZXJlZFJlYWRlciBiciA9IG5ldyBCdWZmZXJlZFJlYWRlcihuZXcgSW5wdXRTdHJlYW1SZWFkZXIoaW5wdXQpKSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJIZWxsbyBXb3JsZCIsIGJyLnJlYWRMaW5lKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBzaW5nbGVCeXRlUmVhZENvbnNpc3RlbnRseVJldHVybnNNaW51c09uZUF0RW9mKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSAoZmluYWwgRGVmbGF0ZTY0Q29tcHJlc3NvcklucHV0U3RyZWFtIGluID0KKyAgICAgICAgICAgICAgICAgICAgbmV3IERlZmxhdGU2NENvbXByZXNzb3JJbnB1dFN0cmVhbShudWxsRGVjb2RlcikpIHsKKyAgICAgICAgICAgIElPVXRpbHMudG9CeXRlQXJyYXkoaW4pOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBpbi5yZWFkKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBpbi5yZWFkKCkpOworICAgICAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgbXVsdGlCeXRlUmVhZENvbnNpc3RlbnRseVJldHVybnNNaW51c09uZUF0RW9mKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBidWYgPSBuZXcgYnl0ZVsyXTsKKyAgICAgICAgdHJ5IChmaW5hbCBEZWZsYXRlNjRDb21wcmVzc29ySW5wdXRTdHJlYW0gaW4gPQorICAgICAgICAgICAgICAgICAgICBuZXcgRGVmbGF0ZTY0Q29tcHJlc3NvcklucHV0U3RyZWFtKG51bGxEZWNvZGVyKSkgeworICAgICAgICAgICAgSU9VdGlscy50b0J5dGVBcnJheShpbik7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIGluLnJlYWQoYnVmKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIGluLnJlYWQoYnVmKSk7CisgICAgICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9kZWZsYXRlNjQvSHVmZm1hbkRlY29kZXJUZXN0LmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9kZWZsYXRlNjQvSHVmZm1hbkRlY29kZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTcyNDlmMAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2RlZmxhdGU2NC9IdWZmbWFuRGVjb2RlclRlc3QuamF2YQpAQCAtMCwwICsxLDIyMiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICoKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuZGVmbGF0ZTY0OworCitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CisKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRFcXVhbHM7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuZmFpbDsKKworcHVibGljIGNsYXNzIEh1ZmZtYW5EZWNvZGVyVGVzdCB7CisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBkZWNvZGVVbmNvbXByZXNzZWRCbG9jaygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBieXRlW10gZGF0YSA9IHsKKyAgICAgICAgICAgICAgICAwYjEsIC8vIGVuZCBvZiBibG9jayArIG5vIGNvbXByZXNzaW9uIG1vZGUKKyAgICAgICAgICAgICAgICAxMSwgMCwgLTEyLCAtMSwgLy8gbGVuICYgfmxlbgorICAgICAgICAgICAgICAgICdIJywgJ2UnLCAnbCcsICdsJywgJ28nLCAnICcsICdXJywgJ28nLCAncicsICdsJywgJ2QnCisgICAgICAgIH07CisKKyAgICAgICAgSHVmZm1hbkRlY29kZXIgZGVjb2RlciA9IG5ldyBIdWZmbWFuRGVjb2RlcihuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oZGF0YSkpOworICAgICAgICBieXRlW10gcmVzdWx0ID0gbmV3IGJ5dGVbMTAwXTsKKyAgICAgICAgaW50IGxlbiA9IGRlY29kZXIuZGVjb2RlKHJlc3VsdCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDExLCBsZW4pOworICAgICAgICBhc3NlcnRFcXVhbHMoIkhlbGxvIFdvcmxkIiwgbmV3IFN0cmluZyhyZXN1bHQsIDAsIGxlbikpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgZGVjb2RlVW5jb21wcmVzc2VkQmxvY2tXaXRoSW52YWxpZExlbk5MZW5WYWx1ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBieXRlW10gZGF0YSA9IHsKKyAgICAgICAgICAgICAgICAwYjEsIC8vIGVuZCBvZiBibG9jayArIG5vIGNvbXByZXNzaW9uIG1vZGUKKyAgICAgICAgICAgICAgICAxMSwgMCwgLTEyLCAtMiwgLy8gbGVuICYgfmxlbgorICAgICAgICAgICAgICAgICdIJywgJ2UnLCAnbCcsICdsJywgJ28nLCAnICcsICdXJywgJ28nLCAncicsICdsJywgJ2QnCisgICAgICAgIH07CisKKyAgICAgICAgSHVmZm1hbkRlY29kZXIgZGVjb2RlciA9IG5ldyBIdWZmbWFuRGVjb2RlcihuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oZGF0YSkpOworICAgICAgICBieXRlW10gcmVzdWx0ID0gbmV3IGJ5dGVbMTAwXTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGludCBsZW4gPSBkZWNvZGVyLmRlY29kZShyZXN1bHQpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIGhhdmUgZmFpbGVkIGJ1dCByZXR1cm5lZCAiICsgbGVuICsgIiBlbnRyaWVzOiAiICsgQXJyYXlzLnRvU3RyaW5nKEFycmF5cy5jb3B5T2YocmVzdWx0LCBsZW4pKSk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIklsbGVnYWwgTEVOIC8gTkxFTiB2YWx1ZXMiLCBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIGRlY29kZVNpbXBsZUZpeGVkSHVmZm1hbkJsb2NrKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBkYXRhID0geworICAgICAgICAgICAgICAgIC8vfC0tLSBiaW5hcnkgZmlsbGluZyAtLS18NzY1NDMyMTAKKyAgICAgICAgICAgICAgICAwYjExMTExMTExMTExMTExMTExMTExMTExMTExMTEwMDExLCAvLyBmaW5hbCBibG9jayArIGZpeGVkIGh1ZmZtYW4gKyBICisgICAgICAgICAgICAgICAgMGIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMTAwMTAwMCwgLy8gSCArIGUKKyAgICAgICAgICAgICAgICAwYjExMTExMTExMTExMTExMTExMTExMTExMTExMDAxMTAxLCAvLyBlICsgbAorICAgICAgICAgICAgICAgIDBiMTExMTExMTExMTExMTExMTExMTExMTExMTEwMDEwMDEsIC8vIGwgKyBsCisgICAgICAgICAgICAgICAgMGIxMTExMTExMTExMTExMTExMTExMTExMTExMTAwMTAwMSwgLy8gbCArIG8KKyAgICAgICAgICAgICAgICAwYjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAxMDEwMTExLCAvLyBvICsgJyAnCisgICAgICAgICAgICAgICAgMGIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMTAwMCwgLy8gJyAnICsgVworICAgICAgICAgICAgICAgIDBiMTExMTExMTExMTExMTExMTExMTExMTExMTEwMDExMTEsIC8vIFcgKyBvCisgICAgICAgICAgICAgICAgMGIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDEwMTExMSwgLy8gbyArIHIKKyAgICAgICAgICAgICAgICAwYjExMTExMTExMTExMTExMTExMTExMTExMTExMDAxMDEwLCAvLyByICsgbAorICAgICAgICAgICAgICAgIDBiMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDEwMDEwMDEsIC8vIGwgKyBkCisgICAgICAgICAgICAgICAgMGIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMSwgLy8gZCArIGVuZCBvZiBibG9jaworICAgICAgICAgICAgICAgIDBiMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMDAgLy8gZW5kIG9mIGJsb2NrICgwMCkgKyBnYXJiYWdlCisgICAgICAgIH07CisKKyAgICAgICAgSHVmZm1hbkRlY29kZXIgZGVjb2RlciA9IG5ldyBIdWZmbWFuRGVjb2RlcihuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oZGF0YSkpOworICAgICAgICBieXRlW10gcmVzdWx0ID0gbmV3IGJ5dGVbMTAwXTsKKyAgICAgICAgaW50IGxlbiA9IGRlY29kZXIuZGVjb2RlKHJlc3VsdCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDExLCBsZW4pOworICAgICAgICBhc3NlcnRFcXVhbHMoIkhlbGxvIFdvcmxkIiwgbmV3IFN0cmluZyhyZXN1bHQsIDAsIGxlbikpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgZGVjb2RlU2ltcGxlRml4ZWRIdWZmbWFuQmxvY2tUb1NtYWxsQnVmZmVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBkYXRhID0geworICAgICAgICAgICAgICAgIC8vfC0tLSBiaW5hcnkgZmlsbGluZyAtLS18NzY1NDMyMTAKKyAgICAgICAgICAgICAgICAwYjExMTExMTExMTExMTExMTExMTExMTExMTExMTEwMDExLCAvLyBmaW5hbCBibG9jayArIGZpeGVkIGh1ZmZtYW4gKyBICisgICAgICAgICAgICAgICAgMGIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMTAwMTAwMCwgLy8gSCArIGUKKyAgICAgICAgICAgICAgICAwYjExMTExMTExMTExMTExMTExMTExMTExMTExMDAxMTAxLCAvLyBlICsgbAorICAgICAgICAgICAgICAgIDBiMTExMTExMTExMTExMTExMTExMTExMTExMTEwMDEwMDEsIC8vIGwgKyBsCisgICAgICAgICAgICAgICAgMGIxMTExMTExMTExMTExMTExMTExMTExMTExMTAwMTAwMSwgLy8gbCArIG8KKyAgICAgICAgICAgICAgICAwYjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAxMDEwMTExLCAvLyBvICsgJyAnCisgICAgICAgICAgICAgICAgMGIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMTAwMCwgLy8gJyAnICsgVworICAgICAgICAgICAgICAgIDBiMTExMTExMTExMTExMTExMTExMTExMTExMTEwMDExMTEsIC8vIFcgKyBvCisgICAgICAgICAgICAgICAgMGIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDEwMTExMSwgLy8gbyArIHIKKyAgICAgICAgICAgICAgICAwYjExMTExMTExMTExMTExMTExMTExMTExMTExMDAxMDEwLCAvLyByICsgbAorICAgICAgICAgICAgICAgIDBiMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDEwMDEwMDEsIC8vIGwgKyBkCisgICAgICAgICAgICAgICAgMGIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMSwgLy8gZCArIGVuZCBvZiBibG9jaworICAgICAgICAgICAgICAgIDBiMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMDAgLy8gZW5kIG9mIGJsb2NrICgwMCkgKyBnYXJiYWdlCisgICAgICAgIH07CisKKyAgICAgICAgSHVmZm1hbkRlY29kZXIgZGVjb2RlciA9IG5ldyBIdWZmbWFuRGVjb2RlcihuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oZGF0YSkpOworICAgICAgICBieXRlW10gcmVzdWx0ID0gbmV3IGJ5dGVbMTBdOworICAgICAgICBpbnQgbGVuOworICAgICAgICBsZW4gPSBkZWNvZGVyLmRlY29kZShyZXN1bHQpOworICAgICAgICBhc3NlcnRFcXVhbHMoMTAsIGxlbik7CisgICAgICAgIGFzc2VydEVxdWFscygiSGVsbG8gV29ybCIsIG5ldyBTdHJpbmcocmVzdWx0LCAwLCBsZW4pKTsKKyAgICAgICAgbGVuID0gZGVjb2Rlci5kZWNvZGUocmVzdWx0KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGxlbik7CisgICAgICAgIGFzc2VydEVxdWFscygiZCIsIG5ldyBTdHJpbmcocmVzdWx0LCAwLCBsZW4pKTsKKyAgICB9CisKKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgZGVjb2RlRml4ZWRIdWZmbWFuQmxvY2tXaXRoTWVtb3J5TG9va3VwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBkYXRhID0geworICAgICAgICAgICAgICAgIC8vfC0tLSBiaW5hcnkgZmlsbGluZyAtLS18NzY1NDMyMTAKKyAgICAgICAgICAgICAgICAwYjExMTExMTExMTExMTExMTExMTExMTExMTExMTEwMDExLCAvLyBmaW5hbCBibG9jayArIGZpeGVkIGh1ZmZtYW4gKyBICisgICAgICAgICAgICAgICAgMGIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMTAwMTAwMCwgLy8gSCArIGUKKyAgICAgICAgICAgICAgICAwYjExMTExMTExMTExMTExMTExMTExMTExMTExMDAxMTAxLCAvLyBlICsgbAorICAgICAgICAgICAgICAgIDBiMTExMTExMTExMTExMTExMTExMTExMTExMTEwMDEwMDEsIC8vIGwgKyBsCisgICAgICAgICAgICAgICAgMGIxMTExMTExMTExMTExMTExMTExMTExMTExMTAwMTAwMSwgLy8gbCArIG8KKyAgICAgICAgICAgICAgICAwYjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAxMDEwMTExLCAvLyBvICsgJyAnCisgICAgICAgICAgICAgICAgMGIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMTAwMCwgLy8gJyAnICsgVworICAgICAgICAgICAgICAgIDBiMTExMTExMTExMTExMTExMTExMTExMTExMTEwMDExMTEsIC8vIFcgKyBvCisgICAgICAgICAgICAgICAgMGIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDEwMTExMSwgLy8gbyArIHIKKyAgICAgICAgICAgICAgICAwYjExMTExMTExMTExMTExMTExMTExMTExMTExMDAxMDEwLCAvLyByICsgbAorICAgICAgICAgICAgICAgIDBiMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDEwMDEwMDEsIC8vIGwgKyBkCisgICAgICAgICAgICAgICAgMGIxMTExMTExMTExMTExMTExMTExMTExMTExMTEwMDAwMSwgLy8gZCArICdcbicKKyAgICAgICAgICAgICAgICAwYjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMTAwMDEwLCAvLyAnXG4nICsgPGxlbj4KKyAgICAgICAgICAgICAgICAwYjExMTExMTExMTExMTExMTExMTExMTExMTEwMDAwMTEwLCAvLyA8bGVuPiArIG9mZnNldCA8MDAxPiArIGRpc3Q2CisgICAgICAgICAgICAgICAgMGIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMTEwMSwgLy8gZGlzdDYgKyBvZmZzZXQgPDExPiArIGVuZCBvZiBibG9jayAoMDAwMDAwKQorICAgICAgICAgICAgICAgIDBiMTExMTExMTExMTExMTExMTExMTExMTExMTExMTEwMDAgLy8gZW5kIG9mIGJsb2NrICgwMDAwKSArIGdhcmJhZ2UKKyAgICAgICAgfTsKKworICAgICAgICBIdWZmbWFuRGVjb2RlciBkZWNvZGVyID0gbmV3IEh1ZmZtYW5EZWNvZGVyKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShkYXRhKSk7CisgICAgICAgIGJ5dGVbXSByZXN1bHQgPSBuZXcgYnl0ZVsxMDBdOworICAgICAgICBpbnQgbGVuID0gZGVjb2Rlci5kZWNvZGUocmVzdWx0KTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoNDgsIGxlbik7CisgICAgICAgIGFzc2VydEVxdWFscygiSGVsbG8gV29ybGRcbkhlbGxvIFdvcmxkXG5IZWxsbyBXb3JsZFxuSGVsbG8gV29ybGRcbiIsIG5ldyBTdHJpbmcocmVzdWx0LCAwLCBsZW4pKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIGRlY29kZUZpeGVkSHVmZm1hbkJsb2NrV2l0aE1lbW9yeUxvb2t1cEluU21hbGxCdWZmZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGRhdGEgPSB7CisgICAgICAgICAgICAgICAgLy98LS0tIGJpbmFyeSBmaWxsaW5nIC0tLXw3NjU0MzIxMAorICAgICAgICAgICAgICAgIDBiMTExMTExMTExMTExMTExMTExMTExMTExMTExMTAwMTEsIC8vIGZpbmFsIGJsb2NrICsgZml4ZWQgaHVmZm1hbiArIEgKKyAgICAgICAgICAgICAgICAwYjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAxMDAxMDAwLCAvLyBIICsgZQorICAgICAgICAgICAgICAgIDBiMTExMTExMTExMTExMTExMTExMTExMTExMTEwMDExMDEsIC8vIGUgKyBsCisgICAgICAgICAgICAgICAgMGIxMTExMTExMTExMTExMTExMTExMTExMTExMTAwMTAwMSwgLy8gbCArIGwKKyAgICAgICAgICAgICAgICAwYjExMTExMTExMTExMTExMTExMTExMTExMTExMDAxMDAxLCAvLyBsICsgbworICAgICAgICAgICAgICAgIDBiMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDEwMTAxMTEsIC8vIG8gKyAnICcKKyAgICAgICAgICAgICAgICAwYjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAxMDAwLCAvLyAnICcgKyBXCisgICAgICAgICAgICAgICAgMGIxMTExMTExMTExMTExMTExMTExMTExMTExMTAwMTExMSwgLy8gVyArIG8KKyAgICAgICAgICAgICAgICAwYjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMTAxMTExLCAvLyBvICsgcgorICAgICAgICAgICAgICAgIDBiMTExMTExMTExMTExMTExMTExMTExMTExMTEwMDEwMTAsIC8vIHIgKyBsCisgICAgICAgICAgICAgICAgMGIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMTAwMTAwMSwgLy8gbCArIGQKKyAgICAgICAgICAgICAgICAwYjExMTExMTExMTExMTExMTExMTExMTExMTExMTAwMDAxLCAvLyBkICsgJ1xuJworICAgICAgICAgICAgICAgIDBiMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAxMDAwMTAsIC8vICdcbicgKyA8bGVuPgorICAgICAgICAgICAgICAgIDBiMTExMTExMTExMTExMTExMTExMTExMTExMTAwMDAxMTAsIC8vIDxsZW4+ICsgb2Zmc2V0IDwwMDE+ICsgZGlzdDYKKyAgICAgICAgICAgICAgICAwYjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAxMTAxLCAvLyBkaXN0NiArIG9mZnNldCA8MTE+ICsgZW5kIG9mIGJsb2NrICgwMDAwMDApCisgICAgICAgICAgICAgICAgMGIxMTExMTExMTExMTExMTExMTExMTExMTExMTExMTAwMCAvLyBlbmQgb2YgYmxvY2sgKDAwMDApICsgZ2FyYmFnZQorICAgICAgICB9OworCisgICAgICAgIEh1ZmZtYW5EZWNvZGVyIGRlY29kZXIgPSBuZXcgSHVmZm1hbkRlY29kZXIobmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGRhdGEpKTsKKyAgICAgICAgYnl0ZVtdIHJlc3VsdCA9IG5ldyBieXRlWzMwXTsKKyAgICAgICAgaW50IGxlbjsKKworICAgICAgICBsZW4gPSBkZWNvZGVyLmRlY29kZShyZXN1bHQpOworICAgICAgICBhc3NlcnRFcXVhbHMoMzAsIGxlbik7CisgICAgICAgIGFzc2VydEVxdWFscygiSGVsbG8gV29ybGRcbkhlbGxvIFdvcmxkXG5IZWxsbyAiLCBuZXcgU3RyaW5nKHJlc3VsdCwgMCwgbGVuKSk7CisKKyAgICAgICAgbGVuID0gZGVjb2Rlci5kZWNvZGUocmVzdWx0KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDE4LCBsZW4pOworICAgICAgICBhc3NlcnRFcXVhbHMoIldvcmxkXG5IZWxsbyBXb3JsZFxuIiwgbmV3IFN0cmluZyhyZXN1bHQsIDAsIGxlbikpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgZGVjb2RlRml4ZWRIdWZmbWFuQmxvY2tXaXRoTWVtb3J5TG9va3VwSW5FeGFjdEJ1ZmZlcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBieXRlW10gZGF0YSA9IHsKKyAgICAgICAgICAgICAgICAvL3wtLS0gYmluYXJ5IGZpbGxpbmcgLS0tfDc2NTQzMjEwCisgICAgICAgICAgICAgICAgMGIxMTExMTExMTExMTExMTExMTExMTExMTExMTExMDAxMSwgLy8gZmluYWwgYmxvY2sgKyBmaXhlZCBodWZmbWFuICsgSAorICAgICAgICAgICAgICAgIDBiMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDEwMDEwMDAsIC8vIEggKyBlCisgICAgICAgICAgICAgICAgMGIxMTExMTExMTExMTExMTExMTExMTExMTExMTAwMTEwMSwgLy8gZSArIGwKKyAgICAgICAgICAgICAgICAwYjExMTExMTExMTExMTExMTExMTExMTExMTExMDAxMDAxLCAvLyBsICsgbAorICAgICAgICAgICAgICAgIDBiMTExMTExMTExMTExMTExMTExMTExMTExMTEwMDEwMDEsIC8vIGwgKyBvCisgICAgICAgICAgICAgICAgMGIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMTAxMDExMSwgLy8gbyArICcgJworICAgICAgICAgICAgICAgIDBiMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDEwMDAsIC8vICcgJyArIFcKKyAgICAgICAgICAgICAgICAwYjExMTExMTExMTExMTExMTExMTExMTExMTExMDAxMTExLCAvLyBXICsgbworICAgICAgICAgICAgICAgIDBiMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAxMDExMTEsIC8vIG8gKyByCisgICAgICAgICAgICAgICAgMGIxMTExMTExMTExMTExMTExMTExMTExMTExMTAwMTAxMCwgLy8gciArIGwKKyAgICAgICAgICAgICAgICAwYjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAxMDAxMDAxLCAvLyBsICsgZAorICAgICAgICAgICAgICAgIDBiMTExMTExMTExMTExMTExMTExMTExMTExMTExMDAwMDEsIC8vIGQgKyAnXG4nCisgICAgICAgICAgICAgICAgMGIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDEwMDAxMCwgLy8gJ1xuJyArIDxsZW4+CisgICAgICAgICAgICAgICAgMGIxMTExMTExMTExMTExMTExMTExMTExMTExMDAwMDExMCwgLy8gPGxlbj4gKyBvZmZzZXQgPDAwMT4gKyBkaXN0NgorICAgICAgICAgICAgICAgIDBiMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDExMDEsIC8vIGRpc3Q2ICsgb2Zmc2V0IDwxMT4gKyBlbmQgb2YgYmxvY2sgKDAwMDAwMCkKKyAgICAgICAgICAgICAgICAwYjExMTExMTExMTExMTExMTExMTExMTExMTExMTExMDAwIC8vIGVuZCBvZiBibG9jayAoMDAwMCkgKyBnYXJiYWdlCisgICAgICAgIH07CisKKyAgICAgICAgSHVmZm1hbkRlY29kZXIgZGVjb2RlciA9IG5ldyBIdWZmbWFuRGVjb2RlcihuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oZGF0YSkpOworICAgICAgICBieXRlW10gcmVzdWx0ID0gbmV3IGJ5dGVbNDhdOworICAgICAgICBpbnQgbGVuOworCisgICAgICAgIGxlbiA9IGRlY29kZXIuZGVjb2RlKHJlc3VsdCk7CisgICAgICAgIGFzc2VydEVxdWFscyg0OCwgbGVuKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJIZWxsbyBXb3JsZFxuSGVsbG8gV29ybGRcbkhlbGxvIFdvcmxkXG5IZWxsbyBXb3JsZFxuIiwgbmV3IFN0cmluZyhyZXN1bHQsIDAsIGxlbikpOworCisgICAgICAgIGxlbiA9IGRlY29kZXIuZGVjb2RlKHJlc3VsdCk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBsZW4pOworCisgICAgICAgIGxlbiA9IGRlY29kZXIuZGVjb2RlKHJlc3VsdCk7CisgICAgICAgIGFzc2VydEVxdWFscygtMSwgbGVuKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9sejQvQmxvY2tMWjRDb21wcmVzc29ySW5wdXRTdHJlYW1UZXN0LmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9sejQvQmxvY2tMWjRDb21wcmVzc29ySW5wdXRTdHJlYW1UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTMzMzFkZAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2x6NC9CbG9ja0xaNENvbXByZXNzb3JJbnB1dFN0cmVhbVRlc3QuamF2YQpAQCAtMCwwICsxLDY4IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLmx6NDsKKworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLkFic3RyYWN0VGVzdENhc2U7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLklPVXRpbHM7CitpbXBvcnQgb3JnLmp1bml0LkFzc2VydDsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworcHVibGljIGNsYXNzIEJsb2NrTFo0Q29tcHJlc3NvcklucHV0U3RyZWFtVGVzdCBleHRlbmRzIEFic3RyYWN0VGVzdENhc2UgeworCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCByZWFkQmxhTHo0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBhID0gbmV3IEJsb2NrTFo0Q29tcHJlc3NvcklucHV0U3RyZWFtKG5ldyBGaWxlSW5wdXRTdHJlYW0oZ2V0RmlsZSgiYmxhLnRhci5ibG9ja19sejQiKSkpOworICAgICAgICAgICAgRmlsZUlucHV0U3RyZWFtIGUgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGdldEZpbGUoImJsYS50YXIiKSkpIHsKKyAgICAgICAgICAgIGJ5dGVbXSBleHBlY3RlZCA9IElPVXRpbHMudG9CeXRlQXJyYXkoZSk7CisgICAgICAgICAgICBieXRlW10gYWN0dWFsID0gSU9VdGlscy50b0J5dGVBcnJheShhKTsKKyAgICAgICAgICAgIEFzc2VydC5hc3NlcnRBcnJheUVxdWFscyhleHBlY3RlZCwgYWN0dWFsKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgc2luZ2xlQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGUgaW5wdXQgPSBnZXRGaWxlKCJibGEudGFyLmJsb2NrX2x6NCIpOworICAgICAgICB0cnkgKElucHV0U3RyZWFtIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShpbnB1dCkpIHsKKyAgICAgICAgICAgIGZpbmFsIEJsb2NrTFo0Q29tcHJlc3NvcklucHV0U3RyZWFtIGluID0KKyAgICAgICAgICAgICAgICAgICAgbmV3IEJsb2NrTFo0Q29tcHJlc3NvcklucHV0U3RyZWFtKGlzKTsKKyAgICAgICAgICAgIElPVXRpbHMudG9CeXRlQXJyYXkoaW4pOworICAgICAgICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygtMSwgaW4ucmVhZCgpKTsKKyAgICAgICAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoLTEsIGluLnJlYWQoKSk7CisgICAgICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBtdWx0aUJ5dGVSZWFkQ29uc2lzdGVudGx5UmV0dXJuc01pbnVzT25lQXRFb2YoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlIGlucHV0ID0gZ2V0RmlsZSgiYmxhLnRhci5ibG9ja19sejQiKTsKKyAgICAgICAgYnl0ZVtdIGJ1ZiA9IG5ldyBieXRlWzJdOworICAgICAgICB0cnkgKElucHV0U3RyZWFtIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShpbnB1dCkpIHsKKyAgICAgICAgICAgIGZpbmFsIEJsb2NrTFo0Q29tcHJlc3NvcklucHV0U3RyZWFtIGluID0KKyAgICAgICAgICAgICAgICAgICAgbmV3IEJsb2NrTFo0Q29tcHJlc3NvcklucHV0U3RyZWFtKGlzKTsKKyAgICAgICAgICAgIElPVXRpbHMudG9CeXRlQXJyYXkoaW4pOworICAgICAgICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygtMSwgaW4ucmVhZChidWYpKTsKKyAgICAgICAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoLTEsIGluLnJlYWQoYnVmKSk7CisgICAgICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvbHo0L0Jsb2NrTFo0Q29tcHJlc3Nvck91dHB1dFN0cmVhbVRlc3QuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2x6NC9CbG9ja0xaNENvbXByZXNzb3JPdXRwdXRTdHJlYW1UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmNhM2Y4OAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2x6NC9CbG9ja0xaNENvbXByZXNzb3JPdXRwdXRTdHJlYW1UZXN0LmphdmEKQEAgLTAsMCArMSwzNzQgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMubHo0OworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLmx6NzdzdXBwb3J0LkxaNzdDb21wcmVzc29yOworaW1wb3J0IG9yZy5qdW5pdC5Bc3NlcnQ7CitpbXBvcnQgb3JnLmp1bml0Lklnbm9yZTsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworcHVibGljIGNsYXNzIEJsb2NrTFo0Q29tcHJlc3Nvck91dHB1dFN0cmVhbVRlc3QgeworCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBwYWlyU2Vlc0JhY2tSZWZlcmVuY2VXaGVuU2V0KCkgeworICAgICAgICBCbG9ja0xaNENvbXByZXNzb3JPdXRwdXRTdHJlYW0uUGFpciBwID0gbmV3IEJsb2NrTFo0Q29tcHJlc3Nvck91dHB1dFN0cmVhbS5QYWlyKCk7CisgICAgICAgIEFzc2VydC5hc3NlcnRGYWxzZShwLmhhc0JhY2tSZWZlcmVuY2UoKSk7CisgICAgICAgIHAuc2V0QmFja1JlZmVyZW5jZShuZXcgTFo3N0NvbXByZXNzb3IuQmFja1JlZmVyZW5jZSgxLCA0KSk7CisgICAgICAgIEFzc2VydC5hc3NlcnRUcnVlKHAuaGFzQmFja1JlZmVyZW5jZSgpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIGNhbldyaXRlQmFja1JlZmVyZW5jZUZvbGxvd2VkQnlMb25nTGl0ZXJhbCgpIHsKKyAgICAgICAgQmxvY2tMWjRDb21wcmVzc29yT3V0cHV0U3RyZWFtLlBhaXIgcCA9IG5ldyBCbG9ja0xaNENvbXByZXNzb3JPdXRwdXRTdHJlYW0uUGFpcigpOworICAgICAgICBwLnNldEJhY2tSZWZlcmVuY2UobmV3IExaNzdDb21wcmVzc29yLkJhY2tSZWZlcmVuY2UoMSwgNCkpOworICAgICAgICAvLyBhIGxlbmd0aCBvZiAxMSB3b3VsZCBiZSBlbm91Z2ggYWNjb3JkaW5nIHRvIHRoZSBzcGVjLCBidXQKKyAgICAgICAgLy8gdGhlIGFsZ29yaXRobSB3ZSB1c2UgZm9yIHJld3JpdGluZyB0aGUgbGFzdCBibG9jayByZXF1aXJlcworICAgICAgICAvLyAxNiBieXRlcworICAgICAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShwLmNhbkJlV3JpdHRlbigxNikpOworICAgIH0KKworICAgIEBUZXN0CisgICAgQElnbm9yZSgid291bGQgcGFzcyBpZiB0aGUgYWxnb3JpdGhtIHVzZWQgZm9yIHJld3JpdGluZyB0aGUgZmluYWwgcGFpcnMgd2FzIHNtYXJ0ZXIiKQorICAgIHB1YmxpYyB2b2lkIGNhbldyaXRlQmFja1JlZmVyZW5jZUZvbGxvd2VkQnlTaG9ydExpdGVyYWxJZk9mZnNldElzQmlnRW5vdWdoKCkgeworICAgICAgICBCbG9ja0xaNENvbXByZXNzb3JPdXRwdXRTdHJlYW0uUGFpciBwID0gbmV3IEJsb2NrTFo0Q29tcHJlc3Nvck91dHB1dFN0cmVhbS5QYWlyKCk7CisgICAgICAgIHAuc2V0QmFja1JlZmVyZW5jZShuZXcgTFo3N0NvbXByZXNzb3IuQmFja1JlZmVyZW5jZSgxMCwgNCkpOworICAgICAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShwLmNhbkJlV3JpdHRlbig1KSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBASWdub3JlKCJ3b3VsZCBwYXNzIGlmIHRoZSBhbGdvcml0aG0gdXNlZCBmb3IgcmV3cml0aW5nIHRoZSBmaW5hbCBwYWlycyB3YXMgc21hcnRlciIpCisgICAgcHVibGljIHZvaWQgY2FuV3JpdGVCYWNrUmVmZXJlbmNlRm9sbG93ZWRCeVNob3J0TGl0ZXJhbElmTGVuZ3RoSXNCaWdFbm91Z2goKSB7CisgICAgICAgIEJsb2NrTFo0Q29tcHJlc3Nvck91dHB1dFN0cmVhbS5QYWlyIHAgPSBuZXcgQmxvY2tMWjRDb21wcmVzc29yT3V0cHV0U3RyZWFtLlBhaXIoKTsKKyAgICAgICAgcC5zZXRCYWNrUmVmZXJlbmNlKG5ldyBMWjc3Q29tcHJlc3Nvci5CYWNrUmVmZXJlbmNlKDEsIDEwKSk7CisgICAgICAgIEFzc2VydC5hc3NlcnRUcnVlKHAuY2FuQmVXcml0dGVuKDUpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIGNhbnRXcml0ZUJhY2tSZWZlcmVuY2VGb2xsb3dlZEJ5TGl0ZXJhbFRoYXRJc1Rvb1Nob3J0KCkgeworICAgICAgICBCbG9ja0xaNENvbXByZXNzb3JPdXRwdXRTdHJlYW0uUGFpciBwID0gbmV3IEJsb2NrTFo0Q29tcHJlc3Nvck91dHB1dFN0cmVhbS5QYWlyKCk7CisgICAgICAgIHAuc2V0QmFja1JlZmVyZW5jZShuZXcgTFo3N0NvbXByZXNzb3IuQmFja1JlZmVyZW5jZSgxMCwgMTQpKTsKKyAgICAgICAgQXNzZXJ0LmFzc2VydEZhbHNlKHAuY2FuQmVXcml0dGVuKDQpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIGNhbnRXcml0ZUJhY2tSZWZlcmVuY2VJZkFjY3VtdWxhdGVkT2Zmc2V0SXNUb29TaG9ydCgpIHsKKyAgICAgICAgQmxvY2tMWjRDb21wcmVzc29yT3V0cHV0U3RyZWFtLlBhaXIgcCA9IG5ldyBCbG9ja0xaNENvbXByZXNzb3JPdXRwdXRTdHJlYW0uUGFpcigpOworICAgICAgICBwLnNldEJhY2tSZWZlcmVuY2UobmV3IExaNzdDb21wcmVzc29yLkJhY2tSZWZlcmVuY2UoMSwgNCkpOworICAgICAgICBBc3NlcnQuYXNzZXJ0RmFsc2UocC5jYW5CZVdyaXR0ZW4oNSkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgcGFpckFjY3VtdWxhdGVzTGVuZ3RocygpIHsKKyAgICAgICAgQmxvY2tMWjRDb21wcmVzc29yT3V0cHV0U3RyZWFtLlBhaXIgcCA9IG5ldyBCbG9ja0xaNENvbXByZXNzb3JPdXRwdXRTdHJlYW0uUGFpcigpOworICAgICAgICBwLnNldEJhY2tSZWZlcmVuY2UobmV3IExaNzdDb21wcmVzc29yLkJhY2tSZWZlcmVuY2UoMSwgNCkpOworICAgICAgICBieXRlW10gYiA9IG5ldyBieXRlW10geyAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5IH07CisgICAgICAgIHAuYWRkTGl0ZXJhbChuZXcgTFo3N0NvbXByZXNzb3IuTGl0ZXJhbEJsb2NrKGIsIDEsIDQpKTsKKyAgICAgICAgcC5hZGRMaXRlcmFsKG5ldyBMWjc3Q29tcHJlc3Nvci5MaXRlcmFsQmxvY2soYiwgMiwgNSkpOworICAgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDEzLCBwLmxlbmd0aCgpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIGNhbldyaXRlUGFpcldpdGhvdXRMaXRlcmFscygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEJsb2NrTFo0Q29tcHJlc3Nvck91dHB1dFN0cmVhbS5QYWlyIHAgPSBuZXcgQmxvY2tMWjRDb21wcmVzc29yT3V0cHV0U3RyZWFtLlBhaXIoKTsKKyAgICAgICAgcC5zZXRCYWNrUmVmZXJlbmNlKG5ldyBMWjc3Q29tcHJlc3Nvci5CYWNrUmVmZXJlbmNlKDEsIDQpKTsKKyAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgcC53cml0ZVRvKGJvcyk7CisgICAgICAgIEFzc2VydC5hc3NlcnRBcnJheUVxdWFscyhuZXcgYnl0ZVtdIHsgMCwgMSwgMCB9LCBib3MudG9CeXRlQXJyYXkoKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB3cml0ZXNDb3JyZWN0U2l6ZUZvcjE5Qnl0ZUxlbmd0aEJhY2tSZWZlcmVuY2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBCbG9ja0xaNENvbXByZXNzb3JPdXRwdXRTdHJlYW0uUGFpciBwID0gbmV3IEJsb2NrTFo0Q29tcHJlc3Nvck91dHB1dFN0cmVhbS5QYWlyKCk7CisgICAgICAgIHAuc2V0QmFja1JlZmVyZW5jZShuZXcgTFo3N0NvbXByZXNzb3IuQmFja1JlZmVyZW5jZSgxLCAxOSkpOworICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICBwLndyaXRlVG8oYm9zKTsKKyAgICAgICAgQXNzZXJ0LmFzc2VydEFycmF5RXF1YWxzKG5ldyBieXRlW10geyAxNSwgMSwgMCwgMCB9LCBib3MudG9CeXRlQXJyYXkoKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB3cml0ZXNDb3JyZWN0U2l6ZUZvcjI3M0J5dGVMZW5ndGhCYWNrUmVmZXJlbmNlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgQmxvY2tMWjRDb21wcmVzc29yT3V0cHV0U3RyZWFtLlBhaXIgcCA9IG5ldyBCbG9ja0xaNENvbXByZXNzb3JPdXRwdXRTdHJlYW0uUGFpcigpOworICAgICAgICBwLnNldEJhY2tSZWZlcmVuY2UobmV3IExaNzdDb21wcmVzc29yLkJhY2tSZWZlcmVuY2UoMSwgMjczKSk7CisgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBib3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIHAud3JpdGVUbyhib3MpOworICAgICAgICBBc3NlcnQuYXNzZXJ0QXJyYXlFcXVhbHMobmV3IGJ5dGVbXSB7IDE1LCAxLCAwLCAoYnl0ZSkgMjU0IH0sIGJvcy50b0J5dGVBcnJheSgpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHdyaXRlc0NvcnJlY3RTaXplRm9yMjc0Qnl0ZUxlbmd0aEJhY2tSZWZlcmVuY2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBCbG9ja0xaNENvbXByZXNzb3JPdXRwdXRTdHJlYW0uUGFpciBwID0gbmV3IEJsb2NrTFo0Q29tcHJlc3Nvck91dHB1dFN0cmVhbS5QYWlyKCk7CisgICAgICAgIHAuc2V0QmFja1JlZmVyZW5jZShuZXcgTFo3N0NvbXByZXNzb3IuQmFja1JlZmVyZW5jZSgxLCAyNzQpKTsKKyAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgcC53cml0ZVRvKGJvcyk7CisgICAgICAgIEFzc2VydC5hc3NlcnRBcnJheUVxdWFscyhuZXcgYnl0ZVtdIHsgMTUsIDEsIDAsIChieXRlKSAyNTUsIDAgfSwgYm9zLnRvQnl0ZUFycmF5KCkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgY2FuV3JpdGVQYWlyV2l0aG91dEJhY2tSZWZlcmVuY2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBCbG9ja0xaNENvbXByZXNzb3JPdXRwdXRTdHJlYW0uUGFpciBwID0gbmV3IEJsb2NrTFo0Q29tcHJlc3Nvck91dHB1dFN0cmVhbS5QYWlyKCk7CisgICAgICAgIGJ5dGVbXSBiID0gbmV3IGJ5dGVbXSB7IDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDkgfTsKKyAgICAgICAgcC5hZGRMaXRlcmFsKG5ldyBMWjc3Q29tcHJlc3Nvci5MaXRlcmFsQmxvY2soYiwgMSwgNCkpOworICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICBwLndyaXRlVG8oYm9zKTsKKyAgICAgICAgQXNzZXJ0LmFzc2VydEFycmF5RXF1YWxzKG5ldyBieXRlW10geyA0PDw0LCAyLCAzLCA0LCA1IH0sIGJvcy50b0J5dGVBcnJheSgpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHdyaXRlc0NvcnJlY3RTaXplRm9yMTVCeXRlTGVuZ3RoTGl0ZXJhbCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEJsb2NrTFo0Q29tcHJlc3Nvck91dHB1dFN0cmVhbS5QYWlyIHAgPSBuZXcgQmxvY2tMWjRDb21wcmVzc29yT3V0cHV0U3RyZWFtLlBhaXIoKTsKKyAgICAgICAgYnl0ZVtdIGIgPSBuZXcgYnl0ZVtdIHsgMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSB9OworICAgICAgICBwLmFkZExpdGVyYWwobmV3IExaNzdDb21wcmVzc29yLkxpdGVyYWxCbG9jayhiLCAwLCA5KSk7CisgICAgICAgIHAuYWRkTGl0ZXJhbChuZXcgTFo3N0NvbXByZXNzb3IuTGl0ZXJhbEJsb2NrKGIsIDAsIDYpKTsKKyAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgcC53cml0ZVRvKGJvcyk7CisgICAgICAgIEFzc2VydC5hc3NlcnRBcnJheUVxdWFscyhuZXcgYnl0ZVtdIHsgKGJ5dGUpICgxNTw8NCksIDAsIDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEsIDIsIDMsIDQsIDUsIDYgfSwKKyAgICAgICAgICAgIGJvcy50b0J5dGVBcnJheSgpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHdyaXRlc0NvcnJlY3RTaXplRm9yMjY5Qnl0ZUxlbmd0aExpdGVyYWwoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBCbG9ja0xaNENvbXByZXNzb3JPdXRwdXRTdHJlYW0uUGFpciBwID0gbmV3IEJsb2NrTFo0Q29tcHJlc3Nvck91dHB1dFN0cmVhbS5QYWlyKCk7CisgICAgICAgIGJ5dGVbXSBiID0gbmV3IGJ5dGVbXSB7IDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwIH07CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMjY7IGkrKykgeworICAgICAgICAgICAgcC5hZGRMaXRlcmFsKG5ldyBMWjc3Q29tcHJlc3Nvci5MaXRlcmFsQmxvY2soYiwgMCwgMTApKTsKKyAgICAgICAgfQorICAgICAgICBwLmFkZExpdGVyYWwobmV3IExaNzdDb21wcmVzc29yLkxpdGVyYWxCbG9jayhiLCAwLCA5KSk7CisgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBib3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIHAud3JpdGVUbyhib3MpOworICAgICAgICBBc3NlcnQuYXNzZXJ0QXJyYXlFcXVhbHMobmV3IGJ5dGVbXSB7IChieXRlKSAoMTU8PDQpLCAoYnl0ZSkgMjU0LCAxIH0sCisgICAgICAgICAgICBBcnJheXMuY29weU9mUmFuZ2UoYm9zLnRvQnl0ZUFycmF5KCksIDAsIDMpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHdyaXRlc0NvcnJlY3RTaXplRm9yMjcwQnl0ZUxlbmd0aExpdGVyYWwoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBCbG9ja0xaNENvbXByZXNzb3JPdXRwdXRTdHJlYW0uUGFpciBwID0gbmV3IEJsb2NrTFo0Q29tcHJlc3Nvck91dHB1dFN0cmVhbS5QYWlyKCk7CisgICAgICAgIGJ5dGVbXSBiID0gbmV3IGJ5dGVbXSB7IDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwIH07CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMjc7IGkrKykgeworICAgICAgICAgICAgcC5hZGRMaXRlcmFsKG5ldyBMWjc3Q29tcHJlc3Nvci5MaXRlcmFsQmxvY2soYiwgMCwgMTApKTsKKyAgICAgICAgfQorICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICBwLndyaXRlVG8oYm9zKTsKKyAgICAgICAgQXNzZXJ0LmFzc2VydEFycmF5RXF1YWxzKG5ldyBieXRlW10geyAoYnl0ZSkgKDE1PDw0KSwgKGJ5dGUpIDI1NSwgMCwgMSB9LAorICAgICAgICAgICAgQXJyYXlzLmNvcHlPZlJhbmdlKGJvcy50b0J5dGVBcnJheSgpLCAwLCA0KSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB3cml0ZXNDb21wbGV0ZVBhaXIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBCbG9ja0xaNENvbXByZXNzb3JPdXRwdXRTdHJlYW0uUGFpciBwID0gbmV3IEJsb2NrTFo0Q29tcHJlc3Nvck91dHB1dFN0cmVhbS5QYWlyKCk7CisgICAgICAgIGJ5dGVbXSBiID0gbmV3IGJ5dGVbXSB7IDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDkgfTsKKyAgICAgICAgcC5hZGRMaXRlcmFsKG5ldyBMWjc3Q29tcHJlc3Nvci5MaXRlcmFsQmxvY2soYiwgMSwgNCkpOworICAgICAgICBiWzJdID0gMTk7CisgICAgICAgIHAuc2V0QmFja1JlZmVyZW5jZShuZXcgTFo3N0NvbXByZXNzb3IuQmFja1JlZmVyZW5jZSgxLCA1KSk7CisgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBib3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIHAud3JpdGVUbyhib3MpOworICAgICAgICBBc3NlcnQuYXNzZXJ0QXJyYXlFcXVhbHMobmV3IGJ5dGVbXSB7ICg0PDw0KSArIDEsIDIsIDMsIDQsIDUsIDEsIDAgfSwKKyAgICAgICAgICAgIGJvcy50b0J5dGVBcnJheSgpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHJld3JpdGluZ09mRmluYWxCbG9ja1dpdGhvdXRUcmFpbGluZ0xaNzdMaXRlcmFscygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZvciAoaW50IGkgPSAxOyBpIDwgMTM7IGkrKykgeworICAgICAgICAgICAgLy8gYWNjb3JkaW5nIHRvIHRoZSBzcGVjIHRoZXNlIGFyZSBhbGwgdG9vIHNob3J0IGJlIGNvbXByZXNzZWQKKyAgICAgICAgICAgIC8vIExaNzdDb21wcmVzc29yIHdpbGwgY3JlYXRlIGEgc2luZ2xlIGJ5dGUgbGl0ZXJhbAorICAgICAgICAgICAgLy8gZm9sbG93ZWQgYnkgYSBiYWNrLXJlZmVyZW5jZSBzdGFydGluZyB3aXRoIGkgPSA1LAorICAgICAgICAgICAgLy8gdGhvdWdoLiAoNCBpcyB0aGUgbWluaW11bSBsZW5ndGggZm9yIGEgYmFjay1yZWZlcmVuY2UKKyAgICAgICAgICAgIC8vIGluIExaNAorICAgICAgICAgICAgYnl0ZVtdIGNvbXByZXNzZWQgPSBjb21wcmVzcyhpKTsKKyAgICAgICAgICAgIGJ5dGVbXSBleHBlY3RlZCA9IHByZXBhcmVFeHBlY3RlZChpICsgMSk7CisgICAgICAgICAgICBleHBlY3RlZFswXSA9IChieXRlKSAoaTw8NCk7CisgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0QXJyYXlFcXVhbHMoImlucHV0IGxlbmd0aCBpcyAiICsgaSwgZXhwZWN0ZWQsIGNvbXByZXNzZWQpOworICAgICAgICB9CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDEzOyBpIDwgMTc7IGkrKykgeworICAgICAgICAgICAgLy8gTFo3N0NvbXByZXNzb3Igd2lsbCBzdGlsbCBjcmVhdGUgYSBzaW5nbGUgYnl0ZSBsaXRlcmFsCisgICAgICAgICAgICAvLyBmb2xsb3dlZCBieSBhIGJhY2stcmVmZXJlbmNlCisgICAgICAgICAgICAvLyBhY2NvcmRpbmcgdG8gdGhlIHNwZWMgdGhlIGJhY2stcmVmZXJlbmNlIGNvdWxkIGJlIHNwbGl0CisgICAgICAgICAgICAvLyBhcyB3ZSBjYW4gY3V0IG91dCBhIGZpdmUgYnl0ZSBsaXRlcmFsIGFuZCB0aGUgb2Zmc2V0CisgICAgICAgICAgICAvLyB3b3VsZCBiZSBiaWcgZW5vdWdoLCBidXQgb3VyIGFsZ29yaXRobSBpbnNpc3RzIG9uIGEKKyAgICAgICAgICAgIC8vIHR3ZWx2ZSBieXRlIGxpdGVyYWwgdHJhaWxlciBhbmQgdGhlIGJhY2stcmVmZXJlbmNlCisgICAgICAgICAgICAvLyB3b3VsZCBmYWxsIGJlbG93IHRoZSBtaW5pbWFsIHNpemUKKyAgICAgICAgICAgIGJ5dGVbXSBjb21wcmVzc2VkID0gY29tcHJlc3MoaSk7CisgICAgICAgICAgICBieXRlW10gZXhwZWN0ZWQgPSBwcmVwYXJlRXhwZWN0ZWQoaSA8IDE1ID8gaSArIDEgOiBpICsgMik7CisgICAgICAgICAgICBpZiAoaSA8IDE1KSB7CisgICAgICAgICAgICAgICAgZXhwZWN0ZWRbMF0gPSAoYnl0ZSkgKGk8PDQpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBleHBlY3RlZFswXSA9IChieXRlKSAoMTU8PDQpOworICAgICAgICAgICAgICAgIGV4cGVjdGVkWzFdID0gKGJ5dGUpIChpIC0gMTUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgQXNzZXJ0LmFzc2VydEFycmF5RXF1YWxzKCJpbnB1dCBsZW5ndGggaXMgIiArIGksIGV4cGVjdGVkLCBjb21wcmVzc2VkKTsKKyAgICAgICAgfQorCisgICAgICAgIGZvciAoaW50IGkgPSAxNzsgaSA8IDIwOyBpKyspIHsKKyAgICAgICAgICAgIC8vIExaNzdDb21wcmVzc29yIHdpbGwgc3RpbGwgY3JlYXRlIGEgc2luZ2xlIGJ5dGUgbGl0ZXJhbAorICAgICAgICAgICAgLy8gZm9sbG93ZWQgYnkgYSBiYWNrLXJlZmVyZW5jZQorICAgICAgICAgICAgLy8gdGhpcyB0aW1lIGV2ZW4gb3VyIGFsZ29yaXRobSBpcyB3aWxsaW5nIHRvIGJyZWFrIHVwIHRoZQorICAgICAgICAgICAgLy8gYmFjay1yZWZlcmVuY2UKKyAgICAgICAgICAgIGJ5dGVbXSBjb21wcmVzc2VkID0gY29tcHJlc3MoaSk7CisgICAgICAgICAgICBieXRlW10gZXhwZWN0ZWQgPSBwcmVwYXJlRXhwZWN0ZWQoMTcpOworICAgICAgICAgICAgZXhwZWN0ZWRbMF0gPSAoYnl0ZSkgKCgxPDw0KSB8IGkgLSAxNyk7CisgICAgICAgICAgICAvLyB0d28tYnl0ZSBvZmZzZXQKKyAgICAgICAgICAgIGV4cGVjdGVkWzJdID0gMTsKKyAgICAgICAgICAgIGV4cGVjdGVkWzNdID0gMDsKKyAgICAgICAgICAgIGV4cGVjdGVkWzRdID0gKGJ5dGUpICgxMjw8NCk7CisgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0QXJyYXlFcXVhbHMoImlucHV0IGxlbmd0aCBpcyAiICsgaSwgZXhwZWN0ZWQsIGNvbXByZXNzZWQpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCByZXdyaXRpbmdPZkZpbmFsQmxvY2tXaXRoVHJhaWxpbmdMWjc3TGl0ZXJhbHMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8IDU7IGkrKykgeworICAgICAgICAgICAgLy8gTFo3N0NvbXByZXNzb3Igd2lsbCBjcmVhdGUgYSBzaW5nbGUgYnl0ZSBsaXRlcmFsCisgICAgICAgICAgICAvLyBmb2xsb3dlZCBieSBhIGJhY2stcmVmZXJlbmNlIG9mIGxlbmd0aCAxNSBmb2xsb3dlZCBieSBhCisgICAgICAgICAgICAvLyBsaXRlcmFsIG9mIGxlbmd0aCBpCisgICAgICAgICAgICAvLyB3ZSBjYW4gc3BsaXQgdGhlIGJhY2stcmVmZXJlbmNlIGFuZCBtZXJnZSBpdCB3aXRoIHRoZSBsaXRlcmFsCisgICAgICAgICAgICBieXRlW10gY29tcHJlc3NlZCA9IGNvbXByZXNzKDE2LCBpKTsKKyAgICAgICAgICAgIGJ5dGVbXSBleHBlY3RlZCA9IHByZXBhcmVFeHBlY3RlZCgxNyk7CisgICAgICAgICAgICBleHBlY3RlZFswXSA9IChieXRlKSAoKDE8PDQpIHwgaSAtIDEpOworICAgICAgICAgICAgLy8gdHdvLWJ5dGUgb2Zmc2V0CisgICAgICAgICAgICBleHBlY3RlZFsyXSA9IDE7CisgICAgICAgICAgICBleHBlY3RlZFszXSA9IDA7CisgICAgICAgICAgICBleHBlY3RlZFs0XSA9IChieXRlKSAoMTI8PDQpOworICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBpOyBqKyspIHsKKyAgICAgICAgICAgICAgICBleHBlY3RlZFtleHBlY3RlZC5sZW5ndGggLSAxIC0gal0gPSAxOworICAgICAgICAgICAgfQorICAgICAgICAgICAgQXNzZXJ0LmFzc2VydEFycmF5RXF1YWxzKCJ0cmFpbGVyIGxlbmd0aCBpcyAiICsgaSwgZXhwZWN0ZWQsIGNvbXByZXNzZWQpOworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSA1OyBpIDwgMTI7IGkrKykgeworICAgICAgICAgICAgLy8gTFo3N0NvbXByZXNzb3Igd2lsbCBjcmVhdGUgYSBzaW5nbGUgYnl0ZSBsaXRlcmFsCisgICAgICAgICAgICAvLyBmb2xsb3dlZCBieSBhIGJhY2stcmVmZXJlbmNlIG9mIGxlbmd0aCAxNSBmb2xsb3dlZCBieQorICAgICAgICAgICAgLy8gYW5vdGhlciBzaW5nbGUgYnl0ZSBsaXRlcmFsIGFuZCBhbm90aGVyIGJhY2stcmVmZXJlbmNlCisgICAgICAgICAgICAvLyBvZiBsZW5ndGggaS0xCisgICAgICAgICAgICAvLyBhY2NvcmRpbmcgdG8gdGhlIHNwZWMgd2UgY291bGQgY29tcGxldGVseSBzYXRpc2Z5IHRoZQorICAgICAgICAgICAgLy8gcmVxdWlyZW1lbnRzIGJ5IGp1c3QgcmV3cml0aW5nIHRoZSBsYXN0IFBhaXIsIGJ1dCBvdXIKKyAgICAgICAgICAgIC8vIGFsZ29yaXRobSB3aWxsIGNoaXAgb2ZmIGEgZmV3IGJ5dGVzIGZyb20gdGhlIGZpcnN0IFBhaXIKKyAgICAgICAgICAgIGJ5dGVbXSBjb21wcmVzc2VkID0gY29tcHJlc3MoMTYsIGkpOworICAgICAgICAgICAgYnl0ZVtdIGV4cGVjdGVkID0gcHJlcGFyZUV4cGVjdGVkKDE3KTsKKyAgICAgICAgICAgIGV4cGVjdGVkWzBdID0gKGJ5dGUpICgoMTw8NCkgfCBpIC0gMSk7CisgICAgICAgICAgICAvLyB0d28tYnl0ZSBvZmZzZXQKKyAgICAgICAgICAgIGV4cGVjdGVkWzJdID0gMTsKKyAgICAgICAgICAgIGV4cGVjdGVkWzNdID0gMDsKKyAgICAgICAgICAgIGV4cGVjdGVkWzRdID0gKGJ5dGUpICgxMjw8NCk7CisgICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IGk7IGorKykgeworICAgICAgICAgICAgICAgIGV4cGVjdGVkW2V4cGVjdGVkLmxlbmd0aCAtIDEgLSBqXSA9IDE7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0QXJyYXlFcXVhbHMoInRyYWlsZXIgbGVuZ3RoIGlzICIgKyBpLCBleHBlY3RlZCwgY29tcHJlc3NlZCk7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDEyOyBpIDwgMTU7IGkrKykgeworICAgICAgICAgICAgLy8gTFo3N0NvbXByZXNzb3Igd2lsbCBjcmVhdGUgYSBzaW5nbGUgYnl0ZSBsaXRlcmFsCisgICAgICAgICAgICAvLyBmb2xsb3dlZCBieSBhIGJhY2stcmVmZXJlbmNlIG9mIGxlbmd0aCAxNSBmb2xsb3dlZCBieQorICAgICAgICAgICAgLy8gYW5vdGhlciBzaW5nbGUgYnl0ZSBsaXRlcmFsIGFuZCBhbm90aGVyIGJhY2stcmVmZXJlbmNlCisgICAgICAgICAgICAvLyBvZiBsZW5ndGggaS0xCisgICAgICAgICAgICAvLyB0aGlzIHNob3VsZG4ndCBhZmZlY3QgdGhlIGZpcnN0IHBhaXIgYXQgYWxsIGFzCisgICAgICAgICAgICAvLyByZXdyaXRpbmcgdGhlIHNlY29uZCBvbmUgaXMgc3VmZmljaWVudAorICAgICAgICAgICAgYnl0ZVtdIGNvbXByZXNzZWQgPSBjb21wcmVzcygxNiwgaSk7CisgICAgICAgICAgICBieXRlW10gZXhwZWN0ZWQgPSBwcmVwYXJlRXhwZWN0ZWQoaSArIDUpOworICAgICAgICAgICAgZXhwZWN0ZWRbMF0gPSAoYnl0ZSkgKCgxPDw0KSB8IDExKTsKKyAgICAgICAgICAgIC8vIHR3by1ieXRlIG9mZnNldAorICAgICAgICAgICAgZXhwZWN0ZWRbMl0gPSAxOworICAgICAgICAgICAgZXhwZWN0ZWRbM10gPSAwOworICAgICAgICAgICAgZXhwZWN0ZWRbNF0gPSAoYnl0ZSkgKGk8PDQpOworICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBpOyBqKyspIHsKKyAgICAgICAgICAgICAgICBleHBlY3RlZFtleHBlY3RlZC5sZW5ndGggLSAxIC0gal0gPSAxOworICAgICAgICAgICAgfQorICAgICAgICAgICAgQXNzZXJ0LmFzc2VydEFycmF5RXF1YWxzKCJ0cmFpbGVyIGxlbmd0aCBpcyAiICsgaSwgZXhwZWN0ZWQsIGNvbXByZXNzZWQpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCByZXdyaXRpbmdPZkZvdXJQYWlycygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIExaNzdDb21wcmVzc29yIGNyZWF0ZXMgdGhyZWUgdGltZXMgYSBsaXRlcmFsIGJsb2NrIGZvbGxvd2VkCisgICAgICAgIC8vIGJ5IGEgYmFjay1yZWZlcmVuY2UgKG9uY2UgNSBieXRlcyBsb25nIGFuZCB0d2ljZSBmb3VyIGJ5dGVzCisgICAgICAgIC8vIGxvbmcgYW5kIGEgZmluYWwgbGl0ZXJhbCBibG9jayBvZiBsZW5ndGggMQorICAgICAgICAvLyBpbiB0aGUgcmVzdWx0IHRoZSB0aHJlZSBsYXN0IHBhaXJzIGFyZSBtZXJnZWQgaW50byBhIHNpbmdsZQorICAgICAgICAvLyBsaXRlcmFsIGFuZCBvbmUgYnl0ZSBpcyBjaG9wcGVkIG9mZiBvZiB0aGUgZmlyc3QgcGFpcidzCisgICAgICAgIC8vIGJhY2stcmVmZXJlbmNlCisgICAgICAgIGJ5dGVbXSBjb21wcmVzc2VkID0gY29tcHJlc3MoNiwgNSwgNSwgMSk7CisgICAgICAgIGJ5dGVbXSBleHBlY3RlZCA9IHByZXBhcmVFeHBlY3RlZCgxNyk7CisgICAgICAgIGV4cGVjdGVkWzBdID0gKGJ5dGUpICgxPDw0KTsKKyAgICAgICAgLy8gdHdvLWJ5dGUgb2Zmc2V0CisgICAgICAgIGV4cGVjdGVkWzJdID0gMTsKKyAgICAgICAgZXhwZWN0ZWRbM10gPSAwOworICAgICAgICBleHBlY3RlZFs0XSA9IChieXRlKSAoMTI8PDQpOworICAgICAgICBmb3IgKGludCBpID0gNjsgaSA8IDExOyBpKyspIHsKKyAgICAgICAgICAgIGV4cGVjdGVkW2ldID0gMTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMTE7IGkgPCAxNjsgaSsrKSB7CisgICAgICAgICAgICBleHBlY3RlZFtpXSA9IDI7CisgICAgICAgIH0KKyAgICAgICAgZXhwZWN0ZWRbMTZdID0gMzsKKyAgICAgICAgQXNzZXJ0LmFzc2VydEFycmF5RXF1YWxzKGV4cGVjdGVkLCBjb21wcmVzc2VkKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHJld3JpdGluZ1dpdGhGaW5hbEJhY2tyZWZlcmVuY2VBbmRPZmZzZXRCaWdnZXJUaGFuMSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIHRoaXMgY2F1c2VkIHRyb3VibGUgd2hlbiBleHBhbmRGcm9tTGlzdCgpIGZlbGwgaW50byB0aGUgIm9mZnNldFJlbWFpbmluZyBpcyBuZWdhdGl2ZSIgc2VsZi1jb3B5IGNhc2UgYXMgdGhlCisgICAgICAgIC8vIGNhbGN1bGF0aW9uIG9mIGNvcHlPZmZzZXQgd2FzIHdyb25nCisgICAgICAgIGJ5dGVbXSB0b0NvbXByZXNzID0gcHJlcGFyZUV4cGVjdGVkKDI1KTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0b0NvbXByZXNzLmxlbmd0aDsgaSArPSA0KSB7CisgICAgICAgICAgICB0b0NvbXByZXNzW2ldID0gMTsKKyAgICAgICAgfQorICAgICAgICAvLyBMWjc3Q29tcHJlc3NvciBjcmVhdGVzIGEgZm91ciBieXRlIGxpdGVyYWwgYW5kIGEgYmFjay1yZWZlcmVuY2Ugd2l0aCBvZmZzZXQgNCBhbmQgbGVuZ3RoIDIxCisgICAgICAgIC8vIHdlJ2xsIG5lZWQgdG8gc3BsaXQgdGhlIGJhY2stcmVmZXJlbmNlIGFuZCBjaG9wIG9mZiB0aGUgbGFzdCAxMiBieXRlcworICAgICAgICBieXRlW10gY29tcHJlc3NlZCA9IGNvbXByZXNzKHRvQ29tcHJlc3MpOworICAgICAgICBieXRlW10gZXhwZWN0ZWQgPSBwcmVwYXJlRXhwZWN0ZWQoMSArIDQgKyAyICsgMSArIDEyKTsKKyAgICAgICAgZXhwZWN0ZWRbMF0gPSAoYnl0ZSkgKCg0PDw0KSB8IDUpOworICAgICAgICBleHBlY3RlZFsxXSA9IDE7CisgICAgICAgIGV4cGVjdGVkWzVdID0gNDsKKyAgICAgICAgZXhwZWN0ZWRbNl0gPSAwOworICAgICAgICBleHBlY3RlZFs3XSA9IChieXRlKSAoMTI8PDQpOworICAgICAgICBmb3IgKGludCBpID0gMTE7IGkgPCBleHBlY3RlZC5sZW5ndGg7IGkgKz0gNCkgeworICAgICAgICAgICAgZXhwZWN0ZWRbaV0gPSAxOworICAgICAgICB9CisgICAgICAgIEFzc2VydC5hc3NlcnRBcnJheUVxdWFscyhleHBlY3RlZCwgY29tcHJlc3NlZCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBieXRlW10gY29tcHJlc3MoaW50IGxlbmd0aCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGNvbXByZXNzKGxlbmd0aCwgMCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBieXRlW10gY29tcHJlc3MoaW50IGxlbmd0aEJlZm9yZVRyYWlsZXIsIGludC4uLiBsZW5ndGhPZlRyYWlsZXJzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBieXRlW10gYiA9IHByZXBhcmVFeHBlY3RlZChsZW5ndGhCZWZvcmVUcmFpbGVyKTsKKyAgICAgICAgcmV0dXJuIGNvbXByZXNzKGIsIGxlbmd0aE9mVHJhaWxlcnMpOworICAgIH0KKworICAgIHByaXZhdGUgYnl0ZVtdIGNvbXByZXNzKGJ5dGVbXSBpbnB1dCwgaW50Li4uIGxlbmd0aE9mVHJhaWxlcnMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRyeSAoQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJhb3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgICAgICAgQmxvY2tMWjRDb21wcmVzc29yT3V0cHV0U3RyZWFtIGxvID0gbmV3IEJsb2NrTFo0Q29tcHJlc3Nvck91dHB1dFN0cmVhbShiYW9zKSkgeworICAgICAgICAgICAgbG8ud3JpdGUoaW5wdXQpOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGhPZlRyYWlsZXJzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgaW50IGxlbmd0aE9mVHJhaWxlciA9IGxlbmd0aE9mVHJhaWxlcnNbaV07CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBsZW5ndGhPZlRyYWlsZXI7IGorKykgeworICAgICAgICAgICAgICAgICAgICBsby53cml0ZShpICsgMSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgbG8uY2xvc2UoKTsKKyAgICAgICAgICAgIHJldHVybiBiYW9zLnRvQnl0ZUFycmF5KCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIGJ5dGVbXSBwcmVwYXJlRXhwZWN0ZWQoaW50IGxlbmd0aCkgeworICAgICAgICBieXRlW10gYiA9IG5ldyBieXRlW2xlbmd0aF07CisgICAgICAgIEFycmF5cy5maWxsKGIsIChieXRlKSAtMSk7CisgICAgICAgIHJldHVybiBiOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2x6NC9CbG9ja0xaNENvbXByZXNzb3JSb3VuZHRyaXBUZXN0LmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9sejQvQmxvY2tMWjRDb21wcmVzc29yUm91bmR0cmlwVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRhNDk0MWQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9sejQvQmxvY2tMWjRDb21wcmVzc29yUm91bmR0cmlwVGVzdC5qYXZhCkBAIC0wLDAgKzEsOTcgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMubHo0OworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLkFic3RyYWN0VGVzdENhc2U7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLmx6NzdzdXBwb3J0LlBhcmFtZXRlcnM7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLklPVXRpbHM7CitpbXBvcnQgb3JnLmp1bml0LkFzc2VydDsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVycy5QYXJhbWV0ZXJpemVkOworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXIuUnVuV2l0aDsKKworQFJ1bldpdGgoUGFyYW1ldGVyaXplZC5jbGFzcykKK3B1YmxpYyBmaW5hbCBjbGFzcyBCbG9ja0xaNENvbXByZXNzb3JSb3VuZHRyaXBUZXN0IGV4dGVuZHMgQWJzdHJhY3RUZXN0Q2FzZSB7CisKKyAgICBAb3JnLmp1bml0LnJ1bm5lcnMuUGFyYW1ldGVyaXplZC5QYXJhbWV0ZXJzKG5hbWUgPSAidXNpbmcgezB9IikKKyAgICBwdWJsaWMgc3RhdGljIENvbGxlY3Rpb248T2JqZWN0W10+IGZhY3RvcnkoKSB7CisgICAgICAgIHJldHVybiBBcnJheXMuYXNMaXN0KG5ldyBPYmplY3RbXVtdIHsKKyAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyAiZGVmYXVsdCIsIEJsb2NrTFo0Q29tcHJlc3Nvck91dHB1dFN0cmVhbS5jcmVhdGVQYXJhbWV0ZXJCdWlsZGVyKCkuYnVpbGQoKSB9LAorICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7ICJ0dW5lZCBmb3Igc3BlZWQiLAorICAgICAgICAgICAgICAgICAgICBCbG9ja0xaNENvbXByZXNzb3JPdXRwdXRTdHJlYW0uY3JlYXRlUGFyYW1ldGVyQnVpbGRlcigpLnR1bmVkRm9yU3BlZWQoKS5idWlsZCgpIH0sCisgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgInR1bmVkIGZvciBjb21wcmVzc2lvbiByYXRpbyIsCisgICAgICAgICAgICAgICAgICAgIEJsb2NrTFo0Q29tcHJlc3Nvck91dHB1dFN0cmVhbS5jcmVhdGVQYXJhbWV0ZXJCdWlsZGVyKCkudHVuZWRGb3JDb21wcmVzc2lvblJhdGlvKCkuYnVpbGQoKSB9CisgICAgICAgICAgICB9KTsKKyAgICB9CisKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBjb25maWc7CisgICAgcHJpdmF0ZSBmaW5hbCBQYXJhbWV0ZXJzIHBhcmFtczsKKworICAgIHB1YmxpYyBCbG9ja0xaNENvbXByZXNzb3JSb3VuZHRyaXBUZXN0KFN0cmluZyBjb25maWcsIFBhcmFtZXRlcnMgcGFyYW1zKSB7CisgICAgICAgIHRoaXMuY29uZmlnID0gY29uZmlnOworICAgICAgICB0aGlzLnBhcmFtcyA9IHBhcmFtczsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcm91bmRUcmlwVGVzdChTdHJpbmcgdGVzdEZpbGUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEZpbGUgaW5wdXQgPSBnZXRGaWxlKHRlc3RGaWxlKTsKKyAgICAgICAgbG9uZyBzdGFydCA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgICAgICBmaW5hbCBGaWxlIG91dHB1dFN6ID0gbmV3IEZpbGUoZGlyLCBpbnB1dC5nZXROYW1lKCkgKyAiLmJsb2NrLmx6NCIpOworICAgICAgICB0cnkgKEZpbGVJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpOworICAgICAgICAgICAgIEZpbGVPdXRwdXRTdHJlYW0gb3MgPSBuZXcgRmlsZU91dHB1dFN0cmVhbShvdXRwdXRTeik7CisgICAgICAgICAgICAgQmxvY2tMWjRDb21wcmVzc29yT3V0cHV0U3RyZWFtIGxvcyA9IG5ldyBCbG9ja0xaNENvbXByZXNzb3JPdXRwdXRTdHJlYW0ob3MsIHBhcmFtcykpIHsKKyAgICAgICAgICAgIElPVXRpbHMuY29weShpcywgbG9zKTsKKyAgICAgICAgfQorICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkNvbmZpZ3VyYXRpb246ICIgKyBjb25maWcpOworICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oaW5wdXQuZ2V0TmFtZSgpICsgIiB3cml0dGVuLCB1bmNvbXByZXNzZWQgYnl0ZXM6ICIgKyBpbnB1dC5sZW5ndGgoKQorICAgICAgICAgICAgKyAiLCBjb21wcmVzc2VkIGJ5dGVzOiAiICsgb3V0cHV0U3oubGVuZ3RoKCkgKyAiIGFmdGVyICIgKyAoU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgLSBzdGFydCkgKyAibXMiKTsKKyAgICAgICAgc3RhcnQgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICAgICAgdHJ5IChGaWxlSW5wdXRTdHJlYW0gaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGlucHV0KTsKKyAgICAgICAgICAgICBCbG9ja0xaNENvbXByZXNzb3JJbnB1dFN0cmVhbSBzaXMgPSBuZXcgQmxvY2tMWjRDb21wcmVzc29ySW5wdXRTdHJlYW0obmV3IEZpbGVJbnB1dFN0cmVhbShvdXRwdXRTeikpKSB7CisgICAgICAgICAgICBieXRlW10gZXhwZWN0ZWQgPSBJT1V0aWxzLnRvQnl0ZUFycmF5KGlzKTsKKyAgICAgICAgICAgIGJ5dGVbXSBhY3R1YWwgPSBJT1V0aWxzLnRvQnl0ZUFycmF5KHNpcyk7CisgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0QXJyYXlFcXVhbHMoZXhwZWN0ZWQsIGFjdHVhbCk7CisgICAgICAgIH0KKyAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKG91dHB1dFN6LmdldE5hbWUoKSArICIgcmVhZCBhZnRlciAiICsgKFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpIC0gc3RhcnQpICsgIm1zIik7CisgICAgfQorCisgICAgLy8gc2hvdWxkIHlpZWxkIGRlY2VudCBjb21wcmVzc2lvbgorICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgYmxhVGFyUm91bmR0cmlwKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcm91bmRUcmlwVGVzdCgiYmxhLnRhciIpOworICAgIH0KKworICAgIC8vIHlpZWxkcyBubyBjb21wcmVzc2lvbiBhdCBhbGwKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIGd6aXBwZWRMb3JlbUlwc3VtUm91bmR0cmlwKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcm91bmRUcmlwVGVzdCgibG9yZW0taXBzdW0udHh0Lmd6Iik7CisgICAgfQorCisgICAgLy8geWllbGRzIG5vIGNvbXByZXNzaW9uIGF0IGFsbAorICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgYmlnZ2VyRmlsZVJvdW5kdHJpcCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJvdW5kVHJpcFRlc3QoIkNPTVBSRVNTLTI1Ni43eiIpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvbHo0L0ZhY3RvcnlUZXN0LmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9sejQvRmFjdG9yeVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zZGI2MjQ5Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvbHo0L0ZhY3RvcnlUZXN0LmphdmEKQEAgLTAsMCArMSw2NiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5sejQ7CisKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuQWJzdHJhY3RUZXN0Q2FzZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuQ29tcHJlc3NvclN0cmVhbUZhY3Rvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLklPVXRpbHM7CitpbXBvcnQgb3JnLmp1bml0LkFzc2VydDsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworcHVibGljIGNsYXNzIEZhY3RvcnlUZXN0IGV4dGVuZHMgQWJzdHJhY3RUZXN0Q2FzZSB7CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIGZyYW1lUm91bmR0cmlwVmlhRmFjdG9yeSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICByb3VuZHRyaXBWaWFGYWN0b3J5KENvbXByZXNzb3JTdHJlYW1GYWN0b3J5LmdldExaNEZyYW1lZCgpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIGJsb2NrUm91bmR0cmlwVmlhRmFjdG9yeSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICByb3VuZHRyaXBWaWFGYWN0b3J5KENvbXByZXNzb3JTdHJlYW1GYWN0b3J5LmdldExaNEJsb2NrKCkpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByb3VuZHRyaXBWaWFGYWN0b3J5KFN0cmluZyBmb3JtYXQpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBGaWxlIGlucHV0ID0gZ2V0RmlsZSgiYmxhLnRhciIpOworICAgICAgICBsb25nIHN0YXJ0ID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgICAgIGZpbmFsIEZpbGUgb3V0cHV0U3ogPSBuZXcgRmlsZShkaXIsIGlucHV0LmdldE5hbWUoKSArICIuIiArIGZvcm1hdCArICIubHo0Iik7CisgICAgICAgIHRyeSAoRmlsZUlucHV0U3RyZWFtIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShpbnB1dCk7CisgICAgICAgICAgICAgRmlsZU91dHB1dFN0cmVhbSBvcyA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKG91dHB1dFN6KTsKKyAgICAgICAgICAgICBPdXRwdXRTdHJlYW0gbG9zID0gbmV3IENvbXByZXNzb3JTdHJlYW1GYWN0b3J5KCkuY3JlYXRlQ29tcHJlc3Nvck91dHB1dFN0cmVhbShmb3JtYXQsIG9zKSkgeworICAgICAgICAgICAgSU9VdGlscy5jb3B5KGlzLCBsb3MpOworICAgICAgICB9CisgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbihpbnB1dC5nZXROYW1lKCkgKyAiIHdyaXR0ZW4sIHVuY29tcHJlc3NlZCBieXRlczogIiArIGlucHV0Lmxlbmd0aCgpCisgICAgICAgICAgICArICIsIGNvbXByZXNzZWQgYnl0ZXM6ICIgKyBvdXRwdXRTei5sZW5ndGgoKSArICIgYWZ0ZXIgIiArIChTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSAtIHN0YXJ0KSArICJtcyIpOworICAgICAgICBzdGFydCA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgICAgICB0cnkgKEZpbGVJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpOworICAgICAgICAgICAgIElucHV0U3RyZWFtIHNpcyA9IG5ldyBDb21wcmVzc29yU3RyZWFtRmFjdG9yeSgpCisgICAgICAgICAgICAgICAgIC5jcmVhdGVDb21wcmVzc29ySW5wdXRTdHJlYW0oZm9ybWF0LCBuZXcgRmlsZUlucHV0U3RyZWFtKG91dHB1dFN6KSkpIHsKKyAgICAgICAgICAgIGJ5dGVbXSBleHBlY3RlZCA9IElPVXRpbHMudG9CeXRlQXJyYXkoaXMpOworICAgICAgICAgICAgYnl0ZVtdIGFjdHVhbCA9IElPVXRpbHMudG9CeXRlQXJyYXkoc2lzKTsKKyAgICAgICAgICAgIEFzc2VydC5hc3NlcnRBcnJheUVxdWFscyhleHBlY3RlZCwgYWN0dWFsKTsKKyAgICAgICAgfQorICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4ob3V0cHV0U3ouZ2V0TmFtZSgpICsgIiByZWFkIGFmdGVyICIgKyAoU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgLSBzdGFydCkgKyAibXMiKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9sejQvRnJhbWVkTFo0Q29tcHJlc3NvcklucHV0U3RyZWFtVGVzdC5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvbHo0L0ZyYW1lZExaNENvbXByZXNzb3JJbnB1dFN0cmVhbVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZmQ1NjRiCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvbHo0L0ZyYW1lZExaNENvbXByZXNzb3JJbnB1dFN0cmVhbVRlc3QuamF2YQpAQCAtMCwwICsxLDY0NSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5sejQ7CisKK2ltcG9ydCBzdGF0aWMgb3JnLmhhbWNyZXN0LkNvcmVNYXRjaGVycy4qOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0Lio7CisKK2ltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuQWJzdHJhY3RUZXN0Q2FzZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuQ29tcHJlc3NvclN0cmVhbUZhY3Rvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLklPVXRpbHM7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBGcmFtZWRMWjRDb21wcmVzc29ySW5wdXRTdHJlYW1UZXN0CisgICAgZXh0ZW5kcyBBYnN0cmFjdFRlc3RDYXNlIHsKKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdE1hdGNoZXMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBhc3NlcnRGYWxzZShGcmFtZWRMWjRDb21wcmVzc29ySW5wdXRTdHJlYW0ubWF0Y2hlcyhuZXcgYnl0ZVsxMF0sIDQpKTsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGIgPSBuZXcgYnl0ZVsxMl07CisgICAgICAgIGZpbmFsIEZpbGUgaW5wdXQgPSBnZXRGaWxlKCJibGEudGFyLmx6NCIpOworICAgICAgICB0cnkgKEZpbGVJbnB1dFN0cmVhbSBpbiA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpKSB7CisgICAgICAgICAgICBJT1V0aWxzLnJlYWRGdWxseShpbiwgYik7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RmFsc2UoRnJhbWVkTFo0Q29tcHJlc3NvcklucHV0U3RyZWFtLm1hdGNoZXMoYiwgMykpOworICAgICAgICBhc3NlcnRUcnVlKEZyYW1lZExaNENvbXByZXNzb3JJbnB1dFN0cmVhbS5tYXRjaGVzKGIsIDQpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShGcmFtZWRMWjRDb21wcmVzc29ySW5wdXRTdHJlYW0ubWF0Y2hlcyhiLCA1KSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCByZWFkQmxhTHo0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBhID0gbmV3IEZyYW1lZExaNENvbXByZXNzb3JJbnB1dFN0cmVhbShuZXcgRmlsZUlucHV0U3RyZWFtKGdldEZpbGUoImJsYS50YXIubHo0IikpKTsKKyAgICAgICAgICAgIEZpbGVJbnB1dFN0cmVhbSBlID0gbmV3IEZpbGVJbnB1dFN0cmVhbShnZXRGaWxlKCJibGEudGFyIikpKSB7CisgICAgICAgICAgICBieXRlW10gZXhwZWN0ZWQgPSBJT1V0aWxzLnRvQnl0ZUFycmF5KGUpOworICAgICAgICAgICAgYnl0ZVtdIGFjdHVhbCA9IElPVXRpbHMudG9CeXRlQXJyYXkoYSk7CisgICAgICAgICAgICBhc3NlcnRBcnJheUVxdWFscyhleHBlY3RlZCwgYWN0dWFsKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgcmVhZEJsYUx6NFZpYUZhY3RvcnkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBhID0gbmV3IENvbXByZXNzb3JTdHJlYW1GYWN0b3J5KCkKKyAgICAgICAgICAgICAgICAgLmNyZWF0ZUNvbXByZXNzb3JJbnB1dFN0cmVhbShDb21wcmVzc29yU3RyZWFtRmFjdG9yeS5nZXRMWjRGcmFtZWQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgRmlsZUlucHV0U3RyZWFtKGdldEZpbGUoImJsYS50YXIubHo0IikpKTsKKyAgICAgICAgICAgIEZpbGVJbnB1dFN0cmVhbSBlID0gbmV3IEZpbGVJbnB1dFN0cmVhbShnZXRGaWxlKCJibGEudGFyIikpKSB7CisgICAgICAgICAgICBieXRlW10gZXhwZWN0ZWQgPSBJT1V0aWxzLnRvQnl0ZUFycmF5KGUpOworICAgICAgICAgICAgYnl0ZVtdIGFjdHVhbCA9IElPVXRpbHMudG9CeXRlQXJyYXkoYSk7CisgICAgICAgICAgICBhc3NlcnRBcnJheUVxdWFscyhleHBlY3RlZCwgYWN0dWFsKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgcmVhZEJsYUx6NFZpYUZhY3RvcnlBdXRvRGV0ZWN0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSAoSW5wdXRTdHJlYW0gYSA9IG5ldyBDb21wcmVzc29yU3RyZWFtRmFjdG9yeSgpCisgICAgICAgICAgICAgICAgIC5jcmVhdGVDb21wcmVzc29ySW5wdXRTdHJlYW0obmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0obmV3IEZpbGVJbnB1dFN0cmVhbShnZXRGaWxlKCJibGEudGFyLmx6NCIpKSkpOworICAgICAgICAgICAgRmlsZUlucHV0U3RyZWFtIGUgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGdldEZpbGUoImJsYS50YXIiKSkpIHsKKyAgICAgICAgICAgIGJ5dGVbXSBleHBlY3RlZCA9IElPVXRpbHMudG9CeXRlQXJyYXkoZSk7CisgICAgICAgICAgICBieXRlW10gYWN0dWFsID0gSU9VdGlscy50b0J5dGVBcnJheShhKTsKKyAgICAgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKGV4cGVjdGVkLCBhY3R1YWwpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCByZWFkQmxhTHo0V2l0aERlY29tcHJlc3NDb25jYXRlbmF0ZWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0cnkgKElucHV0U3RyZWFtIGEgPSBuZXcgRnJhbWVkTFo0Q29tcHJlc3NvcklucHV0U3RyZWFtKG5ldyBGaWxlSW5wdXRTdHJlYW0oZ2V0RmlsZSgiYmxhLnRhci5sejQiKSksIHRydWUpOworICAgICAgICAgICAgRmlsZUlucHV0U3RyZWFtIGUgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGdldEZpbGUoImJsYS50YXIiKSkpIHsKKyAgICAgICAgICAgIGJ5dGVbXSBleHBlY3RlZCA9IElPVXRpbHMudG9CeXRlQXJyYXkoZSk7CisgICAgICAgICAgICBieXRlW10gYWN0dWFsID0gSU9VdGlscy50b0J5dGVBcnJheShhKTsKKyAgICAgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKGV4cGVjdGVkLCBhY3R1YWwpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCByZWFkRG91YmxlZEJsYUx6NFdpdGhEZWNvbXByZXNzQ29uY2F0ZW5hdGVkVHJ1ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICByZWFkRG91YmxlZEJsYUx6NChuZXcgU3RyZWFtV3JhcHBlcigpIHsKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICBwdWJsaWMgSW5wdXRTdHJlYW0gd3JhcChJbnB1dFN0cmVhbSBpbikgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgRnJhbWVkTFo0Q29tcHJlc3NvcklucHV0U3RyZWFtKGluLCB0cnVlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9LCB0cnVlKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHJlYWREb3VibGVkQmxhTHo0V2l0aERlY29tcHJlc3NDb25jYXRlbmF0ZWRGYWxzZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICByZWFkRG91YmxlZEJsYUx6NChuZXcgU3RyZWFtV3JhcHBlcigpIHsKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICBwdWJsaWMgSW5wdXRTdHJlYW0gd3JhcChJbnB1dFN0cmVhbSBpbikgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgRnJhbWVkTFo0Q29tcHJlc3NvcklucHV0U3RyZWFtKGluLCBmYWxzZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSwgZmFsc2UpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgcmVhZERvdWJsZWRCbGFMejRXaXRob3V0RXhwbGljaXREZWNvbXByZXNzQ29uY2F0ZW5hdGVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHJlYWREb3VibGVkQmxhTHo0KG5ldyBTdHJlYW1XcmFwcGVyKCkgeworICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgIHB1YmxpYyBJbnB1dFN0cmVhbSB3cmFwKElucHV0U3RyZWFtIGluKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBGcmFtZWRMWjRDb21wcmVzc29ySW5wdXRTdHJlYW0oaW4pOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0sIGZhbHNlKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHJlYWRCbGFMejRWaWFGYWN0b3J5V2l0aERlY29tcHJlc3NDb25jYXRlbmF0ZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBhID0gbmV3IENvbXByZXNzb3JTdHJlYW1GYWN0b3J5KCkKKyAgICAgICAgICAgICAgICAgLmNyZWF0ZUNvbXByZXNzb3JJbnB1dFN0cmVhbShDb21wcmVzc29yU3RyZWFtRmFjdG9yeS5nZXRMWjRGcmFtZWQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgRmlsZUlucHV0U3RyZWFtKGdldEZpbGUoImJsYS50YXIubHo0IikpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUpOworICAgICAgICAgICAgRmlsZUlucHV0U3RyZWFtIGUgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGdldEZpbGUoImJsYS50YXIiKSkpIHsKKyAgICAgICAgICAgIGJ5dGVbXSBleHBlY3RlZCA9IElPVXRpbHMudG9CeXRlQXJyYXkoZSk7CisgICAgICAgICAgICBieXRlW10gYWN0dWFsID0gSU9VdGlscy50b0J5dGVBcnJheShhKTsKKyAgICAgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKGV4cGVjdGVkLCBhY3R1YWwpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCByZWFkRG91YmxlZEJsYUx6NFZpYUZhY3RvcnlXaXRoRGVjb21wcmVzc0NvbmNhdGVuYXRlZFRydWUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgcmVhZERvdWJsZWRCbGFMejQobmV3IFN0cmVhbVdyYXBwZXIoKSB7CisgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgcHVibGljIElucHV0U3RyZWFtIHdyYXAoSW5wdXRTdHJlYW0gaW4pIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IENvbXByZXNzb3JTdHJlYW1GYWN0b3J5KCkKKyAgICAgICAgICAgICAgICAgICAgICAgIC5jcmVhdGVDb21wcmVzc29ySW5wdXRTdHJlYW0oQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkuZ2V0TFo0RnJhbWVkKCksIGluLCB0cnVlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9LCB0cnVlKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHJlYWREb3VibGVkQmxhTHo0VmlhRmFjdG9yeVdpdGhEZWNvbXByZXNzQ29uY2F0ZW5hdGVkRmFsc2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgcmVhZERvdWJsZWRCbGFMejQobmV3IFN0cmVhbVdyYXBwZXIoKSB7CisgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgcHVibGljIElucHV0U3RyZWFtIHdyYXAoSW5wdXRTdHJlYW0gaW4pIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IENvbXByZXNzb3JTdHJlYW1GYWN0b3J5KCkKKyAgICAgICAgICAgICAgICAgICAgICAgIC5jcmVhdGVDb21wcmVzc29ySW5wdXRTdHJlYW0oQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkuZ2V0TFo0RnJhbWVkKCksIGluLCBmYWxzZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSwgZmFsc2UpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgcmVhZERvdWJsZWRCbGFMejRWaWFGYWN0b3J5V2l0aG91dEV4cGxpY2l0RGVjb21wcmVzc0NvbmNhdGVuYXRlZCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICByZWFkRG91YmxlZEJsYUx6NChuZXcgU3RyZWFtV3JhcHBlcigpIHsKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICBwdWJsaWMgSW5wdXRTdHJlYW0gd3JhcChJbnB1dFN0cmVhbSBpbikgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQ29tcHJlc3NvclN0cmVhbUZhY3RvcnkoKQorICAgICAgICAgICAgICAgICAgICAgICAgLmNyZWF0ZUNvbXByZXNzb3JJbnB1dFN0cmVhbShDb21wcmVzc29yU3RyZWFtRmFjdG9yeS5nZXRMWjRGcmFtZWQoKSwgaW4pOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0sIGZhbHNlKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHJlYWRCbGFEdW1wTHo0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBhID0gbmV3IEZyYW1lZExaNENvbXByZXNzb3JJbnB1dFN0cmVhbShuZXcgRmlsZUlucHV0U3RyZWFtKGdldEZpbGUoImJsYS5kdW1wLmx6NCIpKSk7CisgICAgICAgICAgICBGaWxlSW5wdXRTdHJlYW0gZSA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oZ2V0RmlsZSgiYmxhLmR1bXAiKSkpIHsKKyAgICAgICAgICAgIGJ5dGVbXSBleHBlY3RlZCA9IElPVXRpbHMudG9CeXRlQXJyYXkoZSk7CisgICAgICAgICAgICBieXRlW10gYWN0dWFsID0gSU9VdGlscy50b0J5dGVBcnJheShhKTsKKyAgICAgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKGV4cGVjdGVkLCBhY3R1YWwpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QoZXhwZWN0ZWQgPSBJT0V4Y2VwdGlvbi5jbGFzcykKKyAgICBwdWJsaWMgdm9pZCByZWplY3RzTm9uTFo0U3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBhID0gbmV3IEZyYW1lZExaNENvbXByZXNzb3JJbnB1dFN0cmVhbShuZXcgRmlsZUlucHV0U3RyZWFtKGdldEZpbGUoImJsYS50YXIiKSkpKSB7CisgICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgZXhjZXB0aW9uIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHJlamVjdHNGaWxlV2l0aG91dEZyYW1lRGVzY3JpcHRvcigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBpbnB1dCA9IG5ldyBieXRlW10geworICAgICAgICAgICAgNCwgMHgyMiwgMHg0ZCwgMHgxOCAvLyBzaWduYXR1cmUKKyAgICAgICAgfTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRyeSAoSW5wdXRTdHJlYW0gYSA9IG5ldyBGcmFtZWRMWjRDb21wcmVzc29ySW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGlucHV0KSkpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBleGNlcHRpb24iKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGFzc2VydFRoYXQoZXguZ2V0TWVzc2FnZSgpLCBjb250YWluc1N0cmluZygiZnJhbWUgZmxhZ3MiKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHJlamVjdHNGaWxlV2l0aG91dEJsb2NrU2l6ZUJ5dGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBieXRlW10gaW5wdXQgPSBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgIDQsIDB4MjIsIDB4NGQsIDB4MTgsIC8vIHNpZ25hdHVyZQorICAgICAgICAgICAgMHg2NCwgLy8gZmxhZyAtIFZlcnNpb24gMDEsIGJsb2NrIGluZGVwZW5kZW50LCBubyBibG9jayBjaGVja3N1bSwgbm8gY29udGVudCBzaXplLCB3aXRoIGNvbnRlbnQgY2hlY2tzdW0KKyAgICAgICAgfTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRyeSAoSW5wdXRTdHJlYW0gYSA9IG5ldyBGcmFtZWRMWjRDb21wcmVzc29ySW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGlucHV0KSkpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBleGNlcHRpb24iKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGFzc2VydFRoYXQoZXguZ2V0TWVzc2FnZSgpLCBjb250YWluc1N0cmluZygiQkQgYnl0ZSIpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgcmVqZWN0c0ZpbGVXaXRoV3JvbmdWZXJzaW9uKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGlucHV0ID0gbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICA0LCAweDIyLCAweDRkLCAweDE4LCAvLyBzaWduYXR1cmUKKyAgICAgICAgICAgIDB4MjQsIC8vIGZsYWcgLSBWZXJzaW9uIDAwLCBibG9jayBpbmRlcGVuZGVudCwgbm8gYmxvY2sgY2hlY2tzdW0sIG5vIGNvbnRlbnQgc2l6ZSwgd2l0aCBjb250ZW50IGNoZWNrc3VtCisgICAgICAgIH07CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0cnkgKElucHV0U3RyZWFtIGEgPSBuZXcgRnJhbWVkTFo0Q29tcHJlc3NvcklucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShpbnB1dCkpKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgZXhjZXB0aW9uIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBhc3NlcnRUaGF0KGV4LmdldE1lc3NhZ2UoKSwgY29udGFpbnNTdHJpbmcoInZlcnNpb24iKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHJlamVjdHNGaWxlV2l0aEluc3VmZmljaWVudENvbnRlbnRTaXplKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGlucHV0ID0gbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICA0LCAweDIyLCAweDRkLCAweDE4LCAvLyBzaWduYXR1cmUKKyAgICAgICAgICAgIDB4NkMsIC8vIGZsYWcgLSBWZXJzaW9uIDAxLCBibG9jayBpbmRlcGVuZGVudCwgbm8gYmxvY2sgY2hlY2tzdW0sIHdpdGggY29udGVudCBzaXplLCB3aXRoIGNvbnRlbnQgY2hlY2tzdW0KKyAgICAgICAgICAgIDB4NzAsIC8vIGJsb2NrIHNpemUgNE1CCisgICAgICAgIH07CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0cnkgKElucHV0U3RyZWFtIGEgPSBuZXcgRnJhbWVkTFo0Q29tcHJlc3NvcklucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShpbnB1dCkpKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgZXhjZXB0aW9uIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBhc3NlcnRUaGF0KGV4LmdldE1lc3NhZ2UoKSwgY29udGFpbnNTdHJpbmcoImNvbnRlbnQgc2l6ZSIpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgcmVqZWN0c0ZpbGVXaXRob3V0SGVhZGVyQ2hlY2tzdW0oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBieXRlW10gaW5wdXQgPSBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgIDQsIDB4MjIsIDB4NGQsIDB4MTgsIC8vIHNpZ25hdHVyZQorICAgICAgICAgICAgMHg2NCwgLy8gZmxhZyAtIFZlcnNpb24gMDEsIGJsb2NrIGluZGVwZW5kZW50LCBubyBibG9jayBjaGVja3N1bSwgbm8gY29udGVudCBzaXplLCB3aXRoIGNvbnRlbnQgY2hlY2tzdW0KKyAgICAgICAgICAgIDB4NzAsIC8vIGJsb2NrIHNpemUgNE1CCisgICAgICAgIH07CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0cnkgKElucHV0U3RyZWFtIGEgPSBuZXcgRnJhbWVkTFo0Q29tcHJlc3NvcklucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShpbnB1dCkpKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgZXhjZXB0aW9uIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBhc3NlcnRUaGF0KGV4LmdldE1lc3NhZ2UoKSwgY29udGFpbnNTdHJpbmcoImhlYWRlciBjaGVja3N1bSIpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgcmVqZWN0c0ZpbGVXaXRoQmFkSGVhZGVyQ2hlY2tzdW0oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBieXRlW10gaW5wdXQgPSBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgIDQsIDB4MjIsIDB4NGQsIDB4MTgsIC8vIHNpZ25hdHVyZQorICAgICAgICAgICAgMHg2NCwgLy8gZmxhZyAtIFZlcnNpb24gMDEsIGJsb2NrIGluZGVwZW5kZW50LCBubyBibG9jayBjaGVja3N1bSwgbm8gY29udGVudCBzaXplLCB3aXRoIGNvbnRlbnQgY2hlY2tzdW0KKyAgICAgICAgICAgIDB4NzAsIC8vIGJsb2NrIHNpemUgNE1CCisgICAgICAgICAgICAwLAorICAgICAgICB9OworICAgICAgICB0cnkgeworICAgICAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBhID0gbmV3IEZyYW1lZExaNENvbXByZXNzb3JJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oaW5wdXQpKSkgeworICAgICAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIGV4Y2VwdGlvbiIpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgYXNzZXJ0VGhhdChleC5nZXRNZXNzYWdlKCksIGNvbnRhaW5zU3RyaW5nKCJoZWFkZXIgY2hlY2tzdW0gbWlzbWF0Y2giKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHJlYWRzVW5jb21wcmVzc2VkQmxvY2tzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGlucHV0ID0gbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICA0LCAweDIyLCAweDRkLCAweDE4LCAvLyBzaWduYXR1cmUKKyAgICAgICAgICAgIDB4NjAsIC8vIGZsYWcgLSBWZXJzaW9uIDAxLCBibG9jayBpbmRlcGVuZGVudCwgbm8gYmxvY2sgY2hlY2tzdW0sIG5vIGNvbnRlbnQgc2l6ZSwgbm8gY29udGVudCBjaGVja3N1bQorICAgICAgICAgICAgMHg3MCwgLy8gYmxvY2sgc2l6ZSA0TUIKKyAgICAgICAgICAgIDExNSwgLy8gY2hlY2tzdW0KKyAgICAgICAgICAgIDEzLCAwLCAwLCAoYnl0ZSkgMHg4MCwgLy8gMTMgYnl0ZXMgbGVuZ3RoIGFuZCB1bmNvbXByZXNzZWQgYml0IHNldAorICAgICAgICAgICAgJ0gnLCAnZScsICdsJywgJ2wnLCAnbycsICcsJywgJyAnLCAndycsICdvJywgJ3InLCAnbCcsICdkJywgJyEnLCAvLyBjb250ZW50CisgICAgICAgICAgICAwLCAwLCAwLCAwLCAvLyBlbXB0eSBibG9jayBtYXJrZXIKKyAgICAgICAgfTsKKyAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBhID0gbmV3IEZyYW1lZExaNENvbXByZXNzb3JJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oaW5wdXQpKSkgeworICAgICAgICAgICAgYnl0ZVtdIGFjdHVhbCA9IElPVXRpbHMudG9CeXRlQXJyYXkoYSk7CisgICAgICAgICAgICBhc3NlcnRBcnJheUVxdWFscyhuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAgICAgJ0gnLCAnZScsICdsJywgJ2wnLCAnbycsICcsJywgJyAnLCAndycsICdvJywgJ3InLCAnbCcsICdkJywgJyEnCisgICAgICAgICAgICAgICAgfSwgYWN0dWFsKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgcmVhZHNVbmNvbXByZXNzZWRCbG9ja3NVc2luZ1NpbmdsZUJ5dGVSZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGlucHV0ID0gbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICA0LCAweDIyLCAweDRkLCAweDE4LCAvLyBzaWduYXR1cmUKKyAgICAgICAgICAgIDB4NjAsIC8vIGZsYWcgLSBWZXJzaW9uIDAxLCBibG9jayBpbmRlcGVuZGVudCwgbm8gYmxvY2sgY2hlY2tzdW0sIG5vIGNvbnRlbnQgc2l6ZSwgbm8gY29udGVudCBjaGVja3N1bQorICAgICAgICAgICAgMHg3MCwgLy8gYmxvY2sgc2l6ZSA0TUIKKyAgICAgICAgICAgIDExNSwgLy8gY2hlY2tzdW0KKyAgICAgICAgICAgIDEzLCAwLCAwLCAoYnl0ZSkgMHg4MCwgLy8gMTMgYnl0ZXMgbGVuZ3RoIGFuZCB1bmNvbXByZXNzZWQgYml0IHNldAorICAgICAgICAgICAgJ0gnLCAnZScsICdsJywgJ2wnLCAnbycsICcsJywgJyAnLCAndycsICdvJywgJ3InLCAnbCcsICdkJywgJyEnLCAvLyBjb250ZW50CisgICAgICAgICAgICAwLCAwLCAwLCAwLCAvLyBlbXB0eSBibG9jayBtYXJrZXIKKyAgICAgICAgfTsKKyAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBhID0gbmV3IEZyYW1lZExaNENvbXByZXNzb3JJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oaW5wdXQpKSkgeworICAgICAgICAgICAgaW50IGggPSBhLnJlYWQoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygnSCcsIGgpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCByZWplY3RzQmxvY2tzV2l0aG91dENoZWNrc3VtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGlucHV0ID0gbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICA0LCAweDIyLCAweDRkLCAweDE4LCAvLyBzaWduYXR1cmUKKyAgICAgICAgICAgIDB4NzAsIC8vIGZsYWcgLSBWZXJzaW9uIDAxLCBibG9jayBpbmRlcGVuZGVudCwgd2l0aCBibG9jayBjaGVja3N1bSwgbm8gY29udGVudCBzaXplLCBubyBjb250ZW50IGNoZWNrc3VtCisgICAgICAgICAgICAweDcwLCAvLyBibG9jayBzaXplIDRNQgorICAgICAgICAgICAgMTE0LCAvLyBjaGVja3N1bQorICAgICAgICAgICAgMTMsIDAsIDAsIChieXRlKSAweDgwLCAvLyAxMyBieXRlcyBsZW5ndGggYW5kIHVuY29tcHJlc3NlZCBiaXQgc2V0CisgICAgICAgICAgICAnSCcsICdlJywgJ2wnLCAnbCcsICdvJywgJywnLCAnICcsICd3JywgJ28nLCAncicsICdsJywgJ2QnLCAnIScsIC8vIGNvbnRlbnQKKyAgICAgICAgfTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRyeSAoSW5wdXRTdHJlYW0gYSA9IG5ldyBGcmFtZWRMWjRDb21wcmVzc29ySW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGlucHV0KSkpIHsKKyAgICAgICAgICAgICAgICBJT1V0aWxzLnRvQnl0ZUFycmF5KGEpOworICAgICAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIGV4Y2VwdGlvbiIpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgYXNzZXJ0VGhhdChleC5nZXRNZXNzYWdlKCksIGNvbnRhaW5zU3RyaW5nKCJibG9jayBjaGVja3N1bSIpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgcmVqZWN0c1N0cmVhbXNXaXRob3V0Q29udGVudENoZWNrc3VtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGlucHV0ID0gbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICA0LCAweDIyLCAweDRkLCAweDE4LCAvLyBzaWduYXR1cmUKKyAgICAgICAgICAgIDB4NjQsIC8vIGZsYWcgLSBWZXJzaW9uIDAxLCBibG9jayBpbmRlcGVuZGVudCwgbm8gYmxvY2sgY2hlY2tzdW0sIG5vIGNvbnRlbnQgc2l6ZSwgd2l0aCBjb250ZW50IGNoZWNrc3VtCisgICAgICAgICAgICAweDcwLCAvLyBibG9jayBzaXplIDRNQgorICAgICAgICAgICAgKGJ5dGUpIDE4NSwgLy8gY2hlY2tzdW0KKyAgICAgICAgICAgIDEzLCAwLCAwLCAoYnl0ZSkgMHg4MCwgLy8gMTMgYnl0ZXMgbGVuZ3RoIGFuZCB1bmNvbXByZXNzZWQgYml0IHNldAorICAgICAgICAgICAgJ0gnLCAnZScsICdsJywgJ2wnLCAnbycsICcsJywgJyAnLCAndycsICdvJywgJ3InLCAnbCcsICdkJywgJyEnLCAvLyBjb250ZW50CisgICAgICAgICAgICAwLCAwLCAwLCAwLCAvLyBlbXB0eSBibG9jayBtYXJrZXIKKyAgICAgICAgfTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRyeSAoSW5wdXRTdHJlYW0gYSA9IG5ldyBGcmFtZWRMWjRDb21wcmVzc29ySW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGlucHV0KSkpIHsKKyAgICAgICAgICAgICAgICBJT1V0aWxzLnRvQnl0ZUFycmF5KGEpOworICAgICAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIGV4Y2VwdGlvbiIpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgYXNzZXJ0VGhhdChleC5nZXRNZXNzYWdlKCksIGNvbnRhaW5zU3RyaW5nKCJjb250ZW50IGNoZWNrc3VtIikpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCByZWplY3RzU3RyZWFtc1dpdGhCYWRDb250ZW50Q2hlY2tzdW0oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBieXRlW10gaW5wdXQgPSBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgIDQsIDB4MjIsIDB4NGQsIDB4MTgsIC8vIHNpZ25hdHVyZQorICAgICAgICAgICAgMHg2NCwgLy8gZmxhZyAtIFZlcnNpb24gMDEsIGJsb2NrIGluZGVwZW5kZW50LCBubyBibG9jayBjaGVja3N1bSwgbm8gY29udGVudCBzaXplLCB3aXRoIGNvbnRlbnQgY2hlY2tzdW0KKyAgICAgICAgICAgIDB4NzAsIC8vIGJsb2NrIHNpemUgNE1CCisgICAgICAgICAgICAoYnl0ZSkgMTg1LCAvLyBjaGVja3N1bQorICAgICAgICAgICAgMTMsIDAsIDAsIChieXRlKSAweDgwLCAvLyAxMyBieXRlcyBsZW5ndGggYW5kIHVuY29tcHJlc3NlZCBiaXQgc2V0CisgICAgICAgICAgICAnSCcsICdlJywgJ2wnLCAnbCcsICdvJywgJywnLCAnICcsICd3JywgJ28nLCAncicsICdsJywgJ2QnLCAnIScsIC8vIGNvbnRlbnQKKyAgICAgICAgICAgIDAsIDAsIDAsIDAsIC8vIGVtcHR5IGJsb2NrIG1hcmtlcgorICAgICAgICAgICAgMSwgMiwgMywgNCwKKyAgICAgICAgfTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRyeSAoSW5wdXRTdHJlYW0gYSA9IG5ldyBGcmFtZWRMWjRDb21wcmVzc29ySW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGlucHV0KSkpIHsKKyAgICAgICAgICAgICAgICBJT1V0aWxzLnRvQnl0ZUFycmF5KGEpOworICAgICAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIGV4Y2VwdGlvbiIpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgYXNzZXJ0VGhhdChleC5nZXRNZXNzYWdlKCksIGNvbnRhaW5zU3RyaW5nKCJjb250ZW50IGNoZWNrc3VtIG1pc21hdGNoIikpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBza2lwc092ZXJTa2lwcGFibGVGcmFtZXMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBieXRlW10gaW5wdXQgPSBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgIDQsIDB4MjIsIDB4NGQsIDB4MTgsIC8vIHNpZ25hdHVyZQorICAgICAgICAgICAgMHg2MCwgLy8gZmxhZyAtIFZlcnNpb24gMDEsIGJsb2NrIGluZGVwZW5kZW50LCBubyBibG9jayBjaGVja3N1bSwgbm8gY29udGVudCBzaXplLCBubyBjb250ZW50IGNoZWNrc3VtCisgICAgICAgICAgICAweDcwLCAvLyBibG9jayBzaXplIDRNQgorICAgICAgICAgICAgMTE1LCAvLyBjaGVja3N1bQorICAgICAgICAgICAgMTMsIDAsIDAsIChieXRlKSAweDgwLCAvLyAxMyBieXRlcyBsZW5ndGggYW5kIHVuY29tcHJlc3NlZCBiaXQgc2V0CisgICAgICAgICAgICAnSCcsICdlJywgJ2wnLCAnbCcsICdvJywgJywnLCAnICcsICd3JywgJ28nLCAncicsICdsJywgJ2QnLCAnIScsIC8vIGNvbnRlbnQKKyAgICAgICAgICAgIDAsIDAsIDAsIDAsIC8vIGVtcHR5IGJsb2NrIG1hcmtlcgorICAgICAgICAgICAgMHg1ZiwgMHgyYSwgMHg0ZCwgMHgxOCwgLy8gc2tpcHBhYmxlIGZyYW1lIHNpZ25hdHVyZQorICAgICAgICAgICAgMiwgMCwgMCwgMCwgLy8gc2tpcHBhYmxlIGZyYW1lIGhhcyBsZW5ndGggMgorICAgICAgICAgICAgMSwgMiwgLy8gY29udGVudCBvZiBza2lwcGFibGUgZnJhbWUKKyAgICAgICAgICAgIDQsIDB4MjIsIDB4NGQsIDB4MTgsIC8vIHNpZ25hdHVyZQorICAgICAgICAgICAgMHg2MCwgLy8gZmxhZyAtIFZlcnNpb24gMDEsIGJsb2NrIGluZGVwZW5kZW50LCBubyBibG9jayBjaGVja3N1bSwgbm8gY29udGVudCBzaXplLCBubyBjb250ZW50IGNoZWNrc3VtCisgICAgICAgICAgICAweDcwLCAvLyBibG9jayBzaXplIDRNQgorICAgICAgICAgICAgMTE1LCAvLyBjaGVja3N1bQorICAgICAgICAgICAgMSwgMCwgMCwgKGJ5dGUpIDB4ODAsIC8vIDEgYnl0ZXMgbGVuZ3RoIGFuZCB1bmNvbXByZXNzZWQgYml0IHNldAorICAgICAgICAgICAgJyEnLCAvLyBjb250ZW50CisgICAgICAgICAgICAwLCAwLCAwLCAwLCAvLyBlbXB0eSBibG9jayBtYXJrZXIKKyAgICAgICAgfTsKKyAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBhID0gbmV3IEZyYW1lZExaNENvbXByZXNzb3JJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oaW5wdXQpLCB0cnVlKSkgeworICAgICAgICAgICAgYnl0ZVtdIGFjdHVhbCA9IElPVXRpbHMudG9CeXRlQXJyYXkoYSk7CisgICAgICAgICAgICBhc3NlcnRBcnJheUVxdWFscyhuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAgICAgJ0gnLCAnZScsICdsJywgJ2wnLCAnbycsICcsJywgJyAnLCAndycsICdvJywgJ3InLCAnbCcsICdkJywgJyEnLCAnIScKKyAgICAgICAgICAgICAgICB9LCBhY3R1YWwpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBza2lwc092ZXJUcmFpbGluZ1NraXBwYWJsZUZyYW1lcygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBpbnB1dCA9IG5ldyBieXRlW10geworICAgICAgICAgICAgNCwgMHgyMiwgMHg0ZCwgMHgxOCwgLy8gc2lnbmF0dXJlCisgICAgICAgICAgICAweDYwLCAvLyBmbGFnIC0gVmVyc2lvbiAwMSwgYmxvY2sgaW5kZXBlbmRlbnQsIG5vIGJsb2NrIGNoZWNrc3VtLCBubyBjb250ZW50IHNpemUsIG5vIGNvbnRlbnQgY2hlY2tzdW0KKyAgICAgICAgICAgIDB4NzAsIC8vIGJsb2NrIHNpemUgNE1CCisgICAgICAgICAgICAxMTUsIC8vIGNoZWNrc3VtCisgICAgICAgICAgICAxMywgMCwgMCwgKGJ5dGUpIDB4ODAsIC8vIDEzIGJ5dGVzIGxlbmd0aCBhbmQgdW5jb21wcmVzc2VkIGJpdCBzZXQKKyAgICAgICAgICAgICdIJywgJ2UnLCAnbCcsICdsJywgJ28nLCAnLCcsICcgJywgJ3cnLCAnbycsICdyJywgJ2wnLCAnZCcsICchJywgLy8gY29udGVudAorICAgICAgICAgICAgMCwgMCwgMCwgMCwgLy8gZW1wdHkgYmxvY2sgbWFya2VyCisgICAgICAgICAgICAweDUxLCAweDJhLCAweDRkLCAweDE4LCAvLyBza2lwcGFibGUgZnJhbWUgc2lnbmF0dXJlCisgICAgICAgICAgICAyLCAwLCAwLCAwLCAvLyBza2lwcGFibGUgZnJhbWUgaGFzIGxlbmd0aCAyCisgICAgICAgICAgICAxLCAyLCAvLyBjb250ZW50IG9mIHNraXBwYWJsZSBmcmFtZQorICAgICAgICB9OworICAgICAgICB0cnkgKElucHV0U3RyZWFtIGEgPSBuZXcgRnJhbWVkTFo0Q29tcHJlc3NvcklucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShpbnB1dCksIHRydWUpKSB7CisgICAgICAgICAgICBieXRlW10gYWN0dWFsID0gSU9VdGlscy50b0J5dGVBcnJheShhKTsKKyAgICAgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKG5ldyBieXRlW10geworICAgICAgICAgICAgICAgICAgICAnSCcsICdlJywgJ2wnLCAnbCcsICdvJywgJywnLCAnICcsICd3JywgJ28nLCAncicsICdsJywgJ2QnLCAnIScKKyAgICAgICAgICAgICAgICB9LCBhY3R1YWwpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCByZWplY3RzU2tpcHBhYmxlRnJhbWVGb2xsb3dlZEJ5SnVuaygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBpbnB1dCA9IG5ldyBieXRlW10geworICAgICAgICAgICAgNCwgMHgyMiwgMHg0ZCwgMHgxOCwgLy8gc2lnbmF0dXJlCisgICAgICAgICAgICAweDYwLCAvLyBmbGFnIC0gVmVyc2lvbiAwMSwgYmxvY2sgaW5kZXBlbmRlbnQsIG5vIGJsb2NrIGNoZWNrc3VtLCBubyBjb250ZW50IHNpemUsIG5vIGNvbnRlbnQgY2hlY2tzdW0KKyAgICAgICAgICAgIDB4NzAsIC8vIGJsb2NrIHNpemUgNE1CCisgICAgICAgICAgICAxMTUsIC8vIGNoZWNrc3VtCisgICAgICAgICAgICAxMywgMCwgMCwgKGJ5dGUpIDB4ODAsIC8vIDEzIGJ5dGVzIGxlbmd0aCBhbmQgdW5jb21wcmVzc2VkIGJpdCBzZXQKKyAgICAgICAgICAgICdIJywgJ2UnLCAnbCcsICdsJywgJ28nLCAnLCcsICcgJywgJ3cnLCAnbycsICdyJywgJ2wnLCAnZCcsICchJywgLy8gY29udGVudAorICAgICAgICAgICAgMCwgMCwgMCwgMCwgLy8gZW1wdHkgYmxvY2sgbWFya2VyCisgICAgICAgICAgICAweDUwLCAweDJhLCAweDRkLCAweDE4LCAvLyBza2lwcGFibGUgZnJhbWUgc2lnbmF0dXJlCisgICAgICAgICAgICAyLCAwLCAwLCAwLCAvLyBza2lwcGFibGUgZnJhbWUgaGFzIGxlbmd0aCAyCisgICAgICAgICAgICAxLCAyLCAvLyBjb250ZW50IG9mIHNraXBwYWJsZSBmcmFtZQorICAgICAgICAgICAgMSwgMHgyMiwgMHg0ZCwgMHgxOCwgLy8gYmFkIHNpZ25hdHVyZQorICAgICAgICB9OworICAgICAgICB0cnkgeworICAgICAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBhID0gbmV3IEZyYW1lZExaNENvbXByZXNzb3JJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oaW5wdXQpLCB0cnVlKSkgeworICAgICAgICAgICAgICAgIElPVXRpbHMudG9CeXRlQXJyYXkoYSk7CisgICAgICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgZXhjZXB0aW9uIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBhc3NlcnRUaGF0KGV4LmdldE1lc3NhZ2UoKSwgY29udGFpbnNTdHJpbmcoImdhcmJhZ2UiKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHJlamVjdHNTa2lwcGFibGVGcmFtZUZvbGxvd2VkQnlUb29GZXdCeXRlcygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBpbnB1dCA9IG5ldyBieXRlW10geworICAgICAgICAgICAgNCwgMHgyMiwgMHg0ZCwgMHgxOCwgLy8gc2lnbmF0dXJlCisgICAgICAgICAgICAweDYwLCAvLyBmbGFnIC0gVmVyc2lvbiAwMSwgYmxvY2sgaW5kZXBlbmRlbnQsIG5vIGJsb2NrIGNoZWNrc3VtLCBubyBjb250ZW50IHNpemUsIG5vIGNvbnRlbnQgY2hlY2tzdW0KKyAgICAgICAgICAgIDB4NzAsIC8vIGJsb2NrIHNpemUgNE1CCisgICAgICAgICAgICAxMTUsIC8vIGNoZWNrc3VtCisgICAgICAgICAgICAxMywgMCwgMCwgKGJ5dGUpIDB4ODAsIC8vIDEzIGJ5dGVzIGxlbmd0aCBhbmQgdW5jb21wcmVzc2VkIGJpdCBzZXQKKyAgICAgICAgICAgICdIJywgJ2UnLCAnbCcsICdsJywgJ28nLCAnLCcsICcgJywgJ3cnLCAnbycsICdyJywgJ2wnLCAnZCcsICchJywgLy8gY29udGVudAorICAgICAgICAgICAgMCwgMCwgMCwgMCwgLy8gZW1wdHkgYmxvY2sgbWFya2VyCisgICAgICAgICAgICAweDUyLCAweDJhLCAweDRkLCAweDE4LCAvLyBza2lwcGFibGUgZnJhbWUgc2lnbmF0dXJlCisgICAgICAgICAgICAyLCAwLCAwLCAwLCAvLyBza2lwcGFibGUgZnJhbWUgaGFzIGxlbmd0aCAyCisgICAgICAgICAgICAxLCAyLCAvLyBjb250ZW50IG9mIHNraXBwYWJsZSBmcmFtZQorICAgICAgICAgICAgNCwgLy8gdG9vIHNob3J0IGZvciBzaWduYXR1cmUKKyAgICAgICAgfTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRyeSAoSW5wdXRTdHJlYW0gYSA9IG5ldyBGcmFtZWRMWjRDb21wcmVzc29ySW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGlucHV0KSwgdHJ1ZSkpIHsKKyAgICAgICAgICAgICAgICBJT1V0aWxzLnRvQnl0ZUFycmF5KGEpOworICAgICAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIGV4Y2VwdGlvbiIpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgYXNzZXJ0VGhhdChleC5nZXRNZXNzYWdlKCksIGNvbnRhaW5zU3RyaW5nKCJnYXJiYWdlIikpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCByZWplY3RzU2tpcHBhYmxlRnJhbWVXaXRoUHJlbWF0dXJlRW5kKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGlucHV0ID0gbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICA0LCAweDIyLCAweDRkLCAweDE4LCAvLyBzaWduYXR1cmUKKyAgICAgICAgICAgIDB4NjAsIC8vIGZsYWcgLSBWZXJzaW9uIDAxLCBibG9jayBpbmRlcGVuZGVudCwgbm8gYmxvY2sgY2hlY2tzdW0sIG5vIGNvbnRlbnQgc2l6ZSwgbm8gY29udGVudCBjaGVja3N1bQorICAgICAgICAgICAgMHg3MCwgLy8gYmxvY2sgc2l6ZSA0TUIKKyAgICAgICAgICAgIDExNSwgLy8gY2hlY2tzdW0KKyAgICAgICAgICAgIDEzLCAwLCAwLCAoYnl0ZSkgMHg4MCwgLy8gMTMgYnl0ZXMgbGVuZ3RoIGFuZCB1bmNvbXByZXNzZWQgYml0IHNldAorICAgICAgICAgICAgJ0gnLCAnZScsICdsJywgJ2wnLCAnbycsICcsJywgJyAnLCAndycsICdvJywgJ3InLCAnbCcsICdkJywgJyEnLCAvLyBjb250ZW50CisgICAgICAgICAgICAwLCAwLCAwLCAwLCAvLyBlbXB0eSBibG9jayBtYXJrZXIKKyAgICAgICAgICAgIDB4NTAsIDB4MmEsIDB4NGQsIDB4MTgsIC8vIHNraXBwYWJsZSBmcmFtZSBzaWduYXR1cmUKKyAgICAgICAgICAgIDIsIDAsIDAsIDAsIC8vIHNraXBwYWJsZSBmcmFtZSBoYXMgbGVuZ3RoIDIKKyAgICAgICAgICAgIDEsIC8vIGNvbnRlbnQgb2Ygc2tpcHBhYmxlIGZyYW1lIChzaG91bGQgYmUgdHdvIGJ5dGVzKQorICAgICAgICB9OworICAgICAgICB0cnkgeworICAgICAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBhID0gbmV3IEZyYW1lZExaNENvbXByZXNzb3JJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oaW5wdXQpLCB0cnVlKSkgeworICAgICAgICAgICAgICAgIElPVXRpbHMudG9CeXRlQXJyYXkoYSk7CisgICAgICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgZXhjZXB0aW9uIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBhc3NlcnRUaGF0KGV4LmdldE1lc3NhZ2UoKSwgY29udGFpbnNTdHJpbmcoIlByZW1hdHVyZSBlbmQgb2Ygc3RyZWFtIHdoaWxlIHNraXBwaW5nIGZyYW1lIikpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCByZWplY3RzU2tpcHBhYmxlRnJhbWVXaXRoUHJlbWF0dXJlRW5kSW5MZW5ndGhCeXRlcygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBpbnB1dCA9IG5ldyBieXRlW10geworICAgICAgICAgICAgNCwgMHgyMiwgMHg0ZCwgMHgxOCwgLy8gc2lnbmF0dXJlCisgICAgICAgICAgICAweDYwLCAvLyBmbGFnIC0gVmVyc2lvbiAwMSwgYmxvY2sgaW5kZXBlbmRlbnQsIG5vIGJsb2NrIGNoZWNrc3VtLCBubyBjb250ZW50IHNpemUsIG5vIGNvbnRlbnQgY2hlY2tzdW0KKyAgICAgICAgICAgIDB4NzAsIC8vIGJsb2NrIHNpemUgNE1CCisgICAgICAgICAgICAxMTUsIC8vIGNoZWNrc3VtCisgICAgICAgICAgICAxMywgMCwgMCwgKGJ5dGUpIDB4ODAsIC8vIDEzIGJ5dGVzIGxlbmd0aCBhbmQgdW5jb21wcmVzc2VkIGJpdCBzZXQKKyAgICAgICAgICAgICdIJywgJ2UnLCAnbCcsICdsJywgJ28nLCAnLCcsICcgJywgJ3cnLCAnbycsICdyJywgJ2wnLCAnZCcsICchJywgLy8gY29udGVudAorICAgICAgICAgICAgMCwgMCwgMCwgMCwgLy8gZW1wdHkgYmxvY2sgbWFya2VyCisgICAgICAgICAgICAweDU1LCAweDJhLCAweDRkLCAweDE4LCAvLyBza2lwcGFibGUgZnJhbWUgc2lnbmF0dXJlCisgICAgICAgICAgICAyLCAwLCAwLCAvLyBzaG91bGQgYmUgZm91ciBieXRlIGxlbmd0aAorICAgICAgICB9OworICAgICAgICB0cnkgeworICAgICAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBhID0gbmV3IEZyYW1lZExaNENvbXByZXNzb3JJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oaW5wdXQpLCB0cnVlKSkgeworICAgICAgICAgICAgICAgIElPVXRpbHMudG9CeXRlQXJyYXkoYSk7CisgICAgICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgZXhjZXB0aW9uIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBhc3NlcnRUaGF0KGV4LmdldE1lc3NhZ2UoKSwgY29udGFpbnNTdHJpbmcoInByZW1hdHVyZSBlbmQgb2YgZGF0YSIpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgcmVqZWN0c1NraXBwYWJsZUZyYW1lV2l0aEJhZFNpZ25hdHVyZVRyYWlsZXIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBieXRlW10gaW5wdXQgPSBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgIDQsIDB4MjIsIDB4NGQsIDB4MTgsIC8vIHNpZ25hdHVyZQorICAgICAgICAgICAgMHg2MCwgLy8gZmxhZyAtIFZlcnNpb24gMDEsIGJsb2NrIGluZGVwZW5kZW50LCBubyBibG9jayBjaGVja3N1bSwgbm8gY29udGVudCBzaXplLCBubyBjb250ZW50IGNoZWNrc3VtCisgICAgICAgICAgICAweDcwLCAvLyBibG9jayBzaXplIDRNQgorICAgICAgICAgICAgMTE1LCAvLyBjaGVja3N1bQorICAgICAgICAgICAgMTMsIDAsIDAsIChieXRlKSAweDgwLCAvLyAxMyBieXRlcyBsZW5ndGggYW5kIHVuY29tcHJlc3NlZCBiaXQgc2V0CisgICAgICAgICAgICAnSCcsICdlJywgJ2wnLCAnbCcsICdvJywgJywnLCAnICcsICd3JywgJ28nLCAncicsICdsJywgJ2QnLCAnIScsIC8vIGNvbnRlbnQKKyAgICAgICAgICAgIDAsIDAsIDAsIDAsIC8vIGVtcHR5IGJsb2NrIG1hcmtlcgorICAgICAgICAgICAgMHg1MSwgMHgyYSwgMHg0ZCwgMHgxNywgLy8gYnJva2VuIHNraXBwYWJsZSBmcmFtZSBzaWduYXR1cmUKKyAgICAgICAgfTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRyeSAoSW5wdXRTdHJlYW0gYSA9IG5ldyBGcmFtZWRMWjRDb21wcmVzc29ySW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGlucHV0KSwgdHJ1ZSkpIHsKKyAgICAgICAgICAgICAgICBJT1V0aWxzLnRvQnl0ZUFycmF5KGEpOworICAgICAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIGV4Y2VwdGlvbiIpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgYXNzZXJ0VGhhdChleC5nZXRNZXNzYWdlKCksIGNvbnRhaW5zU3RyaW5nKCJnYXJiYWdlIikpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCByZWplY3RzU2tpcHBhYmxlRnJhbWVXaXRoQmFkU2lnbmF0dXJlUHJlZml4KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGlucHV0ID0gbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICA0LCAweDIyLCAweDRkLCAweDE4LCAvLyBzaWduYXR1cmUKKyAgICAgICAgICAgIDB4NjAsIC8vIGZsYWcgLSBWZXJzaW9uIDAxLCBibG9jayBpbmRlcGVuZGVudCwgbm8gYmxvY2sgY2hlY2tzdW0sIG5vIGNvbnRlbnQgc2l6ZSwgbm8gY29udGVudCBjaGVja3N1bQorICAgICAgICAgICAgMHg3MCwgLy8gYmxvY2sgc2l6ZSA0TUIKKyAgICAgICAgICAgIDExNSwgLy8gY2hlY2tzdW0KKyAgICAgICAgICAgIDEzLCAwLCAwLCAoYnl0ZSkgMHg4MCwgLy8gMTMgYnl0ZXMgbGVuZ3RoIGFuZCB1bmNvbXByZXNzZWQgYml0IHNldAorICAgICAgICAgICAgJ0gnLCAnZScsICdsJywgJ2wnLCAnbycsICcsJywgJyAnLCAndycsICdvJywgJ3InLCAnbCcsICdkJywgJyEnLCAvLyBjb250ZW50CisgICAgICAgICAgICAwLCAwLCAwLCAwLCAvLyBlbXB0eSBibG9jayBtYXJrZXIKKyAgICAgICAgICAgIDB4NjAsIDB4MmEsIDB4NGQsIDB4MTgsIC8vIGJyb2tlbiBza2lwcGFibGUgZnJhbWUgc2lnbmF0dXJlCisgICAgICAgIH07CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0cnkgKElucHV0U3RyZWFtIGEgPSBuZXcgRnJhbWVkTFo0Q29tcHJlc3NvcklucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShpbnB1dCksIHRydWUpKSB7CisgICAgICAgICAgICAgICAgSU9VdGlscy50b0J5dGVBcnJheShhKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBleGNlcHRpb24iKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGFzc2VydFRoYXQoZXguZ2V0TWVzc2FnZSgpLCBjb250YWluc1N0cmluZygiZ2FyYmFnZSIpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgcmVqZWN0c1RyYWlsaW5nQnl0ZXNBZnRlclZhbGlkRnJhbWUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBieXRlW10gaW5wdXQgPSBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgIDQsIDB4MjIsIDB4NGQsIDB4MTgsIC8vIHNpZ25hdHVyZQorICAgICAgICAgICAgMHg2MCwgLy8gZmxhZyAtIFZlcnNpb24gMDEsIGJsb2NrIGluZGVwZW5kZW50LCBubyBibG9jayBjaGVja3N1bSwgbm8gY29udGVudCBzaXplLCBubyBjb250ZW50IGNoZWNrc3VtCisgICAgICAgICAgICAweDcwLCAvLyBibG9jayBzaXplIDRNQgorICAgICAgICAgICAgMTE1LCAvLyBjaGVja3N1bQorICAgICAgICAgICAgMTMsIDAsIDAsIChieXRlKSAweDgwLCAvLyAxMyBieXRlcyBsZW5ndGggYW5kIHVuY29tcHJlc3NlZCBiaXQgc2V0CisgICAgICAgICAgICAnSCcsICdlJywgJ2wnLCAnbCcsICdvJywgJywnLCAnICcsICd3JywgJ28nLCAncicsICdsJywgJ2QnLCAnIScsIC8vIGNvbnRlbnQKKyAgICAgICAgICAgIDAsIDAsIDAsIDAsIC8vIGVtcHR5IGJsb2NrIG1hcmtlcgorICAgICAgICAgICAgMHg1NiwgMHgyYSwgMHg0ZCwgLy8gdG9vIHNob3J0IGZvciBhbnkgc2lnbmF0dXJlCisgICAgICAgIH07CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0cnkgKElucHV0U3RyZWFtIGEgPSBuZXcgRnJhbWVkTFo0Q29tcHJlc3NvcklucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShpbnB1dCksIHRydWUpKSB7CisgICAgICAgICAgICAgICAgSU9VdGlscy50b0J5dGVBcnJheShhKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBleGNlcHRpb24iKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGFzc2VydFRoYXQoZXguZ2V0TWVzc2FnZSgpLCBjb250YWluc1N0cmluZygiZ2FyYmFnZSIpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgc2luZ2xlQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGUgaW5wdXQgPSBnZXRGaWxlKCJibGEudGFyLmx6NCIpOworICAgICAgICB0cnkgKElucHV0U3RyZWFtIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShpbnB1dCkpIHsKKyAgICAgICAgICAgIGZpbmFsIEZyYW1lZExaNENvbXByZXNzb3JJbnB1dFN0cmVhbSBpbiA9CisgICAgICAgICAgICAgICAgICAgIG5ldyBGcmFtZWRMWjRDb21wcmVzc29ySW5wdXRTdHJlYW0oaXMpOworICAgICAgICAgICAgSU9VdGlscy50b0J5dGVBcnJheShpbik7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIGluLnJlYWQoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIGluLnJlYWQoKSk7CisgICAgICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBtdWx0aUJ5dGVSZWFkQ29uc2lzdGVudGx5UmV0dXJuc01pbnVzT25lQXRFb2YoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlIGlucHV0ID0gZ2V0RmlsZSgiYmxhLnRhci5sejQiKTsKKyAgICAgICAgYnl0ZVtdIGJ1ZiA9IG5ldyBieXRlWzJdOworICAgICAgICB0cnkgKElucHV0U3RyZWFtIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShpbnB1dCkpIHsKKyAgICAgICAgICAgIGZpbmFsIEZyYW1lZExaNENvbXByZXNzb3JJbnB1dFN0cmVhbSBpbiA9CisgICAgICAgICAgICAgICAgICAgIG5ldyBGcmFtZWRMWjRDb21wcmVzc29ySW5wdXRTdHJlYW0oaXMpOworICAgICAgICAgICAgSU9VdGlscy50b0J5dGVBcnJheShpbik7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIGluLnJlYWQoYnVmKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIGluLnJlYWQoYnVmKSk7CisgICAgICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgaW50ZXJmYWNlIFN0cmVhbVdyYXBwZXIgeworICAgICAgICBJbnB1dFN0cmVhbSB3cmFwKElucHV0U3RyZWFtIGluKSB0aHJvd3MgRXhjZXB0aW9uOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByZWFkRG91YmxlZEJsYUx6NChTdHJlYW1XcmFwcGVyIHdyYXBwZXIsIGJvb2xlYW4gZXhwZWN0RHVwbGljYXRlT3V0cHV0KSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIHNpbmdsZUlucHV0OworICAgICAgICB0cnkgKElucHV0U3RyZWFtIGkgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGdldEZpbGUoImJsYS50YXIubHo0IikpKSB7CisgICAgICAgICAgICBzaW5nbGVJbnB1dCA9IElPVXRpbHMudG9CeXRlQXJyYXkoaSk7CisgICAgICAgIH0KKyAgICAgICAgYnl0ZVtdIGlucHV0ID0gZHVwbGljYXRlKHNpbmdsZUlucHV0KTsKKyAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBhID0gd3JhcHBlci53cmFwKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShpbnB1dCkpOworICAgICAgICAgICAgRmlsZUlucHV0U3RyZWFtIGUgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGdldEZpbGUoImJsYS50YXIiKSkpIHsKKyAgICAgICAgICAgIGJ5dGVbXSBleHBlY3RlZCA9IElPVXRpbHMudG9CeXRlQXJyYXkoZSk7CisgICAgICAgICAgICBieXRlW10gYWN0dWFsID0gSU9VdGlscy50b0J5dGVBcnJheShhKTsKKyAgICAgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKGV4cGVjdER1cGxpY2F0ZU91dHB1dCA/IGR1cGxpY2F0ZShleHBlY3RlZCkgOiBleHBlY3RlZCwgYWN0dWFsKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGJ5dGVbXSBkdXBsaWNhdGUoYnl0ZVtdIGZyb20pIHsKKyAgICAgICAgYnl0ZVtdIHRvID0gQXJyYXlzLmNvcHlPZihmcm9tLCAyICogZnJvbS5sZW5ndGgpOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGZyb20sIDAsIHRvLCBmcm9tLmxlbmd0aCwgZnJvbS5sZW5ndGgpOworICAgICAgICByZXR1cm4gdG87CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvbHo0L0ZyYW1lZExaNENvbXByZXNzb3JSb3VuZHRyaXBUZXN0LmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9sejQvRnJhbWVkTFo0Q29tcHJlc3NvclJvdW5kdHJpcFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yOWU0NDQzCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvbHo0L0ZyYW1lZExaNENvbXByZXNzb3JSb3VuZHRyaXBUZXN0LmphdmEKQEAgLTAsMCArMSwxMTAgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMubHo0OworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5BYnN0cmFjdFRlc3RDYXNlOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5JT1V0aWxzOworaW1wb3J0IG9yZy5qdW5pdC5Bc3NlcnQ7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lci5SdW5XaXRoOworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXJzLlBhcmFtZXRlcml6ZWQ7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lcnMuUGFyYW1ldGVyaXplZC5QYXJhbWV0ZXJzOworCitAUnVuV2l0aChQYXJhbWV0ZXJpemVkLmNsYXNzKQorcHVibGljIGZpbmFsIGNsYXNzIEZyYW1lZExaNENvbXByZXNzb3JSb3VuZHRyaXBUZXN0IGV4dGVuZHMgQWJzdHJhY3RUZXN0Q2FzZSB7CisKKyAgICBAUGFyYW1ldGVycyhuYW1lID0gInVzaW5nIHswfSIpCisgICAgcHVibGljIHN0YXRpYyBDb2xsZWN0aW9uPE9iamVjdFtdPiBmYWN0b3J5KCkgeworICAgICAgICByZXR1cm4gQXJyYXlzLmFzTGlzdChuZXcgT2JqZWN0W11bXSB7CisgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBuZXcgRnJhbWVkTFo0Q29tcHJlc3Nvck91dHB1dFN0cmVhbS5QYXJhbWV0ZXJzKEZyYW1lZExaNENvbXByZXNzb3JPdXRwdXRTdHJlYW0uQmxvY2tTaXplLks2NCkgfSwKKyAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IG5ldyBGcmFtZWRMWjRDb21wcmVzc29yT3V0cHV0U3RyZWFtLlBhcmFtZXRlcnMoRnJhbWVkTFo0Q29tcHJlc3Nvck91dHB1dFN0cmVhbS5CbG9ja1NpemUuSzI1NikgfSwKKyAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IG5ldyBGcmFtZWRMWjRDb21wcmVzc29yT3V0cHV0U3RyZWFtLlBhcmFtZXRlcnMoRnJhbWVkTFo0Q29tcHJlc3Nvck91dHB1dFN0cmVhbS5CbG9ja1NpemUuTTEpIH0sCisgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBGcmFtZWRMWjRDb21wcmVzc29yT3V0cHV0U3RyZWFtLlBhcmFtZXRlcnMuREVGQVVMVCB9LAorICAgICAgICAgICAgLy8gZGVmYXVsdCB3aXRob3V0IGNvbnRlbnQgY2hlY2tzdW0KKyAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IG5ldyBGcmFtZWRMWjRDb21wcmVzc29yT3V0cHV0U3RyZWFtLlBhcmFtZXRlcnMoRnJhbWVkTFo0Q29tcHJlc3Nvck91dHB1dFN0cmVhbS5CbG9ja1NpemUuTTQsCisgICAgICAgICAgICAgICAgZmFsc2UsIGZhbHNlLCBmYWxzZSkgfSwKKyAgICAgICAgICAgIC8vIGRlZmF1bHQgd2l0aCBibG9jayBjaGVja3N1bQorICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgbmV3IEZyYW1lZExaNENvbXByZXNzb3JPdXRwdXRTdHJlYW0uUGFyYW1ldGVycyhGcmFtZWRMWjRDb21wcmVzc29yT3V0cHV0U3RyZWFtLkJsb2NrU2l6ZS5NNCwKKyAgICAgICAgICAgICAgICB0cnVlLCB0cnVlLCBmYWxzZSkgfSwKKyAgICAgICAgICAgIC8vIHNtYWxsIGJsb2Nrc2l6ZSAoc28gd2UgZ2V0IGVub3VnaCBibG9ja3MpIGFuZCBlbmFibGVkIGJsb2NrIGRlcGVuZGVuY3ksIG90aGVyd2lzZSBkZWZhdWx0cworICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgbmV3IEZyYW1lZExaNENvbXByZXNzb3JPdXRwdXRTdHJlYW0uUGFyYW1ldGVycyhGcmFtZWRMWjRDb21wcmVzc29yT3V0cHV0U3RyZWFtLkJsb2NrU2l6ZS5LNjQsCisgICAgICAgICAgICAgICAgdHJ1ZSwgZmFsc2UsIHRydWUpIH0sCisgICAgICAgICAgICAvLyBkZWZhdWx0LCB0dW5lZCBmb3Igc3BlZWQKKyAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IG5ldyBGcmFtZWRMWjRDb21wcmVzc29yT3V0cHV0U3RyZWFtLlBhcmFtZXRlcnMoRnJhbWVkTFo0Q29tcHJlc3Nvck91dHB1dFN0cmVhbS5CbG9ja1NpemUuTTQsCisgICAgICAgICAgICAgICAgdHJ1ZSwgZmFsc2UsIGZhbHNlLCBCbG9ja0xaNENvbXByZXNzb3JPdXRwdXRTdHJlYW0uY3JlYXRlUGFyYW1ldGVyQnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgIC50dW5lZEZvclNwZWVkKCkuYnVpbGQoKSkgfSwKKyAgICAgICAgfSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBmaW5hbCBGcmFtZWRMWjRDb21wcmVzc29yT3V0cHV0U3RyZWFtLlBhcmFtZXRlcnMgcGFyYW1zOworCisgICAgcHVibGljIEZyYW1lZExaNENvbXByZXNzb3JSb3VuZHRyaXBUZXN0KEZyYW1lZExaNENvbXByZXNzb3JPdXRwdXRTdHJlYW0uUGFyYW1ldGVycyBwYXJhbXMpIHsKKyAgICAgICAgdGhpcy5wYXJhbXMgPSBwYXJhbXM7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHJvdW5kVHJpcFRlc3QoU3RyaW5nIHRlc3RGaWxlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBGaWxlIGlucHV0ID0gZ2V0RmlsZSh0ZXN0RmlsZSk7CisgICAgICAgIGxvbmcgc3RhcnQgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICAgICAgZmluYWwgRmlsZSBvdXRwdXRTeiA9IG5ldyBGaWxlKGRpciwgaW5wdXQuZ2V0TmFtZSgpICsgIi5mcmFtZWQubHo0Iik7CisgICAgICAgIGJ5dGVbXSBleHBlY3RlZDsKKyAgICAgICAgdHJ5IChGaWxlSW5wdXRTdHJlYW0gaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGlucHV0KSkgeworICAgICAgICAgICAgZXhwZWN0ZWQgPSBJT1V0aWxzLnRvQnl0ZUFycmF5KGlzKTsKKyAgICAgICAgfQorICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICB0cnkgKEZyYW1lZExaNENvbXByZXNzb3JPdXRwdXRTdHJlYW0gbG9zID0gbmV3IEZyYW1lZExaNENvbXByZXNzb3JPdXRwdXRTdHJlYW0oYm9zLAorICAgICAgICAgICAgcGFyYW1zKSkgeworICAgICAgICAgICAgSU9VdGlscy5jb3B5KG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShleHBlY3RlZCksIGxvcyk7CisgICAgICAgIH0KKyAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKGlucHV0LmdldE5hbWUoKSArICIgd3JpdHRlbiwgdW5jb21wcmVzc2VkIGJ5dGVzOiAiICsgaW5wdXQubGVuZ3RoKCkKKyAgICAgICAgICAgICsgIiwgY29tcHJlc3NlZCBieXRlczogIiArIG91dHB1dFN6Lmxlbmd0aCgpICsgIiBhZnRlciAiICsgKFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpIC0gc3RhcnQpICsgIm1zIik7CisgICAgICAgIHN0YXJ0ID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgICAgIHRyeSAoRnJhbWVkTFo0Q29tcHJlc3NvcklucHV0U3RyZWFtIHNpcyA9IG5ldyBGcmFtZWRMWjRDb21wcmVzc29ySW5wdXRTdHJlYW0oCisgICAgICAgICAgICBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYm9zLnRvQnl0ZUFycmF5KCkpKSkgeworICAgICAgICAgICAgYnl0ZVtdIGFjdHVhbCA9IElPVXRpbHMudG9CeXRlQXJyYXkoc2lzKTsKKyAgICAgICAgICAgIEFzc2VydC5hc3NlcnRBcnJheUVxdWFscyhleHBlY3RlZCwgYWN0dWFsKTsKKyAgICAgICAgfQorCisgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbihvdXRwdXRTei5nZXROYW1lKCkgKyAiIHJlYWQgYWZ0ZXIgIiArIChTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSAtIHN0YXJ0KSArICJtcyIpOworICAgIH0KKworICAgIC8vIHNob3VsZCB5aWVsZCBkZWNlbnQgY29tcHJlc3Npb24KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIGJsYVRhclJvdW5kdHJpcCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJvdW5kVHJpcFRlc3QoImJsYS50YXIiKTsKKyAgICB9CisKKyAgICAvLyB5aWVsZHMgbm8gY29tcHJlc3Npb24gYXQgYWxsCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBnemlwcGVkTG9yZW1JcHN1bVJvdW5kdHJpcCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJvdW5kVHJpcFRlc3QoImxvcmVtLWlwc3VtLnR4dC5neiIpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgYmlnZ2VyRmlsZVJvdW5kdHJpcCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJvdW5kVHJpcFRlc3QoIkNPTVBSRVNTLTI1Ni43eiIpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvbHo0L1hYSGFzaDMyVGVzdC5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvbHo0L1hYSGFzaDMyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBjN2U0NjIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9sejQvWFhIYXNoMzJUZXN0LmphdmEKQEAgLTAsMCArMSw2NiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5sejQ7CisKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLkFic3RyYWN0VGVzdENhc2U7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLklPVXRpbHM7CisKK2ltcG9ydCBvcmcuanVuaXQuQXNzZXJ0OworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXJzLlBhcmFtZXRlcml6ZWQ7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lcnMuUGFyYW1ldGVyaXplZC5QYXJhbWV0ZXJzOworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXIuUnVuV2l0aDsKKworQFJ1bldpdGgoUGFyYW1ldGVyaXplZC5jbGFzcykKK3B1YmxpYyBjbGFzcyBYWEhhc2gzMlRlc3QgeworCisgICAgcHJpdmF0ZSBmaW5hbCBGaWxlIGZpbGU7CisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgZXhwZWN0ZWRDaGVja3N1bTsKKworICAgIHB1YmxpYyBYWEhhc2gzMlRlc3QoU3RyaW5nIGZpbGVOYW1lLCBTdHJpbmcgYykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmlsZSA9IEFic3RyYWN0VGVzdENhc2UuZ2V0RmlsZShmaWxlTmFtZSk7CisgICAgICAgIGV4cGVjdGVkQ2hlY2tzdW0gPSBjOworICAgIH0KKworICAgIEBQYXJhbWV0ZXJzCisgICAgcHVibGljIHN0YXRpYyBDb2xsZWN0aW9uPE9iamVjdFtdPiBmYWN0b3J5KCkgeworICAgICAgICByZXR1cm4gQXJyYXlzLmFzTGlzdChuZXcgT2JqZWN0W11bXSB7CisgICAgICAgICAgICAvLyByZWZlcmVuY2UgY2hlY2tzdW1zIGNyZWF0ZWQgd2l0aCB4eGgzMnN1bQorICAgICAgICAgICAgeyAiYmxhLnRhciIsICJmYmI1YzhkMSIgfSwKKyAgICAgICAgICAgIHsgImJsYS50YXIueHoiLCAiNDEwNmEyMDgiIH0sCisgICAgICAgICAgICB7ICI4LnBvc2l4LnRhci5neiIsICI5ZmNlMTE2YSIgfSwKKyAgICAgICAgfSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB2ZXJpZnlDaGVja3N1bSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFhYSGFzaDMyIGggPSBuZXcgWFhIYXNoMzIoKTsKKyAgICAgICAgdHJ5IChGaWxlSW5wdXRTdHJlYW0gcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oZmlsZSkpIHsKKyAgICAgICAgICAgIGJ5dGVbXSBiID0gSU9VdGlscy50b0J5dGVBcnJheShzKTsKKyAgICAgICAgICAgIGgudXBkYXRlKGIsIDAsIGIubGVuZ3RoKTsKKyAgICAgICAgfQorICAgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKCJjaGVja3N1bSBmb3IgIiArIGZpbGUuZ2V0TmFtZSgpLCBleHBlY3RlZENoZWNrc3VtLCBMb25nLnRvSGV4U3RyaW5nKGguZ2V0VmFsdWUoKSkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2x6NzdzdXBwb3J0L0Fic3RyYWN0TFo3N0NvbXByZXNzb3JJbnB1dFN0cmVhbVRlc3QuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2x6NzdzdXBwb3J0L0Fic3RyYWN0TFo3N0NvbXByZXNzb3JJbnB1dFN0cmVhbVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xYjhmN2Y5Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvbHo3N3N1cHBvcnQvQWJzdHJhY3RMWjc3Q29tcHJlc3NvcklucHV0U3RyZWFtVGVzdC5qYXZhCkBAIC0wLDAgKzEsODUgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMubHo3N3N1cHBvcnQ7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKKworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworCitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0QXJyYXlFcXVhbHM7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0RXF1YWxzOworCitwdWJsaWMgY2xhc3MgQWJzdHJhY3RMWjc3Q29tcHJlc3NvcklucHV0U3RyZWFtVGVzdCB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBUZXN0U3RyZWFtIGV4dGVuZHMgQWJzdHJhY3RMWjc3Q29tcHJlc3NvcklucHV0U3RyZWFtIHsKKyAgICAgICAgcHJpdmF0ZSBib29sZWFuIGxpdGVyYWw7CisgICAgICAgIFRlc3RTdHJlYW0oSW5wdXRTdHJlYW0gaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBzdXBlcihpbiwgMTAyNCk7CisgICAgICAgIH0KKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBpbnQgcmVhZChmaW5hbCBieXRlW10gYiwgZmluYWwgaW50IG9mZiwgZmluYWwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGlmIChsaXRlcmFsKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHJlYWRMaXRlcmFsKGIsIG9mZiwgbGVuKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiByZWFkQmFja1JlZmVyZW5jZShiLCBvZmYsIGxlbik7CisgICAgICAgIH0KKyAgICAgICAgdm9pZCBsaXRlcmFsKGludCBsZW4pIHsKKyAgICAgICAgICAgIHN0YXJ0TGl0ZXJhbChsZW4pOworICAgICAgICAgICAgbGl0ZXJhbCA9IHRydWU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdChleHBlY3RlZCA9IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbi5jbGFzcykKKyAgICBwdWJsaWMgdm9pZCBjYW50UHJlZmlsbEFmdGVyRGF0YUhhc0JlZW5SZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGRhdGEgPSBuZXcgYnl0ZVtdIHsgMSwgMiwgMywgNCB9OworICAgICAgICB0cnkgKFRlc3RTdHJlYW0gcyA9IG5ldyBUZXN0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShkYXRhKSkpIHsKKyAgICAgICAgICAgIHMubGl0ZXJhbCgzKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCBzLnJlYWQoKSk7CisgICAgICAgICAgICBzLnByZWZpbGwobmV3IGJ5dGVbXSB7IDEsIDIsIDMgfSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHByZWZpbGxDYW5CZVVzZWRGb3JCYWNrUmVmZXJlbmNlcygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBkYXRhID0gbmV3IGJ5dGVbXSB7IDEsIDIsIDMsIDQgfTsKKyAgICAgICAgdHJ5IChUZXN0U3RyZWFtIHMgPSBuZXcgVGVzdFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0obmV3IGJ5dGVbMF0pKSkgeworICAgICAgICAgICAgcy5wcmVmaWxsKGRhdGEpOworICAgICAgICAgICAgcy5zdGFydEJhY2tSZWZlcmVuY2UoMiwgNCk7CisgICAgICAgICAgICBieXRlW10gciA9IG5ldyBieXRlWzRdOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDQsIHMucmVhZChyKSk7CisgICAgICAgICAgICBhc3NlcnRBcnJheUVxdWFscyhuZXcgYnl0ZVtdIHsgMywgNCwgMywgNCB9LCByKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgaWZQcmVmaWxsRXhjZWVkc1dpbmRvd1NpemVUaGVMYXN0Qnl0ZXNBcmVVc2VkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGRhdGEgPSBuZXcgYnl0ZVsyMDQ4XTsKKyAgICAgICAgZGF0YVsyMDQ2XSA9IDM7CisgICAgICAgIGRhdGFbMjA0N10gPSA0OworICAgICAgICB0cnkgKFRlc3RTdHJlYW0gcyA9IG5ldyBUZXN0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShuZXcgYnl0ZVswXSkpKSB7CisgICAgICAgICAgICBzLnByZWZpbGwoZGF0YSk7CisgICAgICAgICAgICBzLnN0YXJ0QmFja1JlZmVyZW5jZSgyLCA0KTsKKyAgICAgICAgICAgIGJ5dGVbXSByID0gbmV3IGJ5dGVbNF07CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoNCwgcy5yZWFkKHIpKTsKKyAgICAgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKG5ldyBieXRlW10geyAzLCA0LCAzLCA0IH0sIHIpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvbHo3N3N1cHBvcnQvTFo3N0NvbXByZXNzb3JUZXN0LmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9sejc3c3VwcG9ydC9MWjc3Q29tcHJlc3NvclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kYjRlM2FiCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvbHo3N3N1cHBvcnQvTFo3N0NvbXByZXNzb3JUZXN0LmphdmEKQEAgLTAsMCArMSwzNTIgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMubHo3N3N1cHBvcnQ7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKKworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworCitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0QXJyYXlFcXVhbHM7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0RXF1YWxzOworCitwdWJsaWMgY2xhc3MgTFo3N0NvbXByZXNzb3JUZXN0IHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBCTEEsIFNBTSwgT05FX1RPX1RFTjsKKworICAgIHN0YXRpYyB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogRXhhbXBsZSBmcm9tICJBbiBFeHBsYW5hdGlvbiBvZiB0aGUgRGVmbGF0ZSBBbGdvcml0aG0iIGJ5ICJBbnRhZXVzIEZlbGRzcGFyIi4KKyAgICAgICAgICAgICAqIEBzZWUgImh0dHA6Ly96bGliLm5ldC9mZWxkc3Bhci5odG1sIgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBCTEEgPSAiQmxhaCBibGFoIGJsYWggYmxhaCBibGFoISIuZ2V0Qnl0ZXMoIkFTQ0lJIik7CisKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBFeGFtcGxlIGZyb20gV2lraXBlZGlhIGFydGljbGUgYWJvdXQgTFpTUy4KKyAgICAgICAgICAgICAqIE5vdGUgdGhlIGV4YW1wbGUgdXNlcyBpbmRpY2VzIGluc3RlYWQgb2Ygb2Zmc2V0cy4KKyAgICAgICAgICAgICAqIEBzZWUgImh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0xlbXBlbCVFMiU4MCU5M1ppdiVFMiU4MCU5M1N0b3JlciVFMiU4MCU5M1N6eW1hbnNraSIKKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgU0FNID0gKCJJIGFtIFNhbVxuIgorICAgICAgICAgICAgICAgICAgICsgIlxuIgorICAgICAgICAgICAgICAgICAgICsgIlNhbSBJIGFtXG4iCisgICAgICAgICAgICAgICAgICAgKyAiXG4iCisgICAgICAgICAgICAgICAgICAgKyAiVGhhdCBTYW0tSS1hbSFcbiIKKyAgICAgICAgICAgICAgICAgICArICJUaGF0IFNhbS1JLWFtIVxuIgorICAgICAgICAgICAgICAgICAgICsgIkkgZG8gbm90IGxpa2VcbiIKKyAgICAgICAgICAgICAgICAgICArICJ0aGF0IFNhbS1JLWFtIVxuIgorICAgICAgICAgICAgICAgICAgICsgIlxuIgorICAgICAgICAgICAgICAgICAgICsgIkRvIHlvdSBsaWtlIGdyZWVuIGVnZ3MgYW5kIGhhbT9cbiIKKyAgICAgICAgICAgICAgICAgICArICJcbiIKKyAgICAgICAgICAgICAgICAgICArICJJIGRvIG5vdCBsaWtlIHRoZW0sIFNhbS1JLWFtLlxuIgorICAgICAgICAgICAgICAgICAgICsgIkkgZG8gbm90IGxpa2UgZ3JlZW4gZWdncyBhbmQgaGFtLiIpLmdldEJ5dGVzKCJBU0NJSSIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIkFTQ0lJIG5vdCBzdXBwb3J0ZWQiKTsKKyAgICAgICAgfQorICAgICAgICBPTkVfVE9fVEVOID0gbmV3IGJ5dGVbXSB7IDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwIH07CisgICAgfQorCisgICAgcHJpdmF0ZSBMaXN0PExaNzdDb21wcmVzc29yLkJsb2NrPiBjb21wcmVzcyhQYXJhbWV0ZXJzIHBhcmFtcywgYnl0ZVtdLi4uIGNodW5rcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgTGlzdDxMWjc3Q29tcHJlc3Nvci5CbG9jaz4gYmxvY2tzID0gbmV3IEFycmF5TGlzdDw+KCk7CisgICAgICAgIExaNzdDb21wcmVzc29yIGMgPSBuZXcgTFo3N0NvbXByZXNzb3IocGFyYW1zLCBuZXcgTFo3N0NvbXByZXNzb3IuQ2FsbGJhY2soKSB7CisgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgYWNjZXB0KExaNzdDb21wcmVzc29yLkJsb2NrIGJsb2NrKSB7CisgICAgICAgICAgICAgICAgICAgIC8vU3lzdGVtLmVyci5wcmludGxuKGJsb2NrKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGJsb2NrIGluc3RhbmNlb2YgTFo3N0NvbXByZXNzb3IuTGl0ZXJhbEJsb2NrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyByZXBsYWNlIHdpdGggYSByZWFsIGNvcHkgb2YgZGF0YSBzbyB0ZXN0cworICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2FuIHNlZSB0aGUgcmVzdWx0cyBhcyB0aGV5J3ZlIGJlZW4gd2hlbgorICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIGNhbGxiYWNrIGhhcyBiZWVuIGNhbGxlZAorICAgICAgICAgICAgICAgICAgICAgICAgTFo3N0NvbXByZXNzb3IuTGl0ZXJhbEJsb2NrIGIgPSAoTFo3N0NvbXByZXNzb3IuTGl0ZXJhbEJsb2NrKSBibG9jazsKKyAgICAgICAgICAgICAgICAgICAgICAgIGludCBsZW4gPSBiLmdldExlbmd0aCgpOworICAgICAgICAgICAgICAgICAgICAgICAgYmxvY2sgPSBuZXcgTFo3N0NvbXByZXNzb3IuTGl0ZXJhbEJsb2NrKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFycmF5cy5jb3B5T2ZSYW5nZShiLmdldERhdGEoKSwgYi5nZXRPZmZzZXQoKSwgYi5nZXRPZmZzZXQoKSArIGxlbiksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgbGVuKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBibG9ja3MuYWRkKGJsb2NrKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9KTsKKyAgICAgICAgZm9yIChieXRlW10gY2h1bmsgOiBjaHVua3MpIHsKKyAgICAgICAgICAgIGMuY29tcHJlc3MoY2h1bmspOworICAgICAgICB9CisgICAgICAgIGMuZmluaXNoKCk7CisgICAgICAgIHJldHVybiBibG9ja3M7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBub25Db21wcmVzc2FibGVXaXRoTGVuZ3RoU21hbGxlclRoYW5MaXRlcmFsTWF4KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgTGlzdDxMWjc3Q29tcHJlc3Nvci5CbG9jaz4gYmxvY2tzID0gY29tcHJlc3MobmV3UGFyYW1ldGVycygxMjgpLCBPTkVfVE9fVEVOKTsKKyAgICAgICAgYXNzZXJ0U2l6ZSgyLCBibG9ja3MpOworICAgICAgICBhc3NlcnRMaXRlcmFsQmxvY2soT05FX1RPX1RFTiwgYmxvY2tzLmdldCgwKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBub25Db21wcmVzc2FibGVXaXRoTGVuZ3RoR3JlYXRlclRoYW5MaXRlcmFsTWF4QnV0TGVzc1RoYW5Ud2ljZVdpbmRvd1NpemUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBMaXN0PExaNzdDb21wcmVzc29yLkJsb2NrPiBibG9ja3MgPSBjb21wcmVzcyhuZXdQYXJhbWV0ZXJzKDgpLCBPTkVfVE9fVEVOKTsKKyAgICAgICAgYXNzZXJ0U2l6ZSgzLCBibG9ja3MpOworICAgICAgICBhc3NlcnRMaXRlcmFsQmxvY2sobmV3IGJ5dGVbXSB7IDEsIDIsIDMsIDQsIDUsIDYsIDcsIDggfSwgYmxvY2tzLmdldCgwKSk7CisgICAgICAgIGFzc2VydExpdGVyYWxCbG9jayhuZXcgYnl0ZVtdIHsgOSwgMTAgfSwgYmxvY2tzLmdldCgxKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBub25Db21wcmVzc2FibGVXaXRoTGVuZ3RoVGhhdEZvcmNlc1dpbmRvd1NsaWRlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgTGlzdDxMWjc3Q29tcHJlc3Nvci5CbG9jaz4gYmxvY2tzID0gY29tcHJlc3MobmV3UGFyYW1ldGVycyg0KSwgT05FX1RPX1RFTik7CisgICAgICAgIGFzc2VydFNpemUoNCwgYmxvY2tzKTsKKyAgICAgICAgYXNzZXJ0TGl0ZXJhbEJsb2NrKG5ldyBieXRlW10geyAxLCAyLCAzLCA0LCB9LCBibG9ja3MuZ2V0KDApKTsKKyAgICAgICAgYXNzZXJ0TGl0ZXJhbEJsb2NrKG5ldyBieXRlW10geyA1LCA2LCA3LCA4IH0sIGJsb2Nrcy5nZXQoMSkpOworICAgICAgICBhc3NlcnRMaXRlcmFsQmxvY2sobmV3IGJ5dGVbXSB7IDksIDEwIH0sIGJsb2Nrcy5nZXQoMikpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgbm9uQ29tcHJlc3NhYmxlU2VudEFzU2luZ2xlQnl0ZXMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBMaXN0PExaNzdDb21wcmVzc29yLkJsb2NrPiBibG9ja3MgPSBjb21wcmVzcyhuZXdQYXJhbWV0ZXJzKDgpLCBzdGFnZ2VyKE9ORV9UT19URU4pKTsKKyAgICAgICAgYXNzZXJ0U2l6ZSgzLCBibG9ja3MpOworICAgICAgICBhc3NlcnRMaXRlcmFsQmxvY2sobmV3IGJ5dGVbXSB7IDEsIDIsIDMsIDQsIDUsIDYsIDcsIDggfSwgYmxvY2tzLmdldCgwKSk7CisgICAgICAgIGFzc2VydExpdGVyYWxCbG9jayhuZXcgYnl0ZVtdIHsgOSwgMTAgfSwgYmxvY2tzLmdldCgxKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBibGFFeGFtcGxlV2l0aEZ1bGxBcnJheUF2YWlsYWJsZUZvckNvbXByZXNzaW9uKCkKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgTGlzdDxMWjc3Q29tcHJlc3Nvci5CbG9jaz4gYmxvY2tzID0gY29tcHJlc3MobmV3UGFyYW1ldGVycygxMjgpLCBCTEEpOworICAgICAgICBhc3NlcnRTaXplKDQsIGJsb2Nrcyk7CisgICAgICAgIGFzc2VydExpdGVyYWxCbG9jaygiQmxhaCBiIiwgYmxvY2tzLmdldCgwKSk7CisgICAgICAgIGFzc2VydEJhY2tSZWZlcmVuY2UoNSwgMTgsIGJsb2Nrcy5nZXQoMSkpOworICAgICAgICBhc3NlcnRMaXRlcmFsQmxvY2soIiEiLCBibG9ja3MuZ2V0KDIpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIGJsYUV4YW1wbGVXaXRoU2hvcnRlckJhY2tSZWZlcmVuY2VMZW5ndGgoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBMaXN0PExaNzdDb21wcmVzc29yLkJsb2NrPiBibG9ja3MgPSBjb21wcmVzcyhuZXdQYXJhbWV0ZXJzKDEyOCwgMywgNSwgMCwgMCksIEJMQSk7CisgICAgICAgIGFzc2VydFNpemUoNywgYmxvY2tzKTsKKyAgICAgICAgYXNzZXJ0TGl0ZXJhbEJsb2NrKCJCbGFoIGIiLCBibG9ja3MuZ2V0KDApKTsKKyAgICAgICAgYXNzZXJ0QmFja1JlZmVyZW5jZSg1LCA1LCBibG9ja3MuZ2V0KDEpKTsKKyAgICAgICAgYXNzZXJ0QmFja1JlZmVyZW5jZSg1LCA1LCBibG9ja3MuZ2V0KDIpKTsKKyAgICAgICAgYXNzZXJ0QmFja1JlZmVyZW5jZSg1LCA1LCBibG9ja3MuZ2V0KDMpKTsKKyAgICAgICAgYXNzZXJ0QmFja1JlZmVyZW5jZSg1LCAzLCBibG9ja3MuZ2V0KDQpKTsKKyAgICAgICAgYXNzZXJ0TGl0ZXJhbEJsb2NrKCIhIiwgYmxvY2tzLmdldCg1KSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBibGFFeGFtcGxlU21hbGxlcldpbmRvd1NpemUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBMaXN0PExaNzdDb21wcmVzc29yLkJsb2NrPiBibG9ja3MgPSBjb21wcmVzcyhuZXdQYXJhbWV0ZXJzKDgpLCBCTEEpOworICAgICAgICBhc3NlcnRTaXplKDYsIGJsb2Nrcyk7CisgICAgICAgIGFzc2VydExpdGVyYWxCbG9jaygiQmxhaCBiIiwgYmxvY2tzLmdldCgwKSk7CisgICAgICAgIGFzc2VydEJhY2tSZWZlcmVuY2UoNSwgNywgYmxvY2tzLmdldCgxKSk7CisgICAgICAgIGFzc2VydEJhY2tSZWZlcmVuY2UoNSwgMywgYmxvY2tzLmdldCgyKSk7CisgICAgICAgIGFzc2VydEJhY2tSZWZlcmVuY2UoNSwgNywgYmxvY2tzLmdldCgzKSk7CisgICAgICAgIGFzc2VydExpdGVyYWxCbG9jaygiaCEiLCBibG9ja3MuZ2V0KDQpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIGJsYUV4YW1wbGVXaXRoU2luZ2xlQnl0ZVdyaXRlcygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIExpc3Q8TFo3N0NvbXByZXNzb3IuQmxvY2s+IGJsb2NrcyA9IGNvbXByZXNzKG5ld1BhcmFtZXRlcnMoMTI4KSwgc3RhZ2dlcihCTEEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDksIGJsb2Nrcy5zaXplKCkpOworICAgICAgICBhc3NlcnRMaXRlcmFsQmxvY2soIkJsYWggYiIsIGJsb2Nrcy5nZXQoMCkpOworICAgICAgICBhc3NlcnRCYWNrUmVmZXJlbmNlKDUsIDMsIGJsb2Nrcy5nZXQoMSkpOworICAgICAgICBhc3NlcnRCYWNrUmVmZXJlbmNlKDUsIDMsIGJsb2Nrcy5nZXQoMikpOworICAgICAgICBhc3NlcnRCYWNrUmVmZXJlbmNlKDUsIDMsIGJsb2Nrcy5nZXQoMykpOworICAgICAgICBhc3NlcnRCYWNrUmVmZXJlbmNlKDUsIDMsIGJsb2Nrcy5nZXQoNCkpOworICAgICAgICBhc3NlcnRCYWNrUmVmZXJlbmNlKDUsIDMsIGJsb2Nrcy5nZXQoNSkpOworICAgICAgICBhc3NlcnRCYWNrUmVmZXJlbmNlKDUsIDMsIGJsb2Nrcy5nZXQoNikpOworICAgICAgICBhc3NlcnRMaXRlcmFsQmxvY2soIiEiLCBibG9ja3MuZ2V0KDcpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHNhbUlBbUV4YW1wbGVXaXRoRnVsbEFycmF5QXZhaWxhYmxlRm9yQ29tcHJlc3Npb24oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBMaXN0PExaNzdDb21wcmVzc29yLkJsb2NrPiBibG9ja3MgPSBjb21wcmVzcyhuZXdQYXJhbWV0ZXJzKDEwMjQpLCBTQU0pOworICAgICAgICBhc3NlcnRFcXVhbHMoMjEsIGJsb2Nrcy5zaXplKCkpOworICAgICAgICBhc3NlcnRMaXRlcmFsQmxvY2soIkkgYW0gU2FtXG5cbiIsIGJsb2Nrcy5nZXQoMCkpOworICAgICAgICBhc3NlcnRCYWNrUmVmZXJlbmNlKDUsIDMsIGJsb2Nrcy5nZXQoMSkpOworICAgICAgICBhc3NlcnRMaXRlcmFsQmxvY2soIiAiLCBibG9ja3MuZ2V0KDIpKTsKKyAgICAgICAgYXNzZXJ0QmFja1JlZmVyZW5jZSgxNCwgNCwgYmxvY2tzLmdldCgzKSk7CisgICAgICAgIGFzc2VydExpdGVyYWxCbG9jaygiXG5cblRoYXQiLCBibG9ja3MuZ2V0KDQpKTsKKyAgICAgICAgYXNzZXJ0QmFja1JlZmVyZW5jZSgyMCwgNCwgYmxvY2tzLmdldCg1KSk7CisgICAgICAgIGFzc2VydExpdGVyYWxCbG9jaygiLUktYW0hIiwgYmxvY2tzLmdldCg2KSk7CisgICAgICAgIGFzc2VydEJhY2tSZWZlcmVuY2UoMTUsIDE2LCBibG9ja3MuZ2V0KDcpKTsKKyAgICAgICAgYXNzZXJ0TGl0ZXJhbEJsb2NrKCJJIGRvIG5vdCBsaWtlXG50IiwgYmxvY2tzLmdldCg4KSk7CisgICAgICAgIGFzc2VydEJhY2tSZWZlcmVuY2UoMjksIDE0LCBibG9ja3MuZ2V0KDkpKTsKKyAgICAgICAgYXNzZXJ0TGl0ZXJhbEJsb2NrKCJcbkRvIHlvdSIsIGJsb2Nrcy5nZXQoMTApKTsKKyAgICAgICAgYXNzZXJ0QmFja1JlZmVyZW5jZSgyOCwgNSwgYmxvY2tzLmdldCgxMSkpOworICAgICAgICBhc3NlcnRMaXRlcmFsQmxvY2soIiBncmVlbiBlZ2dzIGFuZCBoYW0/XG4iLCBibG9ja3MuZ2V0KDEyKSk7CisgICAgICAgIGFzc2VydEJhY2tSZWZlcmVuY2UoNjMsIDE0LCBibG9ja3MuZ2V0KDEzKSk7CisgICAgICAgIGFzc2VydExpdGVyYWxCbG9jaygiIHRoZW0sIiwgYmxvY2tzLmdldCgxNCkpOworICAgICAgICBhc3NlcnRCYWNrUmVmZXJlbmNlKDY0LCA5LCBibG9ja3MuZ2V0KDE1KSk7CisgICAgICAgIGFzc2VydExpdGVyYWxCbG9jaygiLiIsIGJsb2Nrcy5nZXQoMTYpKTsKKyAgICAgICAgYXNzZXJ0QmFja1JlZmVyZW5jZSgzMCwgMTUsIGJsb2Nrcy5nZXQoMTcpKTsKKyAgICAgICAgYXNzZXJ0QmFja1JlZmVyZW5jZSg2NSwgMTgsIGJsb2Nrcy5nZXQoMTgpKTsKKyAgICAgICAgYXNzZXJ0TGl0ZXJhbEJsb2NrKCIuIiwgYmxvY2tzLmdldCgxOSkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgYmxhRXhhbXBsZVdpdGhQcmVmaWxsKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgTGlzdDxMWjc3Q29tcHJlc3Nvci5CbG9jaz4gYmxvY2tzID0gbmV3IEFycmF5TGlzdDw+KCk7CisgICAgICAgIExaNzdDb21wcmVzc29yIGMgPSBuZXcgTFo3N0NvbXByZXNzb3IobmV3UGFyYW1ldGVycygxMjgpLCBuZXcgTFo3N0NvbXByZXNzb3IuQ2FsbGJhY2soKSB7CisgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgYWNjZXB0KExaNzdDb21wcmVzc29yLkJsb2NrIGJsb2NrKSB7CisgICAgICAgICAgICAgICAgICAgIC8vU3lzdGVtLmVyci5wcmludGxuKGJsb2NrKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGJsb2NrIGluc3RhbmNlb2YgTFo3N0NvbXByZXNzb3IuTGl0ZXJhbEJsb2NrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyByZXBsYWNlIHdpdGggYSByZWFsIGNvcHkgb2YgZGF0YSBzbyB0ZXN0cworICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2FuIHNlZSB0aGUgcmVzdWx0cyBhcyB0aGV5J3ZlIGJlZW4gd2hlbgorICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIGNhbGxiYWNrIGhhcyBiZWVuIGNhbGxlZAorICAgICAgICAgICAgICAgICAgICAgICAgTFo3N0NvbXByZXNzb3IuTGl0ZXJhbEJsb2NrIGIgPSAoTFo3N0NvbXByZXNzb3IuTGl0ZXJhbEJsb2NrKSBibG9jazsKKyAgICAgICAgICAgICAgICAgICAgICAgIGludCBsZW4gPSBiLmdldExlbmd0aCgpOworICAgICAgICAgICAgICAgICAgICAgICAgYmxvY2sgPSBuZXcgTFo3N0NvbXByZXNzb3IuTGl0ZXJhbEJsb2NrKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFycmF5cy5jb3B5T2ZSYW5nZShiLmdldERhdGEoKSwgYi5nZXRPZmZzZXQoKSwgYi5nZXRPZmZzZXQoKSArIGxlbiksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgbGVuKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBibG9ja3MuYWRkKGJsb2NrKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9KTsKKyAgICAgICAgYy5wcmVmaWxsKEFycmF5cy5jb3B5T2ZSYW5nZShCTEEsIDAsIDYpKTsKKyAgICAgICAgYy5jb21wcmVzcyhBcnJheXMuY29weU9mUmFuZ2UoQkxBLCA2LCBCTEEubGVuZ3RoKSk7CisgICAgICAgIGMuZmluaXNoKCk7CisgICAgICAgIGFzc2VydFNpemUoMywgYmxvY2tzKTsKKyAgICAgICAgYXNzZXJ0QmFja1JlZmVyZW5jZSg1LCAxOCwgYmxvY2tzLmdldCgwKSk7CisgICAgICAgIGFzc2VydExpdGVyYWxCbG9jaygiISIsIGJsb2Nrcy5nZXQoMSkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgYmxhRXhhbXBsZVdpdGhTaG9ydFByZWZpbGwoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBMaXN0PExaNzdDb21wcmVzc29yLkJsb2NrPiBibG9ja3MgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKyAgICAgICAgTFo3N0NvbXByZXNzb3IgYyA9IG5ldyBMWjc3Q29tcHJlc3NvcihuZXdQYXJhbWV0ZXJzKDEyOCksIG5ldyBMWjc3Q29tcHJlc3Nvci5DYWxsYmFjaygpIHsKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBhY2NlcHQoTFo3N0NvbXByZXNzb3IuQmxvY2sgYmxvY2spIHsKKyAgICAgICAgICAgICAgICAgICAgLy9TeXN0ZW0uZXJyLnByaW50bG4oYmxvY2spOworICAgICAgICAgICAgICAgICAgICBpZiAoYmxvY2sgaW5zdGFuY2VvZiBMWjc3Q29tcHJlc3Nvci5MaXRlcmFsQmxvY2spIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJlcGxhY2Ugd2l0aCBhIHJlYWwgY29weSBvZiBkYXRhIHNvIHRlc3RzCisgICAgICAgICAgICAgICAgICAgICAgICAvLyBjYW4gc2VlIHRoZSByZXN1bHRzIGFzIHRoZXkndmUgYmVlbiB3aGVuCisgICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGUgY2FsbGJhY2sgaGFzIGJlZW4gY2FsbGVkCisgICAgICAgICAgICAgICAgICAgICAgICBMWjc3Q29tcHJlc3Nvci5MaXRlcmFsQmxvY2sgYiA9IChMWjc3Q29tcHJlc3Nvci5MaXRlcmFsQmxvY2spIGJsb2NrOworICAgICAgICAgICAgICAgICAgICAgICAgaW50IGxlbiA9IGIuZ2V0TGVuZ3RoKCk7CisgICAgICAgICAgICAgICAgICAgICAgICBibG9jayA9IG5ldyBMWjc3Q29tcHJlc3Nvci5MaXRlcmFsQmxvY2soCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXJyYXlzLmNvcHlPZlJhbmdlKGIuZ2V0RGF0YSgpLCBiLmdldE9mZnNldCgpLCBiLmdldE9mZnNldCgpICsgbGVuKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCBsZW4pOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGJsb2Nrcy5hZGQoYmxvY2spOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0pOworICAgICAgICBjLnByZWZpbGwoQXJyYXlzLmNvcHlPZlJhbmdlKEJMQSwgMCwgMikpOworICAgICAgICBjLmNvbXByZXNzKEFycmF5cy5jb3B5T2ZSYW5nZShCTEEsIDIsIEJMQS5sZW5ndGgpKTsKKyAgICAgICAgYy5maW5pc2goKTsKKyAgICAgICAgYXNzZXJ0U2l6ZSg0LCBibG9ja3MpOworICAgICAgICBhc3NlcnRMaXRlcmFsQmxvY2soImFoIGIiLCBibG9ja3MuZ2V0KDApKTsKKyAgICAgICAgYXNzZXJ0QmFja1JlZmVyZW5jZSg1LCAxOCwgYmxvY2tzLmdldCgxKSk7CisgICAgICAgIGFzc2VydExpdGVyYWxCbG9jaygiISIsIGJsb2Nrcy5nZXQoMikpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgYmxhRXhhbXBsZVdpdGhQcmVmaWxsQmlnZ2VyVGhhbldpbmRvd1NpemUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBMaXN0PExaNzdDb21wcmVzc29yLkJsb2NrPiBibG9ja3MgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKyAgICAgICAgTFo3N0NvbXByZXNzb3IgYyA9IG5ldyBMWjc3Q29tcHJlc3NvcihuZXdQYXJhbWV0ZXJzKDQpLCBuZXcgTFo3N0NvbXByZXNzb3IuQ2FsbGJhY2soKSB7CisgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgYWNjZXB0KExaNzdDb21wcmVzc29yLkJsb2NrIGJsb2NrKSB7CisgICAgICAgICAgICAgICAgICAgIC8vU3lzdGVtLmVyci5wcmludGxuKGJsb2NrKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGJsb2NrIGluc3RhbmNlb2YgTFo3N0NvbXByZXNzb3IuTGl0ZXJhbEJsb2NrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyByZXBsYWNlIHdpdGggYSByZWFsIGNvcHkgb2YgZGF0YSBzbyB0ZXN0cworICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2FuIHNlZSB0aGUgcmVzdWx0cyBhcyB0aGV5J3ZlIGJlZW4gd2hlbgorICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIGNhbGxiYWNrIGhhcyBiZWVuIGNhbGxlZAorICAgICAgICAgICAgICAgICAgICAgICAgTFo3N0NvbXByZXNzb3IuTGl0ZXJhbEJsb2NrIGIgPSAoTFo3N0NvbXByZXNzb3IuTGl0ZXJhbEJsb2NrKSBibG9jazsKKyAgICAgICAgICAgICAgICAgICAgICAgIGludCBsZW4gPSBiLmdldExlbmd0aCgpOworICAgICAgICAgICAgICAgICAgICAgICAgYmxvY2sgPSBuZXcgTFo3N0NvbXByZXNzb3IuTGl0ZXJhbEJsb2NrKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFycmF5cy5jb3B5T2ZSYW5nZShiLmdldERhdGEoKSwgYi5nZXRPZmZzZXQoKSwgYi5nZXRPZmZzZXQoKSArIGxlbiksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgbGVuKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBibG9ja3MuYWRkKGJsb2NrKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9KTsKKyAgICAgICAgYy5wcmVmaWxsKEFycmF5cy5jb3B5T2ZSYW5nZShCTEEsIDAsIDYpKTsKKyAgICAgICAgYy5jb21wcmVzcyhBcnJheXMuY29weU9mUmFuZ2UoQkxBLCA2LCBCTEEubGVuZ3RoKSk7CisgICAgICAgIGMuZmluaXNoKCk7CisgICAgICAgIGFzc2VydFNpemUoNiwgYmxvY2tzKTsKKyAgICAgICAgYXNzZXJ0TGl0ZXJhbEJsb2NrKCJsYWggIiwgYmxvY2tzLmdldCgwKSk7CisgICAgICAgIGFzc2VydExpdGVyYWxCbG9jaygiYmxhaCIsIGJsb2Nrcy5nZXQoMSkpOworICAgICAgICBhc3NlcnRMaXRlcmFsQmxvY2soIiBibGEiLCBibG9ja3MuZ2V0KDIpKTsKKyAgICAgICAgYXNzZXJ0TGl0ZXJhbEJsb2NrKCJoIGJsIiwgYmxvY2tzLmdldCgzKSk7CisgICAgICAgIGFzc2VydExpdGVyYWxCbG9jaygiYWghIiwgYmxvY2tzLmdldCg0KSk7CisgICAgfQorCisgICAgQFRlc3QoZXhwZWN0ZWQgPSBJbGxlZ2FsU3RhdGVFeGNlcHRpb24uY2xhc3MpCisgICAgcHVibGljIHZvaWQgY2FudFByZWZpbGxUd2ljZSgpIHsKKyAgICAgICAgTFo3N0NvbXByZXNzb3IgYyA9IG5ldyBMWjc3Q29tcHJlc3NvcihuZXdQYXJhbWV0ZXJzKDEyOCksIG5ldyBMWjc3Q29tcHJlc3Nvci5DYWxsYmFjaygpIHsKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBhY2NlcHQoTFo3N0NvbXByZXNzb3IuQmxvY2sgYmxvY2spIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9KTsKKyAgICAgICAgYy5wcmVmaWxsKEFycmF5cy5jb3B5T2ZSYW5nZShCTEEsIDAsIDIpKTsKKyAgICAgICAgYy5wcmVmaWxsKEFycmF5cy5jb3B5T2ZSYW5nZShCTEEsIDIsIDQpKTsKKyAgICB9CisKKyAgICBAVGVzdChleHBlY3RlZCA9IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbi5jbGFzcykKKyAgICBwdWJsaWMgdm9pZCBjYW50UHJlZmlsbEFmdGVyQ29tcHJlc3MoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBMWjc3Q29tcHJlc3NvciBjID0gbmV3IExaNzdDb21wcmVzc29yKG5ld1BhcmFtZXRlcnMoMTI4KSwgbmV3IExaNzdDb21wcmVzc29yLkNhbGxiYWNrKCkgeworICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIGFjY2VwdChMWjc3Q29tcHJlc3Nvci5CbG9jayBibG9jaykgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0pOworICAgICAgICBjLmNvbXByZXNzKEFycmF5cy5jb3B5T2ZSYW5nZShCTEEsIDAsIDIpKTsKKyAgICAgICAgYy5wcmVmaWxsKEFycmF5cy5jb3B5T2ZSYW5nZShCTEEsIDIsIDQpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCB2b2lkIGFzc2VydFNpemUoaW50IGV4cGVjdGVkU2l6ZSwgTGlzdDxMWjc3Q29tcHJlc3Nvci5CbG9jaz4gYmxvY2tzKSB7CisgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZFNpemUsIGJsb2Nrcy5zaXplKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoTFo3N0NvbXByZXNzb3IuQmxvY2suQmxvY2tUeXBlLkVPRCwgYmxvY2tzLmdldChleHBlY3RlZFNpemUgLSAxKS5nZXRUeXBlKCkpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHZvaWQgYXNzZXJ0TGl0ZXJhbEJsb2NrKFN0cmluZyBleHBlY3RlZENvbnRlbnQsIExaNzdDb21wcmVzc29yLkJsb2NrIGJsb2NrKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBhc3NlcnRMaXRlcmFsQmxvY2soZXhwZWN0ZWRDb250ZW50LmdldEJ5dGVzKCJBU0NJSSIpLCBibG9jayk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgdm9pZCBhc3NlcnRMaXRlcmFsQmxvY2soYnl0ZVtdIGV4cGVjdGVkQ29udGVudCwgTFo3N0NvbXByZXNzb3IuQmxvY2sgYmxvY2spIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKExaNzdDb21wcmVzc29yLkxpdGVyYWxCbG9jay5jbGFzcywgYmxvY2suZ2V0Q2xhc3MoKSk7CisgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKGV4cGVjdGVkQ29udGVudCwgKChMWjc3Q29tcHJlc3Nvci5MaXRlcmFsQmxvY2spIGJsb2NrKS5nZXREYXRhKCkpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHZvaWQgYXNzZXJ0QmFja1JlZmVyZW5jZShpbnQgZXhwZWN0ZWRPZmZzZXQsIGludCBleHBlY3RlZExlbmd0aCwgTFo3N0NvbXByZXNzb3IuQmxvY2sgYmxvY2spIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKExaNzdDb21wcmVzc29yLkJhY2tSZWZlcmVuY2UuY2xhc3MsIGJsb2NrLmdldENsYXNzKCkpOworICAgICAgICBMWjc3Q29tcHJlc3Nvci5CYWNrUmVmZXJlbmNlIGIgPSAoTFo3N0NvbXByZXNzb3IuQmFja1JlZmVyZW5jZSkgYmxvY2s7CisgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZE9mZnNldCwgYi5nZXRPZmZzZXQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZExlbmd0aCwgYi5nZXRMZW5ndGgoKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdW10gc3RhZ2dlcihieXRlW10gZGF0YSkgeworICAgICAgICBieXRlW11bXSByID0gbmV3IGJ5dGVbZGF0YS5sZW5ndGhdWzFdOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHJbaV1bMF0gPSBkYXRhW2ldOworICAgICAgICB9CisgICAgICAgIHJldHVybiByOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIFBhcmFtZXRlcnMgbmV3UGFyYW1ldGVycyhpbnQgd2luZG93U2l6ZSkgeworICAgICAgICByZXR1cm4gUGFyYW1ldGVycy5idWlsZGVyKHdpbmRvd1NpemUpLmJ1aWxkKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgUGFyYW1ldGVycyBuZXdQYXJhbWV0ZXJzKGludCB3aW5kb3dTaXplLCBpbnQgbWluQmFja1JlZmVyZW5jZUxlbmd0aCwgaW50IG1heEJhY2tSZWZlcmVuY2VMZW5ndGgsCisgICAgICAgIGludCBtYXhPZmZzZXQsIGludCBtYXhMaXRlcmFsTGVuZ3RoKSB7CisgICAgICAgIHJldHVybiBQYXJhbWV0ZXJzLmJ1aWxkZXIod2luZG93U2l6ZSkKKyAgICAgICAgICAgIC53aXRoTWluQmFja1JlZmVyZW5jZUxlbmd0aChtaW5CYWNrUmVmZXJlbmNlTGVuZ3RoKQorICAgICAgICAgICAgLndpdGhNYXhCYWNrUmVmZXJlbmNlTGVuZ3RoKG1heEJhY2tSZWZlcmVuY2VMZW5ndGgpCisgICAgICAgICAgICAud2l0aE1heE9mZnNldChtYXhPZmZzZXQpCisgICAgICAgICAgICAud2l0aE1heExpdGVyYWxMZW5ndGgobWF4TGl0ZXJhbExlbmd0aCkKKyAgICAgICAgICAgIC50dW5lZEZvckNvbXByZXNzaW9uUmF0aW8oKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvbHo3N3N1cHBvcnQvUGFyYW1ldGVyc1Rlc3QuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2x6NzdzdXBwb3J0L1BhcmFtZXRlcnNUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDRkOGFjNAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2x6NzdzdXBwb3J0L1BhcmFtZXRlcnNUZXN0LmphdmEKQEAgLTAsMCArMSwxMzUgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMubHo3N3N1cHBvcnQ7CisKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEVxdWFsczsKKworcHVibGljIGNsYXNzIFBhcmFtZXRlcnNUZXN0IHsKKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgZGVmYXVsdENvbnN0cnVjdG9yKCkgeworICAgICAgICBQYXJhbWV0ZXJzIHAgPSBuZXdQYXJhbWV0ZXJzKDEyOCk7CisgICAgICAgIGFzc2VydEVxdWFscygxMjgsIHAuZ2V0V2luZG93U2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIHAuZ2V0TWluQmFja1JlZmVyZW5jZUxlbmd0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEyNywgcC5nZXRNYXhCYWNrUmVmZXJlbmNlTGVuZ3RoKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMTI3LCBwLmdldE1heE9mZnNldCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEyOCwgcC5nZXRNYXhMaXRlcmFsTGVuZ3RoKCkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgbWluQmFja1JlZmVyZW5jZUxlbmd0aElzQXRMZWFzdFRocmVlKCkgeworICAgICAgICBQYXJhbWV0ZXJzIHAgPSBuZXdQYXJhbWV0ZXJzKDEyOCwgMiwgMywgNCwgNSk7CisgICAgICAgIGFzc2VydEVxdWFscygzLCBwLmdldE1pbkJhY2tSZWZlcmVuY2VMZW5ndGgoKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBtYXhCYWNrUmVmZXJlbmNlTGVuZ3RoSXNNaW5CYWNrUmVmZXJlbmNlTGVuZ3RoV2hlblNtYWxsZXJUaGFuTWluQmFja1JlZmVyZW5jZUxlbmd0aCgpIHsKKyAgICAgICAgUGFyYW1ldGVycyBwID0gbmV3UGFyYW1ldGVycygxMjgsIDIsIDIsIDQsIDUpOworICAgICAgICBhc3NlcnRFcXVhbHMoMywgcC5nZXRNYXhCYWNrUmVmZXJlbmNlTGVuZ3RoKCkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgbWF4QmFja1JlZmVyZW5jZUxlbmd0aElzTWluQmFja1JlZmVyZW5jZUxlbmd0aFdoZW5TbWFsbGVyVGhhbk1pbkJhY2tSZWZlcmVuY2VMZW5ndGhSZXZlcnNlZEludm9jYXRpb25PcmRlcigpIHsKKyAgICAgICAgUGFyYW1ldGVycyBwID0gUGFyYW1ldGVycy5idWlsZGVyKDEyOCkKKyAgICAgICAgICAgIC53aXRoTWF4QmFja1JlZmVyZW5jZUxlbmd0aCgyKQorICAgICAgICAgICAgLndpdGhNaW5CYWNrUmVmZXJlbmNlTGVuZ3RoKDIpCisgICAgICAgICAgICAud2l0aE1heE9mZnNldCg0KQorICAgICAgICAgICAgLndpdGhNYXhMaXRlcmFsTGVuZ3RoKDUpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIHAuZ2V0TWF4QmFja1JlZmVyZW5jZUxlbmd0aCgpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIG1heEJhY2tSZWZlcmVuY2VMZW5ndGhJc01pbkJhY2tSZWZlcmVuY2VMZW5ndGhJZkJvdGhBcmVFcXVhbCgpIHsKKyAgICAgICAgUGFyYW1ldGVycyBwID0gbmV3UGFyYW1ldGVycygxMjgsIDIsIDMsIDQsIDUpOworICAgICAgICBhc3NlcnRFcXVhbHMoMywgcC5nZXRNYXhCYWNrUmVmZXJlbmNlTGVuZ3RoKCkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgbWF4T2Zmc2V0SXNXaW5kb3dTaXplTWludXMxSWZTZXRUbzAoKSB7CisgICAgICAgIFBhcmFtZXRlcnMgcCA9IG5ld1BhcmFtZXRlcnMoMTI4LCAyLCAzLCAwLCA1KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEyNywgcC5nZXRNYXhPZmZzZXQoKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBtYXhPZmZzZXRJc1dpbmRvd1NpemVNaW51czFJZlNldFRvQU5lZ2F0aXZlVmFsdWUoKSB7CisgICAgICAgIFBhcmFtZXRlcnMgcCA9IG5ld1BhcmFtZXRlcnMoMTI4LCAyLCAzLCAtMSwgNSk7CisgICAgICAgIGFzc2VydEVxdWFscygxMjcsIHAuZ2V0TWF4T2Zmc2V0KCkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgbWF4T2Zmc2V0SXNXaW5kb3dTaXplTWludXMxSWZCaWdnZXJUaGFuV2luZG93U2l6ZSgpIHsKKyAgICAgICAgUGFyYW1ldGVycyBwID0gbmV3UGFyYW1ldGVycygxMjgsIDIsIDMsIDEyOSwgNSk7CisgICAgICAgIGFzc2VydEVxdWFscygxMjcsIHAuZ2V0TWF4T2Zmc2V0KCkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgbWF4TGl0ZXJhbExlbmd0aElzV2luZG93U2l6ZUlmU2V0VG8wKCkgeworICAgICAgICBQYXJhbWV0ZXJzIHAgPSBuZXdQYXJhbWV0ZXJzKDEyOCwgMiwgMywgNCwgMCk7CisgICAgICAgIGFzc2VydEVxdWFscygxMjgsIHAuZ2V0TWF4TGl0ZXJhbExlbmd0aCgpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIG1heExpdGVyYWxMZW5ndGhJc1dpbmRvd1NpemVJZlNldFRvQU5lZ2F0aXZlVmFsdWUoKSB7CisgICAgICAgIFBhcmFtZXRlcnMgcCA9IG5ld1BhcmFtZXRlcnMoMTI4LCAyLCAzLCAwLCAtMSk7CisgICAgICAgIGFzc2VydEVxdWFscygxMjgsIHAuZ2V0TWF4TGl0ZXJhbExlbmd0aCgpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIG1heExpdGVyYWxMZW5ndGhJc1dpbmRvd1NpemVJZlNldFRvQVZhbHVlVG9vQmlnVG9Ib2xkSW5TbGlkaW5nV2luZG93KCkgeworICAgICAgICBQYXJhbWV0ZXJzIHAgPSBuZXdQYXJhbWV0ZXJzKDEyOCwgMiwgMywgMCwgMjU5KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEyOCwgcC5nZXRNYXhMaXRlcmFsTGVuZ3RoKCkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgYWxsUGFyYW1ldGVyc1VzdWFsbHlUYWtlVGhlaXJTcGVjaWZpZWRWYWx1ZXMoKSB7CisgICAgICAgIFBhcmFtZXRlcnMgcCA9IG5ld1BhcmFtZXRlcnMoMjU2LCA0LCA1LCA2LCA3KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDI1NiwgcC5nZXRXaW5kb3dTaXplKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoNCwgcC5nZXRNaW5CYWNrUmVmZXJlbmNlTGVuZ3RoKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoNSwgcC5nZXRNYXhCYWNrUmVmZXJlbmNlTGVuZ3RoKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoNiwgcC5nZXRNYXhPZmZzZXQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg3LCBwLmdldE1heExpdGVyYWxMZW5ndGgoKSk7CisgICAgfQorCisgICAgQFRlc3QoZXhwZWN0ZWQgPSBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24uY2xhc3MpCisgICAgcHVibGljIHZvaWQgd2luZG93U2l6ZU11c3ROb3RCZVNtYWxsZXJUaGFuTWluQmFja1JlZmVyZW5jZUxlbmd0aCgpIHsKKyAgICAgICAgbmV3UGFyYW1ldGVycygxMjgsIDIwMCwgMzAwLCA0MDAsIDUwMCk7CisgICAgfQorCisgICAgQFRlc3QoZXhwZWN0ZWQgPSBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24uY2xhc3MpCisgICAgcHVibGljIHZvaWQgd2luZG93U2l6ZU11c3RCZUFQb3dlck9mVHdvKCkgeworICAgICAgICBuZXdQYXJhbWV0ZXJzKDEwMCwgMjAwLCAzMDAsIDQwMCwgNTAwKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBQYXJhbWV0ZXJzIG5ld1BhcmFtZXRlcnMoaW50IHdpbmRvd1NpemUpIHsKKyAgICAgICAgcmV0dXJuIFBhcmFtZXRlcnMuYnVpbGRlcih3aW5kb3dTaXplKS5idWlsZCgpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIFBhcmFtZXRlcnMgbmV3UGFyYW1ldGVycyhpbnQgd2luZG93U2l6ZSwgaW50IG1pbkJhY2tSZWZlcmVuY2VMZW5ndGgsIGludCBtYXhCYWNrUmVmZXJlbmNlTGVuZ3RoLAorICAgICAgICBpbnQgbWF4T2Zmc2V0LCBpbnQgbWF4TGl0ZXJhbExlbmd0aCkgeworICAgICAgICByZXR1cm4gUGFyYW1ldGVycy5idWlsZGVyKHdpbmRvd1NpemUpCisgICAgICAgICAgICAud2l0aE1pbkJhY2tSZWZlcmVuY2VMZW5ndGgobWluQmFja1JlZmVyZW5jZUxlbmd0aCkKKyAgICAgICAgICAgIC53aXRoTWF4QmFja1JlZmVyZW5jZUxlbmd0aChtYXhCYWNrUmVmZXJlbmNlTGVuZ3RoKQorICAgICAgICAgICAgLndpdGhNYXhPZmZzZXQobWF4T2Zmc2V0KQorICAgICAgICAgICAgLndpdGhNYXhMaXRlcmFsTGVuZ3RoKG1heExpdGVyYWxMZW5ndGgpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9sem1hL0xaTUFVdGlsc1Rlc3RDYXNlLmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9sem1hL0xaTUFVdGlsc1Rlc3RDYXNlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTdiMzgwNgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL2x6bWEvTFpNQVV0aWxzVGVzdENhc2UuamF2YQpAQCAtMCwwICsxLDEwOCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5sem1hOworCitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuKjsKKworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworCitwdWJsaWMgY2xhc3MgTFpNQVV0aWxzVGVzdENhc2UgeworCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SXNDb21wcmVzc2VkRmlsZW5hbWUoKSB7CisgICAgICAgIGFzc2VydEZhbHNlKExaTUFVdGlscy5pc0NvbXByZXNzZWRGaWxlbmFtZSgiIikpOworICAgICAgICBhc3NlcnRGYWxzZShMWk1BVXRpbHMuaXNDb21wcmVzc2VkRmlsZW5hbWUoIi5sem1hIikpOworCisgICAgICAgIGFzc2VydFRydWUoTFpNQVV0aWxzLmlzQ29tcHJlc3NlZEZpbGVuYW1lKCJ4Lmx6bWEiKSk7CisgICAgICAgIGFzc2VydFRydWUoTFpNQVV0aWxzLmlzQ29tcHJlc3NlZEZpbGVuYW1lKCJ4LWx6bWEiKSk7CisKKyAgICAgICAgYXNzZXJ0RmFsc2UoTFpNQVV0aWxzLmlzQ29tcHJlc3NlZEZpbGVuYW1lKCJ4eGd6IikpOworICAgICAgICBhc3NlcnRGYWxzZShMWk1BVXRpbHMuaXNDb21wcmVzc2VkRmlsZW5hbWUoImx6bWF6IikpOworICAgICAgICBhc3NlcnRGYWxzZShMWk1BVXRpbHMuaXNDb21wcmVzc2VkRmlsZW5hbWUoInhheiIpKTsKKworICAgICAgICBhc3NlcnRGYWxzZShMWk1BVXRpbHMuaXNDb21wcmVzc2VkRmlsZW5hbWUoIngubHptYSAiKSk7CisgICAgICAgIGFzc2VydEZhbHNlKExaTUFVdGlscy5pc0NvbXByZXNzZWRGaWxlbmFtZSgieC5sem1hXG4iKSk7CisgICAgICAgIGFzc2VydEZhbHNlKExaTUFVdGlscy5pc0NvbXByZXNzZWRGaWxlbmFtZSgieC5sem1hLnkiKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0VW5jb21wcmVzc2VkRmlsZW5hbWUoKSB7CisgICAgICAgIGFzc2VydEVxdWFscygiIiwgTFpNQVV0aWxzLmdldFVuY29tcHJlc3NlZEZpbGVuYW1lKCIiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiLmx6bWEiLCBMWk1BVXRpbHMuZ2V0VW5jb21wcmVzc2VkRmlsZW5hbWUoIi5sem1hIikpOworCisgICAgICAgIGFzc2VydEVxdWFscygieCIsIExaTUFVdGlscy5nZXRVbmNvbXByZXNzZWRGaWxlbmFtZSgieC5sem1hIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIngiLCBMWk1BVXRpbHMuZ2V0VW5jb21wcmVzc2VkRmlsZW5hbWUoIngtbHptYSIpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIngubHptYSAiLCBMWk1BVXRpbHMuZ2V0VW5jb21wcmVzc2VkRmlsZW5hbWUoIngubHptYSAiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygieC5sem1hXG4iLCBMWk1BVXRpbHMuZ2V0VW5jb21wcmVzc2VkRmlsZW5hbWUoIngubHptYVxuIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIngubHptYS55IiwgTFpNQVV0aWxzLmdldFVuY29tcHJlc3NlZEZpbGVuYW1lKCJ4Lmx6bWEueSIpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRDb21wcmVzc2VkRmlsZW5hbWUoKSB7CisgICAgICAgIGFzc2VydEVxdWFscygiLmx6bWEiLCBMWk1BVXRpbHMuZ2V0Q29tcHJlc3NlZEZpbGVuYW1lKCIiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygieC5sem1hIiwgTFpNQVV0aWxzLmdldENvbXByZXNzZWRGaWxlbmFtZSgieCIpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIngud21mIC5sem1hIiwgTFpNQVV0aWxzLmdldENvbXByZXNzZWRGaWxlbmFtZSgieC53bWYgIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIngud21mXG4ubHptYSIsIExaTUFVdGlscy5nZXRDb21wcmVzc2VkRmlsZW5hbWUoIngud21mXG4iKSk7CisgICAgICAgIGFzc2VydEVxdWFscygieC53bWYueS5sem1hIiwgTFpNQVV0aWxzLmdldENvbXByZXNzZWRGaWxlbmFtZSgieC53bWYueSIpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RNYXRjaGVzKCkgeworICAgICAgICBmaW5hbCBieXRlW10gZGF0YSA9IHsKKyAgICAgICAgICAgIChieXRlKSAweDVELCAwLCAwLAorICAgICAgICB9OworICAgICAgICBhc3NlcnRGYWxzZShMWk1BVXRpbHMubWF0Y2hlcyhkYXRhLCAyKSk7CisgICAgICAgIGFzc2VydFRydWUoTFpNQVV0aWxzLm1hdGNoZXMoZGF0YSwgMykpOworICAgICAgICBhc3NlcnRUcnVlKExaTUFVdGlscy5tYXRjaGVzKGRhdGEsIDQpKTsKKyAgICAgICAgZGF0YVsyXSA9ICcwJzsKKyAgICAgICAgYXNzZXJ0RmFsc2UoTFpNQVV0aWxzLm1hdGNoZXMoZGF0YSwgMykpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdENhY2hpbmdJc0VuYWJsZWRCeURlZmF1bHRBbmRMWk1BSXNQcmVzZW50KCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoTFpNQVV0aWxzLkNhY2hlZEF2YWlsYWJpbGl0eS5DQUNIRURfQVZBSUxBQkxFLCBMWk1BVXRpbHMuZ2V0Q2FjaGVkTFpNQUF2YWlsYWJpbGl0eSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShMWk1BVXRpbHMuaXNMWk1BQ29tcHJlc3Npb25BdmFpbGFibGUoKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2FuVHVybk9mZkNhY2hpbmcoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBMWk1BVXRpbHMuc2V0Q2FjaGVMWk1BQXZhaWxhYmxpdHkoZmFsc2UpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKExaTUFVdGlscy5DYWNoZWRBdmFpbGFiaWxpdHkuRE9OVF9DQUNIRSwgTFpNQVV0aWxzLmdldENhY2hlZExaTUFBdmFpbGFiaWxpdHkoKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKExaTUFVdGlscy5pc0xaTUFDb21wcmVzc2lvbkF2YWlsYWJsZSgpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIExaTUFVdGlscy5zZXRDYWNoZUxaTUFBdmFpbGFibGl0eSh0cnVlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFR1cm5pbmdPbkNhY2hpbmdSZUV2YWx1YXRlc0F2YWlsYWJpbGl0eSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIExaTUFVdGlscy5zZXRDYWNoZUxaTUFBdmFpbGFibGl0eShmYWxzZSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoTFpNQVV0aWxzLkNhY2hlZEF2YWlsYWJpbGl0eS5ET05UX0NBQ0hFLCBMWk1BVXRpbHMuZ2V0Q2FjaGVkTFpNQUF2YWlsYWJpbGl0eSgpKTsKKyAgICAgICAgICAgIExaTUFVdGlscy5zZXRDYWNoZUxaTUFBdmFpbGFibGl0eSh0cnVlKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhMWk1BVXRpbHMuQ2FjaGVkQXZhaWxhYmlsaXR5LkNBQ0hFRF9BVkFJTEFCTEUsIExaTUFVdGlscy5nZXRDYWNoZWRMWk1BQXZhaWxhYmlsaXR5KCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgTFpNQVV0aWxzLnNldENhY2hlTFpNQUF2YWlsYWJsaXR5KHRydWUpOworICAgICAgICB9CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9wYWNrMjAwL1BhY2syMDBVdGlsc1Rlc3QuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL3BhY2syMDAvUGFjazIwMFV0aWxzVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM4NzRmNzUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9wYWNrMjAwL1BhY2syMDBVdGlsc1Rlc3QuamF2YQpAQCAtMCwwICsxLDExOCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5wYWNrMjAwOworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5BYnN0cmFjdFRlc3RDYXNlOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZUVudHJ5OworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZUlucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZVN0cmVhbUZhY3Rvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLklPVXRpbHM7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBQYWNrMjAwVXRpbHNUZXN0IGV4dGVuZHMgQWJzdHJhY3RUZXN0Q2FzZSB7CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3ROb3JtYWxpemUoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgZmluYWwgRmlsZSBpbnB1dCA9IGdldEZpbGUoImJsYS5qYXIiKTsKKyAgICAgICAgZmluYWwgRmlsZVtdIG91dHB1dCA9IGNyZWF0ZVRlbXBEaXJBbmRGaWxlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBQYWNrMjAwVXRpbHMubm9ybWFsaXplKGlucHV0LCBvdXRwdXRbMV0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpKTsKKyAgICAgICAgICAgIHRyeSAoRmlsZUlucHV0U3RyZWFtIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShvdXRwdXRbMV0pKSB7CisgICAgICAgICAgICAgICAgZmluYWwgQXJjaGl2ZUlucHV0U3RyZWFtIGluID0gbmV3IEFyY2hpdmVTdHJlYW1GYWN0b3J5KCkKKyAgICAgICAgICAgICAgICAgICAgICAgIC5jcmVhdGVBcmNoaXZlSW5wdXRTdHJlYW0oImphciIsIGlzKTsKKworICAgICAgICAgICAgICAgIEFyY2hpdmVFbnRyeSBlbnRyeSA9IGluLmdldE5leHRFbnRyeSgpOworICAgICAgICAgICAgICAgIHdoaWxlIChlbnRyeSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGZpbmFsIEZpbGUgYXJjaGl2ZUVudHJ5ID0gbmV3IEZpbGUoZGlyLCBlbnRyeS5nZXROYW1lKCkpOworICAgICAgICAgICAgICAgICAgICBhcmNoaXZlRW50cnkuZ2V0UGFyZW50RmlsZSgpLm1rZGlycygpOworICAgICAgICAgICAgICAgICAgICBpZiAoZW50cnkuaXNEaXJlY3RvcnkoKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgYXJjaGl2ZUVudHJ5Lm1rZGlyKCk7CisgICAgICAgICAgICAgICAgICAgICAgICBlbnRyeSA9IGluLmdldE5leHRFbnRyeSgpOworICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgZmluYWwgT3V0cHV0U3RyZWFtIG91dCA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKGFyY2hpdmVFbnRyeSk7CisgICAgICAgICAgICAgICAgICAgIElPVXRpbHMuY29weShpbiwgb3V0KTsKKyAgICAgICAgICAgICAgICAgICAgb3V0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgICAgIGVudHJ5ID0gaW4uZ2V0TmV4dEVudHJ5KCk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIG91dHB1dFsxXS5kZWxldGUoKTsKKyAgICAgICAgICAgIG91dHB1dFswXS5kZWxldGUoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdE5vcm1hbGl6ZUluUGxhY2UoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgZmluYWwgRmlsZSBpbnB1dCA9IGdldEZpbGUoImJsYS5qYXIiKTsKKyAgICAgICAgZmluYWwgRmlsZVtdIG91dHB1dCA9IGNyZWF0ZVRlbXBEaXJBbmRGaWxlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBGaWxlSW5wdXRTdHJlYW0gaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGlucHV0KTsKKyAgICAgICAgICAgIE91dHB1dFN0cmVhbSBvcyA9IG51bGw7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIG9zID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0ob3V0cHV0WzFdKTsKKyAgICAgICAgICAgICAgICBJT1V0aWxzLmNvcHkoaXMsIG9zKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgaXMuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICBpZiAob3MgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBvcy5jbG9zZSgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgUGFjazIwMFV0aWxzLm5vcm1hbGl6ZShvdXRwdXRbMV0pOworICAgICAgICAgICAgaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKG91dHB1dFsxXSk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGZpbmFsIEFyY2hpdmVJbnB1dFN0cmVhbSBpbiA9IG5ldyBBcmNoaXZlU3RyZWFtRmFjdG9yeSgpCisgICAgICAgICAgICAgICAgICAgIC5jcmVhdGVBcmNoaXZlSW5wdXRTdHJlYW0oImphciIsIGlzKTsKKworICAgICAgICAgICAgICAgIEFyY2hpdmVFbnRyeSBlbnRyeSA9IGluLmdldE5leHRFbnRyeSgpOworICAgICAgICAgICAgICAgIHdoaWxlIChlbnRyeSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGZpbmFsIEZpbGUgYXJjaGl2ZUVudHJ5ID0gbmV3IEZpbGUoZGlyLCBlbnRyeS5nZXROYW1lKCkpOworICAgICAgICAgICAgICAgICAgICBhcmNoaXZlRW50cnkuZ2V0UGFyZW50RmlsZSgpLm1rZGlycygpOworICAgICAgICAgICAgICAgICAgICBpZiAoZW50cnkuaXNEaXJlY3RvcnkoKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgYXJjaGl2ZUVudHJ5Lm1rZGlyKCk7CisgICAgICAgICAgICAgICAgICAgICAgICBlbnRyeSA9IGluLmdldE5leHRFbnRyeSgpOworICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgZmluYWwgT3V0cHV0U3RyZWFtIG91dCA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKGFyY2hpdmVFbnRyeSk7CisgICAgICAgICAgICAgICAgICAgIElPVXRpbHMuY29weShpbiwgb3V0KTsKKyAgICAgICAgICAgICAgICAgICAgb3V0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgICAgIGVudHJ5ID0gaW4uZ2V0TmV4dEVudHJ5KCk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgaXMuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIG91dHB1dFsxXS5kZWxldGUoKTsKKyAgICAgICAgICAgIG91dHB1dFswXS5kZWxldGUoKTsKKyAgICAgICAgfQorICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvc25hcHB5L0ZyYW1lZFNuYXBweUNvbXByZXNzb3JJbnB1dFN0cmVhbVRlc3QuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL3NuYXBweS9GcmFtZWRTbmFwcHlDb21wcmVzc29ySW5wdXRTdHJlYW1UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODc5NDU2ZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL3NuYXBweS9GcmFtZWRTbmFwcHlDb21wcmVzc29ySW5wdXRTdHJlYW1UZXN0LmphdmEKQEAgLTAsMCArMSwyMzEgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuc25hcHB5OworCitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuKjsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLkFic3RyYWN0VGVzdENhc2U7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy56aXAuWmlwRmlsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuZ3ppcC5HemlwQ29tcHJlc3NvcklucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5JT1V0aWxzOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworCitwdWJsaWMgZmluYWwgY2xhc3MgRnJhbWVkU25hcHB5Q29tcHJlc3NvcklucHV0U3RyZWFtVGVzdAorICAgIGV4dGVuZHMgQWJzdHJhY3RUZXN0Q2FzZSB7CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RNYXRjaGVzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RmFsc2UoRnJhbWVkU25hcHB5Q29tcHJlc3NvcklucHV0U3RyZWFtLm1hdGNoZXMobmV3IGJ5dGVbMTBdLCAxMCkpOworICAgICAgICBmaW5hbCBieXRlW10gYiA9IG5ldyBieXRlWzEyXTsKKyAgICAgICAgZmluYWwgRmlsZSBpbnB1dCA9IGdldEZpbGUoImJsYS50YXIuc3oiKTsKKyAgICAgICAgdHJ5IChGaWxlSW5wdXRTdHJlYW0gaW4gPSBuZXcgRmlsZUlucHV0U3RyZWFtKGlucHV0KSkgeworICAgICAgICAgICAgSU9VdGlscy5yZWFkRnVsbHkoaW4sIGIpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEZhbHNlKEZyYW1lZFNuYXBweUNvbXByZXNzb3JJbnB1dFN0cmVhbS5tYXRjaGVzKGIsIDkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShGcmFtZWRTbmFwcHlDb21wcmVzc29ySW5wdXRTdHJlYW0ubWF0Y2hlcyhiLCAxMCkpOworICAgICAgICBhc3NlcnRUcnVlKEZyYW1lZFNuYXBweUNvbXByZXNzb3JJbnB1dFN0cmVhbS5tYXRjaGVzKGIsIDEyKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU29tZXRoaW5nIGJpZyBlbm91Z2ggdG8gbWFrZSBidWZmZXJzIHNsaWRlLgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdExvcmVtSXBzdW0oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgRmlsZSBvdXRwdXRTeiA9IG5ldyBGaWxlKGRpciwgImxvcmVtLWlwc3VtLjEiKTsKKyAgICAgICAgZmluYWwgRmlsZSBvdXRwdXRHeiA9IG5ldyBGaWxlKGRpciwgImxvcmVtLWlwc3VtLjIiKTsKKyAgICAgICAgdHJ5IChGaWxlSW5wdXRTdHJlYW0gaXNTeiA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oZ2V0RmlsZSgibG9yZW0taXBzdW0udHh0LnN6IikpKSB7CisgICAgICAgICAgICBJbnB1dFN0cmVhbSBpbiA9IG5ldyBGcmFtZWRTbmFwcHlDb21wcmVzc29ySW5wdXRTdHJlYW0oaXNTeik7CisgICAgICAgICAgICBGaWxlT3V0cHV0U3RyZWFtIG91dCA9IG51bGw7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIG91dCA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKG91dHB1dFN6KTsKKyAgICAgICAgICAgICAgICBJT1V0aWxzLmNvcHkoaW4sIG91dCk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIGlmIChvdXQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRyeSAoRmlsZUlucHV0U3RyZWFtIGlzR3ogPSBuZXcgRmlsZUlucHV0U3RyZWFtKGdldEZpbGUoImxvcmVtLWlwc3VtLnR4dC5neiIpKSkgeworICAgICAgICAgICAgICAgIGluID0gbmV3IEd6aXBDb21wcmVzc29ySW5wdXRTdHJlYW0oaXNHeik7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgb3V0ID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0ob3V0cHV0R3opOworICAgICAgICAgICAgICAgICAgICBJT1V0aWxzLmNvcHkoaW4sIG91dCk7CisgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKG91dCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHRyeSAoRmlsZUlucHV0U3RyZWFtIHN6ID0gbmV3IEZpbGVJbnB1dFN0cmVhbShvdXRwdXRTeikpIHsKKyAgICAgICAgICAgIHRyeSAoRmlsZUlucHV0U3RyZWFtIGd6ID0gbmV3IEZpbGVJbnB1dFN0cmVhbShvdXRwdXRHeikpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRBcnJheUVxdWFscyhJT1V0aWxzLnRvQnl0ZUFycmF5KHN6KSwKKyAgICAgICAgICAgICAgICAgICAgICAgIElPVXRpbHMudG9CeXRlQXJyYXkoZ3opKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFJlbWFpbmluZ0NodW5rVHlwZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIG91dCA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgdHJ5IChGaWxlSW5wdXRTdHJlYW0gaXNTeiA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oZ2V0RmlsZSgibWl4ZWQudHh0LnN6IikpKSB7CisgICAgICAgICAgICBmaW5hbCBGcmFtZWRTbmFwcHlDb21wcmVzc29ySW5wdXRTdHJlYW0gaW4gPSBuZXcgRnJhbWVkU25hcHB5Q29tcHJlc3NvcklucHV0U3RyZWFtKGlzU3opOworICAgICAgICAgICAgSU9VdGlscy5jb3B5KGluLCBvdXQpOworICAgICAgICAgICAgb3V0LmNsb3NlKCk7CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRBcnJheUVxdWFscyhuZXcgYnl0ZVtdIHsgJzEnLCAnMicsICczJywgJzQnLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzUnLCAnNicsICc3JywgJzgnLCAnOScsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnNScsICc2JywgJzcnLCAnOCcsICc5JywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICc1JywgJzYnLCAnNycsICc4JywgJzknLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzUnLCAnNicsICc3JywgJzgnLCAnOScsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnNScsICc2JywgJzcnLCAnOCcsICc5JywgMTAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnMScsICcyJywgJzMnLCAnNCcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnMScsICcyJywgJzMnLCAnNCcsCisgICAgICAgICAgICB9LCBvdXQudG9CeXRlQXJyYXkoKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QXZhaWxhYmxlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSAoRmlsZUlucHV0U3RyZWFtIGlzU3ogPSBuZXcgRmlsZUlucHV0U3RyZWFtKGdldEZpbGUoIm1peGVkLnR4dC5zeiIpKSkgeworICAgICAgICAgICAgZmluYWwgRnJhbWVkU25hcHB5Q29tcHJlc3NvcklucHV0U3RyZWFtIGluID0gbmV3IEZyYW1lZFNuYXBweUNvbXByZXNzb3JJbnB1dFN0cmVhbShpc1N6KTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygwLCBpbi5hdmFpbGFibGUoKSk7IC8vIG5vIGNodW5rIHJlYWQgc28gZmFyCisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoJzEnLCBpbi5yZWFkKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIGluLmF2YWlsYWJsZSgpKTsgLy8gcmVtYWluZGVyIG9mIGZpcnN0IHVuY29tcHJlc3NlZCBibG9jaworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIGluLnJlYWQobmV3IGJ5dGVbNV0sIDAsIDMpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygnNScsIGluLnJlYWQoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMCwgaW4uYXZhaWxhYmxlKCkpOyAvLyBlbmQgb2YgY2h1bmssIG11c3QgcmVhZCBuZXh0IG9uZQorICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDQsIGluLnJlYWQobmV3IGJ5dGVbNV0sIDAsIDQpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygnNScsIGluLnJlYWQoKSk7CisgICAgICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VW5za2lwcGFibGVDaHVuaygpIHsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGlucHV0ID0gbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAoYnl0ZSkgMHhmZiwgNiwgMCwgMCwgJ3MnLCAnTicsICdhJywgJ1AnLCAncCcsICdZJywKKyAgICAgICAgICAgIDIsIDIsIDAsIDAsIDEsIDEKKyAgICAgICAgfTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZpbmFsIEZyYW1lZFNuYXBweUNvbXByZXNzb3JJbnB1dFN0cmVhbSBpbiA9CisgICAgICAgICAgICAgICAgbmV3IEZyYW1lZFNuYXBweUNvbXByZXNzb3JJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oaW5wdXQpKTsKKyAgICAgICAgICAgIGluLnJlYWQoKTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIGFuIGV4Y2VwdGlvbiIpOworICAgICAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgSU9FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoZXguZ2V0TWVzc2FnZSgpLmNvbnRhaW5zKCJ1bnNraXBwYWJsZSBjaHVuayIpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdENoZWNrc3VtVW5tYXNraW5nKCkgeworICAgICAgICB0ZXN0Q2hlY2tzdW1Vbm1hc2tpbmcoMHhjNzU3bCk7CisgICAgICAgIHRlc3RDaGVja3N1bVVubWFza2luZygweGZmZmZjNzU3bCk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCByZWFkSVdBRmlsZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgKFppcEZpbGUgemlwID0gbmV3IFppcEZpbGUoZ2V0RmlsZSgidGVzdE51bWJlcnNOZXcubnVtYmVycyIpKSkgeworICAgICAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBpcyA9IHppcC5nZXRJbnB1dFN0cmVhbSh6aXAuZ2V0RW50cnkoIkluZGV4L0RvY3VtZW50Lml3YSIpKSkgeworICAgICAgICAgICAgICAgIGZpbmFsIEZyYW1lZFNuYXBweUNvbXByZXNzb3JJbnB1dFN0cmVhbSBpbiA9CisgICAgICAgICAgICAgICAgICAgICAgICBuZXcgRnJhbWVkU25hcHB5Q29tcHJlc3NvcklucHV0U3RyZWFtKGlzLCBGcmFtZWRTbmFwcHlEaWFsZWN0LklXT1JLX0FSQ0hJVkUpOworICAgICAgICAgICAgICAgIEZpbGVPdXRwdXRTdHJlYW0gb3V0ID0gbnVsbDsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBvdXQgPSBuZXcgRmlsZU91dHB1dFN0cmVhbShuZXcgRmlsZShkaXIsICJzbmFwcHlJV0FUZXN0LnJhdyIpKTsKKyAgICAgICAgICAgICAgICAgICAgSU9VdGlscy5jb3B5KGluLCBvdXQpOworICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChvdXQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgb3V0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlICJodHRwczovL2lzc3Vlcy5hcGFjaGUub3JnL2ppcmEvYnJvd3NlL0NPTVBSRVNTLTM1OCIKKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHJlYWRJV0FGaWxlV2l0aEJpZ2dlck9mZnNldCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBGaWxlIG8gPSBuZXcgRmlsZShkaXIsICJDT01QUkVTUy0zNTgucmF3Iik7CisgICAgICAgIHRyeSAoSW5wdXRTdHJlYW0gaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGdldEZpbGUoIkNPTVBSRVNTLTM1OC5pd2EiKSk7CisgICAgICAgICAgICAgRnJhbWVkU25hcHB5Q29tcHJlc3NvcklucHV0U3RyZWFtIGluID0KKyAgICAgICAgICAgICAgICAgbmV3IEZyYW1lZFNuYXBweUNvbXByZXNzb3JJbnB1dFN0cmVhbShpcywgMTw8MTYsIEZyYW1lZFNuYXBweURpYWxlY3QuSVdPUktfQVJDSElWRSk7CisgICAgICAgICAgICAgRmlsZU91dHB1dFN0cmVhbSBvdXQgPSBuZXcgRmlsZU91dHB1dFN0cmVhbShvKSkgeworICAgICAgICAgICAgSU9VdGlscy5jb3B5KGluLCBvdXQpOworICAgICAgICB9CisgICAgICAgIHRyeSAoRmlsZUlucHV0U3RyZWFtIGEgPSBuZXcgRmlsZUlucHV0U3RyZWFtKG8pOworICAgICAgICAgICAgIEZpbGVJbnB1dFN0cmVhbSBlID0gbmV3IEZpbGVJbnB1dFN0cmVhbShnZXRGaWxlKCJDT01QUkVTUy0zNTgudW5jb21wcmVzc2VkIikpKSB7CisgICAgICAgICAgICBieXRlW10gZXhwZWN0ZWQgPSBJT1V0aWxzLnRvQnl0ZUFycmF5KGUpOworICAgICAgICAgICAgYnl0ZVtdIGFjdHVhbCA9IElPVXRpbHMudG9CeXRlQXJyYXkoYSk7CisgICAgICAgICAgICBhc3NlcnRBcnJheUVxdWFscyhleHBlY3RlZCwgYWN0dWFsKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgc2luZ2xlQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGUgaW5wdXQgPSBnZXRGaWxlKCJibGEudGFyLnN6Iik7CisgICAgICAgIHRyeSAoSW5wdXRTdHJlYW0gaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGlucHV0KSkgeworICAgICAgICAgICAgZmluYWwgRnJhbWVkU25hcHB5Q29tcHJlc3NvcklucHV0U3RyZWFtIGluID0KKyAgICAgICAgICAgICAgICAgICAgbmV3IEZyYW1lZFNuYXBweUNvbXByZXNzb3JJbnB1dFN0cmVhbShpcyk7CisgICAgICAgICAgICBJT1V0aWxzLnRvQnl0ZUFycmF5KGluKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygtMSwgaW4ucmVhZCgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygtMSwgaW4ucmVhZCgpKTsKKyAgICAgICAgICAgIGluLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIG11bHRpQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGUgaW5wdXQgPSBnZXRGaWxlKCJibGEudGFyLnN6Iik7CisgICAgICAgIGJ5dGVbXSBidWYgPSBuZXcgYnl0ZVsyXTsKKyAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpKSB7CisgICAgICAgICAgICBmaW5hbCBGcmFtZWRTbmFwcHlDb21wcmVzc29ySW5wdXRTdHJlYW0gaW4gPQorICAgICAgICAgICAgICAgICAgICBuZXcgRnJhbWVkU25hcHB5Q29tcHJlc3NvcklucHV0U3RyZWFtKGlzKTsKKyAgICAgICAgICAgIElPVXRpbHMudG9CeXRlQXJyYXkoaW4pOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBpbi5yZWFkKGJ1ZikpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBpbi5yZWFkKGJ1ZikpOworICAgICAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0Q2hlY2tzdW1Vbm1hc2tpbmcoZmluYWwgbG9uZyB4KSB7CisgICAgICAgIGFzc2VydEVxdWFscyhMb25nLnRvSGV4U3RyaW5nKHgpLAorICAgICAgICAgICAgICAgICAgICAgTG9uZy50b0hleFN0cmluZyhGcmFtZWRTbmFwcHlDb21wcmVzc29ySW5wdXRTdHJlYW0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnVubWFzayhtYXNrKHgpKSkpOworICAgIH0KKworICAgIHByaXZhdGUgbG9uZyBtYXNrKGZpbmFsIGxvbmcgeCkgeworICAgICAgICByZXR1cm4gKCgoeCA+Pj4gMTUpIHwgKHggPDwgMTcpKQorICAgICAgICAgICAgICAgICsgRnJhbWVkU25hcHB5Q29tcHJlc3NvcklucHV0U3RyZWFtLk1BU0tfT0ZGU0VUKQorICAgICAgICAgICAgICYgMHhmZmZmRkZGRkw7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy9zbmFwcHkvU25hcHB5Um91bmR0cmlwVGVzdC5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvc25hcHB5L1NuYXBweVJvdW5kdHJpcFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNTBlZjRlCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvc25hcHB5L1NuYXBweVJvdW5kdHJpcFRlc3QuamF2YQpAQCAtMCwwICsxLDE4NSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5zbmFwcHk7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuUmFuZG9tOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5BYnN0cmFjdFRlc3RDYXNlOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5sejc3c3VwcG9ydC5QYXJhbWV0ZXJzOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5JT1V0aWxzOworaW1wb3J0IG9yZy5qdW5pdC5Bc3NlcnQ7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBTbmFwcHlSb3VuZHRyaXBUZXN0IGV4dGVuZHMgQWJzdHJhY3RUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIHZvaWQgcm91bmRUcmlwVGVzdChTdHJpbmcgdGVzdEZpbGUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJvdW5kVHJpcFRlc3QoZ2V0RmlsZSh0ZXN0RmlsZSksCisgICAgICAgICAgICBTbmFwcHlDb21wcmVzc29yT3V0cHV0U3RyZWFtLmNyZWF0ZVBhcmFtZXRlckJ1aWxkZXIoU25hcHB5Q29tcHJlc3NvcklucHV0U3RyZWFtLkRFRkFVTFRfQkxPQ0tfU0laRSkKKyAgICAgICAgICAgICAgICAuYnVpbGQoKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHJvdW5kVHJpcFRlc3QoZmluYWwgRmlsZSBpbnB1dCwgUGFyYW1ldGVycyBwYXJhbXMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGxvbmcgc3RhcnQgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICAgICAgZmluYWwgRmlsZSBvdXRwdXRTeiA9IG5ldyBGaWxlKGRpciwgaW5wdXQuZ2V0TmFtZSgpICsgIi5yYXcuc3oiKTsKKyAgICAgICAgdHJ5IChGaWxlSW5wdXRTdHJlYW0gaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGlucHV0KTsKKyAgICAgICAgICAgICBGaWxlT3V0cHV0U3RyZWFtIG9zID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0ob3V0cHV0U3opOworICAgICAgICAgICAgIFNuYXBweUNvbXByZXNzb3JPdXRwdXRTdHJlYW0gc29zID0gbmV3IFNuYXBweUNvbXByZXNzb3JPdXRwdXRTdHJlYW0ob3MsIGlucHV0Lmxlbmd0aCgpLCBwYXJhbXMpKSB7CisgICAgICAgICAgICBJT1V0aWxzLmNvcHkoaXMsIHNvcyk7CisgICAgICAgIH0KKyAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKGlucHV0LmdldE5hbWUoKSArICIgd3JpdHRlbiwgdW5jb21wcmVzc2VkIGJ5dGVzOiAiICsgaW5wdXQubGVuZ3RoKCkKKyAgICAgICAgICAgICsgIiwgY29tcHJlc3NlZCBieXRlczogIiArIG91dHB1dFN6Lmxlbmd0aCgpICsgIiBhZnRlciAiICsgKFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpIC0gc3RhcnQpICsgIm1zIik7CisgICAgICAgIHN0YXJ0ID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgICAgIHRyeSAoRmlsZUlucHV0U3RyZWFtIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShpbnB1dCk7CisgICAgICAgICAgICAgU25hcHB5Q29tcHJlc3NvcklucHV0U3RyZWFtIHNpcyA9IG5ldyBTbmFwcHlDb21wcmVzc29ySW5wdXRTdHJlYW0obmV3IEZpbGVJbnB1dFN0cmVhbShvdXRwdXRTeiksCisgICAgICAgICAgICAgICAgIHBhcmFtcy5nZXRXaW5kb3dTaXplKCkpKSB7CisgICAgICAgICAgICBieXRlW10gZXhwZWN0ZWQgPSBJT1V0aWxzLnRvQnl0ZUFycmF5KGlzKTsKKyAgICAgICAgICAgIGJ5dGVbXSBhY3R1YWwgPSBJT1V0aWxzLnRvQnl0ZUFycmF5KHNpcyk7CisgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0QXJyYXlFcXVhbHMoZXhwZWN0ZWQsIGFjdHVhbCk7CisgICAgICAgIH0KKyAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKG91dHB1dFN6LmdldE5hbWUoKSArICIgcmVhZCBhZnRlciAiICsgKFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpIC0gc3RhcnQpICsgIm1zIik7CisgICAgfQorICAgIHByaXZhdGUgdm9pZCByb3VuZFRyaXBUZXN0KGZpbmFsIGJ5dGVbXSBpbnB1dCwgUGFyYW1ldGVycyBwYXJhbXMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGxvbmcgc3RhcnQgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIG9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICB0cnkgKAorICAgICAgICAgICAgIFNuYXBweUNvbXByZXNzb3JPdXRwdXRTdHJlYW0gc29zID0gbmV3IFNuYXBweUNvbXByZXNzb3JPdXRwdXRTdHJlYW0ob3MsIGlucHV0Lmxlbmd0aCwgcGFyYW1zKSkgeworICAgICAgICAgICAgc29zLndyaXRlKGlucHV0KTsKKyAgICAgICAgfQorICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oImJ5dGUgYXJyYXkiICsgIiB3cml0dGVuLCB1bmNvbXByZXNzZWQgYnl0ZXM6ICIgKyBpbnB1dC5sZW5ndGgKKyAgICAgICAgICAgICsgIiwgY29tcHJlc3NlZCBieXRlczogIiArIG9zLnNpemUoKSArICIgYWZ0ZXIgIiArIChTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSAtIHN0YXJ0KSArICJtcyIpOworICAgICAgICBzdGFydCA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgICAgICB0cnkgKAorICAgICAgICAgICAgIFNuYXBweUNvbXByZXNzb3JJbnB1dFN0cmVhbSBzaXMgPSBuZXcgU25hcHB5Q29tcHJlc3NvcklucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShvcy50b0J5dGVBcnJheSgpKSwKKyAgICAgICAgICAgICAgICAgcGFyYW1zLmdldFdpbmRvd1NpemUoKSkpIHsKKyAgICAgICAgICAgIGJ5dGVbXSBleHBlY3RlZCA9IGlucHV0OworICAgICAgICAgICAgYnl0ZVtdIGFjdHVhbCA9IElPVXRpbHMudG9CeXRlQXJyYXkoc2lzKTsKKyAgICAgICAgICAgIEFzc2VydC5hc3NlcnRBcnJheUVxdWFscyhleHBlY3RlZCwgYWN0dWFsKTsKKyAgICAgICAgfQorICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oImJ5dGUgYXJyYXkiICsgIiByZWFkIGFmdGVyICIgKyAoU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgLSBzdGFydCkgKyAibXMiKTsKKyAgICB9CisKKyAgICAvLyBzaG91bGQgeWllbGQgZGVjZW50IGNvbXByZXNzaW9uCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBibGFUYXJSb3VuZHRyaXAoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkNvbmZpZ3VyYXRpb246IGRlZmF1bHQiKTsKKyAgICAgICAgcm91bmRUcmlwVGVzdCgiYmxhLnRhciIpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgYmxhVGFyUm91bmR0cmlwVHVuZWRGb3JTcGVlZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiQ29uZmlndXJhdGlvbjogdHVuZWQgZm9yIHNwZWVkIik7CisgICAgICAgIHJvdW5kVHJpcFRlc3QoZ2V0RmlsZSgiYmxhLnRhciIpLAorICAgICAgICAgICAgU25hcHB5Q29tcHJlc3Nvck91dHB1dFN0cmVhbS5jcmVhdGVQYXJhbWV0ZXJCdWlsZGVyKFNuYXBweUNvbXByZXNzb3JJbnB1dFN0cmVhbS5ERUZBVUxUX0JMT0NLX1NJWkUpCisgICAgICAgICAgICAgICAgLnR1bmVkRm9yU3BlZWQoKQorICAgICAgICAgICAgICAgIC5idWlsZCgpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIGJsYVRhclJvdW5kdHJpcFR1bmVkRm9yQ29tcHJlc3Npb25SYXRpbygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiQ29uZmlndXJhdGlvbjogdHVuZWQgZm9yIGNvbXByZXNzaW9uIHJhdGlvIik7CisgICAgICAgIHJvdW5kVHJpcFRlc3QoZ2V0RmlsZSgiYmxhLnRhciIpLAorICAgICAgICAgICAgU25hcHB5Q29tcHJlc3Nvck91dHB1dFN0cmVhbS5jcmVhdGVQYXJhbWV0ZXJCdWlsZGVyKFNuYXBweUNvbXByZXNzb3JJbnB1dFN0cmVhbS5ERUZBVUxUX0JMT0NLX1NJWkUpCisgICAgICAgICAgICAgICAgLnR1bmVkRm9yQ29tcHJlc3Npb25SYXRpbygpCisgICAgICAgICAgICAgICAgLmJ1aWxkKCkpOworICAgIH0KKworICAgIC8vIHlpZWxkcyBubyBjb21wcmVzc2lvbiBhdCBhbGwKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIGd6aXBwZWRMb3JlbUlwc3VtUm91bmR0cmlwKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcm91bmRUcmlwVGVzdCgibG9yZW0taXBzdW0udHh0Lmd6Iik7CisgICAgfQorCisgICAgLy8geWllbGRzIG5vIGNvbXByZXNzaW9uIGF0IGFsbAorICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgYmlnZ2VyRmlsZVJvdW5kdHJpcCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJvdW5kVHJpcFRlc3QoIkNPTVBSRVNTLTI1Ni43eiIpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdHJ5UmVhbGx5QmlnT2Zmc2V0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gIm5vcm1hbCIgU25hcHB5IGZpbGVzIHdpbGwgbmV2ZXIgcmVhY2ggb2Zmc2V0cyBiZXlvbmQKKyAgICAgICAgLy8gMTZiaXRzIChpLmUuIHRob3NlIHVzaW5nIGZvdXIgYnl0ZXMgdG8gZW5jb2RlIHRoZSBsZW5ndGgpCisgICAgICAgIC8vIGFzIHRoZSBibG9jayBzaXplIGlzIG9ubHkgMzJrLiBUaGlzIG1lYW5zIHdlIG5ldmVyIGV4ZWN1dGUKKyAgICAgICAgLy8gdGhlIGNvZGUgZm9yIGZvdXItYnl0ZSBsZW5ndGggY29waWVzIGluIGVpdGhlciBzdHJlYW0gY2xhc3MKKyAgICAgICAgLy8gdXNpbmcgcmVhbC13b3JsZCBTbmFwcHkgZmlsZXMuCisgICAgICAgIC8vIFRoaXMgaXMgYW4gYXJ0aWZpY2FsIHN0cmVhbSB1c2luZyBhIGJpZ2dlciBibG9jayBzaXplIHRoYXQKKyAgICAgICAgLy8gbWF5IG5vdCBldmVuIGJlIGV4cGFuZGFibGUgYnkgb3RoZXIgU25hcHB5IGltcGxlbWVudGF0aW9ucy4KKyAgICAgICAgLy8gU3RhcnQgd2l0aCB0aGUgZm91ciBieXRlIHNlcXVlbmNlIDAwMDAgYWZ0ZXIgdGhhdCBhZGQgPiA2NGsKKyAgICAgICAgLy8gb2YgcmFuZG9tIG5vaXNlIHRoYXQgZG9lc24ndCBjb250YWluIGFueSAwMDAwIGF0IGFsbCwgdGhlbgorICAgICAgICAvLyBhZGQgMDAwMC4KKyAgICAgICAgRmlsZSBmID0gbmV3IEZpbGUoZGlyLCAicmVhbGx5QmlnT2Zmc2V0VGVzdCIpOworICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gZnMgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCgxPDwxNikgKyAxMDI0KTsKKyAgICAgICAgICAgIGZzLndyaXRlKDApOworICAgICAgICAgICAgZnMud3JpdGUoMCk7CisgICAgICAgICAgICBmcy53cml0ZSgwKTsKKyAgICAgICAgICAgIGZzLndyaXRlKDApOworICAgICAgICAgICAgaW50IGNudCA9IDEgPDwgMTYgKyA1OworICAgICAgICAgICAgUmFuZG9tIHIgPSBuZXcgUmFuZG9tKCk7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMCA7IGkgPCBjbnQ7IGkrKykgeworICAgICAgICAgICAgICAgIGZzLndyaXRlKHIubmV4dEludCgyNTUpICsgMSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmcy53cml0ZSgwKTsKKyAgICAgICAgICAgIGZzLndyaXRlKDApOworICAgICAgICAgICAgZnMud3JpdGUoMCk7CisgICAgICAgICAgICBmcy53cml0ZSgwKTsKKworICAgICAgICByb3VuZFRyaXBUZXN0KGZzLnRvQnl0ZUFycmF5KCksIG5ld1BhcmFtZXRlcnMoMSA8PCAxNywgNCwgNjQsIDEgPDwgMTcgLSAxLCAxIDw8IDE3IC0gMSkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdHJ5UmVhbGx5TG9uZ0xpdGVyYWxzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gIm5vcm1hbCIgU25hcHB5IGZpbGVzIHdpbGwgbmV2ZXIgcmVhY2ggbGl0ZXJhbCBibG9ja3Mgd2l0aAorICAgICAgICAvLyBsZW5ndGggYmV5b25kIDE2Yml0cyAoaS5lLiB0aG9zZSB1c2luZyB0aHJlZSBvciBmb3VyIGJ5dGVzCisgICAgICAgIC8vIHRvIGVuY29kZSB0aGUgbGVuZ3RoKSBhcyB0aGUgYmxvY2sgc2l6ZSBpcyBvbmx5IDMyay4gVGhpcworICAgICAgICAvLyBtZWFucyB3ZSBuZXZlciBleGVjdXRlIHRoZSBjb2RlIGZvciB0aGUgdGhyZWUvZm91ciBieXRlCisgICAgICAgIC8vIGxlbmd0aCBsaXRlcmFscyBpbiBlaXRoZXIgc3RyZWFtIGNsYXNzIHVzaW5nIHJlYWwtd29ybGQKKyAgICAgICAgLy8gU25hcHB5IGZpbGVzLgorICAgICAgICAvLyBXaGF0IHdlJ2QgbmVlZCB3b3VsZCBiZSBhIHNlcXVlbmNlIG9mIGJ5dGVzIHdpdGggbm8gZm91cgorICAgICAgICAvLyBieXRlIHN1YnNlcXVlbmNlIHJlcGVhdGVkIHRoYXQgaXMgbG9uZ2VyIHRoYW4gNjRrLCB3ZSB0cnkKKyAgICAgICAgLy8gb3VyIGJlc3Qgd2l0aCByYW5kb20sIGJ1dCB3aWxsIHByb2JhYmx5IG9ubHkgaGl0IHRoZSB0aHJlZSBieXRlCisgICAgICAgIC8vIG1ldGhvZHMgaW4gYSBmZXcgbHVja3kgY2FzZXMuCisgICAgICAgIC8vIFRoZSBmb3VyIGJ5dGUgbWV0aG9kcyB3b3VsZCByZXF1aXJlIGV2ZW4gbW9yZSBsdWNrIGFuZCBhCisgICAgICAgIC8vIGJ1ZmZlciAoYW5kIGEgZmlsZSB3cml0dGVuIHRvIGRpc2spIHRoYXQgd2FzIDJeNSBiaWdnZXIKKyAgICAgICAgLy8gdGhhbiB0aGUgYnVmZmVyIHVzZWQgaGVyZS4KKyAgICAgICAgRmlsZSBmID0gbmV3IEZpbGUoZGlyLCAicmVhbGx5QmlnTGl0ZXJhbFRlc3QiKTsKKyAgICAgICAgdHJ5IChGaWxlT3V0cHV0U3RyZWFtIGZzID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0oZikpIHsKKyAgICAgICAgICAgIGludCBjbnQgPSAxIDw8IDE5OworICAgICAgICAgICAgUmFuZG9tIHIgPSBuZXcgUmFuZG9tKCk7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMCA7IGkgPCBjbnQ7IGkrKykgeworICAgICAgICAgICAgICAgIGZzLndyaXRlKHIubmV4dEludCgyNTYpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByb3VuZFRyaXBUZXN0KGYsIG5ld1BhcmFtZXRlcnMoMSA8PCAxOCwgNCwgNjQsIDEgPDwgMTYgLSAxLCAxIDw8IDE4IC0gMSkpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIFBhcmFtZXRlcnMgbmV3UGFyYW1ldGVycyhpbnQgd2luZG93U2l6ZSwgaW50IG1pbkJhY2tSZWZlcmVuY2VMZW5ndGgsIGludCBtYXhCYWNrUmVmZXJlbmNlTGVuZ3RoLAorICAgICAgICBpbnQgbWF4T2Zmc2V0LCBpbnQgbWF4TGl0ZXJhbExlbmd0aCkgeworICAgICAgICByZXR1cm4gUGFyYW1ldGVycy5idWlsZGVyKHdpbmRvd1NpemUpCisgICAgICAgICAgICAud2l0aE1pbkJhY2tSZWZlcmVuY2VMZW5ndGgobWluQmFja1JlZmVyZW5jZUxlbmd0aCkKKyAgICAgICAgICAgIC53aXRoTWF4QmFja1JlZmVyZW5jZUxlbmd0aChtYXhCYWNrUmVmZXJlbmNlTGVuZ3RoKQorICAgICAgICAgICAgLndpdGhNYXhPZmZzZXQobWF4T2Zmc2V0KQorICAgICAgICAgICAgLndpdGhNYXhMaXRlcmFsTGVuZ3RoKG1heExpdGVyYWxMZW5ndGgpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy94ei9YWkNvbXByZXNzb3JJbnB1dFN0cmVhbVRlc3QuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL3h6L1haQ29tcHJlc3NvcklucHV0U3RyZWFtVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE0M2RjYTMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy94ei9YWkNvbXByZXNzb3JJbnB1dFN0cmVhbVRlc3QuamF2YQpAQCAtMCwwICsxLDg5IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLnh6OworCitpbXBvcnQgc3RhdGljIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5BYnN0cmFjdFRlc3RDYXNlLmdldEZpbGU7CisKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5JT1V0aWxzOworaW1wb3J0IG9yZy5qdW5pdC5Bc3NlcnQ7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CisKK3B1YmxpYyBjbGFzcyBYWkNvbXByZXNzb3JJbnB1dFN0cmVhbVRlc3QgeworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgcmVkdW5kYW50VGVzdE9mQWxtb3N0RGVwcmVjYXRlZE1hdGNoZXNNZXRob2QoKSB7CisgICAgICAgIGZpbmFsIGJ5dGVbXSBkYXRhID0geworICAgICAgICAgICAgKGJ5dGUpIDB4RkQsICc3JywgJ3onLCAnWCcsICdaJywgJ1wwJworICAgICAgICB9OworICAgICAgICBBc3NlcnQuYXNzZXJ0RmFsc2UoWFpDb21wcmVzc29ySW5wdXRTdHJlYW0ubWF0Y2hlcyhkYXRhLCA1KSk7CisgICAgICAgIEFzc2VydC5hc3NlcnRUcnVlKFhaQ29tcHJlc3NvcklucHV0U3RyZWFtLm1hdGNoZXMoZGF0YSwgNikpOworICAgICAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShYWkNvbXByZXNzb3JJbnB1dFN0cmVhbS5tYXRjaGVzKGRhdGEsIDcpKTsKKyAgICAgICAgZGF0YVs1XSA9ICcwJzsKKyAgICAgICAgQXNzZXJ0LmFzc2VydEZhbHNlKFhaQ29tcHJlc3NvcklucHV0U3RyZWFtLm1hdGNoZXMoZGF0YSwgNikpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgc2luZ2xlQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZk5vRGVjb21wcmVzc0NvbmNhdGVuYXRlZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHNpbmdsZUJ5dGVSZWFkQ29uc2lzdGVudGx5UmV0dXJuc01pbnVzT25lQXRFb2YoZmFsc2UpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgc2luZ2xlQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZkRlY29tcHJlc3NDb25jYXRlbmF0ZWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzaW5nbGVCeXRlUmVhZENvbnNpc3RlbnRseVJldHVybnNNaW51c09uZUF0RW9mKHRydWUpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBzaW5nbGVCeXRlUmVhZENvbnNpc3RlbnRseVJldHVybnNNaW51c09uZUF0RW9mKGJvb2xlYW4gZGVjb21wcmVzc0NvbmNhdGVuYXRlZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgRmlsZSBpbnB1dCA9IGdldEZpbGUoImJsYS50YXIueHoiKTsKKyAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpKSB7CisgICAgICAgICAgICBmaW5hbCBYWkNvbXByZXNzb3JJbnB1dFN0cmVhbSBpbiA9CisgICAgICAgICAgICAgICAgbmV3IFhaQ29tcHJlc3NvcklucHV0U3RyZWFtKGlzLCBkZWNvbXByZXNzQ29uY2F0ZW5hdGVkKTsKKyAgICAgICAgICAgIElPVXRpbHMudG9CeXRlQXJyYXkoaW4pOworICAgICAgICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygtMSwgaW4ucmVhZCgpKTsKKyAgICAgICAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoLTEsIGluLnJlYWQoKSk7CisgICAgICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBtdWx0aUJ5dGVSZWFkQ29uc2lzdGVudGx5UmV0dXJuc01pbnVzT25lQXRFb2ZOb0RlY29tcHJlc3NDb25jYXRlbmF0ZWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBtdWx0aUJ5dGVSZWFkQ29uc2lzdGVudGx5UmV0dXJuc01pbnVzT25lQXRFb2YoZmFsc2UpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgbXVsdGlCeXRlUmVhZENvbnNpc3RlbnRseVJldHVybnNNaW51c09uZUF0RW9mRGVjb21wcmVzc0NvbmNhdGVuYXRlZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG11bHRpQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZih0cnVlKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgbXVsdGlCeXRlUmVhZENvbnNpc3RlbnRseVJldHVybnNNaW51c09uZUF0RW9mKGJvb2xlYW4gZGVjb21wcmVzc0NvbmNhdGVuYXRlZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgRmlsZSBpbnB1dCA9IGdldEZpbGUoImJsYS50YXIueHoiKTsKKyAgICAgICAgYnl0ZVtdIGJ1ZiA9IG5ldyBieXRlWzJdOworICAgICAgICB0cnkgKElucHV0U3RyZWFtIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShpbnB1dCkpIHsKKyAgICAgICAgICAgIGZpbmFsIFhaQ29tcHJlc3NvcklucHV0U3RyZWFtIGluID0KKyAgICAgICAgICAgICAgICBuZXcgWFpDb21wcmVzc29ySW5wdXRTdHJlYW0oaXMsIGRlY29tcHJlc3NDb25jYXRlbmF0ZWQpOworICAgICAgICAgICAgSU9VdGlscy50b0J5dGVBcnJheShpbik7CisgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKC0xLCBpbi5yZWFkKGJ1ZikpOworICAgICAgICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygtMSwgaW4ucmVhZChidWYpKTsKKyAgICAgICAgICAgIGluLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL3h6L1haQ29tcHJlc3Nvck91dHB1dFN0cmVhbVRlc3QuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL3h6L1haQ29tcHJlc3Nvck91dHB1dFN0cmVhbVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40OWU2NmY4Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMveHovWFpDb21wcmVzc29yT3V0cHV0U3RyZWFtVGVzdC5qYXZhCkBAIC0wLDAgKzEsNTUgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMueHo7CisKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEVxdWFsczsKKworCisvKioKKyAqIFVuaXQgdGVzdHMgZm9yIGNsYXNzIHtAbGluayBYWkNvbXByZXNzb3JPdXRwdXRTdHJlYW19LgorICoKKyAqIEBkYXRlIDE2LjA2LjIwMTcKKyAqIEBzZWUgWFpDb21wcmVzc29yT3V0cHV0U3RyZWFtCisgKiovCitwdWJsaWMgY2xhc3MgWFpDb21wcmVzc29yT3V0cHV0U3RyZWFtVGVzdCB7CisKKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFdyaXRlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKworICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYnl0ZUFycmF5T3V0cHV0U3RyZWFtID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSg0NTkwKTsKKyAgICAgICAgdHJ5IChYWkNvbXByZXNzb3JPdXRwdXRTdHJlYW0geFpDb21wcmVzc29yT3V0cHV0U3RyZWFtID0gbmV3IFhaQ29tcHJlc3Nvck91dHB1dFN0cmVhbShieXRlQXJyYXlPdXRwdXRTdHJlYW0pKSB7CisgICAgICAgICAgICB4WkNvbXByZXNzb3JPdXRwdXRTdHJlYW0ud3JpdGUoNDU5MCk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgKFhaQ29tcHJlc3NvcklucHV0U3RyZWFtIHhaQ29tcHJlc3NvcklucHV0U3RyZWFtID0KKyAgICAgICAgICAgIG5ldyBYWkNvbXByZXNzb3JJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYnl0ZUFycmF5T3V0cHV0U3RyZWFtLnRvQnl0ZUFycmF5KCkpKSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDQ1OTAgJSAyNTYsIHhaQ29tcHJlc3NvcklucHV0U3RyZWFtLnJlYWQoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIHhaQ29tcHJlc3NvcklucHV0U3RyZWFtLnJlYWQoKSk7CisgICAgICAgIH0KKyAgICB9CisKKworfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMveHovWFpVdGlsc1Rlc3RDYXNlLmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy94ei9YWlV0aWxzVGVzdENhc2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNzA2OTYxCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMveHovWFpVdGlsc1Rlc3RDYXNlLmphdmEKQEAgLTAsMCArMSwxMTIgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMueHo7CisKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC4qOworCitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CisKK3B1YmxpYyBjbGFzcyBYWlV0aWxzVGVzdENhc2UgeworCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SXNDb21wcmVzc2VkRmlsZW5hbWUoKSB7CisgICAgICAgIGFzc2VydEZhbHNlKFhaVXRpbHMuaXNDb21wcmVzc2VkRmlsZW5hbWUoIiIpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoWFpVdGlscy5pc0NvbXByZXNzZWRGaWxlbmFtZSgiLnh6IikpOworCisgICAgICAgIGFzc2VydFRydWUoWFpVdGlscy5pc0NvbXByZXNzZWRGaWxlbmFtZSgieC50eHoiKSk7CisgICAgICAgIGFzc2VydFRydWUoWFpVdGlscy5pc0NvbXByZXNzZWRGaWxlbmFtZSgieC54eiIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShYWlV0aWxzLmlzQ29tcHJlc3NlZEZpbGVuYW1lKCJ4LXh6IikpOworCisgICAgICAgIGFzc2VydEZhbHNlKFhaVXRpbHMuaXNDb21wcmVzc2VkRmlsZW5hbWUoInh4Z3oiKSk7CisgICAgICAgIGFzc2VydEZhbHNlKFhaVXRpbHMuaXNDb21wcmVzc2VkRmlsZW5hbWUoInh6eiIpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoWFpVdGlscy5pc0NvbXByZXNzZWRGaWxlbmFtZSgieGF6IikpOworCisgICAgICAgIGFzc2VydEZhbHNlKFhaVXRpbHMuaXNDb21wcmVzc2VkRmlsZW5hbWUoIngudHh6ICIpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoWFpVdGlscy5pc0NvbXByZXNzZWRGaWxlbmFtZSgieC50eHpcbiIpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoWFpVdGlscy5pc0NvbXByZXNzZWRGaWxlbmFtZSgieC50eHoueSIpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRVbmNvbXByZXNzZWRGaWxlbmFtZSgpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCBYWlV0aWxzLmdldFVuY29tcHJlc3NlZEZpbGVuYW1lKCIiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiLnh6IiwgWFpVdGlscy5nZXRVbmNvbXByZXNzZWRGaWxlbmFtZSgiLnh6IikpOworCisgICAgICAgIGFzc2VydEVxdWFscygieC50YXIiLCBYWlV0aWxzLmdldFVuY29tcHJlc3NlZEZpbGVuYW1lKCJ4LnR4eiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ4IiwgWFpVdGlscy5nZXRVbmNvbXByZXNzZWRGaWxlbmFtZSgieC54eiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ4IiwgWFpVdGlscy5nZXRVbmNvbXByZXNzZWRGaWxlbmFtZSgieC14eiIpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIngudHh6ICIsIFhaVXRpbHMuZ2V0VW5jb21wcmVzc2VkRmlsZW5hbWUoIngudHh6ICIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ4LnR4elxuIiwgWFpVdGlscy5nZXRVbmNvbXByZXNzZWRGaWxlbmFtZSgieC50eHpcbiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ4LnR4ei55IiwgWFpVdGlscy5nZXRVbmNvbXByZXNzZWRGaWxlbmFtZSgieC50eHoueSIpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRDb21wcmVzc2VkRmlsZW5hbWUoKSB7CisgICAgICAgIGFzc2VydEVxdWFscygiLnh6IiwgWFpVdGlscy5nZXRDb21wcmVzc2VkRmlsZW5hbWUoIiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ4Lnh6IiwgWFpVdGlscy5nZXRDb21wcmVzc2VkRmlsZW5hbWUoIngiKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ4LnR4eiIsIFhaVXRpbHMuZ2V0Q29tcHJlc3NlZEZpbGVuYW1lKCJ4LnRhciIpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIngud21mIC54eiIsIFhaVXRpbHMuZ2V0Q29tcHJlc3NlZEZpbGVuYW1lKCJ4LndtZiAiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygieC53bWZcbi54eiIsIFhaVXRpbHMuZ2V0Q29tcHJlc3NlZEZpbGVuYW1lKCJ4LndtZlxuIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIngud21mLnkueHoiLCBYWlV0aWxzLmdldENvbXByZXNzZWRGaWxlbmFtZSgieC53bWYueSIpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RNYXRjaGVzKCkgeworICAgICAgICBmaW5hbCBieXRlW10gZGF0YSA9IHsKKyAgICAgICAgICAgIChieXRlKSAweEZELCAnNycsICd6JywgJ1gnLCAnWicsICdcMCcKKyAgICAgICAgfTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoWFpVdGlscy5tYXRjaGVzKGRhdGEsIDUpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShYWlV0aWxzLm1hdGNoZXMoZGF0YSwgNikpOworICAgICAgICBhc3NlcnRUcnVlKFhaVXRpbHMubWF0Y2hlcyhkYXRhLCA3KSk7CisgICAgICAgIGRhdGFbNV0gPSAnMCc7CisgICAgICAgIGFzc2VydEZhbHNlKFhaVXRpbHMubWF0Y2hlcyhkYXRhLCA2KSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2FjaGluZ0lzRW5hYmxlZEJ5RGVmYXVsdEFuZFhaSXNQcmVzZW50KCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoWFpVdGlscy5DYWNoZWRBdmFpbGFiaWxpdHkuQ0FDSEVEX0FWQUlMQUJMRSwgWFpVdGlscy5nZXRDYWNoZWRYWkF2YWlsYWJpbGl0eSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShYWlV0aWxzLmlzWFpDb21wcmVzc2lvbkF2YWlsYWJsZSgpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RDYW5UdXJuT2ZmQ2FjaGluZygpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFhaVXRpbHMuc2V0Q2FjaGVYWkF2YWlsYWJsaXR5KGZhbHNlKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhYWlV0aWxzLkNhY2hlZEF2YWlsYWJpbGl0eS5ET05UX0NBQ0hFLCBYWlV0aWxzLmdldENhY2hlZFhaQXZhaWxhYmlsaXR5KCkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShYWlV0aWxzLmlzWFpDb21wcmVzc2lvbkF2YWlsYWJsZSgpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIFhaVXRpbHMuc2V0Q2FjaGVYWkF2YWlsYWJsaXR5KHRydWUpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VHVybmluZ09uQ2FjaGluZ1JlRXZhbHVhdGVzQXZhaWxhYmlsaXR5KCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgWFpVdGlscy5zZXRDYWNoZVhaQXZhaWxhYmxpdHkoZmFsc2UpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKFhaVXRpbHMuQ2FjaGVkQXZhaWxhYmlsaXR5LkRPTlRfQ0FDSEUsIFhaVXRpbHMuZ2V0Q2FjaGVkWFpBdmFpbGFiaWxpdHkoKSk7CisgICAgICAgICAgICBYWlV0aWxzLnNldENhY2hlWFpBdmFpbGFibGl0eSh0cnVlKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhYWlV0aWxzLkNhY2hlZEF2YWlsYWJpbGl0eS5DQUNIRURfQVZBSUxBQkxFLCBYWlV0aWxzLmdldENhY2hlZFhaQXZhaWxhYmlsaXR5KCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgWFpVdGlscy5zZXRDYWNoZVhaQXZhaWxhYmxpdHkodHJ1ZSk7CisgICAgICAgIH0KKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL3ovWkNvbXByZXNzb3JJbnB1dFN0cmVhbVRlc3QuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL3ovWkNvbXByZXNzb3JJbnB1dFN0cmVhbVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45ZTc3ODZiCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvei9aQ29tcHJlc3NvcklucHV0U3RyZWFtVGVzdC5qYXZhCkBAIC0wLDAgKzEsOTQgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuejsKKworaW1wb3J0IG9yZy5qdW5pdC5Bc3NlcnQ7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CisKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uU2VxdWVuY2VJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLklPVXRpbHM7CisKK2ltcG9ydCBzdGF0aWMgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLkFic3RyYWN0VGVzdENhc2UuZ2V0RmlsZTsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uTW9ja2l0by5tb2NrOworaW1wb3J0IHN0YXRpYyBvcmcucG93ZXJtb2NrLmFwaS5tb2NraXRvLlBvd2VyTW9ja2l0by5kb1JldHVybjsKKworCisvKioKKyAqIFVuaXQgdGVzdHMgZm9yIGNsYXNzIHtAbGluayBaQ29tcHJlc3NvcklucHV0U3RyZWFtfS4KKyAqCisgKiBAZGF0ZSAxNi4wNi4yMDE3CisgKiBAc2VlIFpDb21wcmVzc29ySW5wdXRTdHJlYW0KKyAqKi8KK3B1YmxpYyBjbGFzcyBaQ29tcHJlc3NvcklucHV0U3RyZWFtVGVzdCB7CisKKworICAgIEBUZXN0KGV4cGVjdGVkID0gSU9FeGNlcHRpb24uY2xhc3MpCisgICAgcHVibGljIHZvaWQgdGVzdEZhaWxzVG9DcmVhdGVaQ29tcHJlc3NvcklucHV0U3RyZWFtQW5kVGhyb3dzSU9FeGNlcHRpb24oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBib29sZWFuIGphdmE5ID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDbGFzcy5mb3JOYW1lKCJqYXZhLmxhbmcubW9kdWxlLk1vZHVsZURlc2NyaXB0b3IiKTsKKyAgICAgICAgICAgIGphdmE5ID0gdHJ1ZTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAvLyBub3QgSmF2YTkKKyAgICAgICAgfQorICAgICAgICBvcmcuanVuaXQuQXNzdW1lLmFzc3VtZUZhbHNlKCJjYW4ndCB1c2UgUG93ZXJNb2NrIHdpdGggSmF2YTkiLCBqYXZhOSk7CisKKyAgICAgICAgRW51bWVyYXRpb248U2VxdWVuY2VJbnB1dFN0cmVhbT4gZW51bWVyYXRpb24gPSAoRW51bWVyYXRpb248U2VxdWVuY2VJbnB1dFN0cmVhbT4pIG1vY2soRW51bWVyYXRpb24uY2xhc3MpOworICAgICAgICBTZXF1ZW5jZUlucHV0U3RyZWFtIHNlcXVlbmNlSW5wdXRTdHJlYW0gPSBuZXcgU2VxdWVuY2VJbnB1dFN0cmVhbShlbnVtZXJhdGlvbik7CisgICAgICAgIFpDb21wcmVzc29ySW5wdXRTdHJlYW0gekNvbXByZXNzb3JJbnB1dFN0cmVhbSA9IG51bGw7CisKKyAgICAgICAgZG9SZXR1cm4oZmFsc2UpLndoZW4oZW51bWVyYXRpb24pLmhhc01vcmVFbGVtZW50cygpOworCisgICAgICAgIHpDb21wcmVzc29ySW5wdXRTdHJlYW0gPSBuZXcgWkNvbXByZXNzb3JJbnB1dFN0cmVhbShzZXF1ZW5jZUlucHV0U3RyZWFtKTsKKworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgc2luZ2xlQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGUgaW5wdXQgPSBnZXRGaWxlKCJibGEudGFyLloiKTsKKyAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpKSB7CisgICAgICAgICAgICBmaW5hbCBaQ29tcHJlc3NvcklucHV0U3RyZWFtIGluID0KKyAgICAgICAgICAgICAgICAgICAgbmV3IFpDb21wcmVzc29ySW5wdXRTdHJlYW0oaXMpOworICAgICAgICAgICAgSU9VdGlscy50b0J5dGVBcnJheShpbik7CisgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKC0xLCBpbi5yZWFkKCkpOworICAgICAgICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygtMSwgaW4ucmVhZCgpKTsKKyAgICAgICAgICAgIGluLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIG11bHRpQnl0ZVJlYWRDb25zaXN0ZW50bHlSZXR1cm5zTWludXNPbmVBdEVvZigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGUgaW5wdXQgPSBnZXRGaWxlKCJibGEudGFyLloiKTsKKyAgICAgICAgYnl0ZVtdIGJ1ZiA9IG5ldyBieXRlWzJdOworICAgICAgICB0cnkgKElucHV0U3RyZWFtIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShpbnB1dCkpIHsKKyAgICAgICAgICAgIGZpbmFsIFpDb21wcmVzc29ySW5wdXRTdHJlYW0gaW4gPQorICAgICAgICAgICAgICAgICAgICBuZXcgWkNvbXByZXNzb3JJbnB1dFN0cmVhbShpcyk7CisgICAgICAgICAgICBJT1V0aWxzLnRvQnl0ZUFycmF5KGluKTsKKyAgICAgICAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoLTEsIGluLnJlYWQoYnVmKSk7CisgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKC0xLCBpbi5yZWFkKGJ1ZikpOworICAgICAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvenN0YW5kYXJkL1pzdGRDb21wcmVzc29ySW5wdXRTdHJlYW1UZXN0LmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy96c3RhbmRhcmQvWnN0ZENvbXByZXNzb3JJbnB1dFN0cmVhbVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZDVmMDY2Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvenN0YW5kYXJkL1pzdGRDb21wcmVzc29ySW5wdXRTdHJlYW1UZXN0LmphdmEKQEAgLTAsMCArMSwxNzMgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuenN0YW5kYXJkOworCitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0RXF1YWxzOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydFRydWU7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5BYnN0cmFjdFRlc3RDYXNlOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5Db21wcmVzc29ySW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLkNvbXByZXNzb3JTdHJlYW1GYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy56c3RhbmRhcmQuWnN0ZENvbXByZXNzb3JJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuSU9VdGlsczsKK2ltcG9ydCBvcmcuanVuaXQuQXNzZXJ0OworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworCitwdWJsaWMgY2xhc3MgWnN0ZENvbXByZXNzb3JJbnB1dFN0cmVhbVRlc3QgZXh0ZW5kcyBBYnN0cmFjdFRlc3RDYXNlIHsKKworICAgIC8qKgorICAgICAqIFRlc3QgYnJpZGdlIHdvcmtzIGZpbmUuCisgICAgICogCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiAKKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3Rac3RkRGVjb2RlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgRmlsZSBpbnB1dCA9IGdldEZpbGUoInpzdGFuZGFyZC50ZXN0ZGF0YS56c3QiKTsKKyAgICAgICAgZmluYWwgRmlsZSBleHBlY3RlZCA9IGdldEZpbGUoInpzdGFuZGFyZC50ZXN0ZGF0YSIpOworICAgICAgICB0cnkgKElucHV0U3RyZWFtIGlucHV0U3RyZWFtID0gbmV3IEZpbGVJbnB1dFN0cmVhbShpbnB1dCk7CisgICAgICAgICAgICBJbnB1dFN0cmVhbSBleHBlY3RlZFN0cmVhbSA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oZXhwZWN0ZWQpOworICAgICAgICAgICAgWnN0ZENvbXByZXNzb3JJbnB1dFN0cmVhbSB6c3RkSW5wdXRTdHJlYW0gPSBuZXcgWnN0ZENvbXByZXNzb3JJbnB1dFN0cmVhbShpbnB1dFN0cmVhbSkpIHsKKyAgICAgICAgICAgIGZpbmFsIGJ5dGVbXSBiID0gbmV3IGJ5dGVbOTddOworICAgICAgICAgICAgSU9VdGlscy5yZWFkRnVsbHkoZXhwZWN0ZWRTdHJlYW0sIGIpOworICAgICAgICAgICAgZmluYWwgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgICAgIGludCByZWFkQnl0ZSA9IC0xOworICAgICAgICAgICAgd2hpbGUoKHJlYWRCeXRlID0genN0ZElucHV0U3RyZWFtLnJlYWQoKSkgIT0gLTEpIHsKKyAgICAgICAgICAgICAgICBib3Mud3JpdGUocmVhZEJ5dGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgQXNzZXJ0LmFzc2VydEFycmF5RXF1YWxzKGIsIGJvcy50b0J5dGVBcnJheSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdENhY2hpbmdJc0VuYWJsZWRCeURlZmF1bHRBbmRac3RkVXRpbHNQcmVzZW50KCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoWnN0ZFV0aWxzLkNhY2hlZEF2YWlsYWJpbGl0eS5DQUNIRURfQVZBSUxBQkxFLCBac3RkVXRpbHMuZ2V0Q2FjaGVkWnN0ZEF2YWlsYWJpbGl0eSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShac3RkVXRpbHMuaXNac3RkQ29tcHJlc3Npb25BdmFpbGFibGUoKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2FuVHVybk9mZkNhY2hpbmcoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBac3RkVXRpbHMuc2V0Q2FjaGVac3RkQXZhaWxhYmxpdHkoZmFsc2UpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKFpzdGRVdGlscy5DYWNoZWRBdmFpbGFiaWxpdHkuRE9OVF9DQUNIRSwgWnN0ZFV0aWxzLmdldENhY2hlZFpzdGRBdmFpbGFiaWxpdHkoKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKFpzdGRVdGlscy5pc1pzdGRDb21wcmVzc2lvbkF2YWlsYWJsZSgpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIFpzdGRVdGlscy5zZXRDYWNoZVpzdGRBdmFpbGFibGl0eSh0cnVlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFR1cm5pbmdPbkNhY2hpbmdSZUV2YWx1YXRlc0F2YWlsYWJpbGl0eSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFpzdGRVdGlscy5zZXRDYWNoZVpzdGRBdmFpbGFibGl0eShmYWxzZSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoWnN0ZFV0aWxzLkNhY2hlZEF2YWlsYWJpbGl0eS5ET05UX0NBQ0hFLCBac3RkVXRpbHMuZ2V0Q2FjaGVkWnN0ZEF2YWlsYWJpbGl0eSgpKTsKKyAgICAgICAgICAgIFpzdGRVdGlscy5zZXRDYWNoZVpzdGRBdmFpbGFibGl0eSh0cnVlKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhac3RkVXRpbHMuQ2FjaGVkQXZhaWxhYmlsaXR5LkNBQ0hFRF9BVkFJTEFCTEUsIFpzdGRVdGlscy5nZXRDYWNoZWRac3RkQXZhaWxhYmlsaXR5KCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgWnN0ZFV0aWxzLnNldENhY2hlWnN0ZEF2YWlsYWJsaXR5KHRydWUpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBzaG91bGRCZUFibGVUb1NraXBBQnl0ZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEZpbGUgaW5wdXQgPSBnZXRGaWxlKCJ6c3RhbmRhcmQudGVzdGRhdGEuenN0Iik7CisgICAgICAgIHRyeSAoSW5wdXRTdHJlYW0gaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGlucHV0KSkgeworICAgICAgICAgICAgZmluYWwgWnN0ZENvbXByZXNzb3JJbnB1dFN0cmVhbSBpbiA9CisgICAgICAgICAgICAgICAgICAgIG5ldyBac3RkQ29tcHJlc3NvcklucHV0U3RyZWFtKGlzKTsKKyAgICAgICAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMSwgaW4uc2tpcCgxKSk7CisgICAgICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBzaW5nbGVCeXRlUmVhZFdvcmtzQXNFeHBlY3RlZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisKKyAgICAgICAgZmluYWwgRmlsZSBpbnB1dCA9IGdldEZpbGUoInpzdGFuZGFyZC50ZXN0ZGF0YS56c3QiKTsKKworICAgICAgICBmaW5hbCBGaWxlIG9yaWdpbmFsID0gZ2V0RmlsZSgienN0YW5kYXJkLnRlc3RkYXRhIik7CisgICAgICAgIGZpbmFsIGxvbmcgb3JpZ2luYWxGaWxlTGVuZ3RoID0gb3JpZ2luYWwubGVuZ3RoKCk7CisKKyAgICAgICAgYnl0ZVtdIG9yaWdpbmFsRmlsZUNvbnRlbnQgPSBuZXcgYnl0ZVsoKGludCkgb3JpZ2luYWxGaWxlTGVuZ3RoKV07CisKKyAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBvaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKG9yaWdpbmFsKSkgeworICAgICAgICAgICAgb2lzLnJlYWQob3JpZ2luYWxGaWxlQ29udGVudCk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgKElucHV0U3RyZWFtIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShpbnB1dCkpIHsKKyAgICAgICAgICAgIGZpbmFsIFpzdGRDb21wcmVzc29ySW5wdXRTdHJlYW0gaW4gPQorICAgICAgICAgICAgICAgICAgICBuZXcgWnN0ZENvbXByZXNzb3JJbnB1dFN0cmVhbShpcyk7CisKKyAgICAgICAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMob3JpZ2luYWxGaWxlQ29udGVudFswXSwgaW4ucmVhZCgpKTsKKyAgICAgICAgICAgIGluLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHNpbmdsZUJ5dGVSZWFkQ29uc2lzdGVudGx5UmV0dXJuc01pbnVzT25lQXRFb2YoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlIGlucHV0ID0gZ2V0RmlsZSgienN0YW5kYXJkLnRlc3RkYXRhLnpzdCIpOworICAgICAgICB0cnkgKElucHV0U3RyZWFtIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShpbnB1dCkpIHsKKyAgICAgICAgICAgIGZpbmFsIFpzdGRDb21wcmVzc29ySW5wdXRTdHJlYW0gaW4gPQorICAgICAgICAgICAgICAgICAgICBuZXcgWnN0ZENvbXByZXNzb3JJbnB1dFN0cmVhbShpcyk7CisgICAgICAgICAgICBJT1V0aWxzLnRvQnl0ZUFycmF5KGluKTsKKyAgICAgICAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoLTEsIGluLnJlYWQoKSk7CisgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKC0xLCBpbi5yZWFkKCkpOworICAgICAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgbXVsdGlCeXRlUmVhZENvbnNpc3RlbnRseVJldHVybnNNaW51c09uZUF0RW9mKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgRmlsZSBpbnB1dCA9IGdldEZpbGUoInpzdGFuZGFyZC50ZXN0ZGF0YS56c3QiKTsKKyAgICAgICAgYnl0ZVtdIGJ1ZiA9IG5ldyBieXRlWzJdOworICAgICAgICB0cnkgKElucHV0U3RyZWFtIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShpbnB1dCkpIHsKKyAgICAgICAgICAgIGZpbmFsIFpzdGRDb21wcmVzc29ySW5wdXRTdHJlYW0gaW4gPQorICAgICAgICAgICAgICAgICAgICBuZXcgWnN0ZENvbXByZXNzb3JJbnB1dFN0cmVhbShpcyk7CisgICAgICAgICAgICBJT1V0aWxzLnRvQnl0ZUFycmF5KGluKTsKKyAgICAgICAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoLTEsIGluLnJlYWQoYnVmKSk7CisgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKC0xLCBpbi5yZWFkKGJ1ZikpOworICAgICAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFpzdGFuZGFyZFVuYXJjaGl2ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBGaWxlIGlucHV0ID0gZ2V0RmlsZSgiYmxhLnRhci56c3QiKTsKKyAgICAgICAgZmluYWwgRmlsZSBvdXRwdXQgPSBuZXcgRmlsZShkaXIsICJibGEudGFyIik7CisgICAgICAgIHRyeSAoSW5wdXRTdHJlYW0gaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGlucHV0KSkgeworICAgICAgICAgICAgZmluYWwgQ29tcHJlc3NvcklucHV0U3RyZWFtIGluID0gbmV3IENvbXByZXNzb3JTdHJlYW1GYWN0b3J5KCkKKyAgICAgICAgICAgICAgICAgICAgLmNyZWF0ZUNvbXByZXNzb3JJbnB1dFN0cmVhbSgienN0ZCIsIGlzKTsKKyAgICAgICAgICAgIEZpbGVPdXRwdXRTdHJlYW0gb3V0ID0gbnVsbDsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgb3V0ID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0ob3V0cHV0KTsKKyAgICAgICAgICAgICAgICBJT1V0aWxzLmNvcHkoaW4sIG91dCk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIGlmIChvdXQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvenN0YW5kYXJkL1pzdGRSb3VuZHRyaXBUZXN0LmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy96c3RhbmRhcmQvWnN0ZFJvdW5kdHJpcFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42ZTlkZmVmCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvY29tcHJlc3NvcnMvenN0YW5kYXJkL1pzdGRSb3VuZHRyaXBUZXN0LmphdmEKQEAgLTAsMCArMSwxMTkgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuenN0YW5kYXJkOworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5BYnN0cmFjdFRlc3RDYXNlOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5jb21wcmVzc29ycy5Db21wcmVzc29ySW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLkNvbXByZXNzb3JPdXRwdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLkNvbXByZXNzb3JTdHJlYW1GYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5JT1V0aWxzOworaW1wb3J0IG9yZy5qdW5pdC5Bc3NlcnQ7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CisKK3B1YmxpYyBjbGFzcyBac3RkUm91bmR0cmlwVGVzdCBleHRlbmRzIEFic3RyYWN0VGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBpbnRlcmZhY2UgT3V0cHV0U3RyZWFtQ3JlYXRvciB7CisgICAgICAgIFpzdGRDb21wcmVzc29yT3V0cHV0U3RyZWFtIHdyYXAoRmlsZU91dHB1dFN0cmVhbSBvcykgdGhyb3dzIElPRXhjZXB0aW9uOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgZGlyZWN0Um91bmR0cmlwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHJvdW5kdHJpcChuZXcgT3V0cHV0U3RyZWFtQ3JlYXRvcigpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIFpzdGRDb21wcmVzc29yT3V0cHV0U3RyZWFtIHdyYXAoRmlsZU91dHB1dFN0cmVhbSBvcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFpzdGRDb21wcmVzc29yT3V0cHV0U3RyZWFtKG9zKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHJvdW5kdHJpcChPdXRwdXRTdHJlYW1DcmVhdG9yIG9jKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBGaWxlIGlucHV0ID0gZ2V0RmlsZSgiYmxhLnRhciIpOworICAgICAgICBsb25nIHN0YXJ0ID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgICAgIGZpbmFsIEZpbGUgb3V0cHV0ID0gbmV3IEZpbGUoZGlyLCBpbnB1dC5nZXROYW1lKCkgKyAiLnpzdGQiKTsKKyAgICAgICAgdHJ5IChGaWxlSW5wdXRTdHJlYW0gaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGlucHV0KTsKKyAgICAgICAgICAgICBGaWxlT3V0cHV0U3RyZWFtIG9zID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0ob3V0cHV0KTsKKyAgICAgICAgICAgICBac3RkQ29tcHJlc3Nvck91dHB1dFN0cmVhbSB6b3MgPSBvYy53cmFwKG9zKSkgeworICAgICAgICAgICAgSU9VdGlscy5jb3B5KGlzLCB6b3MpOworICAgICAgICB9CisgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbihpbnB1dC5nZXROYW1lKCkgKyAiIHdyaXR0ZW4sIHVuY29tcHJlc3NlZCBieXRlczogIiArIGlucHV0Lmxlbmd0aCgpCisgICAgICAgICAgICArICIsIGNvbXByZXNzZWQgYnl0ZXM6ICIgKyBvdXRwdXQubGVuZ3RoKCkgKyAiIGFmdGVyICIgKyAoU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgLSBzdGFydCkgKyAibXMiKTsKKyAgICAgICAgc3RhcnQgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICAgICAgdHJ5IChGaWxlSW5wdXRTdHJlYW0gaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGlucHV0KTsKKyAgICAgICAgICAgICBac3RkQ29tcHJlc3NvcklucHV0U3RyZWFtIHppcyA9IG5ldyBac3RkQ29tcHJlc3NvcklucHV0U3RyZWFtKG5ldyBGaWxlSW5wdXRTdHJlYW0ob3V0cHV0KSkpIHsKKyAgICAgICAgICAgIGJ5dGVbXSBleHBlY3RlZCA9IElPVXRpbHMudG9CeXRlQXJyYXkoaXMpOworICAgICAgICAgICAgYnl0ZVtdIGFjdHVhbCA9IElPVXRpbHMudG9CeXRlQXJyYXkoemlzKTsKKyAgICAgICAgICAgIEFzc2VydC5hc3NlcnRBcnJheUVxdWFscyhleHBlY3RlZCwgYWN0dWFsKTsKKyAgICAgICAgfQorICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4ob3V0cHV0LmdldE5hbWUoKSArICIgcmVhZCBhZnRlciAiICsgKFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpIC0gc3RhcnQpICsgIm1zIik7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBmYWN0b3J5Um91bmR0cmlwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEZpbGUgaW5wdXQgPSBnZXRGaWxlKCJibGEudGFyIik7CisgICAgICAgIGxvbmcgc3RhcnQgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICAgICAgZmluYWwgRmlsZSBvdXRwdXQgPSBuZXcgRmlsZShkaXIsIGlucHV0LmdldE5hbWUoKSArICIuenN0ZCIpOworICAgICAgICB0cnkgKEZpbGVJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5wdXQpOworICAgICAgICAgICAgIEZpbGVPdXRwdXRTdHJlYW0gb3MgPSBuZXcgRmlsZU91dHB1dFN0cmVhbShvdXRwdXQpOworICAgICAgICAgICAgIENvbXByZXNzb3JPdXRwdXRTdHJlYW0gem9zID0gbmV3IENvbXByZXNzb3JTdHJlYW1GYWN0b3J5KCkuY3JlYXRlQ29tcHJlc3Nvck91dHB1dFN0cmVhbSgienN0ZCIsIG9zKSkgeworICAgICAgICAgICAgSU9VdGlscy5jb3B5KGlzLCB6b3MpOworICAgICAgICB9CisgICAgICAgIHN0YXJ0ID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgICAgIHRyeSAoRmlsZUlucHV0U3RyZWFtIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShpbnB1dCk7CisgICAgICAgICAgICAgQ29tcHJlc3NvcklucHV0U3RyZWFtIHppcyA9IG5ldyBDb21wcmVzc29yU3RyZWFtRmFjdG9yeSgpCisgICAgICAgICAgICAgLmNyZWF0ZUNvbXByZXNzb3JJbnB1dFN0cmVhbSgienN0ZCIsIG5ldyBGaWxlSW5wdXRTdHJlYW0ob3V0cHV0KSkpIHsKKyAgICAgICAgICAgIGJ5dGVbXSBleHBlY3RlZCA9IElPVXRpbHMudG9CeXRlQXJyYXkoaXMpOworICAgICAgICAgICAgYnl0ZVtdIGFjdHVhbCA9IElPVXRpbHMudG9CeXRlQXJyYXkoemlzKTsKKyAgICAgICAgICAgIEFzc2VydC5hc3NlcnRBcnJheUVxdWFscyhleHBlY3RlZCwgYWN0dWFsKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgcm91bmR0cmlwV2l0aEN1c3RvbUxldmVsKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHJvdW5kdHJpcChuZXcgT3V0cHV0U3RyZWFtQ3JlYXRvcigpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIFpzdGRDb21wcmVzc29yT3V0cHV0U3RyZWFtIHdyYXAoRmlsZU91dHB1dFN0cmVhbSBvcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFpzdGRDb21wcmVzc29yT3V0cHV0U3RyZWFtKG9zLCAxKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCByb3VuZHRyaXBXaXRoQ2xvc2VGcmFtZU9uRmx1c2goKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgcm91bmR0cmlwKG5ldyBPdXRwdXRTdHJlYW1DcmVhdG9yKCkgeworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgWnN0ZENvbXByZXNzb3JPdXRwdXRTdHJlYW0gd3JhcChGaWxlT3V0cHV0U3RyZWFtIG9zKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgWnN0ZENvbXByZXNzb3JPdXRwdXRTdHJlYW0ob3MsIDMsIHRydWUpOworICAgICAgICAgICAgfQorICAgICAgICB9KTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHJvdW5kdHJpcFdpdGhDaGVja3N1bSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICByb3VuZHRyaXAobmV3IE91dHB1dFN0cmVhbUNyZWF0b3IoKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBac3RkQ29tcHJlc3Nvck91dHB1dFN0cmVhbSB3cmFwKEZpbGVPdXRwdXRTdHJlYW0gb3MpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBac3RkQ29tcHJlc3Nvck91dHB1dFN0cmVhbShvcywgMywgZmFsc2UsIHRydWUpOworICAgICAgICAgICAgfQorICAgICAgICB9KTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzL3pzdGFuZGFyZC9ac3RkVXRpbHNUZXN0LmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy96c3RhbmRhcmQvWnN0ZFV0aWxzVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjViYmEwYWQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy9jb21wcmVzc29ycy96c3RhbmRhcmQvWnN0ZFV0aWxzVGVzdC5qYXZhCkBAIC0wLDAgKzEsNTIgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuenN0YW5kYXJkOworCitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0RmFsc2U7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VHJ1ZTsKKworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworCitwdWJsaWMgY2xhc3MgWnN0ZFV0aWxzVGVzdCB7CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RNYXRjaGVzWnN0YW5kYXJkRnJhbWUoKSB7CisgICAgICAgIGZpbmFsIGJ5dGVbXSBkYXRhID0geworICAgICAgICAgICAgKGJ5dGUpIDB4MjgsIChieXRlKSAweEI1LCAoYnl0ZSkgMHgyRiwgKGJ5dGUpIDB4RkQsCisgICAgICAgIH07CisgICAgICAgIGFzc2VydEZhbHNlKFpzdGRVdGlscy5tYXRjaGVzKGRhdGEsIDMpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShac3RkVXRpbHMubWF0Y2hlcyhkYXRhLCA0KSk7CisgICAgICAgIGFzc2VydFRydWUoWnN0ZFV0aWxzLm1hdGNoZXMoZGF0YSwgNSkpOworICAgICAgICBkYXRhWzNdID0gJzAnOworICAgICAgICBhc3NlcnRGYWxzZShac3RkVXRpbHMubWF0Y2hlcyhkYXRhLCA0KSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWF0Y2hlc1NraXBwYWJsZUZyYW1lKCkgeworICAgICAgICBmaW5hbCBieXRlW10gZGF0YSA9IHsKKyAgICAgICAgICAgIDAsIChieXRlKSAweDJBLCAoYnl0ZSkgMHg0RCwgKGJ5dGUpIDB4MTgsCisgICAgICAgIH07CisgICAgICAgIGFzc2VydEZhbHNlKFpzdGRVdGlscy5tYXRjaGVzKGRhdGEsIDQpKTsKKyAgICAgICAgZm9yIChieXRlIGIgPSAoYnl0ZSkgMHg1MDsgYiA8IDB4NjA7IGIrKykgeworICAgICAgICAgICAgZGF0YVswXSA9IGI7CisgICAgICAgICAgICBhc3NlcnRUcnVlKFpzdGRVdGlscy5tYXRjaGVzKGRhdGEsIDQpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRGYWxzZShac3RkVXRpbHMubWF0Y2hlcyhkYXRhLCAzKSk7CisgICAgICAgIGFzc2VydFRydWUoWnN0ZFV0aWxzLm1hdGNoZXMoZGF0YSwgNSkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL3V0aWxzL0JpdElucHV0U3RyZWFtVGVzdC5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvdXRpbHMvQml0SW5wdXRTdHJlYW1UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTJkZTcxYgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL3V0aWxzL0JpdElucHV0U3RyZWFtVGVzdC5qYXZhCkBAIC0wLDAgKzEsMjE3IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzOworCitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0RXF1YWxzOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLkJ5dGVPcmRlcjsKKworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworCitwdWJsaWMgY2xhc3MgQml0SW5wdXRTdHJlYW1UZXN0IHsKKworICAgIEBUZXN0KGV4cGVjdGVkID0gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLmNsYXNzKQorICAgIHB1YmxpYyB2b2lkIHNob3VsZE5vdEFsbG93UmVhZGluZ09mQU5lZ2F0aXZlQW1vdW50T2ZCaXRzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IChmaW5hbCBCaXRJbnB1dFN0cmVhbSBiaXMgPSBuZXcgQml0SW5wdXRTdHJlYW0oZ2V0U3RyZWFtKCksIEJ5dGVPcmRlci5MSVRUTEVfRU5ESUFOKSkgeworICAgICAgICAgICAgYmlzLnJlYWRCaXRzKC0xKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0KGV4cGVjdGVkID0gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLmNsYXNzKQorICAgIHB1YmxpYyB2b2lkIHNob3VsZE5vdEFsbG93UmVhZGluZ09mTW9yZVRoYW42M0JpdHNBdEFUaW1lKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IChmaW5hbCBCaXRJbnB1dFN0cmVhbSBiaXMgPSBuZXcgQml0SW5wdXRTdHJlYW0oZ2V0U3RyZWFtKCksIEJ5dGVPcmRlci5MSVRUTEVfRU5ESUFOKSkgeworICAgICAgICAgICAgYmlzLnJlYWRCaXRzKDY0KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFJlYWRpbmcyNEJpdHNJbkxpdHRsZUVuZGlhbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRyeSAoZmluYWwgQml0SW5wdXRTdHJlYW0gYmlzID0gbmV3IEJpdElucHV0U3RyZWFtKGdldFN0cmVhbSgpLCBCeXRlT3JkZXIuTElUVExFX0VORElBTikpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygweDAwMDE0MGY4LCBiaXMucmVhZEJpdHMoMjQpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFJlYWRpbmcyNEJpdHNJbkJpZ0VuZGlhbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRyeSAoZmluYWwgQml0SW5wdXRTdHJlYW0gYmlzID0gbmV3IEJpdElucHV0U3RyZWFtKGdldFN0cmVhbSgpLCBCeXRlT3JkZXIuQklHX0VORElBTikpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygweDAwZjg0MDAxLCBiaXMucmVhZEJpdHMoMjQpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFJlYWRpbmcxN0JpdHNJbkxpdHRsZUVuZGlhbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRyeSAoZmluYWwgQml0SW5wdXRTdHJlYW0gYmlzID0gbmV3IEJpdElucHV0U3RyZWFtKGdldFN0cmVhbSgpLCBCeXRlT3JkZXIuTElUVExFX0VORElBTikpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygweDAwMDE0MGY4LCBiaXMucmVhZEJpdHMoMTcpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFJlYWRpbmcxN0JpdHNJbkJpZ0VuZGlhbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRyeSAoZmluYWwgQml0SW5wdXRTdHJlYW0gYmlzID0gbmV3IEJpdElucHV0U3RyZWFtKGdldFN0cmVhbSgpLCBCeXRlT3JkZXIuQklHX0VORElBTikpIHsKKyAgICAgICAgICAgIC8vIDEtMTExMTAwMDAtMTAwMDAwMDAKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygweDAwMDFmMDgwLCBiaXMucmVhZEJpdHMoMTcpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFJlYWRpbmczMEJpdHNJbkxpdHRsZUVuZGlhbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRyeSAoZmluYWwgQml0SW5wdXRTdHJlYW0gYmlzID0gbmV3IEJpdElucHV0U3RyZWFtKGdldFN0cmVhbSgpLCBCeXRlT3JkZXIuTElUVExFX0VORElBTikpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygweDJmMDE0MGY4LCBiaXMucmVhZEJpdHMoMzApKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFJlYWRpbmczMEJpdHNJbkJpZ0VuZGlhbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRyeSAoZmluYWwgQml0SW5wdXRTdHJlYW0gYmlzID0gbmV3IEJpdElucHV0U3RyZWFtKGdldFN0cmVhbSgpLCBCeXRlT3JkZXIuQklHX0VORElBTikpIHsKKyAgICAgICAgICAgIC8vIDExMTExMC0wMDAxMDAwMC0wMDAwMDAwMC0wMTAwMTAxMQorICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDB4M2UxMDAwNGIsIGJpcy5yZWFkQml0cygzMCkpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVhZGluZzMxQml0c0luTGl0dGxlRW5kaWFuKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IChmaW5hbCBCaXRJbnB1dFN0cmVhbSBiaXMgPSBuZXcgQml0SW5wdXRTdHJlYW0oZ2V0U3RyZWFtKCksIEJ5dGVPcmRlci5MSVRUTEVfRU5ESUFOKSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDB4MmYwMTQwZjgsIGJpcy5yZWFkQml0cygzMSkpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVhZGluZzMxQml0c0luQmlnRW5kaWFuKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IChmaW5hbCBCaXRJbnB1dFN0cmVhbSBiaXMgPSBuZXcgQml0SW5wdXRTdHJlYW0oZ2V0U3RyZWFtKCksIEJ5dGVPcmRlci5CSUdfRU5ESUFOKSkgeworICAgICAgICAgICAgLy8gMTExMTEwMC0wMDEwMDAwMC0wMDAwMDAwMC0xMDAxMDExMQorICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDB4N2MyMDAwOTcsIGJpcy5yZWFkQml0cygzMSkpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2xlYXJCaXRDYWNoZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRyeSAoZmluYWwgQml0SW5wdXRTdHJlYW0gYmlzID0gbmV3IEJpdElucHV0U3RyZWFtKGdldFN0cmVhbSgpLCBCeXRlT3JkZXIuTElUVExFX0VORElBTikpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygweDA4LCBiaXMucmVhZEJpdHMoNCkpOworICAgICAgICAgICAgYmlzLmNsZWFyQml0Q2FjaGUoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygwLCBiaXMucmVhZEJpdHMoMSkpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RU9GKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IChmaW5hbCBCaXRJbnB1dFN0cmVhbSBiaXMgPSBuZXcgQml0SW5wdXRTdHJlYW0oZ2V0U3RyZWFtKCksIEJ5dGVPcmRlci5MSVRUTEVfRU5ESUFOKSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDB4MmYwMTQwZjgsIGJpcy5yZWFkQml0cygzMCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBiaXMucmVhZEJpdHMoMykpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSAiaHR0cHM6Ly9pc3N1ZXMuYXBhY2hlLm9yZy9qaXJhL2Jyb3dzZS9DT01QUkVTUy0zNjMiCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBsaXR0bGVFbmRpYW5XaXRoT3ZlcmZsb3coKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gaW4gPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0obmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAgICAgODcsIC8vIDAxMDEwMTExCisgICAgICAgICAgICAgICAgNDUsIC8vIDAwMTAxMTAxCisgICAgICAgICAgICAgICAgNjYsIC8vIDAxMDAwMDEwCisgICAgICAgICAgICAgICAgMTUsIC8vIDAwMDAxMTExCisgICAgICAgICAgICAgICAgOTAsIC8vIDAxMDExMDEwCisgICAgICAgICAgICAgICAgMjksIC8vIDAwMDExMTAxCisgICAgICAgICAgICAgICAgODgsIC8vIDAxMDExMDAwCisgICAgICAgICAgICAgICAgNjEsIC8vIDAwMTExMTAxCisgICAgICAgICAgICAgICAgMzMsIC8vIDAwMTAwMDAxCisgICAgICAgICAgICAgICAgNzQgIC8vIDAxMDAxMDEwCisgICAgICAgICAgICB9KTsKKyAgICAgICAgdHJ5IChmaW5hbCBCaXRJbnB1dFN0cmVhbSBiaW4gPSBuZXcgQml0SW5wdXRTdHJlYW0oaW4sIEJ5dGVPcmRlci5MSVRUTEVfRU5ESUFOKSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDIzLCAvLyAxMDExMQorICAgICAgICAgICAgICAgICAgICAgICAgIGJpbi5yZWFkQml0cyg1KSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoNzE0NTk1NjA1NjQ0MTg1OTYybCwgLy8gMDAwMS0wMDExMTEwMS0wMTAxMTAwMC0wMDAxMTEwMS0wMTAxMTAxMC0wMDAwMTExMS0wMTAwMDAxMC0wMDEwMTEwMS0wMTAKKyAgICAgICAgICAgICAgICAgICAgICAgICBiaW4ucmVhZEJpdHMoNjMpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygxMTg2LCAvLyAwMTAwMTAxMC0wMDEwCisgICAgICAgICAgICAgICAgICAgICAgICAgYmluLnJlYWRCaXRzKDEyKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoLTEgLCBiaW4ucmVhZEJpdHMoMSkpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBiaWdFbmRpYW5XaXRoT3ZlcmZsb3coKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gaW4gPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0obmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAgICAgODcsIC8vIDAxMDEwMTExCisgICAgICAgICAgICAgICAgNDUsIC8vIDAwMTAxMTAxCisgICAgICAgICAgICAgICAgNjYsIC8vIDAxMDAwMDEwCisgICAgICAgICAgICAgICAgMTUsIC8vIDAwMDAxMTExCisgICAgICAgICAgICAgICAgOTAsIC8vIDAxMDExMDEwCisgICAgICAgICAgICAgICAgMjksIC8vIDAwMDExMTAxCisgICAgICAgICAgICAgICAgODgsIC8vIDAxMDExMDAwCisgICAgICAgICAgICAgICAgNjEsIC8vIDAwMTExMTAxCisgICAgICAgICAgICAgICAgMzMsIC8vIDAwMTAwMDAxCisgICAgICAgICAgICAgICAgNzQgIC8vIDAxMDAxMDEwCisgICAgICAgICAgICB9KTsKKyAgICAgICAgdHJ5IChmaW5hbCBCaXRJbnB1dFN0cmVhbSBiaW4gPSBuZXcgQml0SW5wdXRTdHJlYW0oaW4sIEJ5dGVPcmRlci5CSUdfRU5ESUFOKSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDEwLCAvLyAwMTAxMAorICAgICAgICAgICAgICAgICAgICAgICAgIGJpbi5yZWFkQml0cyg1KSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoODI3NDI3NDY1NDc0MDY0NDgxOGwsIC8vMTExLTAwMTAxMTAxLTAxMDAwMDEwLTAwMDAxMTExLTAxMDExMDEwLTAwMDExMTAxLTAxMDExMDAwLTAwMTExMTAxLTAwMTAKKyAgICAgICAgICAgICAgICAgICAgYmluLnJlYWRCaXRzKDYzKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMzMwLCAvLyAwMDAxLTAxMDAxMDEwCisgICAgICAgICAgICAgICAgICAgICAgICAgYmluLnJlYWRCaXRzKDEyKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoLTEgLCBiaW4ucmVhZEJpdHMoMSkpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBhbGlnbldpdGhCeXRlQm91bmRhcnlXaGVuQXRCb3VuZGFyeSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgKGZpbmFsIEJpdElucHV0U3RyZWFtIGJpcyA9IG5ldyBCaXRJbnB1dFN0cmVhbShnZXRTdHJlYW0oKSwgQnl0ZU9yZGVyLkxJVFRMRV9FTkRJQU4pKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMHhGOCwgYmlzLnJlYWRCaXRzKDgpKTsKKyAgICAgICAgICAgIGJpcy5hbGlnbldpdGhCeXRlQm91bmRhcnkoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygwLCBiaXMucmVhZEJpdHMoNCkpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBhbGlnbldpdGhCeXRlQm91bmRhcnlXaGVuTm90QXRCb3VuZGFyeSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgKGZpbmFsIEJpdElucHV0U3RyZWFtIGJpcyA9IG5ldyBCaXRJbnB1dFN0cmVhbShnZXRTdHJlYW0oKSwgQnl0ZU9yZGVyLkxJVFRMRV9FTkRJQU4pKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMHgwOCwgYmlzLnJlYWRCaXRzKDQpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyg0LCBiaXMuYml0c0NhY2hlZCgpKTsKKyAgICAgICAgICAgIGJpcy5hbGlnbldpdGhCeXRlQm91bmRhcnkoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygwLCBiaXMuYml0c0NhY2hlZCgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygwLCBiaXMucmVhZEJpdHMoNCkpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBhdmFpbGFibGVXaXRob3V0Q2FjaGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IChmaW5hbCBCaXRJbnB1dFN0cmVhbSBiaXMgPSBuZXcgQml0SW5wdXRTdHJlYW0oZ2V0U3RyZWFtKCksIEJ5dGVPcmRlci5MSVRUTEVfRU5ESUFOKSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDMyLCBiaXMuYml0c0F2YWlsYWJsZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgYXZhaWxhYmxlV2l0aENhY2hlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSAoZmluYWwgQml0SW5wdXRTdHJlYW0gYmlzID0gbmV3IEJpdElucHV0U3RyZWFtKGdldFN0cmVhbSgpLCBCeXRlT3JkZXIuTElUVExFX0VORElBTikpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygweDA4LCBiaXMucmVhZEJpdHMoNCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDI4LCBiaXMuYml0c0F2YWlsYWJsZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgQnl0ZUFycmF5SW5wdXRTdHJlYW0gZ2V0U3RyZWFtKCkgeworICAgICAgICByZXR1cm4gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKG5ldyBieXRlW10geworICAgICAgICAgICAgICAgIChieXRlKSAweEY4LCAgLy8gMTExMTEwMDAKKyAgICAgICAgICAgICAgICAweDQwLCAgICAgICAgIC8vIDAxMDAwMDAwCisgICAgICAgICAgICAgICAgMHgwMSwgICAgICAgICAvLyAwMDAwMDAwMQorICAgICAgICAgICAgICAgIDB4MkYgfSk7ICAgICAgLy8gMDAxMDExMTEKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL3V0aWxzL0J5dGVVdGlsc1Rlc3QuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL3V0aWxzL0J5dGVVdGlsc1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xNjcxZWMwCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvdXRpbHMvQnl0ZVV0aWxzVGVzdC5qYXZhCkBAIC0wLDAgKzEsMjA3IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICoKKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlsczsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5EYXRhSW5wdXQ7CitpbXBvcnQgamF2YS5pby5EYXRhSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5EYXRhT3V0cHV0OworaW1wb3J0IGphdmEuaW8uRGF0YU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CisKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworaW1wb3J0IHN0YXRpYyBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuQnl0ZVV0aWxzLio7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0QXJyYXlFcXVhbHM7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0RXF1YWxzOworCitwdWJsaWMgY2xhc3MgQnl0ZVV0aWxzVGVzdCB7CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIGZyb21MaXR0bGVFbmRpYW5Gcm9tQXJyYXlPbmVBcmcoKSB7CisgICAgICAgIGJ5dGVbXSBiID0gbmV3IGJ5dGVbXSB7IDIsIDMsIDQgfTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIgKyAzICogMjU2ICsgNCAqIDI1NiAqIDI1NiwgZnJvbUxpdHRsZUVuZGlhbihiKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBmcm9tTGl0dGxlRW5kaWFuRnJvbUFycmF5T25lQXJnVW5zaWduZWRJbnQzMigpIHsKKyAgICAgICAgYnl0ZVtdIGIgPSBuZXcgYnl0ZVtdIHsgMiwgMywgNCwgKGJ5dGUpIDEyOCB9OworICAgICAgICBhc3NlcnRFcXVhbHMoMiArIDMgKiAyNTYgKyA0ICogMjU2ICogMjU2ICsgMTI4bCAqIDI1NiAqIDI1NiAqIDI1NiwgZnJvbUxpdHRsZUVuZGlhbihiKSk7CisgICAgfQorCisgICAgQFRlc3QoZXhwZWN0ZWQgPSBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24uY2xhc3MpCisgICAgcHVibGljIHZvaWQgZnJvbUxpdHRsZUVuZGlhbkZyb21BcnJheU9uZUFyZ1Rocm93c0Zvckxlbmd0aFRvb0JpZygpIHsKKyAgICAgICAgZnJvbUxpdHRsZUVuZGlhbihuZXcgYnl0ZVtdIHsgMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSB9KTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIGZyb21MaXR0bGVFbmRpYW5Gcm9tQXJyYXkoKSB7CisgICAgICAgIGJ5dGVbXSBiID0gbmV3IGJ5dGVbXSB7IDEsIDIsIDMsIDQsIDUgfTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIgKyAzICogMjU2ICsgNCAqIDI1NiAqIDI1NiwgZnJvbUxpdHRsZUVuZGlhbihiLCAxLCAzKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBmcm9tTGl0dGxlRW5kaWFuRnJvbUFycmF5VW5zaWduZWRJbnQzMigpIHsKKyAgICAgICAgYnl0ZVtdIGIgPSBuZXcgYnl0ZVtdIHsgMSwgMiwgMywgNCwgKGJ5dGUpIDEyOCB9OworICAgICAgICBhc3NlcnRFcXVhbHMoMiArIDMgKiAyNTYgKyA0ICogMjU2ICogMjU2ICsgMTI4bCAqIDI1NiAqIDI1NiAqIDI1NiwgZnJvbUxpdHRsZUVuZGlhbihiLCAxLCA0KSk7CisgICAgfQorCisgICAgQFRlc3QoZXhwZWN0ZWQgPSBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24uY2xhc3MpCisgICAgcHVibGljIHZvaWQgZnJvbUxpdHRsZUVuZGlhbkZyb21BcnJheVRocm93c0Zvckxlbmd0aFRvb0JpZygpIHsKKyAgICAgICAgZnJvbUxpdHRsZUVuZGlhbihuZXcgYnl0ZVswXSwgMCwgOSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBmcm9tTGl0dGxlRW5kaWFuRnJvbVN0cmVhbSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGJpbiA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShuZXcgYnl0ZVtdIHsgMiwgMywgNCwgNSB9KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIgKyAzICogMjU2ICsgNCAqIDI1NiAqIDI1NiwgZnJvbUxpdHRsZUVuZGlhbihiaW4sIDMpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIGZyb21MaXR0bGVFbmRpYW5Gcm9tU3RyZWFtVW5zaWduZWRJbnQzMigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGJpbiA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShuZXcgYnl0ZVtdIHsgMiwgMywgNCwgKGJ5dGUpIDEyOCB9KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIgKyAzICogMjU2ICsgNCAqIDI1NiAqIDI1NiArIDEyOGwgKiAyNTYgKiAyNTYgKiAyNTYsIGZyb21MaXR0bGVFbmRpYW4oYmluLCA0KSk7CisgICAgfQorCisgICAgQFRlc3QoZXhwZWN0ZWQgPSBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24uY2xhc3MpCisgICAgcHVibGljIHZvaWQgZnJvbUxpdHRsZUVuZGlhbkZyb21TdHJlYW1UaHJvd3NGb3JMZW5ndGhUb29CaWcoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmcm9tTGl0dGxlRW5kaWFuKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShuZXcgYnl0ZVswXSksIDkpOworICAgIH0KKworICAgIEBUZXN0KGV4cGVjdGVkID0gSU9FeGNlcHRpb24uY2xhc3MpCisgICAgcHVibGljIHZvaWQgZnJvbUxpdHRsZUVuZGlhbkZyb21TdHJlYW1UaHJvd3NGb3JQcmVtYXR1cmVFbmQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBCeXRlQXJyYXlJbnB1dFN0cmVhbSBiaW4gPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0obmV3IGJ5dGVbXSB7IDIsIDMgfSk7CisgICAgICAgIGZyb21MaXR0bGVFbmRpYW4oYmluLCAzKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIGZyb21MaXR0bGVFbmRpYW5Gcm9tU3VwcGxpZXIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBCeXRlQXJyYXlJbnB1dFN0cmVhbSBiaW4gPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0obmV3IGJ5dGVbXSB7IDIsIDMsIDQsIDUgfSk7CisgICAgICAgIGFzc2VydEVxdWFscygyICsgMyAqIDI1NiArIDQgKiAyNTYgKiAyNTYsIGZyb21MaXR0bGVFbmRpYW4obmV3IElucHV0U3RyZWFtQnl0ZVN1cHBsaWVyKGJpbiksIDMpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIGZyb21MaXR0bGVFbmRpYW5Gcm9tU3VwcGxpZXJVbnNpZ25lZEludDMyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gYmluID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKG5ldyBieXRlW10geyAyLCAzLCA0LCAoYnl0ZSkgMTI4IH0pOworICAgICAgICBhc3NlcnRFcXVhbHMoMiArIDMgKiAyNTYgKyA0ICogMjU2ICogMjU2ICsgMTI4bCAqIDI1NiAqIDI1NiAqIDI1NiwKKyAgICAgICAgICAgIGZyb21MaXR0bGVFbmRpYW4obmV3IElucHV0U3RyZWFtQnl0ZVN1cHBsaWVyKGJpbiksIDQpKTsKKyAgICB9CisKKyAgICBAVGVzdChleHBlY3RlZCA9IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi5jbGFzcykKKyAgICBwdWJsaWMgdm9pZCBmcm9tTGl0dGxlRW5kaWFuRnJvbVN1cHBsaWVyVGhyb3dzRm9yTGVuZ3RoVG9vQmlnKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZnJvbUxpdHRsZUVuZGlhbihuZXcgSW5wdXRTdHJlYW1CeXRlU3VwcGxpZXIobmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKG5ldyBieXRlWzBdKSksIDkpOworICAgIH0KKworICAgIEBUZXN0KGV4cGVjdGVkID0gSU9FeGNlcHRpb24uY2xhc3MpCisgICAgcHVibGljIHZvaWQgZnJvbUxpdHRsZUVuZGlhbkZyb21TdXBwbGllclRocm93c0ZvclByZW1hdHVyZUVuZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGJpbiA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShuZXcgYnl0ZVtdIHsgMiwgMyB9KTsKKyAgICAgICAgZnJvbUxpdHRsZUVuZGlhbihuZXcgSW5wdXRTdHJlYW1CeXRlU3VwcGxpZXIoYmluKSwgMyk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBmcm9tTGl0dGxlRW5kaWFuRnJvbURhdGFJbnB1dCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIERhdGFJbnB1dCBkaW4gPSBuZXcgRGF0YUlucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShuZXcgYnl0ZVtdIHsgMiwgMywgNCwgNSB9KSk7CisgICAgICAgIGFzc2VydEVxdWFscygyICsgMyAqIDI1NiArIDQgKiAyNTYgKiAyNTYsIGZyb21MaXR0bGVFbmRpYW4oZGluLCAzKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBmcm9tTGl0dGxlRW5kaWFuRnJvbURhdGFJbnB1dFVuc2lnbmVkSW50MzIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBEYXRhSW5wdXQgZGluID0gbmV3IERhdGFJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0obmV3IGJ5dGVbXSB7IDIsIDMsIDQsIChieXRlKSAxMjggfSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMiArIDMgKiAyNTYgKyA0ICogMjU2ICogMjU2ICsgMTI4bCAqIDI1NiAqIDI1NiAqIDI1NiwgZnJvbUxpdHRsZUVuZGlhbihkaW4sIDQpKTsKKyAgICB9CisKKyAgICBAVGVzdChleHBlY3RlZCA9IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi5jbGFzcykKKyAgICBwdWJsaWMgdm9pZCBmcm9tTGl0dGxlRW5kaWFuRnJvbURhdGFJbnB1dFRocm93c0Zvckxlbmd0aFRvb0JpZygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIERhdGFJbnB1dCBkaW4gPSBuZXcgRGF0YUlucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShuZXcgYnl0ZVswXSkpOworICAgICAgICBmcm9tTGl0dGxlRW5kaWFuKGRpbiwgOSk7CisgICAgfQorCisgICAgQFRlc3QoZXhwZWN0ZWQgPSBqYXZhLmlvLkVPRkV4Y2VwdGlvbi5jbGFzcykKKyAgICBwdWJsaWMgdm9pZCBmcm9tTGl0dGxlRW5kaWFuRnJvbURhdGFJbnB1dFRocm93c0ZvclByZW1hdHVyZUVuZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIERhdGFJbnB1dCBkaW4gPSBuZXcgRGF0YUlucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShuZXcgYnl0ZVtdIHsgMiwgMyB9KSk7CisgICAgICAgIGZyb21MaXR0bGVFbmRpYW4oZGluLCAzKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRvTGl0dGxlRW5kaWFuVG9TdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICB0b0xpdHRsZUVuZGlhbihib3MsIDIgKyAzICogMjU2ICsgNCAqIDI1NiAqIDI1NiwgMyk7CisgICAgICAgIGJvcy5jbG9zZSgpOworICAgICAgICBhc3NlcnRBcnJheUVxdWFscyhuZXcgYnl0ZVtdIHsgMiwgMywgNCB9LCBib3MudG9CeXRlQXJyYXkoKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0b0xpdHRsZUVuZGlhblRvU3RyZWFtVW5zaWduZWRJbnQzMigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBib3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIHRvTGl0dGxlRW5kaWFuKGJvcywgMiArIDMgKiAyNTYgKyA0ICogMjU2ICogMjU2ICsgMTI4bCAqIDI1NiAqIDI1NiAqIDI1NiwgNCk7CisgICAgICAgIGJvcy5jbG9zZSgpOworICAgICAgICBhc3NlcnRBcnJheUVxdWFscyhuZXcgYnl0ZVtdIHsgMiwgMywgNCwgKGJ5dGUpIDEyOCB9LCBib3MudG9CeXRlQXJyYXkoKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0b0xpdHRsZUVuZGlhblRvQ29uc3VtZXIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICB0b0xpdHRsZUVuZGlhbihuZXcgT3V0cHV0U3RyZWFtQnl0ZUNvbnN1bWVyKGJvcyksIDIgKyAzICogMjU2ICsgNCAqIDI1NiAqIDI1NiwgMyk7CisgICAgICAgIGJvcy5jbG9zZSgpOworICAgICAgICBhc3NlcnRBcnJheUVxdWFscyhuZXcgYnl0ZVtdIHsgMiwgMywgNCB9LCBib3MudG9CeXRlQXJyYXkoKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0b0xpdHRsZUVuZGlhblRvQ29uc3VtZXJVbnNpZ25lZEludDMyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgdG9MaXR0bGVFbmRpYW4obmV3IE91dHB1dFN0cmVhbUJ5dGVDb25zdW1lcihib3MpLCAyICsgMyAqIDI1NiArIDQgKiAyNTYgKiAyNTYgKyAxMjhsICogMjU2ICogMjU2ICogMjU2LCA0KTsKKyAgICAgICAgYm9zLmNsb3NlKCk7CisgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKG5ldyBieXRlW10geyAyLCAzLCA0LCAoYnl0ZSkgMTI4IH0sIGJvcy50b0J5dGVBcnJheSgpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRvTGl0dGxlRW5kaWFuVG9EYXRhT3V0cHV0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgRGF0YU91dHB1dCBkb3MgPSBuZXcgRGF0YU91dHB1dFN0cmVhbShib3MpOworICAgICAgICB0b0xpdHRsZUVuZGlhbihkb3MsIDIgKyAzICogMjU2ICsgNCAqIDI1NiAqIDI1NiwgMyk7CisgICAgICAgIGJvcy5jbG9zZSgpOworICAgICAgICBhc3NlcnRBcnJheUVxdWFscyhuZXcgYnl0ZVtdIHsgMiwgMywgNCB9LCBib3MudG9CeXRlQXJyYXkoKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0b0xpdHRsZUVuZGlhblRvRGF0YU91dHB1dFVuc2lnbmVkSW50MzIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICBEYXRhT3V0cHV0IGRvcyA9IG5ldyBEYXRhT3V0cHV0U3RyZWFtKGJvcyk7CisgICAgICAgIHRvTGl0dGxlRW5kaWFuKGRvcywgMiArIDMgKiAyNTYgKyA0ICogMjU2ICogMjU2ICsgMTI4bCAqIDI1NiAqIDI1NiAqIDI1NiwgNCk7CisgICAgICAgIGJvcy5jbG9zZSgpOworICAgICAgICBhc3NlcnRBcnJheUVxdWFscyhuZXcgYnl0ZVtdIHsgMiwgMywgNCwgKGJ5dGUpIDEyOCB9LCBib3MudG9CeXRlQXJyYXkoKSk7CisgICAgfQorCisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRvTGl0dGxlRW5kaWFuVG9CeXRlQXJyYXkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBieXRlW10gYiA9IG5ldyBieXRlWzRdOworICAgICAgICB0b0xpdHRsZUVuZGlhbihiLCAyICsgMyAqIDI1NiArIDQgKiAyNTYgKiAyNTYsIDEsIDMpOworICAgICAgICBhc3NlcnRBcnJheUVxdWFscyhuZXcgYnl0ZVtdIHsgMiwgMywgNCB9LCBBcnJheXMuY29weU9mUmFuZ2UoYiwgMSwgNCkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdG9MaXR0bGVFbmRpYW5Ub0J5dGVBcnJheVVuc2lnbmVkSW50MzIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBieXRlW10gYiA9IG5ldyBieXRlWzRdOworICAgICAgICB0b0xpdHRsZUVuZGlhbihiLCAyICsgMyAqIDI1NiArIDQgKiAyNTYgKiAyNTYgKyAxMjhsICogMjU2ICogMjU2ICogMjU2LCAwLCA0KTsKKyAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMobmV3IGJ5dGVbXSB7IDIsIDMsIDQsIChieXRlKSAxMjggfSwgYik7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvdXRpbHMvQ2hhcnNldHNUZXN0LmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy91dGlscy9DaGFyc2V0c1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zZjM5ZTFjCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvdXRpbHMvQ2hhcnNldHNUZXN0LmphdmEKQEAgLTAsMCArMSw0MCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlsczsKKworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldDsKKworaW1wb3J0IG9yZy5qdW5pdC5Bc3NlcnQ7CisKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworLyoqCisgKiBTYW5pdHkgY2hlY2tzIGZvciB7QGxpbmsgQ2hhcnNldHN9LgorICoKKyAqLworcHVibGljIGNsYXNzIENoYXJzZXRzVGVzdCB7CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RUb0NoYXJzZXQoKSB7CisgICAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoQ2hhcnNldC5kZWZhdWx0Q2hhcnNldCgpLCBDaGFyc2V0cy50b0NoYXJzZXQoKFN0cmluZykgbnVsbCkpOworICAgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKENoYXJzZXQuZGVmYXVsdENoYXJzZXQoKSwgQ2hhcnNldHMudG9DaGFyc2V0KChDaGFyc2V0KSBudWxsKSk7CisgICAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoQ2hhcnNldC5kZWZhdWx0Q2hhcnNldCgpLCBDaGFyc2V0cy50b0NoYXJzZXQoQ2hhcnNldC5kZWZhdWx0Q2hhcnNldCgpKSk7CisgICAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoQ2hhcnNldC5mb3JOYW1lKCJVVEYtOCIpLCBDaGFyc2V0cy50b0NoYXJzZXQoQ2hhcnNldC5mb3JOYW1lKCJVVEYtOCIpKSk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy91dGlscy9DaGVja3N1bUNhbGN1bGF0aW5nSW5wdXRTdHJlYW1UZXN0LmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy91dGlscy9DaGVja3N1bUNhbGN1bGF0aW5nSW5wdXRTdHJlYW1UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTllNTI0NgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL3V0aWxzL0NoZWNrc3VtQ2FsY3VsYXRpbmdJbnB1dFN0cmVhbVRlc3QuamF2YQpAQCAtMCwwICsxLDEzNiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHM7CisKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLnppcC5BZGxlcjMyOworaW1wb3J0IGphdmEudXRpbC56aXAuQ1JDMzI7CisKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC4qOworCisvKioKKyAqIFVuaXQgdGVzdHMgZm9yIGNsYXNzIHtAbGluayBDaGVja3N1bUNhbGN1bGF0aW5nSW5wdXRTdHJlYW0gb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzLkNoZWNrc3VtQ2FsY3VsYXRpbmdJbnB1dFN0cmVhbX0uCisgKgorICogQGRhdGUgMTMuMDYuMjAxNworICogQHNlZSBDaGVja3N1bUNhbGN1bGF0aW5nSW5wdXRTdHJlYW0KKyAqKi8KK3B1YmxpYyBjbGFzcyBDaGVja3N1bUNhbGN1bGF0aW5nSW5wdXRTdHJlYW1UZXN0IHsKKworCisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RTa2lwUmV0dXJuaW5nWmVybygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisKKyAgICAgICAgQWRsZXIzMiBhZGxlcjMyID0gbmV3IEFkbGVyMzIoKTsKKyAgICAgICAgYnl0ZVtdIGJ5dGVBcnJheSA9IG5ldyBieXRlWzBdOworICAgICAgICBCeXRlQXJyYXlJbnB1dFN0cmVhbSBieXRlQXJyYXlJbnB1dFN0cmVhbSA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShieXRlQXJyYXkpOworICAgICAgICBDaGVja3N1bUNhbGN1bGF0aW5nSW5wdXRTdHJlYW0gY2hlY2tzdW1DYWxjdWxhdGluZ0lucHV0U3RyZWFtID0gbmV3IENoZWNrc3VtQ2FsY3VsYXRpbmdJbnB1dFN0cmVhbShhZGxlcjMyLCBieXRlQXJyYXlJbnB1dFN0cmVhbSk7CisgICAgICAgIGxvbmcgc2tpcFJlc3VsdCA9IGNoZWNrc3VtQ2FsY3VsYXRpbmdJbnB1dFN0cmVhbS5za2lwKDYwTCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDBMLCBza2lwUmVzdWx0KTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoMUwsIGNoZWNrc3VtQ2FsY3VsYXRpbmdJbnB1dFN0cmVhbS5nZXRWYWx1ZSgpKTsKKworCisgICAgfQorCisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RTa2lwUmV0dXJuaW5nUG9zaXRpdmUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCisgICAgICAgIEFkbGVyMzIgYWRsZXIzMiA9IG5ldyBBZGxlcjMyKCk7CisgICAgICAgIGJ5dGVbXSBieXRlQXJyYXkgPSBuZXcgYnl0ZVs2XTsKKyAgICAgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gYnl0ZUFycmF5SW5wdXRTdHJlYW0gPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYnl0ZUFycmF5KTsKKyAgICAgICAgQ2hlY2tzdW1DYWxjdWxhdGluZ0lucHV0U3RyZWFtIGNoZWNrc3VtQ2FsY3VsYXRpbmdJbnB1dFN0cmVhbSA9IG5ldyBDaGVja3N1bUNhbGN1bGF0aW5nSW5wdXRTdHJlYW0oYWRsZXIzMiwgYnl0ZUFycmF5SW5wdXRTdHJlYW0pOworICAgICAgICBsb25nIHNraXBSZXN1bHQgPSBjaGVja3N1bUNhbGN1bGF0aW5nSW5wdXRTdHJlYW0uc2tpcCgoYnl0ZSkwKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoMUwsIHNraXBSZXN1bHQpOworCisgICAgICAgIGFzc2VydEVxdWFscyg2NTUzN0wsIGNoZWNrc3VtQ2FsY3VsYXRpbmdJbnB1dFN0cmVhbS5nZXRWYWx1ZSgpKTsKKworICAgIH0KKworCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVhZFRha2luZ05vQXJndW1lbnRzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKworICAgICAgICBBZGxlcjMyIGFkbGVyMzIgPSBuZXcgQWRsZXIzMigpOworICAgICAgICBieXRlW10gYnl0ZUFycmF5ID0gbmV3IGJ5dGVbNl07CisgICAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGJ5dGVBcnJheUlucHV0U3RyZWFtID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJ5dGVBcnJheSk7CisgICAgICAgIENoZWNrc3VtQ2FsY3VsYXRpbmdJbnB1dFN0cmVhbSBjaGVja3N1bUNhbGN1bGF0aW5nSW5wdXRTdHJlYW0gPSBuZXcgQ2hlY2tzdW1DYWxjdWxhdGluZ0lucHV0U3RyZWFtKGFkbGVyMzIsIGJ5dGVBcnJheUlucHV0U3RyZWFtKTsKKyAgICAgICAgQnVmZmVyZWRJbnB1dFN0cmVhbSBidWZmZXJlZElucHV0U3RyZWFtID0gbmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0oY2hlY2tzdW1DYWxjdWxhdGluZ0lucHV0U3RyZWFtKTsKKyAgICAgICAgaW50IGlucHV0U3RyZWFtUmVhZFJlc3VsdCA9IGJ1ZmZlcmVkSW5wdXRTdHJlYW0ucmVhZChieXRlQXJyYXksIDAsIDEpOworICAgICAgICBpbnQgY2hlY2tTdW1DYWxjdWxhdGlvblJlYWRSZXN1bHQgPSBjaGVja3N1bUNhbGN1bGF0aW5nSW5wdXRTdHJlYW0ucmVhZCgpOworCisgICAgICAgIGFzc2VydEZhbHNlKGNoZWNrU3VtQ2FsY3VsYXRpb25SZWFkUmVzdWx0ID09IGlucHV0U3RyZWFtUmVhZFJlc3VsdCk7CisgICAgICAgIGFzc2VydEVxdWFscygoLTEpLCBjaGVja1N1bUNhbGN1bGF0aW9uUmVhZFJlc3VsdCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGJ5dGVBcnJheUlucHV0U3RyZWFtLmF2YWlsYWJsZSgpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoMzkzMjE3TCwgY2hlY2tzdW1DYWxjdWxhdGluZ0lucHV0U3RyZWFtLmdldFZhbHVlKCkpOworCisgICAgfQorCisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RSZWFkVGFraW5nQnl0ZUFycmF5KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKworICAgICAgICBBZGxlcjMyIGFkbGVyMzIgPSBuZXcgQWRsZXIzMigpOworICAgICAgICBieXRlW10gYnl0ZUFycmF5ID0gbmV3IGJ5dGVbNl07CisgICAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGJ5dGVBcnJheUlucHV0U3RyZWFtID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJ5dGVBcnJheSk7CisgICAgICAgIENoZWNrc3VtQ2FsY3VsYXRpbmdJbnB1dFN0cmVhbSBjaGVja3N1bUNhbGN1bGF0aW5nSW5wdXRTdHJlYW0gPSBuZXcgQ2hlY2tzdW1DYWxjdWxhdGluZ0lucHV0U3RyZWFtKGFkbGVyMzIsIGJ5dGVBcnJheUlucHV0U3RyZWFtKTsKKyAgICAgICAgaW50IHJlYWRSZXN1bHQgPSBjaGVja3N1bUNhbGN1bGF0aW5nSW5wdXRTdHJlYW0ucmVhZChieXRlQXJyYXkpOworCisgICAgICAgIGFzc2VydEVxdWFscyg2LCByZWFkUmVzdWx0KTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgYnl0ZUFycmF5SW5wdXRTdHJlYW0uYXZhaWxhYmxlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMzkzMjE3TCwgY2hlY2tzdW1DYWxjdWxhdGluZ0lucHV0U3RyZWFtLmdldFZhbHVlKCkpOworCisgICAgfQorCisKKyAgICBAVGVzdChleHBlY3RlZCA9IE51bGxQb2ludGVyRXhjZXB0aW9uLmNsYXNzKQorICAgIHB1YmxpYyB2b2lkIHRlc3RDbGFzc0luc3RhbnRpYXRpb25XaXRoUGFyYW1ldGVyQmVpbmdOdWxsVGhyb3dzTnVsbFBvaW50ZXJFeGNlcHRpb25PbmUoKSB7CisKKyAgICAgICAgQ2hlY2tzdW1DYWxjdWxhdGluZ0lucHV0U3RyZWFtIGNoZWNrc3VtQ2FsY3VsYXRpbmdJbnB1dFN0cmVhbSA9IG5ldyBDaGVja3N1bUNhbGN1bGF0aW5nSW5wdXRTdHJlYW0obnVsbCxudWxsKTsKKworCisgICAgfQorCisKKyAgICBAVGVzdChleHBlY3RlZCA9IE51bGxQb2ludGVyRXhjZXB0aW9uLmNsYXNzKQorICAgIHB1YmxpYyB2b2lkIHRlc3RDbGFzc0luc3RhbnRpYXRpb25XaXRoUGFyYW1ldGVyQmVpbmdOdWxsVGhyb3dzTnVsbFBvaW50ZXJFeGNlcHRpb25Ud28oKSB7CisKKyAgICAgICAgQ2hlY2tzdW1DYWxjdWxhdGluZ0lucHV0U3RyZWFtIGNoZWNrc3VtQ2FsY3VsYXRpbmdJbnB1dFN0cmVhbSA9IG5ldyBDaGVja3N1bUNhbGN1bGF0aW5nSW5wdXRTdHJlYW0obnVsbCxuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0obmV3IGJ5dGVbMV0pKTsKKworCisgICAgfQorCisKKyAgICBAVGVzdChleHBlY3RlZCA9IE51bGxQb2ludGVyRXhjZXB0aW9uLmNsYXNzKQorICAgIHB1YmxpYyB2b2lkIHRlc3RDbGFzc0luc3RhbnRpYXRpb25XaXRoUGFyYW1ldGVyQmVpbmdOdWxsVGhyb3dzTnVsbFBvaW50ZXJFeGNlcHRpb25UaHJlZSgpIHsKKworICAgICAgICBDaGVja3N1bUNhbGN1bGF0aW5nSW5wdXRTdHJlYW0gY2hlY2tzdW1DYWxjdWxhdGluZ0lucHV0U3RyZWFtID0gbmV3IENoZWNrc3VtQ2FsY3VsYXRpbmdJbnB1dFN0cmVhbShuZXcgQ1JDMzIoKSxudWxsKTsKKworICAgIH0KKworCit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvdXRpbHMvQ2hlY2tzdW1WZXJpZnlpbmdJbnB1dFN0cmVhbVRlc3QuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL3V0aWxzL0NoZWNrc3VtVmVyaWZ5aW5nSW5wdXRTdHJlYW1UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2M5YjEwMAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL3V0aWxzL0NoZWNrc3VtVmVyaWZ5aW5nSW5wdXRTdHJlYW1UZXN0LmphdmEKQEAgLTAsMCArMSw4NiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHM7CisKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLkFkbGVyMzI7CitpbXBvcnQgamF2YS51dGlsLnppcC5DUkMzMjsKKworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEFycmF5RXF1YWxzOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEVxdWFsczsKKworLyoqCisgKiBVbml0IHRlc3RzIGZvciBjbGFzcyB7QGxpbmsgQ2hlY2tzdW1WZXJpZnlpbmdJbnB1dFN0cmVhbSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuQ2hlY2tzdW1WZXJpZnlpbmdJbnB1dFN0cmVhbX0uCisgKgorICogQGRhdGUgMTMuMDYuMjAxNworICogQHNlZSBDaGVja3N1bVZlcmlmeWluZ0lucHV0U3RyZWFtCisgKiovCitwdWJsaWMgY2xhc3MgQ2hlY2tzdW1WZXJpZnlpbmdJbnB1dFN0cmVhbVRlc3QgeworCisKKworICAgIEBUZXN0KGV4cGVjdGVkID0gSU9FeGNlcHRpb24uY2xhc3MpCisgICAgcHVibGljIHZvaWQgdGVzdFJlYWRUYWtpbmdCeXRlQXJyYXlUaHJvd3NJT0V4Y2VwdGlvbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisKKyAgICAgICAgQWRsZXIzMiBhZGxlcjMyID0gbmV3IEFkbGVyMzIoKTsKKyAgICAgICAgYnl0ZVtdIGJ5dGVBcnJheSA9IG5ldyBieXRlWzNdOworICAgICAgICBCeXRlQXJyYXlJbnB1dFN0cmVhbSBieXRlQXJyYXlJbnB1dFN0cmVhbSA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShieXRlQXJyYXkpOworICAgICAgICBDaGVja3N1bVZlcmlmeWluZ0lucHV0U3RyZWFtIGNoZWNrc3VtVmVyaWZ5aW5nSW5wdXRTdHJlYW0gPSBuZXcgQ2hlY2tzdW1WZXJpZnlpbmdJbnB1dFN0cmVhbShhZGxlcjMyLCBieXRlQXJyYXlJbnB1dFN0cmVhbSwgKC0xODU5TCksIChieXRlKSAoLTY4KSk7CisKKyAgICAgICAgY2hlY2tzdW1WZXJpZnlpbmdJbnB1dFN0cmVhbS5yZWFkKGJ5dGVBcnJheSk7CisKKyAgICB9CisKKworICAgIEBUZXN0KGV4cGVjdGVkID0gSU9FeGNlcHRpb24uY2xhc3MpCisgICAgcHVibGljIHZvaWQgdGVzdFJlYWRUYWtpbmdOb0FyZ3VtZW50c1Rocm93c0lPRXhjZXB0aW9uKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKworICAgICAgICBDUkMzMiBjUkMzMl8gPSBuZXcgQ1JDMzIoKTsKKyAgICAgICAgYnl0ZVtdIGJ5dGVBcnJheSA9IG5ldyBieXRlWzldOworICAgICAgICBCeXRlQXJyYXlJbnB1dFN0cmVhbSBieXRlQXJyYXlJbnB1dFN0cmVhbSA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShieXRlQXJyYXkpOworICAgICAgICBDaGVja3N1bVZlcmlmeWluZ0lucHV0U3RyZWFtIGNoZWNrc3VtVmVyaWZ5aW5nSW5wdXRTdHJlYW0gPSBuZXcgQ2hlY2tzdW1WZXJpZnlpbmdJbnB1dFN0cmVhbShjUkMzMl8sIGJ5dGVBcnJheUlucHV0U3RyZWFtLCAoYnl0ZSkxLCAoYnl0ZSkxKTsKKworICAgICAgICBjaGVja3N1bVZlcmlmeWluZ0lucHV0U3RyZWFtLnJlYWQoKTsKKworICAgIH0KKworCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2tpcCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisKKyAgICAgICAgQ1JDMzIgY1JDMzJfID0gbmV3IENSQzMyKCk7CisgICAgICAgIGJ5dGVbXSBieXRlQXJyYXkgPSBuZXcgYnl0ZVs0XTsKKyAgICAgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gYnl0ZUFycmF5SW5wdXRTdHJlYW0gPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYnl0ZUFycmF5KTsKKyAgICAgICAgQ2hlY2tzdW1WZXJpZnlpbmdJbnB1dFN0cmVhbSBjaGVja3N1bVZlcmlmeWluZ0lucHV0U3RyZWFtID0gbmV3IENoZWNrc3VtVmVyaWZ5aW5nSW5wdXRTdHJlYW0oY1JDMzJfLCBieXRlQXJyYXlJbnB1dFN0cmVhbSwgKGJ5dGUpMzMsIDIzMDNMKTsKKyAgICAgICAgaW50IGludE9uZSA9IGNoZWNrc3VtVmVyaWZ5aW5nSW5wdXRTdHJlYW0ucmVhZChieXRlQXJyYXkpOworCisgICAgICAgIGxvbmcgc2tpcFJldHVyblZhbHVlID0gY2hlY2tzdW1WZXJpZnlpbmdJbnB1dFN0cmVhbS5za2lwKChieXRlKTEpOworCisgICAgICAgIGFzc2VydEVxdWFscyg1NTgxNjE2OTJMLCBjUkMzMl8uZ2V0VmFsdWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBieXRlQXJyYXlJbnB1dFN0cmVhbS5hdmFpbGFibGUoKSk7CisKKyAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMobmV3IGJ5dGVbXSB7KGJ5dGUpMCwgKGJ5dGUpMCwgKGJ5dGUpMCwgKGJ5dGUpMH0sIGJ5dGVBcnJheSk7CisgICAgICAgIGFzc2VydEVxdWFscygwTCwgc2tpcFJldHVyblZhbHVlKTsKKworICAgIH0KKworCisKK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy91dGlscy9Db3VudGluZ1N0cmVhbVRlc3QuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL3V0aWxzL0NvdW50aW5nU3RyZWFtVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNiZTE4NzAKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy91dGlscy9Db3VudGluZ1N0cmVhbVRlc3QuamF2YQpAQCAtMCwwICsxLDc1IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLnV0aWxzOworCitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0QXJyYXlFcXVhbHM7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0RXF1YWxzOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKKworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworCitwdWJsaWMgY2xhc3MgQ291bnRpbmdTdHJlYW1UZXN0IHsKKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgb3V0cHV0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIEkgZG9uJ3QgbGlrZSAidGVzdCBhbGwgYXQgb25jZSIgdGVzdHMgZWl0aGVyLCBidXQgdGhlIGNsYXNzCisgICAgICAgIC8vIGlzIHNvIHRyaXZpYWwKKyAgICAgICAgZmluYWwgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgdHJ5IChmaW5hbCBDb3VudGluZ091dHB1dFN0cmVhbSBvID0gbmV3IENvdW50aW5nT3V0cHV0U3RyZWFtKGJvcykpIHsKKyAgICAgICAgICAgIG8ud3JpdGUoMSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMSwgby5nZXRCeXRlc1dyaXR0ZW4oKSk7CisgICAgICAgICAgICBvLndyaXRlKG5ldyBieXRlW10geyAyLCAzIH0pOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIG8uZ2V0Qnl0ZXNXcml0dGVuKCkpOworICAgICAgICAgICAgby53cml0ZShuZXcgYnl0ZVtdIHsgMiwgMywgNCwgNSwgfSwgMiwgMSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoNCwgby5nZXRCeXRlc1dyaXR0ZW4oKSk7CisgICAgICAgICAgICBvLmNvdW50KC0xKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyg0LCBvLmdldEJ5dGVzV3JpdHRlbigpKTsKKyAgICAgICAgICAgIG8uY291bnQoLTIpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIG8uZ2V0Qnl0ZXNXcml0dGVuKCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKG5ldyBieXRlW10geyAxLCAyLCAzLCA0IH0sIGJvcy50b0J5dGVBcnJheSgpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIGlucHV0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIEkgZG9uJ3QgbGlrZSAidGVzdCBhbGwgYXQgb25jZSIgdGVzdHMgZWl0aGVyLCBidXQgdGhlIGNsYXNzCisgICAgICAgIC8vIGlzIHNvIHRyaXZpYWwKKyAgICAgICAgZmluYWwgQnl0ZUFycmF5SW5wdXRTdHJlYW0gYmlzID0KKyAgICAgICAgICAgIG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShuZXcgYnl0ZVtdIHsgMSwgMiwgMywgNCB9KTsKKyAgICAgICAgdHJ5IChmaW5hbCBDb3VudGluZ0lucHV0U3RyZWFtIGkgPSBuZXcgQ291bnRpbmdJbnB1dFN0cmVhbShiaXMpKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMSwgaS5yZWFkKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGkuZ2V0Qnl0ZXNSZWFkKCkpOworICAgICAgICAgICAgYnl0ZVtdIGIgPSBuZXcgYnl0ZVsyXTsKKyAgICAgICAgICAgIGkucmVhZChiKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygzLCBpLmdldEJ5dGVzUmVhZCgpKTsKKyAgICAgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKG5ldyBieXRlW10geyAyLCAzIH0sIGIpOworICAgICAgICAgICAgYiA9IG5ldyBieXRlWzNdOworICAgICAgICAgICAgaS5yZWFkKGIsIDEsIDEpOworICAgICAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMobmV3IGJ5dGVbXSB7IDAsIDQsIDAgfSwgYik7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoNCwgaS5nZXRCeXRlc1JlYWQoKSk7CisgICAgICAgICAgICBpLmNvdW50KC0xKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyg0LCBpLmdldEJ5dGVzUmVhZCgpKTsKKyAgICAgICAgICAgIGkuY291bnQoLTIpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIGkuZ2V0Qnl0ZXNSZWFkKCkpOworICAgICAgICB9CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy91dGlscy9GaXhlZExlbmd0aEJsb2NrT3V0cHV0U3RyZWFtVGVzdC5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvdXRpbHMvRml4ZWRMZW5ndGhCbG9ja091dHB1dFN0cmVhbVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jZmRhNjFiCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvdXRpbHMvRml4ZWRMZW5ndGhCbG9ja091dHB1dFN0cmVhbVRlc3QuamF2YQpAQCAtMCwwICsxLDM4MyBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlsczsKKworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEVxdWFsczsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRGYWxzZTsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUaGF0OworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydFRydWU7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuZmFpbDsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRGF0YUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRGF0YU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLkNsb3NlZENoYW5uZWxFeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuV3JpdGFibGVCeXRlQ2hhbm5lbDsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LlN0YW5kYXJkQ2hhcnNldHM7CitpbXBvcnQgamF2YS5uaW8uZmlsZS5GaWxlczsKK2ltcG9ydCBqYXZhLm5pby5maWxlLlBhdGg7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljLkF0b21pY0Jvb2xlYW47CitpbXBvcnQgb3JnLmhhbWNyZXN0LmNvcmUuSXNJbnN0YW5jZU9mOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5tb2NraXRvLmludGVybmFsLm1hdGNoZXJzLkdyZWF0ZXJPckVxdWFsOworCitwdWJsaWMgY2xhc3MgRml4ZWRMZW5ndGhCbG9ja091dHB1dFN0cmVhbVRlc3QgeworCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U21hbGxXcml0ZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RXcml0ZUFuZFBhZCgxMDI0MCwgImhlbGxvIHdvcmxkIVxuIiwgZmFsc2UpOworICAgICAgICB0ZXN0V3JpdGVBbmRQYWQoNTEyLCAiaGVsbG8gd29ybGQhXG4iLCBmYWxzZSk7CisgICAgICAgIHRlc3RXcml0ZUFuZFBhZCgxMSwgImhlbGxvIHdvcmxkIVxuIiwgZmFsc2UpOworICAgICAgICB0ZXN0V3JpdGVBbmRQYWQoMywgImhlbGxvIHdvcmxkIVxuIiwgZmFsc2UpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFNtYWxsV3JpdGVUb1N0cmVhbSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RXcml0ZUFuZFBhZFRvU3RyZWFtKDEwMjQwLCAiaGVsbG8gd29ybGQhXG4iLCBmYWxzZSk7CisgICAgICAgIHRlc3RXcml0ZUFuZFBhZFRvU3RyZWFtKDUxMiwgImhlbGxvIHdvcmxkIVxuIiwgZmFsc2UpOworICAgICAgICB0ZXN0V3JpdGVBbmRQYWRUb1N0cmVhbSgxMSwgImhlbGxvIHdvcmxkIVxuIiwgZmFsc2UpOworICAgICAgICB0ZXN0V3JpdGVBbmRQYWRUb1N0cmVhbSgzLCAiaGVsbG8gICAgIHdvcmxkIVxuIiwgZmFsc2UpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFdyaXRlU2luZ2xlQnl0ZXMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgYmxvY2tTaXplID0gNDsKKyAgICAgICAgTW9ja1dyaXRhYmxlQnl0ZUNoYW5uZWwgbW9jayA9IG5ldyBNb2NrV3JpdGFibGVCeXRlQ2hhbm5lbChibG9ja1NpemUsIGZhbHNlKTsKKyAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvcyA9IG1vY2suYm9zOworICAgICAgICBTdHJpbmcgdGV4dCA9ICJoZWxsbyB3b3JsZCBhdmVuZ2VycyI7CisgICAgICAgIGJ5dGUgbXNnW10gPSB0ZXh0LmdldEJ5dGVzKCk7CisgICAgICAgIGludCBsZW4gPSBtc2cubGVuZ3RoOworICAgICAgICB0cnkgKEZpeGVkTGVuZ3RoQmxvY2tPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IEZpeGVkTGVuZ3RoQmxvY2tPdXRwdXRTdHJlYW0obW9jaywgYmxvY2tTaXplKSkgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW47IGkrKykgeworICAgICAgICAgICAgICAgIG91dC53cml0ZShtc2dbaV0pOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGJ5dGVbXSBvdXRwdXQgPSBib3MudG9CeXRlQXJyYXkoKTsKKworICAgICAgICB2YWxpZGF0ZShibG9ja1NpemUsIG1zZywgb3V0cHV0KTsKKyAgICB9CisKKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFdyaXRlQnVmKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIGh3YSA9ICJoZWxsbyB3b3JsZCBhdmVuZ2VycyI7CisgICAgICAgIHRlc3RCdWYoNCwgaHdhKTsKKyAgICAgICAgdGVzdEJ1Zig1MTIsIGh3YSk7CisgICAgICAgIHRlc3RCdWYoMTAyNDAsIGh3YSk7CisgICAgICAgIHRlc3RCdWYoMTEsIGh3YSArIGh3YSArIGh3YSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TXVsdGlXcml0ZUJ1ZigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCBibG9ja1NpemUgPSAxMzsKKyAgICAgICAgTW9ja1dyaXRhYmxlQnl0ZUNoYW5uZWwgbW9jayA9IG5ldyBNb2NrV3JpdGFibGVCeXRlQ2hhbm5lbChibG9ja1NpemUsIGZhbHNlKTsKKyAgICAgICAgU3RyaW5nIHRlc3RTdHJpbmcgPSAiaGVsbG8gd29ybGQiOworICAgICAgICBieXRlIG1zZ1tdID0gdGVzdFN0cmluZy5nZXRCeXRlcygpOworICAgICAgICBpbnQgcmVwcyA9IDE3OworCisgICAgICAgIHRyeSAoRml4ZWRMZW5ndGhCbG9ja091dHB1dFN0cmVhbSBvdXQgPSBuZXcgRml4ZWRMZW5ndGhCbG9ja091dHB1dFN0cmVhbShtb2NrLCBibG9ja1NpemUpKSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcHM7IGkrKykgeworICAgICAgICAgICAgICAgIEJ5dGVCdWZmZXIgYnVmID0gZ2V0Qnl0ZUJ1ZmZlcihtc2cpOworICAgICAgICAgICAgICAgIG91dC53cml0ZShidWYpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBib3MgPSBtb2NrLmJvczsKKyAgICAgICAgZG91YmxlIHYgPSBNYXRoLmNlaWwoKHJlcHMgKiBtc2cubGVuZ3RoKSAvIChkb3VibGUpIGJsb2NrU2l6ZSkgKiBibG9ja1NpemU7CisgICAgICAgIGFzc2VydEVxdWFscygid3Jvbmcgc2l6ZSIsIChsb25nKSB2LCBib3Muc2l6ZSgpKTsKKyAgICAgICAgaW50IHN0ckxlbiA9IG1zZy5sZW5ndGggKiByZXBzOworICAgICAgICBieXRlW10gb3V0cHV0ID0gYm9zLnRvQnl0ZUFycmF5KCk7CisgICAgICAgIFN0cmluZyBsID0gbmV3IFN0cmluZyhvdXRwdXQsIDAsIHN0ckxlbik7CisgICAgICAgIFN0cmluZ0J1aWxkZXIgYnVmID0gbmV3IFN0cmluZ0J1aWxkZXIoc3RyTGVuKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBzOyBpKyspIHsKKyAgICAgICAgICAgIGJ1Zi5hcHBlbmQodGVzdFN0cmluZyk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKGJ1Zi50b1N0cmluZygpLCBsKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IHN0ckxlbjsgaSA8IG91dHB1dC5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIG91dHB1dFtpXSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RQYXJ0aWFsV3JpdGluZ1Rocm93c0V4Y2VwdGlvbigpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRlc3RXcml0ZUFuZFBhZCg1MTIsICJoZWxsbyB3b3JsZCFcbiIsIHRydWUpOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGZvciBwYXJ0aWFsIHdyaXRlIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgU3RyaW5nIG1zZyA9IGUuZ2V0TWVzc2FnZSgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJleGNlcHRpb24gbWVzc2FnZSIsCisgICAgICAgICAgICAgICAgIkZhaWxlZCB0byB3cml0ZSA1MTIgYnl0ZXMgYXRvbWljYWxseS4gT25seSB3cm90ZSAgNTExIiwgbXNnKTsKKyAgICAgICAgfQorCisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0V3JpdGVGYWlsc0FmdGVyRkxDbG9zZWRUaHJvd3NFeGNlcHRpb24oKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBGaXhlZExlbmd0aEJsb2NrT3V0cHV0U3RyZWFtIG91dCA9IGdldENsb3NlZEZMQk9TKCk7CisgICAgICAgICAgICBvdXQud3JpdGUoMSk7CisgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBDbG9zZWQgQ2hhbm5lbCBFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYXNzZXJ0VGhhdChlLCBJc0luc3RhbmNlT2YuaW5zdGFuY2VPZihDbG9zZWRDaGFubmVsRXhjZXB0aW9uLmNsYXNzKSk7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBGaXhlZExlbmd0aEJsb2NrT3V0cHV0U3RyZWFtIG91dCA9IGdldENsb3NlZEZMQk9TKCk7CisgICAgICAgICAgICBvdXQud3JpdGUobmV3IGJ5dGVbXSB7MCwxLDIsM30pOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgQ2xvc2VkIENoYW5uZWwgRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGFzc2VydFRoYXQoZSwgSXNJbnN0YW5jZU9mLmluc3RhbmNlT2YoQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbi5jbGFzcykpOworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBGaXhlZExlbmd0aEJsb2NrT3V0cHV0U3RyZWFtIG91dCA9IGdldENsb3NlZEZMQk9TKCk7CisgICAgICAgICAgICBvdXQud3JpdGUoQnl0ZUJ1ZmZlci53cmFwKG5ldyBieXRlW10gezAsMSwyLDN9KSk7CisgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBDbG9zZWQgQ2hhbm5lbCBFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYXNzZXJ0VGhhdChlLCBJc0luc3RhbmNlT2YuaW5zdGFuY2VPZihDbG9zZWRDaGFubmVsRXhjZXB0aW9uLmNsYXNzKSk7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICB9CisKKyAgICBwcml2YXRlIEZpeGVkTGVuZ3RoQmxvY2tPdXRwdXRTdHJlYW0gZ2V0Q2xvc2VkRkxCT1MoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgYmxvY2tTaXplID0gNTEyOworICAgICAgICBGaXhlZExlbmd0aEJsb2NrT3V0cHV0U3RyZWFtIG91dCA9IG5ldyBGaXhlZExlbmd0aEJsb2NrT3V0cHV0U3RyZWFtKAorICAgICAgICAgICAgbmV3IE1vY2tPdXRwdXRTdHJlYW0oYmxvY2tTaXplLCBmYWxzZSksIGJsb2NrU2l6ZSk7CisgICAgICAgIG91dC53cml0ZSgxKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShvdXQuaXNPcGVuKCkpOworICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICAgICAgYXNzZXJ0RmFsc2Uob3V0LmlzT3BlbigpKTsKKyAgICAgICAgcmV0dXJuIG91dDsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RXcml0ZUZhaWxzQWZ0ZXJEZXN0Q2xvc2VkVGhyb3dzRXhjZXB0aW9uKCkgeworICAgICAgICBpbnQgYmxvY2tTaXplID0gMjsKKyAgICAgICAgTW9ja091dHB1dFN0cmVhbSBtb2NrID0gbmV3IE1vY2tPdXRwdXRTdHJlYW0oYmxvY2tTaXplLCBmYWxzZSk7CisgICAgICAgIEZpeGVkTGVuZ3RoQmxvY2tPdXRwdXRTdHJlYW0gb3V0ID0KKyAgICAgICAgICAgIG5ldyBGaXhlZExlbmd0aEJsb2NrT3V0cHV0U3RyZWFtKG1vY2ssIGJsb2NrU2l6ZSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvdXQud3JpdGUoMSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKG91dC5pc09wZW4oKSk7CisgICAgICAgICAgICBtb2NrLmNsb3NlKCk7CisgICAgICAgICAgICBvdXQud3JpdGUoMSk7CisgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBJTyBFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRGYWxzZShvdXQuaXNPcGVuKCkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFdpdGhGaWxlT3V0cHV0U3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgUGF0aCB0ZW1wRmlsZSA9IEZpbGVzLmNyZWF0ZVRlbXBGaWxlKCJ4eHgiLCAieXl5Iik7CisgICAgICAgIFJ1bnRpbWUuZ2V0UnVudGltZSgpLmFkZFNodXRkb3duSG9vayhuZXcgVGhyZWFkKCkgeworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgRmlsZXMuZGVsZXRlSWZFeGlzdHModGVtcEZpbGUpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0pOworICAgICAgICBpbnQgYmxvY2tTaXplID0gNTEyOworICAgICAgICBpbnQgcmVwcyA9IDEwMDA7CisgICAgICAgIE91dHB1dFN0cmVhbSBvcyA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKHRlbXBGaWxlLnRvRmlsZSgpKTsKKyAgICAgICAgdHJ5IChGaXhlZExlbmd0aEJsb2NrT3V0cHV0U3RyZWFtIG91dCA9IG5ldyBGaXhlZExlbmd0aEJsb2NrT3V0cHV0U3RyZWFtKAorICAgICAgICAgICAgb3MsIGJsb2NrU2l6ZSkpIHsKKyAgICAgICAgICAgIERhdGFPdXRwdXRTdHJlYW0gZG9zID0gbmV3IERhdGFPdXRwdXRTdHJlYW0ob3V0KTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwczsgaSsrKSB7CisgICAgICAgICAgICAgICBkb3Mud3JpdGVJbnQoaSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgbG9uZyBleHBlY3RlZERhdGFTaXplID0gcmVwcyAqIDRMOworICAgICAgICBsb25nIGV4cGVjdGVkRmlsZVNpemUgPSAobG9uZylNYXRoLmNlaWwoZXhwZWN0ZWREYXRhU2l6ZS8oZG91YmxlKWJsb2NrU2l6ZSkqYmxvY2tTaXplOworICAgICAgICBhc3NlcnRFcXVhbHMoImZpbGUgc2l6ZSIsZXhwZWN0ZWRGaWxlU2l6ZSwgRmlsZXMuc2l6ZSh0ZW1wRmlsZSkpOworICAgICAgICBEYXRhSW5wdXRTdHJlYW0gZGluID0gbmV3IERhdGFJbnB1dFN0cmVhbShGaWxlcy5uZXdJbnB1dFN0cmVhbSh0ZW1wRmlsZSkpOworICAgICAgICBmb3IoaW50IGk9MDtpPHJlcHM7aSsrKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImZpbGUgaW50IixpLGRpbi5yZWFkSW50KCkpOworICAgICAgICB9CisgICAgICAgIGZvcihpbnQgaT0wO2k8ZXhwZWN0ZWRGaWxlU2l6ZSAtIGV4cGVjdGVkRGF0YVNpemU7aSsrKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMCxkaW4ucmVhZCgpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoLTEsZGluLnJlYWQoKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RCdWYoaW50IGJsb2NrU2l6ZSwgU3RyaW5nIHRleHQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIE1vY2tXcml0YWJsZUJ5dGVDaGFubmVsIG1vY2sgPSBuZXcgTW9ja1dyaXRhYmxlQnl0ZUNoYW5uZWwoYmxvY2tTaXplLCBmYWxzZSk7CisKKyAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvcyA9IG1vY2suYm9zOworICAgICAgICBieXRlIG1zZ1tdID0gdGV4dC5nZXRCeXRlcygpOworICAgICAgICBCeXRlQnVmZmVyIGJ1ZiA9IGdldEJ5dGVCdWZmZXIobXNnKTsKKyAgICAgICAgdHJ5IChGaXhlZExlbmd0aEJsb2NrT3V0cHV0U3RyZWFtIG91dCA9IG5ldyBGaXhlZExlbmd0aEJsb2NrT3V0cHV0U3RyZWFtKG1vY2ssIGJsb2NrU2l6ZSkpIHsKKyAgICAgICAgICAgIG91dC53cml0ZShidWYpOworICAgICAgICB9CisgICAgICAgIGRvdWJsZSB2ID0gTWF0aC5jZWlsKG1zZy5sZW5ndGggLyAoZG91YmxlKSBibG9ja1NpemUpICogYmxvY2tTaXplOworICAgICAgICBhc3NlcnRFcXVhbHMoIndyb25nIHNpemUiLCAobG9uZykgdiwgYm9zLnNpemUoKSk7CisgICAgICAgIGJ5dGVbXSBvdXRwdXQgPSBib3MudG9CeXRlQXJyYXkoKTsKKyAgICAgICAgU3RyaW5nIGwgPSBuZXcgU3RyaW5nKG91dHB1dCwgMCwgbXNnLmxlbmd0aCk7CisgICAgICAgIGFzc2VydEVxdWFscyh0ZXh0LCBsKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IG1zZy5sZW5ndGg7IGkgPCBib3Muc2l6ZSgpOyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhTdHJpbmcuZm9ybWF0KCJvdXRwdXRbJWRdIiwgaSksIDAsIG91dHB1dFtpXSk7CisKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgQnl0ZUJ1ZmZlciBnZXRCeXRlQnVmZmVyKGJ5dGVbXSBtc2cpIHsKKyAgICAgICAgaW50IGxlbiA9IG1zZy5sZW5ndGg7CisgICAgICAgIEJ5dGVCdWZmZXIgYnVmID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZShsZW4pOworICAgICAgICBidWYucHV0KG1zZyk7CisgICAgICAgIGJ1Zi5mbGlwKCk7CisgICAgICAgIHJldHVybiBidWY7CisgICAgfQorCisKKyAgICBwcml2YXRlIHZvaWQgdGVzdFdyaXRlQW5kUGFkKGludCBibG9ja1NpemUsIFN0cmluZyB0ZXh0LCBib29sZWFuIGRvUGFydGlhbFdyaXRlKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBNb2NrV3JpdGFibGVCeXRlQ2hhbm5lbCBtb2NrID0gbmV3IE1vY2tXcml0YWJsZUJ5dGVDaGFubmVsKGJsb2NrU2l6ZSwgZG9QYXJ0aWFsV3JpdGUpOworICAgICAgICBieXRlW10gbXNnID0gdGV4dC5nZXRCeXRlcyhTdGFuZGFyZENoYXJzZXRzLlVTX0FTQ0lJKTsKKworICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm9zID0gbW9jay5ib3M7CisgICAgICAgIHRyeSAoRml4ZWRMZW5ndGhCbG9ja091dHB1dFN0cmVhbSBvdXQgPSBuZXcgRml4ZWRMZW5ndGhCbG9ja091dHB1dFN0cmVhbShtb2NrLCBibG9ja1NpemUpKSB7CisKKyAgICAgICAgICAgIG91dC53cml0ZShtc2cpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJubyBwYXJ0aWFsIHdyaXRlIiwgKG1zZy5sZW5ndGggLyBibG9ja1NpemUpICogYmxvY2tTaXplLCBib3Muc2l6ZSgpKTsKKyAgICAgICAgfQorICAgICAgICB2YWxpZGF0ZShibG9ja1NpemUsIG1zZywgYm9zLnRvQnl0ZUFycmF5KCkpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0V3JpdGVBbmRQYWRUb1N0cmVhbShpbnQgYmxvY2tTaXplLCBTdHJpbmcgdGV4dCwgYm9vbGVhbiBkb1BhcnRpYWxXcml0ZSkKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgTW9ja091dHB1dFN0cmVhbSBtb2NrID0gbmV3IE1vY2tPdXRwdXRTdHJlYW0oYmxvY2tTaXplLCBkb1BhcnRpYWxXcml0ZSk7CisgICAgICAgIGJ5dGVbXSBtc2cgPSB0ZXh0LmdldEJ5dGVzKFN0YW5kYXJkQ2hhcnNldHMuVVNfQVNDSUkpOworCisgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBib3MgPSBtb2NrLmJvczsKKyAgICAgICAgdHJ5IChGaXhlZExlbmd0aEJsb2NrT3V0cHV0U3RyZWFtIG91dCA9IG5ldyBGaXhlZExlbmd0aEJsb2NrT3V0cHV0U3RyZWFtKG1vY2ssIGJsb2NrU2l6ZSkpIHsKKyAgICAgICAgICAgIG91dC53cml0ZShtc2cpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJubyBwYXJ0aWFsIHdyaXRlIiwgKG1zZy5sZW5ndGggLyBibG9ja1NpemUpICogYmxvY2tTaXplLCBib3Muc2l6ZSgpKTsKKyAgICAgICAgfQorICAgICAgICB2YWxpZGF0ZShibG9ja1NpemUsIG1zZywgYm9zLnRvQnl0ZUFycmF5KCkpOworCisgICAgfQorCisKKyAgICBwcml2YXRlIHZvaWQgdmFsaWRhdGUoaW50IGJsb2NrU2l6ZSwgYnl0ZVtdIGV4cGVjdGVkQnl0ZXMsIGJ5dGVbXSBhY3R1YWxCeXRlcykgeworICAgICAgICBkb3VibGUgdiA9IE1hdGguY2VpbChleHBlY3RlZEJ5dGVzLmxlbmd0aCAvIChkb3VibGUpIGJsb2NrU2l6ZSkgKiBibG9ja1NpemU7CisgICAgICAgIGFzc2VydEVxdWFscygid3Jvbmcgc2l6ZSIsIChsb25nKSB2LCBhY3R1YWxCeXRlcy5sZW5ndGgpOworICAgICAgICBhc3NlcnRDb250YWluc0F0T2Zmc2V0KCJvdXRwdXQiLCBleHBlY3RlZEJ5dGVzLCAwLCBhY3R1YWxCeXRlcyk7CisgICAgICAgIGZvciAoaW50IGkgPSBleHBlY3RlZEJ5dGVzLmxlbmd0aDsgaSA8IGFjdHVhbEJ5dGVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoU3RyaW5nLmZvcm1hdCgib3V0cHV0WyVkXSIsIGkpLCAwLCBhY3R1YWxCeXRlc1tpXSk7CisKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgYXNzZXJ0Q29udGFpbnNBdE9mZnNldChTdHJpbmcgbXNnLCBieXRlW10gZXhwZWN0ZWQsIGludCBvZmZzZXQsCisgICAgICAgIGJ5dGVbXSBhY3R1YWwpIHsKKyAgICAgICAgYXNzZXJ0VGhhdChhY3R1YWwubGVuZ3RoLCBuZXcgR3JlYXRlck9yRXF1YWw8PihvZmZzZXQgKyBleHBlY3RlZC5sZW5ndGgpKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBleHBlY3RlZC5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKFN0cmluZy5mb3JtYXQoIiVzIChbJWRdKSIsIG1zZywgaSksIGV4cGVjdGVkW2ldLCBhY3R1YWxbaSArIG9mZnNldF0pOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgTW9ja091dHB1dFN0cmVhbSBleHRlbmRzIE91dHB1dFN0cmVhbSB7CisKKyAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBpbnQgcmVxdWlyZWRXcml0ZVNpemU7CisgICAgICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiBkb1BhcnRpYWxXcml0ZTsKKyAgICAgICAgcHJpdmF0ZSBBdG9taWNCb29sZWFuIGNsb3NlZCA9IG5ldyBBdG9taWNCb29sZWFuKCk7CisKKyAgICAgICAgcHJpdmF0ZSBNb2NrT3V0cHV0U3RyZWFtKGludCByZXF1aXJlZFdyaXRlU2l6ZSwgYm9vbGVhbiBkb1BhcnRpYWxXcml0ZSkgeworICAgICAgICAgICAgdGhpcy5yZXF1aXJlZFdyaXRlU2l6ZSA9IHJlcXVpcmVkV3JpdGVTaXplOworICAgICAgICAgICAgdGhpcy5kb1BhcnRpYWxXcml0ZSA9IGRvUGFydGlhbFdyaXRlOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIHdyaXRlKGJ5dGVbXSBiLCBpbnQgb2ZmLCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgY2hlY2tJc09wZW4oKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygid3JpdGUgc2l6ZSIsIHJlcXVpcmVkV3JpdGVTaXplLCBsZW4pOworICAgICAgICAgICAgaWYgKGRvUGFydGlhbFdyaXRlKSB7CisgICAgICAgICAgICAgICAgbGVuLS07CisgICAgICAgICAgICB9CisgICAgICAgICAgICBib3Mud3JpdGUoYiwgb2ZmLCBsZW4pOworICAgICAgICB9CisKKyAgICAgICAgcHJpdmF0ZSB2b2lkIGNoZWNrSXNPcGVuKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGlmIChjbG9zZWQuZ2V0KCkpIHsKKyAgICAgICAgICAgICAgICBJT0V4Y2VwdGlvbiBlID0gbmV3IElPRXhjZXB0aW9uKCJDbG9zZWQiKTsKKyAgICAgICAgICAgICAgICB0aHJvdyBlOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIHdyaXRlKGludCBiKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgY2hlY2tJc09wZW4oKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygid3JpdGUgc2l6ZSIsIHJlcXVpcmVkV3JpdGVTaXplLCAxKTsKKyAgICAgICAgICAgIGJvcy53cml0ZShiKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBpZiAoY2xvc2VkLmNvbXBhcmVBbmRTZXQoZmFsc2UsIHRydWUpKSB7CisgICAgICAgICAgICAgICAgYm9zLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBNb2NrV3JpdGFibGVCeXRlQ2hhbm5lbCBpbXBsZW1lbnRzIFdyaXRhYmxlQnl0ZUNoYW5uZWwgeworCisgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBib3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIHByaXZhdGUgZmluYWwgaW50IHJlcXVpcmVkV3JpdGVTaXplOworICAgICAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gZG9QYXJ0aWFsV3JpdGU7CisKKyAgICAgICAgcHJpdmF0ZSBNb2NrV3JpdGFibGVCeXRlQ2hhbm5lbChpbnQgcmVxdWlyZWRXcml0ZVNpemUsIGJvb2xlYW4gZG9QYXJ0aWFsV3JpdGUpIHsKKyAgICAgICAgICAgIHRoaXMucmVxdWlyZWRXcml0ZVNpemUgPSByZXF1aXJlZFdyaXRlU2l6ZTsKKyAgICAgICAgICAgIHRoaXMuZG9QYXJ0aWFsV3JpdGUgPSBkb1BhcnRpYWxXcml0ZTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgaW50IHdyaXRlKEJ5dGVCdWZmZXIgc3JjKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJ3cml0ZSBzaXplIiwgcmVxdWlyZWRXcml0ZVNpemUsIHNyYy5yZW1haW5pbmcoKSk7CisgICAgICAgICAgICBpZiAoZG9QYXJ0aWFsV3JpdGUpIHsKKyAgICAgICAgICAgICAgICBzcmMubGltaXQoc3JjLmxpbWl0KCkgLSAxKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGludCBieXRlc091dCA9IHNyYy5yZW1haW5pbmcoKTsKKyAgICAgICAgICAgIHdoaWxlIChzcmMuaGFzUmVtYWluaW5nKCkpIHsKKyAgICAgICAgICAgICAgICBib3Mud3JpdGUoc3JjLmdldCgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBieXRlc091dDsKKyAgICAgICAgfQorCisgICAgICAgIEF0b21pY0Jvb2xlYW4gY2xvc2VkID0gbmV3IEF0b21pY0Jvb2xlYW4oKTsKKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaXNPcGVuKCkgeworICAgICAgICAgICAgcmV0dXJuICFjbG9zZWQuZ2V0KCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgY2xvc2VkLmNvbXBhcmVBbmRTZXQoZmFsc2UsIHRydWUpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvdXRpbHMvSU9VdGlsc1Rlc3QuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL3V0aWxzL0lPVXRpbHNUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmNlNzc5ZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL3V0aWxzL0lPVXRpbHNUZXN0LmphdmEKQEAgLTAsMCArMSwxMzggQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHM7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRU9GRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uRmlsdGVySW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLkJ5dGVCdWZmZXI7CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuUmVhZGFibGVCeXRlQ2hhbm5lbDsKKworaW1wb3J0IG9yZy5qdW5pdC5Bc3NlcnQ7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CisKK3B1YmxpYyBjbGFzcyBJT1V0aWxzVGVzdCB7CisKKyAgICBwcml2YXRlIGludGVyZmFjZSBTdHJlYW1XcmFwcGVyIHsKKyAgICAgICAgSW5wdXRTdHJlYW0gd3JhcChJbnB1dFN0cmVhbSB0b1dyYXApOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgc2tpcFVzaW5nU2tpcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBza2lwKG5ldyBTdHJlYW1XcmFwcGVyKCkgeworICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgIHB1YmxpYyBJbnB1dFN0cmVhbSB3cmFwKGZpbmFsIElucHV0U3RyZWFtIHRvV3JhcCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gdG9XcmFwOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0pOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgc2tpcFVzaW5nUmVhZCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBza2lwKG5ldyBTdHJlYW1XcmFwcGVyKCkgeworICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgIHB1YmxpYyBJbnB1dFN0cmVhbSB3cmFwKGZpbmFsIElucHV0U3RyZWFtIHRvV3JhcCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEZpbHRlcklucHV0U3RyZWFtKHRvV3JhcCkgeworICAgICAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWMgbG9uZyBza2lwKGZpbmFsIGxvbmcgcykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0pOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgc2tpcFVzaW5nU2tpcEFuZFJlYWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc2tpcChuZXcgU3RyZWFtV3JhcHBlcigpIHsKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICBwdWJsaWMgSW5wdXRTdHJlYW0gd3JhcChmaW5hbCBJbnB1dFN0cmVhbSB0b1dyYXApIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBGaWx0ZXJJbnB1dFN0cmVhbSh0b1dyYXApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gc2tpcHBlZDsKKyAgICAgICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljIGxvbmcgc2tpcChmaW5hbCBsb25nIHMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFza2lwcGVkKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvV3JhcC5za2lwKDUpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBza2lwcGVkID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDU7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0pOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgcmVhZEZ1bGx5T25DaGFubmVsUmVhZHNGdWxseSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEJ5dGVCdWZmZXIgYiA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUoMjApOworICAgICAgICBmaW5hbCBieXRlW10gc291cmNlID0gbmV3IGJ5dGVbMjBdOworICAgICAgICBmb3IgKGJ5dGUgaSA9IDA7IGkgPCAyMDsgaSsrKSB7CisgICAgICAgICAgICBzb3VyY2VbaV0gPSBpOworICAgICAgICB9CisgICAgICAgIHJlYWRGdWxseShzb3VyY2UsIGIpOworICAgICAgICBBc3NlcnQuYXNzZXJ0QXJyYXlFcXVhbHMoc291cmNlLCBiLmFycmF5KCkpOworICAgIH0KKworICAgIEBUZXN0KGV4cGVjdGVkID0gRU9GRXhjZXB0aW9uLmNsYXNzKQorICAgIHB1YmxpYyB2b2lkIHJlYWRGdWxseU9uQ2hhbm5lbFRocm93c0VvZigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEJ5dGVCdWZmZXIgYiA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUoMjEpOworICAgICAgICBmaW5hbCBieXRlW10gc291cmNlID0gbmV3IGJ5dGVbMjBdOworICAgICAgICBmb3IgKGJ5dGUgaSA9IDA7IGkgPCAyMDsgaSsrKSB7CisgICAgICAgICAgICBzb3VyY2VbaV0gPSBpOworICAgICAgICB9CisgICAgICAgIHJlYWRGdWxseShzb3VyY2UsIGIpOworICAgIH0KKworICAgIEBUZXN0KGV4cGVjdGVkID0gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLmNsYXNzKQorICAgIHB1YmxpYyB2b2lkIGNvcHlUaHJvd3NPblplcm9CdWZmZXJTaXplKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgSU9VdGlscy5jb3B5KG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShuZXcgYnl0ZVswXSksIG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKSwgMCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCByZWFkRnVsbHkoZmluYWwgYnl0ZVtdIHNvdXJjZSwgQnl0ZUJ1ZmZlciBiKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBJT1V0aWxzLnJlYWRGdWxseShuZXcgUmVhZGFibGVCeXRlQ2hhbm5lbCgpIHsKKyAgICAgICAgICAgICAgICBwcml2YXRlIGludCBpZHg7CisgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgcHVibGljIGludCByZWFkKEJ5dGVCdWZmZXIgYnVmKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChpZHggPj0gc291cmNlLmxlbmd0aCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGJ1Zi5wdXQoc291cmNlW2lkeCsrXSk7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiAxOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHsgfQorICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGlzT3BlbigpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSwgYik7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHNraXAoZmluYWwgU3RyZWFtV3JhcHBlciB3cmFwcGVyKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgQnl0ZUFycmF5SW5wdXRTdHJlYW0gaW4gPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0obmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAgICAgMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExCisgICAgICAgICAgICB9KTsKKyAgICAgICAgZmluYWwgSW5wdXRTdHJlYW0gc3V0ID0gd3JhcHBlci53cmFwKGluKTsKKyAgICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygxMCwgSU9VdGlscy5za2lwKHN1dCwgMTApKTsKKyAgICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygxMSwgc3V0LnJlYWQoKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvdXRpbHMvU2Vla2FibGVJbk1lbW9yeUJ5dGVDaGFubmVsVGVzdC5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvdXRpbHMvU2Vla2FibGVJbk1lbW9yeUJ5dGVDaGFubmVsVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMyYWYzMDgKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy91dGlscy9TZWVrYWJsZUluTWVtb3J5Qnl0ZUNoYW5uZWxUZXN0LmphdmEKQEAgLTAsMCArMSwyMDIgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHM7CisKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5DbG9zZWRDaGFubmVsRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCitpbXBvcnQgc3RhdGljIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlscy5DaGFyc2V0TmFtZXMuVVRGXzg7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0QXJyYXlFcXVhbHM7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0RXF1YWxzOworCitwdWJsaWMgY2xhc3MgU2Vla2FibGVJbk1lbW9yeUJ5dGVDaGFubmVsVGVzdCB7CisKKyAgICBwcml2YXRlIGZpbmFsIGJ5dGVbXSB0ZXN0RGF0YSA9ICJTb21lIGRhdGEiLmdldEJ5dGVzKENoYXJzZXQuZm9yTmFtZShVVEZfOCkpOworCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBzaG91bGRSZWFkQ29udGVudHNQcm9wZXJseSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vZ2l2ZW4KKyAgICAgICAgU2Vla2FibGVJbk1lbW9yeUJ5dGVDaGFubmVsIGMgPSBuZXcgU2Vla2FibGVJbk1lbW9yeUJ5dGVDaGFubmVsKHRlc3REYXRhKTsKKyAgICAgICAgQnl0ZUJ1ZmZlciByZWFkQnVmZmVyID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZSh0ZXN0RGF0YS5sZW5ndGgpOworICAgICAgICAvL3doZW4KKyAgICAgICAgaW50IHJlYWRDb3VudCA9IGMucmVhZChyZWFkQnVmZmVyKTsKKyAgICAgICAgLy90aGVuCisgICAgICAgIGFzc2VydEVxdWFscyh0ZXN0RGF0YS5sZW5ndGgsIHJlYWRDb3VudCk7CisgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKHRlc3REYXRhLCByZWFkQnVmZmVyLmFycmF5KCkpOworICAgICAgICBhc3NlcnRFcXVhbHModGVzdERhdGEubGVuZ3RoLCBjLnBvc2l0aW9uKCkpOworICAgICAgICBjLmNsb3NlKCk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBzaG91bGRSZWFkQ29udGVudHNXaGVuQmlnZ2VyQnVmZmVyU3VwcGxpZWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvL2dpdmVuCisgICAgICAgIFNlZWthYmxlSW5NZW1vcnlCeXRlQ2hhbm5lbCBjID0gbmV3IFNlZWthYmxlSW5NZW1vcnlCeXRlQ2hhbm5lbCh0ZXN0RGF0YSk7CisgICAgICAgIEJ5dGVCdWZmZXIgcmVhZEJ1ZmZlciA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUodGVzdERhdGEubGVuZ3RoICsgMSk7CisgICAgICAgIC8vd2hlbgorICAgICAgICBpbnQgcmVhZENvdW50ID0gYy5yZWFkKHJlYWRCdWZmZXIpOworICAgICAgICAvL3RoZW4KKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRlc3REYXRhLmxlbmd0aCwgcmVhZENvdW50KTsKKyAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHModGVzdERhdGEsIEFycmF5cy5jb3B5T2YocmVhZEJ1ZmZlci5hcnJheSgpLCB0ZXN0RGF0YS5sZW5ndGgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRlc3REYXRhLmxlbmd0aCwgYy5wb3NpdGlvbigpKTsKKyAgICAgICAgYy5jbG9zZSgpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgc2hvdWxkUmVhZERhdGFGcm9tU2V0UG9zaXRpb24oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvL2dpdmVuCisgICAgICAgIFNlZWthYmxlSW5NZW1vcnlCeXRlQ2hhbm5lbCBjID0gbmV3IFNlZWthYmxlSW5NZW1vcnlCeXRlQ2hhbm5lbCh0ZXN0RGF0YSk7CisgICAgICAgIEJ5dGVCdWZmZXIgcmVhZEJ1ZmZlciA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUoNCk7CisgICAgICAgIC8vd2hlbgorICAgICAgICBjLnBvc2l0aW9uKDVMKTsKKyAgICAgICAgaW50IHJlYWRDb3VudCA9IGMucmVhZChyZWFkQnVmZmVyKTsKKyAgICAgICAgLy90aGVuCisgICAgICAgIGFzc2VydEVxdWFscyg0TCwgcmVhZENvdW50KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJkYXRhIiwgbmV3IFN0cmluZyhyZWFkQnVmZmVyLmFycmF5KCksIENoYXJzZXQuZm9yTmFtZShVVEZfOCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRlc3REYXRhLmxlbmd0aCwgYy5wb3NpdGlvbigpKTsKKyAgICAgICAgYy5jbG9zZSgpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgc2hvdWxkU2lnbmFsRU9GV2hlblBvc2l0aW9uQXRUaGVFbmQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvL2dpdmVuCisgICAgICAgIFNlZWthYmxlSW5NZW1vcnlCeXRlQ2hhbm5lbCBjID0gbmV3IFNlZWthYmxlSW5NZW1vcnlCeXRlQ2hhbm5lbCh0ZXN0RGF0YSk7CisgICAgICAgIEJ5dGVCdWZmZXIgcmVhZEJ1ZmZlciA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUodGVzdERhdGEubGVuZ3RoKTsKKyAgICAgICAgLy93aGVuCisgICAgICAgIGMucG9zaXRpb24odGVzdERhdGEubGVuZ3RoICsgMSk7CisgICAgICAgIGludCByZWFkQ291bnQgPSBjLnJlYWQocmVhZEJ1ZmZlcik7CisgICAgICAgIC8vdGhlbgorICAgICAgICBhc3NlcnRFcXVhbHMoMEwsIHJlYWRCdWZmZXIucG9zaXRpb24oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygtMSwgcmVhZENvdW50KTsKKyAgICAgICAgYy5jbG9zZSgpOworICAgIH0KKworICAgIEBUZXN0KGV4cGVjdGVkID0gQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbi5jbGFzcykKKyAgICBwdWJsaWMgdm9pZCBzaG91bGRUaHJvd0V4Y2VwdGlvbk9uUmVhZGluZ0Nsb3NlZENoYW5uZWwoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvL2dpdmVuCisgICAgICAgIFNlZWthYmxlSW5NZW1vcnlCeXRlQ2hhbm5lbCBjID0gbmV3IFNlZWthYmxlSW5NZW1vcnlCeXRlQ2hhbm5lbCgpOworICAgICAgICAvL3doZW4KKyAgICAgICAgYy5jbG9zZSgpOworICAgICAgICBjLnJlYWQoQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBzaG91bGRXcml0ZURhdGFQcm9wZXJseSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vZ2l2ZW4KKyAgICAgICAgU2Vla2FibGVJbk1lbW9yeUJ5dGVDaGFubmVsIGMgPSBuZXcgU2Vla2FibGVJbk1lbW9yeUJ5dGVDaGFubmVsKCk7CisgICAgICAgIEJ5dGVCdWZmZXIgaW5EYXRhID0gQnl0ZUJ1ZmZlci53cmFwKHRlc3REYXRhKTsKKyAgICAgICAgLy93aGVuCisgICAgICAgIGludCB3cml0ZUNvdW50ID0gYy53cml0ZShpbkRhdGEpOworICAgICAgICAvL3RoZW4KKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRlc3REYXRhLmxlbmd0aCwgd3JpdGVDb3VudCk7CisgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKHRlc3REYXRhLCBBcnJheXMuY29weU9mKGMuYXJyYXkoKSwgKGludCkgYy5zaXplKCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRlc3REYXRhLmxlbmd0aCwgYy5wb3NpdGlvbigpKTsKKyAgICAgICAgYy5jbG9zZSgpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgc2hvdWxkV3JpdGVEYXRhUHJvcGVybHlBZnRlclBvc2l0aW9uU2V0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy9naXZlbgorICAgICAgICBTZWVrYWJsZUluTWVtb3J5Qnl0ZUNoYW5uZWwgYyA9IG5ldyBTZWVrYWJsZUluTWVtb3J5Qnl0ZUNoYW5uZWwodGVzdERhdGEpOworICAgICAgICBCeXRlQnVmZmVyIGluRGF0YSA9IEJ5dGVCdWZmZXIud3JhcCh0ZXN0RGF0YSk7CisgICAgICAgIEJ5dGVCdWZmZXIgZXhwZWN0ZWREYXRhID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZSh0ZXN0RGF0YS5sZW5ndGggKyA1KS5wdXQodGVzdERhdGEsIDAsIDUpLnB1dCh0ZXN0RGF0YSk7CisgICAgICAgIC8vd2hlbgorICAgICAgICBjLnBvc2l0aW9uKDVMKTsKKyAgICAgICAgaW50IHdyaXRlQ291bnQgPSBjLndyaXRlKGluRGF0YSk7CisKKyAgICAgICAgLy90aGVuCisgICAgICAgIGFzc2VydEVxdWFscyh0ZXN0RGF0YS5sZW5ndGgsIHdyaXRlQ291bnQpOworICAgICAgICBhc3NlcnRBcnJheUVxdWFscyhleHBlY3RlZERhdGEuYXJyYXkoKSwgQXJyYXlzLmNvcHlPZihjLmFycmF5KCksIChpbnQpIGMuc2l6ZSgpKSk7CisgICAgICAgIGFzc2VydEVxdWFscyh0ZXN0RGF0YS5sZW5ndGggKyA1LCBjLnBvc2l0aW9uKCkpOworICAgICAgICBjLmNsb3NlKCk7CisgICAgfQorCisKKyAgICBAVGVzdChleHBlY3RlZCA9IENsb3NlZENoYW5uZWxFeGNlcHRpb24uY2xhc3MpCisgICAgcHVibGljIHZvaWQgc2hvdWxkVGhyb3dFeGNlcHRpb25PbldyaXRpbmdUb0Nsb3NlZENoYW5uZWwoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvL2dpdmVuCisgICAgICAgIFNlZWthYmxlSW5NZW1vcnlCeXRlQ2hhbm5lbCBjID0gbmV3IFNlZWthYmxlSW5NZW1vcnlCeXRlQ2hhbm5lbCgpOworICAgICAgICAvL3doZW4KKyAgICAgICAgYy5jbG9zZSgpOworICAgICAgICBjLndyaXRlKEJ5dGVCdWZmZXIuYWxsb2NhdGUoMSkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgc2hvdWxkVHJ1bmNhdGVDb250ZW50c1Byb3Blcmx5KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy9naXZlbgorICAgICAgICBTZWVrYWJsZUluTWVtb3J5Qnl0ZUNoYW5uZWwgYyA9IG5ldyBTZWVrYWJsZUluTWVtb3J5Qnl0ZUNoYW5uZWwodGVzdERhdGEpOworICAgICAgICAvL3doZW4KKyAgICAgICAgYy50cnVuY2F0ZSg0KTsKKyAgICAgICAgLy90aGVuCisgICAgICAgIGJ5dGVbXSBieXRlcyA9IEFycmF5cy5jb3B5T2YoYy5hcnJheSgpLCAoaW50KSBjLnNpemUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiU29tZSIsIG5ldyBTdHJpbmcoYnl0ZXMsIENoYXJzZXQuZm9yTmFtZShVVEZfOCkpKTsKKyAgICAgICAgYy5jbG9zZSgpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgc2hvdWxkU2V0UHJvcGVyUG9zaXRpb25PblRydW5jYXRlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy9naXZlbgorICAgICAgICBTZWVrYWJsZUluTWVtb3J5Qnl0ZUNoYW5uZWwgYyA9IG5ldyBTZWVrYWJsZUluTWVtb3J5Qnl0ZUNoYW5uZWwodGVzdERhdGEpOworICAgICAgICAvL3doZW4KKyAgICAgICAgYy5wb3NpdGlvbih0ZXN0RGF0YS5sZW5ndGgpOworICAgICAgICBjLnRydW5jYXRlKDRMKTsKKyAgICAgICAgLy90aGVuCisgICAgICAgIGFzc2VydEVxdWFscyg0TCwgYy5wb3NpdGlvbigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDRMLCBjLnNpemUoKSk7CisgICAgICAgIGMuY2xvc2UoKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHNob3VsZFNldFByb3BlclBvc2l0aW9uKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy9naXZlbgorICAgICAgICBTZWVrYWJsZUluTWVtb3J5Qnl0ZUNoYW5uZWwgYyA9IG5ldyBTZWVrYWJsZUluTWVtb3J5Qnl0ZUNoYW5uZWwodGVzdERhdGEpOworICAgICAgICAvL3doZW4KKyAgICAgICAgbG9uZyBwb3NBdEZvdXIgPSBjLnBvc2l0aW9uKDRMKS5wb3NpdGlvbigpOworICAgICAgICBsb25nIHBvc0F0VGhlRW5kID0gYy5wb3NpdGlvbih0ZXN0RGF0YS5sZW5ndGgpLnBvc2l0aW9uKCk7CisgICAgICAgIGxvbmcgcG9zUGFzdFRoZUVuZCA9IGMucG9zaXRpb24odGVzdERhdGEubGVuZ3RoICsgMUwpLnBvc2l0aW9uKCk7CisgICAgICAgIC8vdGhlbgorICAgICAgICBhc3NlcnRFcXVhbHMoNEwsIHBvc0F0Rm91cik7CisgICAgICAgIGFzc2VydEVxdWFscyhjLnNpemUoKSwgcG9zQXRUaGVFbmQpOworICAgICAgICBhc3NlcnRFcXVhbHMocG9zUGFzdFRoZUVuZCwgcG9zUGFzdFRoZUVuZCk7CisgICAgICAgIGMuY2xvc2UoKTsKKyAgICB9CisKKyAgICBAVGVzdChleHBlY3RlZCA9IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi5jbGFzcykKKyAgICBwdWJsaWMgdm9pZCBzaG91bGRUaHJvd0V4Y2VwdGlvbldoZW5TZXR0aW5nSW5jb3JyZWN0UG9zaXRpb24oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvL2dpdmVuCisgICAgICAgIFNlZWthYmxlSW5NZW1vcnlCeXRlQ2hhbm5lbCBjID0gbmV3IFNlZWthYmxlSW5NZW1vcnlCeXRlQ2hhbm5lbCgpOworICAgICAgICAvL3doZW4KKyAgICAgICAgYy5wb3NpdGlvbihJbnRlZ2VyLk1BWF9WQUxVRSArIDFMKTsKKyAgICAgICAgYy5jbG9zZSgpOworICAgIH0KKworICAgIEBUZXN0KGV4cGVjdGVkID0gQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbi5jbGFzcykKKyAgICBwdWJsaWMgdm9pZCBzaG91bGRUaHJvd0V4Y2VwdGlvbldoZW5TZXR0aW5nUG9zaXRpb25PbkNsb3NlZENoYW5uZWwoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvL2dpdmVuCisgICAgICAgIFNlZWthYmxlSW5NZW1vcnlCeXRlQ2hhbm5lbCBjID0gbmV3IFNlZWthYmxlSW5NZW1vcnlCeXRlQ2hhbm5lbCgpOworICAgICAgICAvL3doZW4KKyAgICAgICAgYy5jbG9zZSgpOworICAgICAgICBjLnBvc2l0aW9uKDFMKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL3V0aWxzL1NlcnZpY2VMb2FkZXJJdGVyYXRvclRlc3QuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL3V0aWxzL1NlcnZpY2VMb2FkZXJJdGVyYXRvclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jMzlmNDAxCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvY29tcHJlc3MvdXRpbHMvU2VydmljZUxvYWRlckl0ZXJhdG9yVGVzdC5qYXZhCkBAIC0wLDAgKzEsNzMgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHM7CisKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworaW1wb3J0IGphdmEudXRpbC5Ob1N1Y2hFbGVtZW50RXhjZXB0aW9uOworCitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0RmFsc2U7CisKKy8qKgorICogVW5pdCB0ZXN0cyBmb3IgY2xhc3Mge0BsaW5rIFNlcnZpY2VMb2FkZXJJdGVyYXRvciBvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MudXRpbHMuU2VydmljZUxvYWRlckl0ZXJhdG9yfS4KKyAqCisgKiBAZGF0ZSAxMy4wNi4yMDE3CisgKiBAc2VlIFNlcnZpY2VMb2FkZXJJdGVyYXRvcgorICoqLworcHVibGljIGNsYXNzIFNlcnZpY2VMb2FkZXJJdGVyYXRvclRlc3QgeworCisKKworICAgIEBUZXN0KGV4cGVjdGVkID0gTm9TdWNoRWxlbWVudEV4Y2VwdGlvbi5jbGFzcykKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TmV4dFRocm93c05vU3VjaEVsZW1lbnRFeGNlcHRpb24oKSB7CisKKyAgICAgICAgQ2xhc3M8U3RyaW5nPiBjbGFzeiA9IFN0cmluZy5jbGFzczsKKyAgICAgICAgU2VydmljZUxvYWRlckl0ZXJhdG9yPFN0cmluZz4gc2VydmljZUxvYWRlckl0ZXJhdG9yID0gbmV3IFNlcnZpY2VMb2FkZXJJdGVyYXRvcjxTdHJpbmc+KGNsYXN6KTsKKworICAgICAgICBzZXJ2aWNlTG9hZGVySXRlcmF0b3IubmV4dCgpOworCisgICAgfQorCisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RIYXNOZXh0UmV0dXJuc0ZhbHNlKCkgeworCisgICAgICAgIENsYXNzPE9iamVjdD4gY2xhc3ogPSBPYmplY3QuY2xhc3M7CisgICAgICAgIFNlcnZpY2VMb2FkZXJJdGVyYXRvcjxPYmplY3Q+IHNlcnZpY2VMb2FkZXJJdGVyYXRvciA9IG5ldyBTZXJ2aWNlTG9hZGVySXRlcmF0b3I8T2JqZWN0PihjbGFzeik7CisgICAgICAgIGJvb2xlYW4gcmVzdWx0ID0gc2VydmljZUxvYWRlckl0ZXJhdG9yLmhhc05leHQoKTsKKworICAgICAgICBhc3NlcnRGYWxzZShyZXN1bHQpOworCisgICAgfQorCisKKyAgICBAVGVzdChleHBlY3RlZCA9IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uLmNsYXNzKQorICAgIHB1YmxpYyB2b2lkIHRlc3RSZW1vdmVUaHJvd3NVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpIHsKKworICAgICAgICBDbGFzczxJbnRlZ2VyPiBjbGFzeiA9IEludGVnZXIuY2xhc3M7CisgICAgICAgIFNlcnZpY2VMb2FkZXJJdGVyYXRvcjxJbnRlZ2VyPiBzZXJ2aWNlTG9hZGVySXRlcmF0b3IgPSBuZXcgU2VydmljZUxvYWRlckl0ZXJhdG9yPEludGVnZXI+KGNsYXN6KTsKKworICAgICAgICBzZXJ2aWNlTG9hZGVySXRlcmF0b3IucmVtb3ZlKCk7CisKKworICAgIH0KKworCisKK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy91dGlscy9Ta2lwU2hpZWxkaW5nSW5wdXRTdHJlYW1UZXN0LmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy9jb21wcmVzcy91dGlscy9Ta2lwU2hpZWxkaW5nSW5wdXRTdHJlYW1UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWFlNjljZgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL3V0aWxzL1NraXBTaGllbGRpbmdJbnB1dFN0cmVhbVRlc3QuamF2YQpAQCAtMCwwICsxLDkxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy51dGlsczsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuanVuaXQuQXNzZXJ0OworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworCitwdWJsaWMgY2xhc3MgU2tpcFNoaWVsZGluZ0lucHV0U3RyZWFtVGVzdCB7CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHNraXBEZWxlZ2F0ZXNUb1JlYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0cnkgKElucHV0U3RyZWFtIGkgPSBuZXcgU2tpcFNoaWVsZGluZ0lucHV0U3RyZWFtKG5ldyBJbnB1dFN0cmVhbSgpIHsKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICBwdWJsaWMgbG9uZyBza2lwKGxvbmcgbikgeworICAgICAgICAgICAgICAgICAgICBBc3NlcnQuZmFpbCgic2tpcCBpbnZva2VkIik7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgcHVibGljIGludCByZWFkKCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgIHB1YmxpYyBpbnQgcmVhZChieXRlW10gYiwgaW50IG9mZiwgaW50IGxlbikgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbGVuOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0pKSB7CisgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKDEwMCwgaS5za2lwKDEwMCkpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBza2lwSGFzQW5VcHBlckJvdW5kT25SZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBpID0gbmV3IFNraXBTaGllbGRpbmdJbnB1dFN0cmVhbShuZXcgSW5wdXRTdHJlYW0oKSB7CisgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgcHVibGljIGxvbmcgc2tpcChsb25nIG4pIHsKKyAgICAgICAgICAgICAgICAgICAgQXNzZXJ0LmZhaWwoInNraXAgaW52b2tlZCIpOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgIHB1YmxpYyBpbnQgcmVhZCgpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICBwdWJsaWMgaW50IHJlYWQoYnl0ZVtdIGIsIGludCBvZmYsIGludCBsZW4pIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGxlbjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9KSkgeworICAgICAgICAgICAgQXNzZXJ0LmFzc2VydFRydWUoSW50ZWdlci5NQVhfVkFMVUUgPiBpLnNraXAoTG9uZy5NQVhfVkFMVUUpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgc2tpcFN3YWxsb3dzTmVnYXRpdmVBcmd1bWVudHMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0cnkgKElucHV0U3RyZWFtIGkgPSBuZXcgU2tpcFNoaWVsZGluZ0lucHV0U3RyZWFtKG5ldyBJbnB1dFN0cmVhbSgpIHsKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICBwdWJsaWMgbG9uZyBza2lwKGxvbmcgbikgeworICAgICAgICAgICAgICAgICAgICBBc3NlcnQuZmFpbCgic2tpcCBpbnZva2VkIik7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgcHVibGljIGludCByZWFkKCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgIHB1YmxpYyBpbnQgcmVhZChieXRlW10gYiwgaW50IG9mZiwgaW50IGxlbikgeworICAgICAgICAgICAgICAgICAgICBBc3NlcnQuZmFpbCgicmVhZCBpbnZva2VkIik7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBsZW47CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSkpIHsKKyAgICAgICAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoMCwgaS5za2lwKExvbmcuTUlOX1ZBTFVFKSk7CisgICAgICAgIH0KKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy83ei1lbXB0eS1taGMtb2ZmLjd6IGIvc3JjL3Rlc3QvcmVzb3VyY2VzLzd6LWVtcHR5LW1oYy1vZmYuN3oKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGUwMGM0MwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy83ei1lbXB0eS1taGMtb2ZmLjd6CkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy83ei1oZWxsby1taGMtb2ZmLWNvcHkuN3ogYi9zcmMvdGVzdC9yZXNvdXJjZXMvN3otaGVsbG8tbWhjLW9mZi1jb3B5Ljd6Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJjYzkxZGEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvN3otaGVsbG8tbWhjLW9mZi1jb3B5Ljd6CkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy83ei1oZWxsby1taGMtb2ZmLWx6bWEyLjd6IGIvc3JjL3Rlc3QvcmVzb3VyY2VzLzd6LWhlbGxvLW1oYy1vZmYtbHptYTIuN3oKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGZiY2QyNQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy83ei1oZWxsby1taGMtb2ZmLWx6bWEyLjd6CkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy84LnBvc2l4LnRhci5neiBiL3NyYy90ZXN0L3Jlc291cmNlcy84LnBvc2l4LnRhci5negpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lZTU1MjAyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzLzgucG9zaXgudGFyLmd6CkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy84LnN0YXIudGFyLmd6IGIvc3JjL3Rlc3QvcmVzb3VyY2VzLzguc3Rhci50YXIuZ3oKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjYzYzc4ZAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy84LnN0YXIudGFyLmd6CkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0xMTQudGFyIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL0NPTVBSRVNTLTExNC50YXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTIyN2Y5OAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0xMTQudGFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0xMTcudGFyIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL0NPTVBSRVNTLTExNy50YXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTFhYmViOQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0xMTcudGFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0xMzEuYnoyIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL0NPTVBSRVNTLTEzMS5iejIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjhkYjYxMAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0xMzEuYnoyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0xNzgudGFyIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL0NPTVBSRVNTLTE3OC50YXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmExMzIxOQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0xNzgudGFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0xODkuemlwIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL0NPTVBSRVNTLTE4OS56aXAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTk5NTRkYgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0xODkuemlwCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0xOTcudGFyIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL0NPTVBSRVNTLTE5Ny50YXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmY0MmVlMAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0xOTcudGFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0yMDguemlwIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL0NPTVBSRVNTLTIwOC56aXAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjIxMDA3NAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0yMDguemlwCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0yMTBfdW5peF90aW1lX3ppcF90ZXN0LnppcCBiL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0yMTBfdW5peF90aW1lX3ppcF90ZXN0LnppcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43MjQ5YWUxCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL0NPTVBSRVNTLTIxMF91bml4X3RpbWVfemlwX3Rlc3QuemlwCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0yMTFfdWlkX2dpZF96aXBfdGVzdC56aXAgYi9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtMjExX3VpZF9naWRfemlwX3Rlc3QuemlwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIxZDQwNWMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtMjExX3VpZF9naWRfemlwX3Rlc3QuemlwCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0yMTRfdW5peF9zeW1saW5rcy56aXAgYi9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtMjE0X3VuaXhfc3ltbGlua3MuemlwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUyMjFhODQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtMjE0X3VuaXhfc3ltbGlua3MuemlwCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0yMTkuemlwIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL0NPTVBSRVNTLTIxOS56aXAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGU3YjVjOAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0yMTkuemlwCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0yMjcuemlwIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL0NPTVBSRVNTLTIyNy56aXAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmY1NGNhNgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0yMjcuemlwCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0yMjguemlwIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL0NPTVBSRVNTLTIyOC56aXAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjVlY2IxMgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0yMjguemlwCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0yNDUudGFyLmd6IGIvc3JjL3Rlc3QvcmVzb3VyY2VzL0NPTVBSRVNTLTI0NS50YXIuZ3oKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTEzZGI4NgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0yNDUudGFyLmd6CkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0yNTYuN3ogYi9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtMjU2Ljd6Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFjNmEyZTcKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtMjU2Ljd6CkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0yNjQuemlwIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL0NPTVBSRVNTLTI2NC56aXAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzVmMmJlNwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0yNjQuemlwCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0yNzkudGFyIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL0NPTVBSRVNTLTI3OS50YXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWViMDkzMgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0yNzkudGFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0zMjAvQlppcDItc29saWQuN3ogYi9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtMzIwL0JaaXAyLXNvbGlkLjd6Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmExZmYxMWIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtMzIwL0JaaXAyLXNvbGlkLjd6CkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0zMjAvQlppcDIuN3ogYi9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtMzIwL0JaaXAyLjd6Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMyNzJlY2QKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtMzIwL0JaaXAyLjd6CkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0zMjAvQ29weS1zb2xpZC43eiBiL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0zMjAvQ29weS1zb2xpZC43egpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wMDg1NjRkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL0NPTVBSRVNTLTMyMC9Db3B5LXNvbGlkLjd6CkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0zMjAvQ29weS43eiBiL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0zMjAvQ29weS43egpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45NThjZDhmCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL0NPTVBSRVNTLTMyMC9Db3B5Ljd6CkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0zMjAvRGVmbGF0ZS1zb2xpZC43eiBiL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0zMjAvRGVmbGF0ZS1zb2xpZC43egpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wMGViODRkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL0NPTVBSRVNTLTMyMC9EZWZsYXRlLXNvbGlkLjd6CkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0zMjAvRGVmbGF0ZS43eiBiL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0zMjAvRGVmbGF0ZS43egpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNWUzNTcwCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL0NPTVBSRVNTLTMyMC9EZWZsYXRlLjd6CkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0zMjAvTFpNQS1zb2xpZC43eiBiL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0zMjAvTFpNQS1zb2xpZC43egpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41ZjU1OTkzCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL0NPTVBSRVNTLTMyMC9MWk1BLXNvbGlkLjd6CkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0zMjAvTFpNQS43eiBiL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0zMjAvTFpNQS43egpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNDE2ZDExCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL0NPTVBSRVNTLTMyMC9MWk1BLjd6CkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0zMjAvTFpNQTItc29saWQuN3ogYi9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtMzIwL0xaTUEyLXNvbGlkLjd6Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVhOWY4MDcKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtMzIwL0xaTUEyLXNvbGlkLjd6CkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0zMjAvTFpNQTIuN3ogYi9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtMzIwL0xaTUEyLjd6Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM2YzgzNDcKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtMzIwL0xaTUEyLjd6CkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0zMjAvUFBNZC1zb2xpZC43eiBiL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0zMjAvUFBNZC1zb2xpZC43egpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41YTNlZTBhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL0NPTVBSRVNTLTMyMC9QUE1kLXNvbGlkLjd6CkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0zMjAvUFBNZC43eiBiL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0zMjAvUFBNZC43egpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMzczOTZhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL0NPTVBSRVNTLTMyMC9QUE1kLjd6CkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0zMjAvcmVjcmVhdGUuc2ggYi9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtMzIwL3JlY3JlYXRlLnNoCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA5YmQwZGMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtMzIwL3JlY3JlYXRlLnNoCkBAIC0wLDAgKzEsOSBAQAorIyEvYmluL2Jhc2gKKworcm0gKi43egorZm9yIENPTVBSRVNTSU9OIGluICJMWk1BIiAiTFpNQTIiICJQUE1kIiAiQlppcDIiICJEZWZsYXRlIiAiQ29weSI7IGRvCisgICMgTmV3IHNvbGlkIGJsb2NrIGV2ZXJ5IDEwIGZpbGVzLgorICA3emEgYSAtbTA9JENPTVBSRVNTSU9OIC1tczEwZiAgJENPTVBSRVNTSU9OLXNvbGlkLjd6IC4uLy4uLy4uLy4uL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzCisgICMgRWFjaCBmaWxlIGluIGlzb2xhdGlvbgorICA3emEgYSAtbTA9JENPTVBSRVNTSU9OIC1tcz1vZmYgJENPTVBSRVNTSU9OLjd6ICAgICAgIC4uLy4uLy4uLy4uL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2NvbXByZXNzL2NvbXByZXNzb3JzCitkb25lCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtMzI0LnRhciBiL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0zMjQudGFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjEzN2I1NmUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtMzI0LnRhcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtMzM1LnRhciBiL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0zMzUudGFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAyNjZiNjMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtMzM1LnRhcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtMzQ4Ljd6IGIvc3JjL3Rlc3QvcmVzb3VyY2VzL0NPTVBSRVNTLTM0OC43egpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44ZmIyNmMyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL0NPTVBSRVNTLTM0OC43egpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtMzUxLnppcCBiL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0zNTEuemlwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjllNGMzMzEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtMzUxLnppcApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtMzU1LnRhciBiL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0zNTUudGFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZlYjk0ZjIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtMzU1LnRhcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtMzU2LnRhciBiL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0zNTYudGFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRkZDZiZTkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtMzU2LnRhcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtMzU4Lml3YSBiL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0zNTguaXdhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjExNmQ3OWMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtMzU4Lml3YQpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtMzU4LnVuY29tcHJlc3NlZCBiL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0zNTgudW5jb21wcmVzc2VkCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU3Y2ZhMzQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtMzU4LnVuY29tcHJlc3NlZApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtMzc5LmphciBiL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0zNzkuamFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgyMTFmMzIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtMzc5LmphcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtMzgwL0NPTVBSRVNTLTM4MC1kZC56aXAgYi9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtMzgwL0NPTVBSRVNTLTM4MC1kZC56aXAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTU1Nzk5NgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0zODAvQ09NUFJFU1MtMzgwLWRkLnppcApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtMzgwL0NPTVBSRVNTLTM4MC1pbnB1dCBiL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0zODAvQ09NUFJFU1MtMzgwLWlucHV0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRhZjFmNTYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtMzgwL0NPTVBSRVNTLTM4MC1pbnB1dApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtMzgwL0NPTVBSRVNTLTM4MC1yZWFkYmV5b25kbWVtb3J5LnppcCBiL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0zODAvQ09NUFJFU1MtMzgwLXJlYWRiZXlvbmRtZW1vcnkuemlwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk5ZjM1MmQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtMzgwL0NPTVBSRVNTLTM4MC1yZWFkYmV5b25kbWVtb3J5LnppcApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtMzgwL0NPTVBSRVNTLTM4MC56aXAgYi9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtMzgwL0NPTVBSRVNTLTM4MC56aXAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDkxNDZiZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9DT01QUkVTUy0zODAvQ09NUFJFU1MtMzgwLnppcApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtMzgyIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL0NPTVBSRVNTLTM4MgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iZTI1N2YyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL0NPTVBSRVNTLTM4MgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtMzg2IGIvc3JjL3Rlc3QvcmVzb3VyY2VzL0NPTVBSRVNTLTM4NgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNmQ3ZjUyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL0NPTVBSRVNTLTM4NgpAQCAtMCwwICsxIEBACisfnR5CClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvcmVzb3VyY2VzL0NPTVBSRVNTLTQxNy50YXIgYi9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtNDE3LnRhcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MDc2ODNiCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL0NPTVBSRVNTLTQxNy50YXIKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvcmVzb3VyY2VzL0NPTVBSRVNTLTQ1OS5jcGlvIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL0NPTVBSRVNTLTQ1OS5jcGlvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhhZTE2NjIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvQ09NUFJFU1MtNDU5LmNwaW8KQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvcmVzb3VyY2VzL01FVEEtSU5GL3NlcnZpY2VzL29yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZVN0cmVhbVByb3ZpZGVyIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL01FVEEtSU5GL3NlcnZpY2VzL29yZy5hcGFjaGUuY29tbW9ucy5jb21wcmVzcy5hcmNoaXZlcnMuQXJjaGl2ZVN0cmVhbVByb3ZpZGVyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRlYTIzNmYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvTUVUQS1JTkYvc2VydmljZXMvb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5BcmNoaXZlU3RyZWFtUHJvdmlkZXIKQEAgLTAsMCArMSBAQAorb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmFyY2hpdmVycy5UZXN0QXJjaGl2ZVN0cmVhbVByb3ZpZGVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvTUVUQS1JTkYvc2VydmljZXMvb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLkNvbXByZXNzb3JTdHJlYW1Qcm92aWRlciBiL3NyYy90ZXN0L3Jlc291cmNlcy9NRVRBLUlORi9zZXJ2aWNlcy9vcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuQ29tcHJlc3NvclN0cmVhbVByb3ZpZGVyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc4MmQ1ODEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvTUVUQS1JTkYvc2VydmljZXMvb3JnLmFwYWNoZS5jb21tb25zLmNvbXByZXNzLmNvbXByZXNzb3JzLkNvbXByZXNzb3JTdHJlYW1Qcm92aWRlcgpAQCAtMCwwICsxIEBACitvcmcuYXBhY2hlLmNvbW1vbnMuY29tcHJlc3MuY29tcHJlc3NvcnMuVGVzdENvbXByZXNzb3JTdHJlYW1Qcm92aWRlcgpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvcmVzb3VyY2VzL09TWF9BcmNoaXZlV2l0aE5lc3RlZEFyY2hpdmUuemlwIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL09TWF9BcmNoaXZlV2l0aE5lc3RlZEFyY2hpdmUuemlwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjcyYjVkNzAKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvT1NYX0FyY2hpdmVXaXRoTmVzdGVkQXJjaGl2ZS56aXAKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvcmVzb3VyY2VzL1NIUlVOSy5aSVAgYi9zcmMvdGVzdC9yZXNvdXJjZXMvU0hSVU5LLlpJUApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNzJhOGU3Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL1NIUlVOSy5aSVAKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvcmVzb3VyY2VzL2FwYWNoZS1tYXZlbi0yLjIuMS56aXAuMDAxIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2FwYWNoZS1tYXZlbi0yLjIuMS56aXAuMDAxCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY5MTM4OGUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvYXBhY2hlLW1hdmVuLTIuMi4xLnppcC4wMDEKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvcmVzb3VyY2VzL2FyY2hpdmVfd2l0aF9ieXRlc19hZnRlcl9kYXRhLnppcCBiL3NyYy90ZXN0L3Jlc291cmNlcy9hcmNoaXZlX3dpdGhfYnl0ZXNfYWZ0ZXJfZGF0YS56aXAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODkzN2VkZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9hcmNoaXZlX3dpdGhfYnl0ZXNfYWZ0ZXJfZGF0YS56aXAKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvcmVzb3VyY2VzL2FyY2hpdmVfd2l0aF90cmFpbGVyLmR1bXAgYi9zcmMvdGVzdC9yZXNvdXJjZXMvYXJjaGl2ZV93aXRoX3RyYWlsZXIuZHVtcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lYjdjNGFlCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2FyY2hpdmVfd2l0aF90cmFpbGVyLmR1bXAKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvcmVzb3VyY2VzL2FyY2hpdmVfd2l0aF90cmFpbGVyLnRhciBiL3NyYy90ZXN0L3Jlc291cmNlcy9hcmNoaXZlX3dpdGhfdHJhaWxlci50YXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmY4ODljNwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9hcmNoaXZlX3dpdGhfdHJhaWxlci50YXIKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvcmVzb3VyY2VzL2FyY2hpdmVfd2l0aF90cmFpbGVyLnppcCBiL3NyYy90ZXN0L3Jlc291cmNlcy9hcmNoaXZlX3dpdGhfdHJhaWxlci56aXAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2U1ZmIxZgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9hcmNoaXZlX3dpdGhfdHJhaWxlci56aXAKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvcmVzb3VyY2VzL2FyY2hpdmVzL0ZyZWVCU0QuYXIgYi9zcmMvdGVzdC9yZXNvdXJjZXMvYXJjaGl2ZXMvRnJlZUJTRC5hcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42YmY5MTE2Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2FyY2hpdmVzL0ZyZWVCU0QuYXIKQEAgLTAsMCArMSwyOSBAQAorITxhcmNoPgorMS8gICAgICAgICAgICAgIDEyMzgyNzgyMjEgIDE3MjEgIDE3MjEgIDEwMDY2NCAgMjcgICAgICAgIGAKK2FiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6CisKKzEyLyAgICAgICAgICAgICAxMjM4Mjc4MjIxICAxNzIxICAxNzIxICAxMDA2NjQgIDI3ICAgICAgICBgCithYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5egorCisxMjMvICAgICAgICAgICAgMTIzODI3ODIyMSAgMTcyMSAgMTcyMSAgMTAwNjY0ICAyNyAgICAgICAgYAorYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoKKworMTIzNC8gICAgICAgICAgIDEyMzgyNzgyMjIgIDE3MjEgIDE3MjEgIDEwMDY2NCAgMjcgICAgICAgIGAKK2FiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6CisKKzEyMzQ1LyAgICAgICAgICAxMjM4Mjc4MjIyICAxNzIxICAxNzIxICAxMDA2NjQgIDI3ICAgICAgICBgCithYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5egorCisxMjM0NTAvICAgICAgICAgMTIzODI3ODIyMiAgMTcyMSAgMTcyMSAgMTAwNjQ0ICAyNyAgICAgICAgYAorYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoKKworMTIzNDU2LyAgICAgICAgIDEyMzgyNzgyMjIgIDE3MjEgIDE3MjEgIDEwMDY2NCAgMjYgICAgICAgIGAKK2JjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoKKzEyMzQ1Ny8gICAgICAgICAxMjM4Mjc4MjIyICAxNzIxICAxNzIxICAxMDA2NDQgIDI1ICAgICAgICBgCitjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoKKworMTIzNDU4LyAgICAgICAgIDEyMzgyNzgyMjIgIDE3MjEgIDE3MjEgIDEwMDY0NCAgMjQgICAgICAgIGAKK2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6CisxMjM0NTkvICAgICAgICAgMTIzODI3ODIyMiAgMTcyMSAgMTcyMSAgMTAwNjQ0ICAyMyAgICAgICAgYAorZWZnaGlqa2xtbm9wcXJzdHV2d3h5egorCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvYXJjaGl2ZXMvRnJlZUJTRC56aXAgYi9zcmMvdGVzdC9yZXNvdXJjZXMvYXJjaGl2ZXMvRnJlZUJTRC56aXAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGY3MjFhYgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9hcmNoaXZlcy9GcmVlQlNELnppcApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvYXJjaGl2ZXMvRnJlZUJTRF8udGFyIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2FyY2hpdmVzL0ZyZWVCU0RfLnRhcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mZGRkMWNkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2FyY2hpdmVzL0ZyZWVCU0RfLnRhcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvYXJjaGl2ZXMvRnJlZUJTRF9iaW4uY3BpbyBiL3NyYy90ZXN0L3Jlc291cmNlcy9hcmNoaXZlcy9GcmVlQlNEX2Jpbi5jcGlvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFiOTk2ZjIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvYXJjaGl2ZXMvRnJlZUJTRF9iaW4uY3BpbwpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvYXJjaGl2ZXMvRnJlZUJTRF9jcmMuY3BpbyBiL3NyYy90ZXN0L3Jlc291cmNlcy9hcmNoaXZlcy9GcmVlQlNEX2NyYy5jcGlvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc2YmE0Y2EKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvYXJjaGl2ZXMvRnJlZUJTRF9jcmMuY3BpbwpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvYXJjaGl2ZXMvRnJlZUJTRF9ocGJpbi5jcGlvIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2FyY2hpdmVzL0ZyZWVCU0RfaHBiaW4uY3BpbwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hYjk5NmYyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2FyY2hpdmVzL0ZyZWVCU0RfaHBiaW4uY3BpbwpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvYXJjaGl2ZXMvRnJlZUJTRF9uZXdjLmNwaW8gYi9zcmMvdGVzdC9yZXNvdXJjZXMvYXJjaGl2ZXMvRnJlZUJTRF9uZXdjLmNwaW8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2ZkNzlhNgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9hcmNoaXZlcy9GcmVlQlNEX25ld2MuY3BpbwpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvYXJjaGl2ZXMvRnJlZUJTRF9wYXgudGFyIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2FyY2hpdmVzL0ZyZWVCU0RfcGF4LnRhcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hMjBkODc5Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2FyY2hpdmVzL0ZyZWVCU0RfcGF4LnRhcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvYXJjaGl2ZXMvRnJlZUJTRF91c3Rhci50YXIgYi9zcmMvdGVzdC9yZXNvdXJjZXMvYXJjaGl2ZXMvRnJlZUJTRF91c3Rhci50YXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmRkZDFjZAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9hcmNoaXZlcy9GcmVlQlNEX3VzdGFyLnRhcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvYXJjaGl2ZXMvU3VuT1MuYXIgYi9zcmMvdGVzdC9yZXNvdXJjZXMvYXJjaGl2ZXMvU3VuT1MuYXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODBjMzYzYgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9hcmNoaXZlcy9TdW5PUy5hcgpAQCAtMCwwICsxLDI5IEBACishPGFyY2g+CisxLyAgICAgICAgICAgICAgMTIzODI2NDQ2MiAgMjYwNiAgMSAgICAgMTAwNjQ0ICAyNyAgICAgICAgYAorYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoKKworMTIvICAgICAgICAgICAgIDEyMzgyNzcyNjAgIDI2MDYgIDEgICAgIDEwMDY0NCAgMjcgICAgICAgIGAKK2FiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6CisKKzEyMy8gICAgICAgICAgICAxMjM4Mjc3MjY1ICAyNjA2ICAxICAgICAxMDA2NDQgIDI3ICAgICAgICBgCithYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5egorCisxMjM0LyAgICAgICAgICAgMTIzODI3NzI3NSAgMjYwNiAgMSAgICAgMTAwNjQ0ICAyNyAgICAgICAgYAorYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoKKworMTIzNDUvICAgICAgICAgIDEyMzgyNzcyNzcgIDI2MDYgIDEgICAgIDEwMDY0NCAgMjcgICAgICAgIGAKK2FiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6CisKKzEyMzQ1MC8gICAgICAgICAxMjM4Mjc3Mzg1ICAyNjA2ICAxICAgICAxMDA2NDQgIDI3ICAgICAgICBgCithYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5egorCisxMjM0NTYvICAgICAgICAgMTIzODI3NzYyMCAgMjYwNiAgMSAgICAgMTAwNjQ0ICAyNiAgICAgICAgYAorYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5egorMTIzNDU3LyAgICAgICAgIDEyMzgyNzc2NjAgIDI2MDYgIDEgICAgIDEwMDY0NCAgMjUgICAgICAgIGAKK2NkZWZnaGlqa2xtbm9wcXJzdHV2d3h5egorCisxMjM0NTgvICAgICAgICAgMTIzODI3NzY3MCAgMjYwNiAgMSAgICAgMTAwNjQ0ICAyNCAgICAgICAgYAorZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoKKzEyMzQ1OS8gICAgICAgICAxMjM4Mjc3Njc5ICAyNjA2ICAxICAgICAxMDA2NDQgIDIzICAgICAgICBgCitlZmdoaWprbG1ub3BxcnN0dXZ3eHl6CisKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9hcmNoaXZlcy9TdW5PUy56aXAgYi9zcmMvdGVzdC9yZXNvdXJjZXMvYXJjaGl2ZXMvU3VuT1MuemlwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAxYTg2M2EKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvYXJjaGl2ZXMvU3VuT1MuemlwCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9hcmNoaXZlcy9TdW5PU18tYy5jcGlvIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2FyY2hpdmVzL1N1bk9TXy1jLmNwaW8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjk4YTk2ZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9hcmNoaXZlcy9TdW5PU18tYy5jcGlvCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9hcmNoaXZlcy9TdW5PU18uY3BpbyBiL3NyYy90ZXN0L3Jlc291cmNlcy9hcmNoaXZlcy9TdW5PU18uY3BpbwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lYWI5MDhkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2FyY2hpdmVzL1N1bk9TXy5jcGlvCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9hcmNoaXZlcy9TdW5PU19jQUVmLnRhciBiL3NyYy90ZXN0L3Jlc291cmNlcy9hcmNoaXZlcy9TdW5PU19jQUVmLnRhcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45NzAyMjc4Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2FyY2hpdmVzL1N1bk9TX2NBRWYudGFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9hcmNoaXZlcy9TdW5PU19jRWYudGFyIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2FyY2hpdmVzL1N1bk9TX2NFZi50YXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTFjMzAxZAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9hcmNoaXZlcy9TdW5PU19jRWYudGFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9hcmNoaXZlcy9TdW5PU19jZi50YXIgYi9zcmMvdGVzdC9yZXNvdXJjZXMvYXJjaGl2ZXMvU3VuT1NfY2YudGFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ5NjIwNDEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvYXJjaGl2ZXMvU3VuT1NfY2YudGFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9hcmNoaXZlcy9TdW5PU19jcmMuY3BpbyBiL3NyYy90ZXN0L3Jlc291cmNlcy9hcmNoaXZlcy9TdW5PU19jcmMuY3BpbwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNWFmMWZiCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2FyY2hpdmVzL1N1bk9TX2NyYy5jcGlvCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9hcmNoaXZlcy9TdW5PU19vZGMuY3BpbyBiL3NyYy90ZXN0L3Jlc291cmNlcy9hcmNoaXZlcy9TdW5PU19vZGMuY3BpbwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iYjQ0ZTAxCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2FyY2hpdmVzL1N1bk9TX29kYy5jcGlvCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9hcmNoaXZlcy9maWxlcy50eHQgYi9zcmMvdGVzdC9yZXNvdXJjZXMvYXJjaGl2ZXMvZmlsZXMudHh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRiNDAzNTkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvYXJjaGl2ZXMvZmlsZXMudHh0CkBAIC0wLDAgKzEsMTEgQEAKKyMgU2l6ZXMgYW5kIGZpbGVuYW1lcyBpbiB0aGUgYXJjaGl2ZXMKKzI3IDEKKzI3IDEyCisyNyAxMjMKKzI3IDEyMzQKKzI3IDEyMzQ1CisyNyAxMjM0NTAKKzI2IDEyMzQ1NgorMjUgMTIzNDU3CisyNCAxMjM0NTgKKzIzIDEyMzQ1OQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvcmVzb3VyY2VzL2JsYS43eiBiL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEuN3oKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjIzZDc0YgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEuN3oKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvcmVzb3VyY2VzL2JsYS5hciBiL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEuYXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzk4ZTliNwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEuYXIKQEAgLTAsMCArMSwyNyBAQAorITxhcmNoPgordGVzdDEueG1sICAgICAgIDEyMDE0NDU4NjkgIDUwMSAgIDUwMSAgIDEwMDY0NCAgNjEwICAgICAgIGAKKzw/eG1sIHZlcnNpb24gPSAnMS4wJz8+DQorPCFET0NUWVBFIGNvbm5lY3Rpb25zPg0KKzxjb25uZWN0aW9ucz4NCis8PDw8PDw8IEhFQUQ6dGVzdGRhdGEvdGVzdC54bWwKKz09PT09PT0KKyAgICBhcw0KKz4+Pj4+Pj4gNzVjYjYzZmY3MDA1MzQ0NTg5YjU3ZDE3MzM4YjY0NzgzZjhmNDMwYzp0ZXN0ZGF0YS90ZXN0LnhtbAorICAgPGNvbm5lY3Rpb24+DQorICAgICAgPEpEQkNfUE9SVD4xNTIxPC9KREJDX1BPUlQ+DQorICAgICAgPEhPU1ROQU1FPjEwLjI0OC40MC4xMTE8L0hPU1ROQU1FPg0KKyAgICAgIDxDb25uZWN0aW9uVHlwZT5KREJDPC9Db25uZWN0aW9uVHlwZT4NCisgICAgICA8RGVwbG95UGFzc3dvcmQ+ZmFsc2U8L0RlcGxveVBhc3N3b3JkPg0KKyAgICAgIDx1c2VyPmFwcHNydjwvdXNlcj4NCisgICAgICA8Q29ubmVjdGlvbk5hbWU+RGV2LURCPC9Db25uZWN0aW9uTmFtZT4NCisgICAgICA8U0lEPk8xMGdJTjE8L1NJRD4NCisgICAgICA8SmRiY0RyaXZlcj5vcmFjbGUuamRiYy5kcml2ZXIuT3JhY2xlRHJpdmVyPC9KZGJjRHJpdmVyPg0KKyAgICAgIDxPUkFDTEVfSkRCQ19UWVBFPnRoaW48L09SQUNMRV9KREJDX1RZUEU+DQorICAgPC9jb25uZWN0aW9uPg0KKzwvY29ubmVjdGlvbnM+DQordGVzdDIueG1sICAgICAgIDEyMDE0NDU4NjkgIDUwMSAgIDUwMSAgIDEwMDY0NCAgODIgICAgICAgIGAKKzw/eG1sIHZlcnNpb24gPSAnMS4wJz8+DQorPCFET0NUWVBFIGNvbm5lY3Rpb25zPg0KKzxtZWlueG1sPg0KKwk8bGVlciAvPg0KKzwvbWVpbnhtbD4KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEuYXJqIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2JsYS5hcmoKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzQ3YjkyMwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEuYXJqCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEuY3BpbyBiL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEuY3BpbwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40N2RhNDIwCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2JsYS5jcGlvCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEuZGVmbGF0ZS43eiBiL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEuZGVmbGF0ZS43egpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42OTZjM2U0Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2JsYS5kZWZsYXRlLjd6CkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEuZGVmbGF0ZTY0Ljd6IGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2JsYS5kZWZsYXRlNjQuN3oKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTRmNjBiZAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEuZGVmbGF0ZTY0Ljd6CkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEuZHVtcCBiL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEuZHVtcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MWY5NmEzCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2JsYS5kdW1wCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEuZHVtcC5sejQgYi9zcmMvdGVzdC9yZXNvdXJjZXMvYmxhLmR1bXAubHo0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQyYTgxM2YKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvYmxhLmR1bXAubHo0CkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEuZW5jcnlwdGVkLjd6IGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2JsYS5lbmNyeXB0ZWQuN3oKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjYyN2Y0MQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEuZW5jcnlwdGVkLjd6CkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEuamFyIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2JsYS5qYXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWQzZWQ4MgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEucGFjayBiL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEucGFjawpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMzMyY2E0Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2JsYS5wYWNrCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEudGFyIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2JsYS50YXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzdhZjUzNwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEudGFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEudGFyLlogYi9zcmMvdGVzdC9yZXNvdXJjZXMvYmxhLnRhci5aCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU0NWQ2MmQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvYmxhLnRhci5aCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEudGFyLmJsb2NrX2x6NCBiL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEudGFyLmJsb2NrX2x6NApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xY2ViOTk3Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2JsYS50YXIuYmxvY2tfbHo0CkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEudGFyLmJyIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2JsYS50YXIuYnIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzViMWY5OQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEudGFyLmJyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEudGFyLmJ6MiBiL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEudGFyLmJ6MgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mZTM4ODU4Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2JsYS50YXIuYnoyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEudGFyLmRlZmxhdGUgYi9zcmMvdGVzdC9yZXNvdXJjZXMvYmxhLnRhci5kZWZsYXRlCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM4Mzg5OGYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvYmxhLnRhci5kZWZsYXRlCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEudGFyLmRlZmxhdGV6IGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2JsYS50YXIuZGVmbGF0ZXoKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzJlYmU3NwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEudGFyLmRlZmxhdGV6CkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEudGFyLmx6NCBiL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEudGFyLmx6NApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jYmY1N2ZhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2JsYS50YXIubHo0CkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEudGFyLmx6bWEgYi9zcmMvdGVzdC9yZXNvdXJjZXMvYmxhLnRhci5sem1hCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjEwOTY4ZmQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvYmxhLnRhci5sem1hCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEudGFyLnN6IGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2JsYS50YXIuc3oKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmQ3NGI0ZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEudGFyLnN6CkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEudGFyLnh6IGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2JsYS50YXIueHoKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzc3YzRhYgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEudGFyLnh6CkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEudGd6IGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2JsYS50Z3oKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDc0MWYxZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEudGd6CkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEudHh0LmJ6MiBiL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEudHh0LmJ6MgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NzMwOWRhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2JsYS50eHQuYnoyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEudW5peC5hcmogYi9zcmMvdGVzdC9yZXNvdXJjZXMvYmxhLnVuaXguYXJqCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRjOWJjNGQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvYmxhLnVuaXguYXJqCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEueG1sLmJ6MiBiL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEueG1sLmJ6MgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hMmJiY2ZjCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2JsYS54bWwuYnoyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEuei5kdW1wIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2JsYS56LmR1bXAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTY3YTk1ZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEuei5kdW1wCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEuemlwIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2JsYS56aXAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTYwZWVkYwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9ibGEuemlwCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9icm90bGkudGVzdGRhdGEuY29tcHJlc3NlZCBiL3NyYy90ZXN0L3Jlc291cmNlcy9icm90bGkudGVzdGRhdGEuY29tcHJlc3NlZApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNzY5NTE2Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2Jyb3RsaS50ZXN0ZGF0YS5jb21wcmVzc2VkCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9icm90bGkudGVzdGRhdGEudW5jb21wcmVzc2VkIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2Jyb3RsaS50ZXN0ZGF0YS51bmNvbXByZXNzZWQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2Y5Y2Y4NgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9icm90bGkudGVzdGRhdGEudW5jb21wcmVzc2VkCkBAIC0wLDAgKzEgQEAKK1hYWFhYWFhYWFhZWVlZWVlZWVlZClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvcmVzb3VyY2VzL2J6aXAyLXppcC56aXAgYi9zcmMvdGVzdC9yZXNvdXJjZXMvYnppcDItemlwLnppcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMWE4NWM3Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2J6aXAyLXppcC56aXAKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvcmVzb3VyY2VzL2ltcGxvZGluZy00S2RpY3QtMnRyZWVzLnppcCBiL3NyYy90ZXN0L3Jlc291cmNlcy9pbXBsb2RpbmctNEtkaWN0LTJ0cmVlcy56aXAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTA2ZTQxMAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9pbXBsb2RpbmctNEtkaWN0LTJ0cmVlcy56aXAKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvcmVzb3VyY2VzL2ltcGxvZGluZy04S2RpY3QtM3RyZWVzLnppcCBiL3NyYy90ZXN0L3Jlc291cmNlcy9pbXBsb2RpbmctOEtkaWN0LTN0cmVlcy56aXAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2I5NjZlMAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9pbXBsb2RpbmctOEtkaWN0LTN0cmVlcy56aXAKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvcmVzb3VyY2VzL2ludmFsaWQtemlwLnppcCBiL3NyYy90ZXN0L3Jlc291cmNlcy9pbnZhbGlkLXppcC56aXAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmY2ZjFlYwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9pbnZhbGlkLXppcC56aXAKQEAgLTAsMCArMSwyIEBACitUaGlzIGlzIG5vdCByZWFsbHkgYSB2YWxpZCB6aXAgZmlsZSBldmVuIHRob3VnaCBpdCBoYXMgdGhlIHppcCBleHRlbnNpb24uCitaaXBBcmNoaXZlSW5wdXRTdHJlYW0uZ2V0TmV4dFppcEVudHJ5KCkgc2hvdWxkIHRocm93IGFuIGV4Y2VwdGlvbi4KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9sb25nZmlsZV9ic2QuYXIgYi9zcmMvdGVzdC9yZXNvdXJjZXMvbG9uZ2ZpbGVfYnNkLmFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY3YzM2ODIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvbG9uZ2ZpbGVfYnNkLmFyCkBAIC0wLDAgKzEsNSBAQAorITxhcmNoPgorIzEvMjggICAgICAgICAgIDEzMTEyNTY1MTEgIDEwMDAgIDEwMDAgIDEwMDY0NCAgNDIgICAgICAgIGAKK3RoaXNfaXNfYV9sb25nX2ZpbGVfbmFtZS50eHRIZWxsbywgd29ybGQhCisjMS8zNiAgICAgICAgICAgMTQ1NDY5NDAxNiAgMTAwMCAgMTAwMCAgMTAwNjY0ICA0MCAgICAgICAgYAordGhpc19pc19hX2xvbmdfZmlsZV9uYW1lX2FzX3dlbGwudHh0QnllCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvbG9uZ2ZpbGVfZ251LmFyIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2xvbmdmaWxlX2dudS5hcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMjc5OWEwCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2xvbmdmaWxlX2dudS5hcgpAQCAtMCwwICsxLDggQEAKKyE8YXJjaD4KKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDY4ICAgICAgICBgCit0aGlzX2lzX2FfbG9uZ19maWxlX25hbWUudHh0LwordGhpc19pc19hX2xvbmdfZmlsZV9uYW1lX2FzX3dlbGwudHh0LworLzAgICAgICAgICAgICAgIDE0NTQ2OTM5ODAgIDEwMDAgIDEwMDAgIDEwMDY2NCAgMTQgICAgICAgIGAKK0hlbGxvLCB3b3JsZCEKKy8zMCAgICAgICAgICAgICAxNDU0Njk0MDE2ICAxMDAwICAxMDAwICAxMDA2NjQgIDQgICAgICAgICBgCitCeWUKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9sb25ncGF0aC9jeWd3aW5fZ251LnRhciBiL3NyYy90ZXN0L3Jlc291cmNlcy9sb25ncGF0aC9jeWd3aW5fZ251LnRhcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hOTkyZjQ1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2xvbmdwYXRoL2N5Z3dpbl9nbnUudGFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9sb25ncGF0aC9jeWd3aW5fb2xkZ251LnRhciBiL3NyYy90ZXN0L3Jlc291cmNlcy9sb25ncGF0aC9jeWd3aW5fb2xkZ251LnRhcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kZTg4MjRhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2xvbmdwYXRoL2N5Z3dpbl9vbGRnbnUudGFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9sb25ncGF0aC9jeWd3aW5fcGF4LnRhciBiL3NyYy90ZXN0L3Jlc291cmNlcy9sb25ncGF0aC9jeWd3aW5fcGF4LnRhcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lZjM4NGIyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2xvbmdwYXRoL2N5Z3dpbl9wYXgudGFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9sb25ncGF0aC9jeWd3aW5fcG9zaXgudGFyIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2xvbmdwYXRoL2N5Z3dpbl9wb3NpeC50YXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTJmNGNiOQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9sb25ncGF0aC9jeWd3aW5fcG9zaXgudGFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9sb25ncGF0aC9jeWd3aW5fdXN0YXIudGFyIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2xvbmdwYXRoL2N5Z3dpbl91c3Rhci50YXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjBhZTgyZgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9sb25ncGF0aC9jeWd3aW5fdXN0YXIudGFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9sb25ncGF0aC9maWxlcy50eHQgYi9zcmMvdGVzdC9yZXNvdXJjZXMvbG9uZ3BhdGgvZmlsZXMudHh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmViYTZiNjUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvbG9uZ3BhdGgvZmlsZXMudHh0CkBAIC0wLDAgKzEsNDIgQEAKKyMgICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyMgICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyMgICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisjICAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyMgICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorIyAgIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisjIAorIyAgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyMgCisjICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorIyAgIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisjICAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisjICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorIyAgIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorIworIworIyAgIEZpbGUgcHJlZml4ZXMgY29ycmVzcG9uZCB0byB0aGUgZm9sbG93aW5nIE9TZXM6CisjICAgY3lnd2luIC0gQ1lHV0lOX05ULTUuMSAxLjcuMSgwLjIxOC81LzMpCisjICAgaHVkc29uIC0gU3VuT1MgNS4xMAorIyAgIG1pbm90YXVyIC0gRnJlZUJTRCA4LjAtU1RBQkxFCisjICAgdm1ndW1wIC0gTGludXggMi42LjI0LTI3LXNlcnZlciAKKyMgICB3aW5YUF9hbnQgLSBBbnQgMS43LjEgb24gV2luZG93cy9YUAorIworY29tcHJlc3MtdGVzdC8KK2NvbXByZXNzLXRlc3QvZGlyMS8KK2NvbXByZXNzLXRlc3QvZGlyMS9kaXIyLworY29tcHJlc3MtdGVzdC9kaXIxL2RpcjIvZGlyMy8KK2NvbXByZXNzLXRlc3QvZGlyMS9kaXIyL2RpcjMvZGlyNC8KK2NvbXByZXNzLXRlc3QvZGlyMS9kaXIyL2RpcjMvZGlyNC9kaXI1LworY29tcHJlc3MtdGVzdC9kaXIxL2RpcjIvZGlyMy9kaXI0L2RpcjUvZGlyNi8KK2NvbXByZXNzLXRlc3QvZGlyMS9kaXIyL2RpcjMvZGlyNC9kaXI1L2RpcjYvZGlyNy8KK2NvbXByZXNzLXRlc3QvZGlyMS9kaXIyL2RpcjMvZGlyNC9kaXI1L2RpcjYvZGlyNy9kaXI4LworY29tcHJlc3MtdGVzdC9kaXIxL2RpcjIvZGlyMy9kaXI0L2RpcjUvZGlyNi9kaXI3L2RpcjgvZGlyOS8KK2NvbXByZXNzLXRlc3QvZGlyMS9kaXIyL2RpcjMvZGlyNC9kaXI1L2RpcjYvZGlyNy9kaXI4L2RpcjkvZGlyMTAvCitjb21wcmVzcy10ZXN0L2RpcjEvZGlyMi9kaXIzL2RpcjQvZGlyNS9kaXI2L2RpcjcvZGlyOC9kaXI5L2RpcjEwL2ZpbGUxMjM0NTY3ODkwMTIzNDU2Nzg5MC50eHQKK2NvbXByZXNzLXRlc3QvZGlyMS9kaXIyL2RpcjMvZGlyNC9kaXI1L2RpcjYvZGlyNy9kaXI4L2RpcjkvZGlyMTAvZmlsZTEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAudHh0Citjb21wcmVzcy10ZXN0L2RpcjEvZGlyMi9kaXIzL2RpcjQvZGlyNS9kaXI2L2RpcjcvZGlyOC9kaXI5L2RpcjEwL2ZpbGUxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAudHh0Citjb21wcmVzcy10ZXN0L2RpcjEvZGlyMi9kaXIzL2RpcjQvZGlyNS9kaXI2L2RpcjcvZGlyOC9kaXI5L2RpcjEwL2ZpbGUudHh0Citjb21wcmVzcy10ZXN0L2RpcjEvZGlyMi9kaXIzL2RpcjQvZGlyNS9kaXI2L2RpcjcvZGlyOC9kaXI5L2RpcjEwL2ZpbGUxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAudHh0Citjb21wcmVzcy10ZXN0L2RpcjEvZGlyMi9kaXIzL2RpcjQvZGlyNS9kaXI2L2RpcjcvZGlyOC9kaXI5L2RpcjEwL2ZpbGUxMjM0NTY3ODkwLnR4dAorY29tcHJlc3MtdGVzdC9kaXIxL2RpcjIvZGlyMy9kaXI0L2RpcjUvZGlyNi9kaXI3L2RpcjgvZGlyOS9kaXIxMC9maWxlMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MC50eHQKK2NvbXByZXNzLXRlc3QvZGlyMS9kaXIyL2RpcjMvZGlyNC9kaXI1L2RpcjYvZGlyNy9kaXI4L2RpcjkvZGlyMTAvZmlsZTEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwLnR4dApcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9sb25ncGF0aC9odWRzb24tRS50YXIgYi9zcmMvdGVzdC9yZXNvdXJjZXMvbG9uZ3BhdGgvaHVkc29uLUUudGFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFmY2M4NzAKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvbG9uZ3BhdGgvaHVkc29uLUUudGFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9sb25ncGF0aC9odWRzb24udGFyIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2xvbmdwYXRoL2h1ZHNvbi50YXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGZhNzMzMAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9sb25ncGF0aC9odWRzb24udGFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9sb25ncGF0aC9taW5vdGF1ci0wLmphciBiL3NyYy90ZXN0L3Jlc291cmNlcy9sb25ncGF0aC9taW5vdGF1ci0wLmphcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MzM0NmNhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2xvbmdwYXRoL21pbm90YXVyLTAuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9sb25ncGF0aC9taW5vdGF1ci1NLmphciBiL3NyYy90ZXN0L3Jlc291cmNlcy9sb25ncGF0aC9taW5vdGF1ci1NLmphcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MTU3MjRhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2xvbmdwYXRoL21pbm90YXVyLU0uamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9sb25ncGF0aC9taW5vdGF1ci1jLnppcCBiL3NyYy90ZXN0L3Jlc291cmNlcy9sb25ncGF0aC9taW5vdGF1ci1jLnppcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MDNiNzAwCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2xvbmdwYXRoL21pbm90YXVyLWMuemlwCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9sb25ncGF0aC9taW5vdGF1ci16LnppcCBiL3NyYy90ZXN0L3Jlc291cmNlcy9sb25ncGF0aC9taW5vdGF1ci16LnppcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xYWI5YjJlCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2xvbmdwYXRoL21pbm90YXVyLXouemlwCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9sb25ncGF0aC9taW5vdGF1ci5hciBiL3NyYy90ZXN0L3Jlc291cmNlcy9sb25ncGF0aC9taW5vdGF1ci5hcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iMjY1MzJiCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2xvbmdwYXRoL21pbm90YXVyLmFyCkBAIC0wLDAgKzEsMTcgQEAKKyE8YXJjaD4KKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDM1MCAgICAgICBgCitmaWxlMTIzNDU2Nzg5MDEyMzQ1Njc4OTAudHh0LworZmlsZTEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAudHh0LworZmlsZTEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MC50eHQvCitmaWxlMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwLnR4dC8KK2ZpbGUxMjM0NTY3ODkwLnR4dC8KK2ZpbGUxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwLnR4dC8KK2ZpbGUxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MC50eHQvCisvMCAgICAgICAgICAgICAgMTI3MzMxOTgxMSAgMTcyMSAgMTcyMSAgMTAwNjY0ICAwICAgICAgICAgYAorLzMwICAgICAgICAgICAgIDEyNzMzMTk4NDIgIDE3MjEgIDE3MjEgIDEwMDY2NCAgMCAgICAgICAgIGAKKy8xMTAgICAgICAgICAgICAxMjczMzE5ODM1ICAxNzIxICAxNzIxICAxMDA2NjQgIDAgICAgICAgICBgCitmaWxlLnR4dC8gICAgICAgMTI3MzMxOTc3NyAgMTcyMSAgMTcyMSAgMTAwNjY0ICAwICAgICAgICAgYAorLzE4MCAgICAgICAgICAgIDEyNzMzMTk4MTcgIDE3MjEgIDE3MjEgIDEwMDY2NCAgMCAgICAgICAgIGAKKy8yMjAgICAgICAgICAgICAxMjczMzE5Nzk0ICAxNzIxICAxNzIxICAxMDA2NjQgIDAgICAgICAgICBgCisvMjQwICAgICAgICAgICAgMTI3MzMxOTgyMyAgMTcyMSAgMTcyMSAgMTAwNjY0ICAwICAgICAgICAgYAorLzI5MCAgICAgICAgICAgIDEyNzMzMTk4MjggIDE3MjEgIDE3MjEgIDEwMDY2NCAgMCAgICAgICAgIGAKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9sb25ncGF0aC9taW5vdGF1ci5jcGlvIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2xvbmdwYXRoL21pbm90YXVyLmNwaW8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDQ0NWRjNgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9sb25ncGF0aC9taW5vdGF1ci5jcGlvCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9sb25ncGF0aC9taW5vdGF1ci5qYXIgYi9zcmMvdGVzdC9yZXNvdXJjZXMvbG9uZ3BhdGgvbWlub3RhdXIuamFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ4MGQxYjkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvbG9uZ3BhdGgvbWlub3RhdXIuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9sb25ncGF0aC9taW5vdGF1ci56aXAgYi9zcmMvdGVzdC9yZXNvdXJjZXMvbG9uZ3BhdGgvbWlub3RhdXIuemlwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgyYTY3OTAKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvbG9uZ3BhdGgvbWlub3RhdXIuemlwCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9sb25ncGF0aC9taW5vdGF1cl9wYXgudGFyIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2xvbmdwYXRoL21pbm90YXVyX3BheC50YXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGQ0NDhiZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9sb25ncGF0aC9taW5vdGF1cl9wYXgudGFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9sb25ncGF0aC9taW5vdGF1cl9wb3NpeC50YXIgYi9zcmMvdGVzdC9yZXNvdXJjZXMvbG9uZ3BhdGgvbWlub3RhdXJfcG9zaXgudGFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU4M2NlN2MKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvbG9uZ3BhdGgvbWlub3RhdXJfcG9zaXgudGFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9sb25ncGF0aC9taW5vdGF1cl91c3Rhci50YXIgYi9zcmMvdGVzdC9yZXNvdXJjZXMvbG9uZ3BhdGgvbWlub3RhdXJfdXN0YXIudGFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY3OTMwY2EKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvbG9uZ3BhdGgvbWlub3RhdXJfdXN0YXIudGFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9sb25ncGF0aC92bWd1bXBfZ251LnRhciBiL3NyYy90ZXN0L3Jlc291cmNlcy9sb25ncGF0aC92bWd1bXBfZ251LnRhcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNTViNGJlCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2xvbmdwYXRoL3ZtZ3VtcF9nbnUudGFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9sb25ncGF0aC92bWd1bXBfb2xkZ251LnRhciBiL3NyYy90ZXN0L3Jlc291cmNlcy9sb25ncGF0aC92bWd1bXBfb2xkZ251LnRhcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMDA4OWQyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2xvbmdwYXRoL3ZtZ3VtcF9vbGRnbnUudGFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9sb25ncGF0aC92bWd1bXBfcGF4LnRhciBiL3NyYy90ZXN0L3Jlc291cmNlcy9sb25ncGF0aC92bWd1bXBfcGF4LnRhcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMzc0ZjgyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2xvbmdwYXRoL3ZtZ3VtcF9wYXgudGFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9sb25ncGF0aC92bWd1bXBfcG9zaXgudGFyIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2xvbmdwYXRoL3ZtZ3VtcF9wb3NpeC50YXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDFhYzJhYQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9sb25ncGF0aC92bWd1bXBfcG9zaXgudGFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9sb25ncGF0aC92bWd1bXBfdXN0YXIudGFyIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2xvbmdwYXRoL3ZtZ3VtcF91c3Rhci50YXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGQzOTRhZAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9sb25ncGF0aC92bWd1bXBfdXN0YXIudGFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9sb25ncGF0aC93aW5YUF9hbnRnbnUudGFyIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2xvbmdwYXRoL3dpblhQX2FudGdudS50YXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjMyMWMxMwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9sb25ncGF0aC93aW5YUF9hbnRnbnUudGFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy9sb25nc3ltbGluay9maWxlcy50eHQgYi9zcmMvdGVzdC9yZXNvdXJjZXMvbG9uZ3N5bWxpbmsvZmlsZXMudHh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJhZjBhZmQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvbG9uZ3N5bWxpbmsvZmlsZXMudHh0CkBAIC0wLDAgKzEgQEAKKzB4eHh4eHh4eHgxMHh4eHh4eHh4MjB4eHh4eHh4eDMweHh4eHh4eHg0MHh4eHh4eHh4NTB4eHh4eHh4eDYweHh4eHh4eHg3MHh4eHh4eHh4ODB4eHh4eHh4eDkweHh4eHh4eHgxMDB4eHh4eHh4MTEweHh4eHh4eDEyMHh4eHh4eHgxMzB4eHh4eHh4IC0+IDB5eXl5eXl5eXkxMHl5eXl5eXl5MjB5eXl5eXl5eTMweXl5eXl5eXk0MHl5eXl5eXl5NTB5eXl5eXl5eTYweXl5eXl5eXk3MHl5eXl5eXl5ODB5eXl5eXl5eTkweXl5eXl5eXkxMDB5eXl5eXl5MTEweXl5eXl5eTEyMHl5eXl5eXkxMzB5eXl5eXl5CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvbG9uZ3N5bWxpbmsvZ251LnRhciBiL3NyYy90ZXN0L3Jlc291cmNlcy9sb25nc3ltbGluay9nbnUudGFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI3NDdmMTEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvbG9uZ3N5bWxpbmsvZ251LnRhcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvbG9yZW0taXBzdW0udHh0Lmd6IGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2xvcmVtLWlwc3VtLnR4dC5negpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41YjQyZDhlCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2xvcmVtLWlwc3VtLnR4dC5negpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvbG9yZW0taXBzdW0udHh0LnN6IGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2xvcmVtLWlwc3VtLnR4dC5zegpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45YTZiMWZiCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL2xvcmVtLWlwc3VtLnR4dC5zegpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvbWl4ZWQudHh0LnN6IGIvc3JjL3Rlc3QvcmVzb3VyY2VzL21peGVkLnR4dC5zegpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40ZDIxZDM5Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL21peGVkLnR4dC5zegpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvbWl4ZWQuemlwIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL21peGVkLnppcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hMzZmMmFmCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL21peGVkLnppcApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvbW9ieS1pbXBsb2RlZC56aXAgYi9zcmMvdGVzdC9yZXNvdXJjZXMvbW9ieS1pbXBsb2RlZC56aXAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzFkYWM0MwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9tb2J5LWltcGxvZGVkLnppcApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvbW9ieS56aXAgYi9zcmMvdGVzdC9yZXNvdXJjZXMvbW9ieS56aXAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWUzZjllZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9tb2J5LnppcApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvbXVsdGlwbGUuYnoyIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL211bHRpcGxlLmJ6MgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNmRjM2E3Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL211bHRpcGxlLmJ6MgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvbXVsdGlwbGUuZ3ogYi9zcmMvdGVzdC9yZXNvdXJjZXMvbXVsdGlwbGUuZ3oKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjVmZDA2NwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9tdWx0aXBsZS5negpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvbXVsdGlwbGUueHogYi9zcmMvdGVzdC9yZXNvdXJjZXMvbXVsdGlwbGUueHoKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWQyMjU2YgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9tdWx0aXBsZS54egpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvb2xkZ251X3NwYXJzZS50YXIgYi9zcmMvdGVzdC9yZXNvdXJjZXMvb2xkZ251X3NwYXJzZS50YXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjk5NTM0MwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9vbGRnbnVfc3BhcnNlLnRhcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvb3JkZXJ0ZXN0LnppcCBiL3NyYy90ZXN0L3Jlc291cmNlcy9vcmRlcnRlc3QuemlwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjUyMTE1OGEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvb3JkZXJ0ZXN0LnppcApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvcGFzc3dvcmQtZW5jcnlwdGVkLnppcCBiL3NyYy90ZXN0L3Jlc291cmNlcy9wYXNzd29yZC1lbmNyeXB0ZWQuemlwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkzOTAyOWMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvcGFzc3dvcmQtZW5jcnlwdGVkLnppcApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvcGF4X2dudV9zcGFyc2UudGFyIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL3BheF9nbnVfc3BhcnNlLnRhcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMWZiNGRkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL3BheF9nbnVfc3BhcnNlLnRhcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvcG9zaXgwMF9zcGFyc2UudGFyIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL3Bvc2l4MDBfc3BhcnNlLnRhcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43MDE5OWY0Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL3Bvc2l4MDBfc3BhcnNlLnRhcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvcG9zaXgwMV9zcGFyc2UudGFyIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL3Bvc2l4MDFfc3BhcnNlLnRhcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44YjQzNzMyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL3Bvc2l4MDFfc3BhcnNlLnRhcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvcG9zaXgxMF9zcGFyc2UudGFyIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL3Bvc2l4MTBfc3BhcnNlLnRhcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lN2FjMzhkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL3Bvc2l4MTBfc3BhcnNlLnRhcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvcHJlZXBvY2gtcG9zaXgudGFyIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL3ByZWVwb2NoLXBvc2l4LnRhcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lOWE4OWMzCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL3ByZWVwb2NoLXBvc2l4LnRhcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvcHJlZXBvY2gtc3Rhci50YXIgYi9zcmMvdGVzdC9yZXNvdXJjZXMvcHJlZXBvY2gtc3Rhci50YXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDk5ZWM4ZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy9wcmVlcG9jaC1zdGFyLnRhcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvcmVkbGluZS5jcGlvIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL3JlZGxpbmUuY3BpbwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNzU0ZDczCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL3JlZGxpbmUuY3BpbwpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvc2ltcGxlLWFpeC1uYXRpdmUtdGFyLnRhciBiL3NyYy90ZXN0L3Jlc291cmNlcy9zaW1wbGUtYWl4LW5hdGl2ZS10YXIudGFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ4YjFkMTEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvc2ltcGxlLWFpeC1uYXRpdmUtdGFyLnRhcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvdGVzdCB3aXRoIHNwYWNlcy50eHQgYi9zcmMvdGVzdC9yZXNvdXJjZXMvdGVzdCB3aXRoIHNwYWNlcy50eHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjE1YzZhNAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0IHdpdGggc3BhY2VzLnR4dApAQCAtMCwwICsxLDExIEBACitURVNUIFdJVEggU1BBQ0VTIElOIEZJTEVOQU1FCisxMTExMTExMTExMTExMTExMTExMTExMTExMTEwMDAxMDEwMTEKKzExMTExMTExMTExMTExMTExMTExMTExMTExMTAwMDEwMTAxMQorMTExMTExMTExMTExMTExMTExMTExMTExMTExMDAwMTAxMDExCisxMTExMTExMTExMTExMTExMTExMTExMTExMTEwMDAxMDEwMTEKKzExMTExMTExMTExMTExMTExMTExMTExMTExMTAwMDEwMTAxMQorMTExMTExMTExMTExMTExMTExMTExMTExMTExMDAwMTAxMDExCisxMTExMTExMTExMTExMTExMTExMTExMTExMTEwMDAxMDEwMTEKKzExMTExMTExMTExMTExMTExMTExMTExMTExMTAwMDEwMTAxMQorMTExMTExMTExMTExMTExMTExMTExMTExMTExMDAwMTAxMDExCisxMTExMTExMTExMTExMTExMTExMTExMTExMTEwMDAxMDEwMTEKXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvdGVzdC13aW56aXAuemlwIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL3Rlc3Qtd2luemlwLnppcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40MWUzOWU3Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL3Rlc3Qtd2luemlwLnppcApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvdGVzdC50eHQgYi9zcmMvdGVzdC9yZXNvdXJjZXMvdGVzdC50eHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmVlY2I3NQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0LnR4dApAQCAtMCwwICsxLDEwIEBACisxMTExMTExMTExMTExMTExMTExMTExMTExMTEwMDAxMDEwMTEKKzExMTExMTExMTExMTExMTExMTExMTExMTExMTAwMDEwMTAxMQorMTExMTExMTExMTExMTExMTExMTExMTExMTExMDAwMTAxMDExCisxMTExMTExMTExMTExMTExMTExMTExMTExMTEwMDAxMDEwMTEKKzExMTExMTExMTExMTExMTExMTExMTExMTExMTAwMDEwMTAxMQorMTExMTExMTExMTExMTExMTExMTExMTExMTExMDAwMTAxMDExCisxMTExMTExMTExMTExMTExMTExMTExMTExMTEwMDAxMDEwMTEKKzExMTExMTExMTExMTExMTExMTExMTExMTExMTAwMDEwMTAxMQorMTExMTExMTExMTExMTExMTExMTExMTExMTExMDAwMTAxMDExCisxMTExMTExMTExMTExMTExMTExMTExMTExMTEwMDAxMDEwMTEKXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvdGVzdDEueG1sIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL3Rlc3QxLnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNjkwYzE5Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL3Rlc3QxLnhtbApAQCAtMCwwICsxLDQgQEAKKzw/eG1sIHZlcnNpb24gPSAnMS4wJz8+Cis8IURPQ1RZUEUgY29ubmVjdGlvbnM+Cis8Y29ubmVjdGlvbnM+Cis8L2Nvbm5lY3Rpb25zPgpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvcmVzb3VyY2VzL3Rlc3QyLnhtbCBiL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0Mi54bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGM5ZGRkMAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0Mi54bWwKQEAgLTAsMCArMSw1IEBACis8P3htbCB2ZXJzaW9uID0gJzEuMCc/PgorPCFET0NUWVBFIGNvbm5lY3Rpb25zPgorPG1laW54bWw+CisgICAgPGxlZXIgLz4KKzwvbWVpbnhtbD4KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0My54bWwgYi9zcmMvdGVzdC9yZXNvdXJjZXMvdGVzdDMueG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIzNGM1YjcKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvdGVzdDMueG1sCkBAIC0wLDAgKzEsMTAgQEAKKzw/eG1sIHZlcnNpb24gPSAnMS4wJz8+Cis8IURPQ1RZUEUgY29ubmVjdGlvbnM+Cis8dGV4dD4KK0xvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZXRldHVyIHNhZGlwc2NpbmcgZWxpdHIsIAorc2VkIGRpYW0gbm9udW15IGVpcm1vZCB0ZW1wb3IgaW52aWR1bnQgdXQgbGFib3JlIGV0IGRvbG9yZSBtYWduYSBhbGlxdXlhbSBlcmF0LCAKK3NlZCBkaWFtIHZvbHVwdHVhLiAKK0F0IHZlcm8gZW9zIGV0IGFjY3VzYW0gZXQganVzdG8gZHVvIGRvbG9yZXMgZXQgZWEgcmVidW0uIAorU3RldCBjbGl0YSBrYXNkIGd1YmVyZ3Jlbiwgbm8gc2VhIHRha2ltYXRhIHNhbmN0dXMgZXN0IAorTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQuCis8L3RleHQ+CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZXNvdXJjZXMvdGVzdDQueG1sIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL3Rlc3Q0LnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMzJjOWQxCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL3Rlc3Q0LnhtbApAQCAtMCwwICsxLDYgQEAKKzw/eG1sIHZlcnNpb24gPSAnMS4wJz8+Cis8IURPQ1RZUEUgY29ubmVjdGlvbnM+Cis8Y29ubmVjdGlvbnM+CitHZXJtYW4gVW1sYXV0czogw5zDhMOWw58KK1N0b3JlZCBhcyBVVEYtOCAoTWFjIE9TWCAxMC40LngpCis8L2Nvbm5lY3Rpb25zPgpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvcmVzb3VyY2VzL3Rlc3RBSUZGLmFpZiBiL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0QUlGRi5haWYKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTdlYWMxZAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0QUlGRi5haWYKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvcmVzb3VyY2VzL3Rlc3RDb21wcmVzczIwOS5kb2MgYi9zcmMvdGVzdC9yZXNvdXJjZXMvdGVzdENvbXByZXNzMjA5LmRvYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NzFkMzBkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL3Rlc3RDb21wcmVzczIwOS5kb2MKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvcmVzb3VyY2VzL3Rlc3ROdW1iZXJzTmV3Lm51bWJlcnMgYi9zcmMvdGVzdC9yZXNvdXJjZXMvdGVzdE51bWJlcnNOZXcubnVtYmVycwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zZjlhMDEzCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL3Rlc3ROdW1iZXJzTmV3Lm51bWJlcnMKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvcmVzb3VyY2VzL3V0ZjgtN3ppcC10ZXN0LnppcCBiL3NyYy90ZXN0L3Jlc291cmNlcy91dGY4LTd6aXAtdGVzdC56aXAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmM4Njc3MwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy91dGY4LTd6aXAtdGVzdC56aXAKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvcmVzb3VyY2VzL3V0Zjgtd2luemlwLXRlc3QuemlwIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL3V0Zjgtd2luemlwLXRlc3QuemlwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMyNjEwMDQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvdXRmOC13aW56aXAtdGVzdC56aXAKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvcmVzb3VyY2VzL3ppcDY0c3VwcG9ydC50YXIuYnoyIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL3ppcDY0c3VwcG9ydC50YXIuYnoyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRiYzU5MDcKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvemlwNjRzdXBwb3J0LnRhci5iejIKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvcmVzb3VyY2VzL3ppcGJvbWIueGxzeCBiL3NyYy90ZXN0L3Jlc291cmNlcy96aXBib21iLnhsc3gKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDZhNDIxMQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy96aXBib21iLnhsc3gKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvcmVzb3VyY2VzL3pzdGQtdGVzdHMudGFyIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL3pzdGQtdGVzdHMudGFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQzMDY3ZmQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9yZXNvdXJjZXMvenN0ZC10ZXN0cy50YXIKQmluYXJ5IGZpbGVzIGRpZmZlcgo=